早上好,所有人! 事后来看,这最终将成为一个令人眼花缭乱的问题之一,但对于我的生活,我很难过。我正在阅读C语言编程语言中的一些练习,并且我已经设法编写了一些代码来初始化循环。经过一些谷歌搜索,我找到了更好的方法将循环初始化为0,但我不明白为什么我写的循环没有完成。我用调试器发现它是因为'c'变量永远不会达到50,它变为49然后翻到0,但我无法弄清楚为什么它会翻滚。代码附在下面,有谁知道这里发生了什么?
#include <stdio.h>
#define IN 1
#define OUT 0
/* Write a program to print a histogram of the lengths of words in
itsinput. */
main()
{
int c=0;
int histogram[50]={0}
int current_length=0;
int state=OUT;
//Here we borrow C so we don't have to use i
printf("Initializing...\n");
while(c<51){
histogram[c] =0;
c=c+1;
}
c=0;
printf("Done\n");
while( (c=getchar()) != EOF){
if( (c==32 || c==10) && state==IN ){
//End of word
state=OUT;
histogram[current_length++];
}else if( (c>=33 && c<=126) && state==OUT ){
//Start of word
state=IN;
current_length=0;
}else if( (c>=33 && c<=126) && state==IN ){
//In a word
current_length++;
} else {
//Not in a word
//Example, " " or " \n "
;
}
}
//Print the histogram
//Recycle current_length to hold the length of the longest word
//Find longest word
for( c=0; c<50; c++){
if( c>histogram[c] )
current_length=histogram[c];
}
for( c=current_length; c>=0; c--){
for( state=0; state<=50; state++){
if( histogram[c]>=current_length )
printf("_");
else
printf(" ");
}
}
}
答案 0 :(得分:5)
这是因为histogram[c] = 0
在histogram
时写入c = 50
内存。所以基本上histogram[50]
会覆盖c并使其为0。
这是因为数组从C中的0
开始。所以 50个元素数组中的最后一个有效索引是49 。
从技术上讲,虽然有趣且可利用,但你不能依赖于此。这是未定义行为的表现。内存可能很容易有另一种布局,导致事情“正常工作”或做一些更有趣的事情。
答案 1 :(得分:1)
histogram
有50个元素:从索引0到索引49
您尝试写入索引50. 所有下注已关闭
DO
while (c < 50)
或者,以避免魔术常量
while (c < sizeof histogram / sizeof *histogram)
答案 2 :(得分:0)
您正在访问直方图中的元素0到50,它只包含0到49的元素(C / C ++使用零索引,因此数组的最大元素将始终为size-1)。
为避免这样的错误,您可以将直方图大小定义为常量,并将其用于与直方图数组相关的所有操作:
#define HISTOGRAM_SIZE 50
或(仅适用于C99或C ++,见下面的评论):
const int HISTOGRAM_SIZE = 50;
然后:
int histogram[HISTOGRAM_SIZE];
和
while(c<HISTOGRAM_SIZE)
'#define'是一个C-preprocessor语句,将在编译之前处理。对于编译器来说,它看起来好像你已经在任何地方使用HISTOGRAM_SIZE写了50,所以你不会得到任何额外的开销。
'const int'给你一个类似的解决方案,在很多情况下会给出与define相同的结果(我不是100%确定在哪种情况下,其他人可以自由详细说明),但也会给出你是类型检查的额外奖励。