LV020-字符数组和字符串
一、什么是字符数组
元素的数据类型为字符类型的数组称为 字符数组,字符数组实际上是一系列字符的集合,例如:
c
char a[10]; /* 定义一个长度为 10 的一维字符数组 */
char b[2][10]; /* 定义一个 2 行 3 列的二维字符数组 */二、字符数组初始化
1. 一维字符数组
1.1 使用字符列表
c
char str1[4] = {'t', 'o', 'm'}; // 编译器自动添加 '\0',等效于 "tom\0"
char str2[3] = {'t', 'o', 'm'}; // 无 '\0',不可作为字符串操作
char str3[] = {'j', 'a', 'c', 'k'}; // 省略长度,逐个字符赋值, 数组大小为 4,无 '\0'
char str4[3] = {'a', 'b', 'c', 'd'}; // 编译警告:数组大小为 3,元素超过 3 个在使用字符列表初始化字符数组时,\0 的添加规则如下:
- 若赋值的元素数量少于数组长度,未显式初始化部分自动填 \0(类似整型数组默认初始化为 0)。
- 若赋值的元素数量等于数组长度或未指定数组长度(由编译器自动推断),则不会自动添加 \0。
- 若赋值的元素数量超过数组长度,编译器会警告或报错。
注意:定义为局部变量的字符数组在未赋初值时,内容是随机的。
1.2 使用字面量
在 C 语言中,字符串字面量(如 "I am happy")在内存中以字符数组形式存储,并自动以空字符 '\0' 结尾。因此,可以直接用字符串字面量初始化字符数组,编译器会自动在末尾添加 '\0',无需手动处理。
c
char a[] = {"world!"}; /* 用字符串常量赋值 */
char a[] = "world!"; /* 用字符串常量赋值 */(1)给字符数组赋值时,通常将字符串一次性地赋值(可以指明数组长度,也可以不指明),而不是一个字符一个字符地赋值。
(2)字符数组 只有在定义时才能将整个字符串一次性地赋值 给它,一旦定义完了,就只能一个字符一个字符地赋值了。
(3)当使用字符串给字符数组赋值,且未给出长度时,创建的字符数组真实长度为 字符串长度 + 1,原因就在于用字符串进行赋值时,字符串结束处自带一个 字符串结束标志: \0。所以这也就意味着,我们若是要指定字符数组的大小,一定要留够 字符串长度 + 1 的长度,这样字符串才更加完整,也会比较严谨。
1.3 小结
| 字符数组声明形式 | 等价写法 |
| char a [3] = {'h', 'e', 'l'}; | char a [3]; a [0] = 'h'; a [1] = 'h'; a [2] = 'l'; |
| char a [3] = {'h'}; | char a [3]; a [0] = 'h'; a [1] = '\0'; a [2] = '\0'; |
| char a [3] = {"hel"}; | char a [3]; a [0] = 'h'; a [1] = 'e'; a [2] = 'l'; /* 这里若是长度定义为 4 就会更加合理 */ |
| char a [] = {"hel"}; | char a [4]; a [0] = 'h'; a [1] = 'e'; a [2] = 'l'; a [3] = '\0'; |
c
char fruit[][7]={"Apple", "Orange"};效果如下表
| 行名 | 每行元素 | ||||||
| fruit [0] | 'A' | 'p' | 'p' | 'l' | 'e' | '\0' | '\0' |
| fruit [1] | 'O' | 'r' | 'a' | 'r' | 'g' | 'e' | '\0' |
与一般的数组一样,访问元素时只能一个逐个字符访问,但是若是只输出的话要注意赋值方式的不同,输出时也会不一样。
1. 逐个字符访问输出
c
#include <stdio.h>
int main(int argc, const char *argv[])
{
char a[6] = { 'h', '\0', 'e', 'l', 'l','o'}; /* 逐个赋值,中间带有 '\0' */
char b[] = "h\0ello"; /* 字符串常量赋值, 中间带有 '\0' */
char c[] = "hello"; /* 字符串常量赋值, 中间没带有 '\0' */
int i, n;
printf("---------Character by character---------\n");
n = sizeof(a)/sizeof(char);
printf("\nlength(a)=%d\t",n);
for(i = 0; i < n; i++)
printf("%c",a[i]);
n = sizeof(b)/sizeof(char);
printf("\nlength(b)=%d\t",n);
for(i = 0; i < n; i++)
printf("%c",a[i]);
n = sizeof(c)/sizeof(char);
printf("\nlength(c)=%d\t",n);
for(i = 0; i < n; i++)
printf("%c",a[i]);
printf("\n------------------end------------------\n");
return 0;
}注意数组 b [] 打印是有问题的。
2. 以字符串的形式访问输出
c
#include <stdio.h>
int main(int argc, const char *argv[])
{
char a[6] = { 'h', 'e', 'l', '\0', 'l','o'}; /* 逐个赋值,中间带有 '\0' */
char b[6] = { 'h', 'e', 'l', 'l','o', '!'}; /* 逐个赋值,整个字符数组不带 '\0' */
char c[] = "h\0ello"; /* 字符串常量赋值, 中间带有 '\0' */
char d[] = "hello"; /* 字符串常量赋值, 中间没带有 '\0' */
int n;
printf("---------Character by character---------\n");
n = sizeof(a)/sizeof(char);
printf("length(a)=%d, a[6]=%s\n", n, a);
n = sizeof(b)/sizeof(char);
printf("length(b)=%d, b[]=%s\n", n, b);
n = sizeof(c)/sizeof(char);
printf("length(c)=%d,c[]=%s\n", n, c);
n = sizeof(d)/sizeof(char);
printf("length(d)=%d,c[]=%s\n", n, d);
printf("\n------------------end------------------\n");
return 0;
}
注意数组 b [] 打印是有问题的。
3. 小结
(1)注意字符数组中的 \0 ,当输出时,该字符会对输出结果造成影响。
(2)注意在字符数组逐个赋值时,若没有字符串结束标志 \0 ,那么尽量不要使用 printf 函数的 %s 格式进行输出,就如上面两个示例中的 b [] 数组
参考资料:
25 字符数组与字符串及多维数组详解:定义与初始化、访问与遍历、%s 格式符、内存剖析、编程实战_多维字符串数组怎么定义-CSDN博客