11 · 字符串 ★C 与 Java 差异最大处
C 没有 String 类! 字符串就是「以
'\0'结尾的 char 数组」,一切操作靠函数手工完成。
两种写法(务必区分)
char a[] = "hello"; // 字符数组:可修改,占 6 字节(含 '\0')
char *p = "hello"; // 指向字符串字面量:内容在只读区,❌ 不能改!
a[0] = 'H'; // ✅ 合法
p[0] = 'H'; // 💥 崩溃(只读内存,未定义行为)
内存真相
"hello" → 'h' 'e' 'l' 'l' 'o' '\0'
↑ 这个 0 是字符串能工作的全部秘密
- 所有字符串函数都靠扫描
'\0'来判断结尾。 - 忘了
'\0'→ 函数会一直读到越界,输出乱码。
string.h 常用函数(背下来)
| 函数 | 作用 | 坑 |
|---|---|---|
strlen(s) |
长度(不含 '\0') | |
strcpy(dst, src) |
复制 | ⚠️ 不检查 dst 容量,会溢出 |
strcat(dst, src) |
拼接 | ⚠️ 同样不安全 |
strcmp(a, b) |
比较 | 返回 0 表示相等(不是 1!) |
strchr(s, c) |
查找字符 | 返回指针 |
strstr(s, sub) |
查找子串 | 返回指针 |
strncpy/strncat |
带长度版本 | 相对安全 |
fgets(buf, n, stdin) |
安全读一行 | 比 gets 安全 |
#include <string.h>
char s[20] = "hello";
printf("%zu\n", strlen(s)); // 5(不含 '\0')
strcat(s, ", world"); // s = "hello, world"
if (strcmp(s, "hello, world") == 0) printf("相等\n");
手写 strLen(理解 '\0' 必做练习)
size_t my_strlen(const char *s) {
size_t n = 0;
while (s[n] != '\0') n++; // 一直数到 '\0'
return n;
}
⚡ Java 对比
| Java | C | |
|---|---|---|
| 类型 | String 对象 |
char[] + '\0' |
| 不可变 | 不可变 | 字面量只读,数组可改 |
| 长度 | s.length() |
strlen(s) |
| 比较 | s.equals(t) |
strcmp(s,t)==0 |
| 拼接 | + |
strcat(先保证空间够) |
| 越界 | 抛异常 | 未定义行为 |
常见坑
char s[5] = "hello";→ 装不下(要 6 字节),编译能过但无终止符。strcmp返回 0 才是相等,很多人写成if (strcmp(a,b))意思正好相反。- 用
==比较字符串,比的是地址不是内容,永远是错的。
关联
08-数组 · 09-指针 · 20-未定义行为与安全函数