C语言数组是否以NULL结尾?新手如何不使用sizeof正确计算数组长度?
问题解答
核心结论:不是所有C语言数组都会以NULL结尾
只有用来表示字符串的char类型数组,才会以'\0'(ASCII值为0的字符,注意它和指针NULL概念不同,但数值均为0)作为结束标志——这是字符串的约定规则,而非数组的通用特性。其他类型的数组(比如你代码里的int数组),编译器不会自动添加任何结束标识,数组内存里仅包含你初始化的元素,超出部分是未知的垃圾数据。
你的代码为什么“偶尔有效”?
你写的循环通过a[i] != '\0'判断终止,但你的int数组{1,2,3,4,5,6,7,8,9}里根本没有0值,循环会持续越界访问数组后的内存,直到碰巧读到一个0才停止。你觉得“仅对元素个数为奇数的数组有效”完全是巧合——只是某次内存中数组后的第一个0出现的位置,刚好对应奇数个元素的长度,本质属于未定义行为,结果完全不可靠。
不用sizeof,如何正确计算数组长度?
分两种场景处理:
1. 在数组定义的同一作用域内
可以利用数组指针的特性计算:
#include <stdio.h> int main() { int a[] = {1,2,3,4,5,6,7,8,9}; // &a 是指向整个数组的指针,类型为 int(*)[9] // &a + 1 会跳转至数组末尾的下一个位置 // 与数组首地址a(自动转为int*类型)相减,结果即为元素个数 int size = (int)(&a + 1 - a); printf("size=%d\n", size); return 0; }
原理:指向数组的指针加1,偏移量是整个数组的大小;数组名作为首地址是指向单个元素的指针,同类型指针相减的结果为元素个数差。
2. 数组已退化为指针(如作为函数参数传递)
此时数组名会变成指向首元素的指针,丢失了数组长度信息,无法通过指针本身计算长度,必须:
- 手动将长度作为参数传递给函数;
- 或自行给数组添加哨兵值(比如约定最后一个元素为0,类似字符串的规则),但这需要你初始化数组时手动添加,并非数组自带特性。
小提醒:关于void main()
标准C中没有void main()的写法,规范写法是int main(),最后返回0表示程序正常结束。
内容的提问来源于stack exchange,提问作者Pranav Vasishta
相关产品推荐
相关产品推荐

