C语言int数组首元素与循环赋值不符及数组动态性问题
C语言字符频率统计相关问题解答
问题1:nfreq数组首元素值异常的原因及解决
你遇到的nfreq[0]在循环内显示为1,但外部输出变成116的问题,核心原因是数组越界访问破坏了内存:
代码中char nstr[] = "";的声明会创建一个仅能容纳1个字符(即终止符'\0')的数组。而append函数会往这个数组末尾添加字符,每次调用都会写入超出数组大小的内存区域(比如第一次添加空格时,会修改nstr[0]和nstr[1],但nstr只有1个元素的空间)。
由于栈上变量的分配顺序,nstr和nfreq的内存地址相邻,越界写入nstr的操作会直接覆盖nfreq的内存内容。后续添加t字符(ASCII码116)时,刚好覆盖了nfreq[0]的位置,导致最终输出时nfreq[0]变成116。
解决方法
给nstr分配足够的存储空间,比如:
char nstr[256] = ""; // 最多可能有256个不同ASCII字符,256的空间足够
问题2:int nfreq[] = {}的数组大小是否会动态变化
在C语言中,这种声明方式属于未定义行为(严格来说,C标准不允许空初始化列表的数组声明),实际编译器(如GCC)会将其视为大小为0的数组。
C语言的数组大小是编译期确定的固定值,不存在动态扩容的特性。循环中往这个数组添加元素本质是越界访问内存,属于非法操作,可能导致程序崩溃、数据破坏等不可预测的结果。如果需要动态调整大小的数组,应该使用malloc/realloc等动态内存分配函数来实现。
原代码及运行结果
void append(char* s, char c) { int len = strlen(s); s[len] = c; s[len+1] = '\0'; } int main() { char str[] = "test sentence"; char nstr[] = ""; int freq[256] = {}; int nfreq[256] = {}; for(int i = 0; str[i] != '\0'; i++) { freq[str[i]]++; } printf("\nCharacter Frequency\n"); int j = 0; for(int i = 0; i < sizeof(freq) / sizeof(int); i++) { if(freq[i] != 0) { printf("%5c%10d\n", i, freq[i]); char c = i; append(nstr, c); int f = freq[i]; nfreq[j] = f; printf("Num in nfreq[%d] is %d\n", j, nfreq[j]); j++; } } for(int i = 0; i < strlen(nstr); i++) { printf("%d ", nfreq[i]); } printf("\n"); printf("size of nfreq : %lu\n", sizeof(nfreq) / sizeof(nfreq[0])); printf("size of str : %lu\n", strlen(str)); printf("size of nstr : %lu\n", strlen(nstr)); printf("nstr is : %s\n", nstr); return 0; }
运行输出:
Character Frequency 1 c 1 e 4 n 2 s 2 t 3
预期nfreq数组为{1,1,4,2,2,3},实际输出为{116,1,4,2,2,3}。
内容的提问来源于stack exchange,提问作者user21085283
相关产品推荐
相关产品推荐

