C语言数组初始化疑问:为何count[]={0}报错而{0,0,0,0}正常?
数组初始化导致程序异常的原因
问题场景
我正在完成一项读取字符串并输出每个单词长度的练习,要求预先不知晓字符串中的单词数量(示例字符串为"viVa la VIDA loca",包含4个单词),编写了以下代码:
int textStats(char* filename); int main() { FILE*file; file=fopen("file","r"); if(file==NULL) { printf("Error in opening the file "); exit(1); } textStats(file); } int textStats(char* filename) { int i,j; int n=0; int N=20; char str[N]; while(fscanf(filename,"%c",&str[n])!=EOF) { n++; } for(i=0; i<n; i++) { printf("%c",str[i]); } i=j=0; int count[]={0}; while(str[i]!='\0') { if(isalpha(tolower(str[i]))) { count[j]++; } if(isspace(str[i])|| str[i]=='\0') { j++; } i++; } for(i=0;i<j;i++) { printf("word %d with count %d\n",i+1,count[i]); } }
核心疑问:为何将count数组初始化为count[]={0}时程序会报错,但初始化为count[]={0,0,0,0}时能得到正确结果?
原因解析
1. 数组初始化的实际效果
在C语言中:
int count[]={0};会创建一个长度仅为1的数组,只有count[0]被初始化为0,数组没有多余的存储空间。int count[]={0,0,0,0};会创建一个长度为4的数组,四个元素全部被初始化为0,刚好匹配示例里的4个单词数量。
2. 数组越界触发未定义行为
当使用长度为1的count数组时,处理示例的4个单词会让j的值从0递增到4(遇到3个空格+字符串结束符,共触发4次j++)。此时访问count[1]、count[2]、count[3]都是在访问数组边界外的内存——这属于C语言中的未定义行为,程序可能崩溃、输出乱码或出现其他异常。
而长度为4的数组刚好能容纳4个单词的统计结果,所有访问都是合法的内存区域,因此能正常输出正确结果。
额外代码问题提示
顺便提几个代码里的潜在问题,避免后续踩坑:
textStats函数参数类型不匹配:调用时传入的是FILE*类型,但声明和定义里写的是char* filename,会导致编译错误,应改为int textStats(FILE* file);。str数组缺少终止符:fscanf仅读取字符,不会自动添加'\0',while(str[i]!='\0')可能会读到数组外的内存,触发未定义行为,读取完成后需手动添加str[n] = '\0';(注意n不能超过N-1)。- 固定长度数组不满足需求:既然要求预先不知晓单词数量,应该用动态内存分配(比如
malloc),先统计单词总数再分配对应大小的数组,或者边统计边动态扩容。
内容的提问来源于stack exchange,提问作者Severjan Lici
相关产品推荐
相关产品推荐

