第十三章、字符串
字符串 是用来记录人类的文字信息的一种数据类型,在 C 语言中没有内置定义字符串类型,我们通常使用字符型一维数组来存储字符串信息。
1. 字符串和存储结构
字符串有两种存储方式:
- 字面值
- 字符型数组
字符串的字面值
字符串字面值用双引号(") 括起来的字符序列。如:
"Hello World!"
"name:%s, age:%d\n"
字符串的字面值中,每一个字符都是使用字符的字面值构成,如上述示例中的 \n就是换行符的转义。
如果有些字符无法表示,则需要使用转义字符,如:
"I'm \"laowei\""
"这是UTF8编码的\"中文\"两个字(\xe4\xb8\xad\xe6\x96\x87)"
"这是GBK编码的\"中文\"两个字(\xd6\xd0\xce\xc4)"
C 语言的字符串在内存中的存储方式如下:
- 字符串在内存中是以字符型一维数组进行存储的。
- C 语言的字符串规定以 零字符
'\0'作为结束标志。
如字符串 laowei 在内存中的物理存储结构,如下:
----+-----+-----+-----+-----+-----+-----+-----+----
... | 'l' | 'a' | 'o' | 'w' | 'e' | 'i' | '\0'| ...
----+-----+-----+-----+-----+-----+-----+-----+----
可见字符串 "laowei" 实际占用的字节数是 7 个字节(尾零占用一个字节)。
字符串的字面值的返回值是字符串字面值的起始地址,类型是 const char * 类型的指针。字符串的字面值在编译过程中它会尽可能放在只读存储区,因此对字符串字面值进行修改可能会产生不可预知的结果。
字符型数组
如果需要对字符串进行存储和修改,则需要用字符型数组来存储字符串。下面我们来说一下字符型数组的定义方式和初始化方法。
char s1[] = "hello"; // s1 包含尾零,共6字节。
char s2[30] = "hello"; // s2 前 5 个字节为"hello" 后面为字符0,共30字节,
char s3[] = {'h', 'e', 'l', 'l', 'o'}; // s3 不包含尾零,共5字节。
char s4[10]; // s4 长度为 10,每个字节的数值不确定。
示例:
// filename : char_array.c
#include <stdio.h>
int main(int argc, char *argv[]) {
char s1[] = "hello";
char s2[30] = "hello";
char s3[] = {'h', 'e', 'l', 'l', 'o'};
char s4[10];
printf("sizeof(s1): %ld\n", sizeof(s1));
printf("sizeof(s2): %ld\n", sizeof(s2));
printf("sizeof(s3): %ld\n", sizeof(s3));
printf("sizeof(s4): %ld\n", sizeof(s4));
return 0;
}
运行结果如下:
weimingze@mzstudio:~$ gcc -o char_array char_array.c
weimingze@mzstudio:~$ ./char_array
sizeof(s1): 6
sizeof(s2): 30
sizeof(s3): 5
sizeof(s4): 10