C循环不会退出

时间:2012-03-24 12:17:09

标签: c

早上好,所有人! 事后来看,这最终将成为一个令人眼花缭乱的问题之一,但对于我的生活,我很难过。我正在阅读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(" ");
        }
    }
}

3 个答案:

答案 0 :(得分:5)

这是因为histogram[c] = 0histogram时写入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%确定在哪种情况下,其他人可以自由详细说明),但也会给出你是类型检查的额外奖励。

相关问题