K&R《C程序设计语言》练习1-14字符频率统计代码报0xC0000005错误
问题解答
你遇到的报错和i7-3540M处理器性能没有任何关系。退出码0xC0000005是Windows平台下的内存访问越界错误,完全由代码的逻辑问题导致,具体错误点如下:
- 第一个问题:变长数组定义逻辑错误。你在
m = 1时定义了int a[m],此时数组a的固定长度就是1,后续修改m的值不会扩容数组。当输入字符数超过1后,对a[i]赋值就已经是越界写内存,属于未定义行为,输入字符越多越界越严重,最终触发崩溃。 - 第二个问题:输出时下标错位。你在输出前先执行了
++i,再访问a[i],不仅导致字符和统计频率完全不匹配,还会在循环最后一次执行时访问数组边界外的内存,进一步加重越界问题,你测试用例的输出结果错位就是这个原因导致的。 - 第三个问题:统计逻辑冗余错误。当前你每次遍历整个数组统计当前字符的出现次数,不仅时间效率低,还会重复输出同一个字符的统计结果,比如测试用例里的b就输出了两次,不符合题目要求统计不同字符频率的要求。
正确实现思路
这道题不需要存储完整的输入字符串,ASCII字符总共只有128个,直接用固定长度的计数器数组就能实现:
- 定义长度为128的计数数组,所有元素初始化为0
- 每读入一个字符,直接给对应下标的计数元素+1
- 输入读完后遍历计数数组,输出计数大于0的字符和对应频率,再绘制直方图
示例实现代码
#include <stdio.h> int main() { int c; int cnt[128] = {0}; // 覆盖所有ASCII字符的计数器 // 读入输入并统计 while ((c = getchar()) != EOF) { // 可根据需求过滤不需要统计的字符,比如换行、回车等 if (c != '\n' && c != '\r') { cnt[c]++; } } // 输出频率和直方图 for (int i = 0; i < 128; i++) { if (cnt[i] > 0) { putchar(i); putchar('|'); // 输出直方图横条 for (int j = 0; j < cnt[i]; j++) { putchar('#'); } printf(" %d\n", cnt[i]); } } return 0; }
内容的提问来源于stack exchange,提问作者MatthewV_xD
相关产品推荐
相关产品推荐

