Skip to content

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';
### 2. 二维字符数组
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;
}

image-20260210154215805

注意数组 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;
}

image-20260210154328671

注意数组 b [] 打印是有问题的。

3. 小结

(1)注意字符数组中的 \0 ,当输出时,该字符会对输出结果造成影响。

(2)注意在字符数组逐个赋值时,若没有字符串结束标志 \0 ,那么尽量不要使用 printf 函数的 %s 格式进行输出,就如上面两个示例中的 b [] 数组

参考资料:

25 字符数组与字符串及多维数组详解:定义与初始化、访问与遍历、%s 格式符、内存剖析、编程实战_多维字符串数组怎么定义-CSDN博客