项目场景:
出现这种问题一般都是数据越界所造成的,下面将以字符串输出中因忽略‘\0’的作用所造成的越界问题
相信很多刚接触C语言的小伙伴们在学习整型、浮点型都自我感觉还不错,但随之而来的字符类型字符串的学习,我们往往都会感觉到一阵头大,特别是当自己跃跃欲试尝试着自己输出的时候发现自己的输出结果会和自己预料的相差很大,其实出现这些问题的很大一部分原因是因为隐藏在暗处的‘\0’在作怪,理解好‘\0’的作用,可以说对我们的帮助是非常大的。
以下我将结合一些实际中经常出现的问题,带着大家一起来探索‘\0’的作用:
问题描述
使用%s的形式输出char类型的数组时出现:‘烫烫??(鶆’
代码:
#include
//#include
int main()
{
char str[] = { 'a', 'b', 'c', 'd'};
printf("%s\n", str);
return 0;
}
输出结果:
原因分析:
‘\0’作用就相当于实际生活中十字路口出的红灯,是读取数据内容结束的标志,每当程序运行内容遇到它时,那么读取操作就会停止了,输出的内容将是‘\0’这个字符前面的内容
例如在上述的实例问题中,所声明的str字符型数组中并没有写入‘\0’这个元素,也就意味着打印输出的这段字符串内容没有结束的标志,这是非常危险的。
因为每当我们声明一个数组时,计算机会为我们在内存中随机的分配一段空间来存储我们的数组内容,没有了‘\0’的阻止,就意味着我们程序会继续读取后面的内容并打印出来,直至遇到下个‘\0’才结束,这也是为什么输出结果中除了有我们想要输出的内容之外,还存在 ‘烫烫??(鶆’ 这些内容。
解决方案:
方法一:在数组元素后面直接添加‘\0’
方法二:取消大括号,直接赋值一段双引号的字符串
方法一:
通过查看数组长度来验证一下我们上面所分析的原因:
#include
#include
int main()
{
char str1[] = { 'a', 'b', 'c', 'd'};
char str2[] = { 'a', 'b', 'c', 'd', '\0'};
printf("str1长度为:%d\n", strlen(str1));
printf("str2长度为:%d\n", strlen(str2));
return 0;
}
输出结果:
从结果可以看出,str1的结果并不符合实际长度4,这也说明了多读取了后面的内容,直至读取位置第16字节的时候才遇到了‘\0’结束
问题反思:为什么str2的长度也是4,‘\0’字符不占用空间吗?
首先我们得明确,‘\0’他是客观存在的,和普通一样占用1个字节的空间,但strlen()读取的内容是它之前部分
我们可以通过sizeof()函数来查看str2的数组长度:
#include
#include
int main()
{
//char str1[] = { 'a', 'b', 'c', 'd'};
char str2[] = { 'a', 'b', 'c', 'd', '\0'};
//printf("str1长度为:%d\n", strlen(str1));
printf("str2长度为:%d\n", sizeof(str2));
return 0;
结果:
思维拓展:
我通过上述的实例情况可以知道‘\0’是可以影响字符串元素输出的得多少,只输出其前面的内容,因此如果在char型数组中间添加‘\0’,是可以控制我们想要输出的内容的
哈哈哈,好像也没啥用
方法二:
#include
#include
int main()
{
char str[] = "abcdef";
printf("%s", str);
return 0;
}
通过观察,我们发现可以正常输出。这是因为这样声明的时候系统会在字符串后面自动添加‘\0’,但是他并没有显示出来。
我们可以通过Visual Studio 编辑器的调试功能来查看一下:
可以看到最后是以‘\0’来结束的,这也是我比较推荐的一种声明方法
注意:
前面我们提到了‘\0’,同样占用空间,因此在用这种方法声明的时候,我们得注意分配空间是否足够,否则会出现数组元素越界的错误