嵌入式自学 Day07:我踩过的 6 个字符串坑——strlen、sizeof、\0、gets 全讲透
这是我的嵌入式自学Day07。
前几天一直在学数组,我以为字符数组不过是「存字符的数组」。
直到写出这样一段代码:
chars[10]="hello";printf("%d\n",strlen(s));printf("%d\n",sizeof(s));我本来以为两个都会输出10。
结果程序却打印:
5 10当时第一反应就是:
数组长度明明是10,为什么 strlen 却只有5?
后来才发现,我一直把字符数组和字符串混为一谈了。
今天就把我踩过的几个坑整理出来,希望刚学 C 的朋友少绕一点弯路。
坑一:字符数组 ≠ 字符串
很多人第一次都会觉得:
char 数组就是字符串。
其实不是。
例如:
chars[10]="hello";内存真正存的是:
下标: 0 1 2 3 4 5 6 7 8 9 内容: h e l l o \0 ? ? ? ?数组长度是10。
真正的字符串只有hello,因为它在\0就结束了。
为什么会错?
数组只是存储空间。
字符串其实是一段以\0结尾的数据。
正确代码
chars1[]="hello";chars2[10]="hello";s1长度是 6(包含\0)s2长度是 10
一句话总结
字符数组是容器,字符串只是容器里以
\0结束的一段内容。
坑二:别把\0当成普通字符
错误示例
chars[5]="hello";为什么错?
“hello” 实际需要 6 个字节(包含\0)。
正确代码
chars[6]="hello";// 或 char s[] = "hello";一句话总结
字符串真正结束的位置不是最后一个字母,而是
\0。
坑三:strlen 为什么不是 sizeof?
错误示例
chars[10]="hello";printf("%zu\n",strlen(s));printf("%zu\n",sizeof(s));为什么错?
strlen():统计\0前面的字符数sizeof():统计整个数组大小
输出:
strlen=5 sizeof=10一句话总结
strlen 看字符串长度,sizeof 看内存大小。
坑四:字符串不能直接用 = 复制
错误示例
chars1[]="hello";chars2[20];s2=s1;正确代码
chars1[]="hello";chars2[20];strcpy(s2,s1);一句话总结
字符串复制请用
strcpy()。
坑五:strcat() 不是无限拼接
错误示例
chars[10]="hello";strcat(s,"world");为什么错?
目标数组空间不足会越界。
正确代码
chars[20]="hello";strcat(s,"world");一句话总结
拼接前先确认目标数组容量。
坑六:gets() 为什么被淘汰?
错误示例
chars[10];gets(s);为什么错?
不会检查输入长度,容易数组越界。
正确代码
chars[10];fgets(s,sizeof(s),stdin);一句话总结
不要再使用 gets()。
今日避坑指南
- 字符数组不等于字符串
- 字符串必须以
\0结束 strlen()看字符串长度sizeof()看数组大小strcpy()复制字符串strcat()注意空间- 不要使用
gets()
今日学习感悟
真正理解字符串,不是记住几个函数,而是理解\0才是 C 字符串结束的标志。以后无论是串口、协议解析还是嵌入式开发,这都是必须掌握的基础。
下一篇预告:为什么冒泡排序这么慢?一篇讲透 C 语言三种经典排序算法——排序算法专题,三种排序横向对比。