3
数组与字符串:C 里没有 string 类型
Arrays · Strings (char[])
Python 里 "hello" 就是个字符串,想用就用。C 不伺候——字符串就是一个 char 数组,而且必须以 '\0' 这个看不见的结束符收尾。这一点是 C 字符串一切坑的根源,务必记牢。
一维数组与二维数组
数组:一批同类型数据挤在连续的格子里
int nums[5] = {10, 20, 30, 40, 50}; // 长度为 5 的 int 数组
printf("%d\n", nums[0]); // 10 —— 下标从 0 开始,不是 1
nums[2] = 99; // 修改第三个元素
// 二维数组:可以理解成"表格"
int grid[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
printf("%d\n", grid[1][2]); // 6 —— 第 2 行第 3 列
字符数组与字符串:记住那个 \0
C 用 char[] 存字符串。"abc" 看起来是 3 个字符,实际占 4 个字节——末尾偷偷藏了一个 '\0'(ASCII 码 0)作为结束标记。所有字符串函数都靠这个 \0 判断"到头了",没它就会一直读到内存里去。
字符串的本质
char s1[] = "hello"; // 编译器自动帮你加 '\0',长度实际是 6
char s2[6] = {'h','e','l','l','o','\0'}; // 手动写,最后一个必须是 '\0'
// 下面这个是错的!数组只有 5 格,塞不下结束符 '\0'
// char bad[5] = "hello"; // 越界,printf 打印它会往后乱读
常用字符串函数(<string.h>)
| 函数 | 干什么 |
|---|---|
strlen(s) | 求字符串长度(不含末尾的 \0)。 |
strcpy(dst, src) | 把 src 复制到 dst。危险:dst 太小就溢出。 |
strncpy(dst, src, n) | 最多复制 n 个字符,比 strcpy 安全,但可能不加 \0。 |
strcmp(a, b) | 比较两个字符串,相等返回 0。别用 == 比字符串。 |
strcat(dst, src) | 把 src 接到 dst 尾巴上。 |
strstr(s, sub) | 在 s 里找子串 sub,找到返回位置,找不到返回 NULL。 |
sprintf(buf, ...) | 把格式化结果"打印"到字符串里,而不是屏幕。 |
实战:拼接、比较、求长度
#include <stdio.h>
#include <string.h>
int main() {
char name[20] = "C";
char msg[40];
strcat(name, " Language"); // name 变成 "C Language"
printf("长度 = %zu\n", strlen(name)); // 10("C Language" 共 10 个字符)
if (strcmp(name, "C Language") == 0) {
printf("字符串相等\n"); // 注意:用 strcmp,不是 ==
}
sprintf(msg, "你好,%s!", name); // 拼接到 msg 里
printf("%s\n", msg);
return 0;
}
运行结果
长度 = 11
字符串相等
你好,C Language!
数组退化成指针
数组名当函数参数传进去时,它会"退化"成指向首元素的指针,sizeof(数组) 再也拿不到真正的长度。所以:数组传进函数,长度必须另外当参数传进去。这就是为什么很多 C 函数都要收一个 size 参数。