用作计数器的整数值的意外输出

Unexpected output for integer values used as counter

在编写应该是一个非常简单的程序时(出自 K&R C 书),我得到了一些我不理解的输出。如果我马上 EOFnl_count 是正确的 0,但是 space_count 总是 32767(最大 int 范围的一半),并且 tab_count 是一个很大的值(通常很高或很低)。

当我将所有变量初始化为 0 时,程序运行正常。我在这里错过了什么?

 10 int main(void)
 11 {
 12         int tab_count, space_count, nl_count;
 13 
 14         //tab_count = space_count = nl_count = 0;
 15 
 16         int c;
 17         while( (c = getchar()) != EOF ){
 18                 if( c == '\t' )
 19                         tab_count++;
 20                 if( c == ' ' )
 21                         space_count++;
 22                 if( c == '\n' )
 23                         nl_count++;
 24         }
 25 
 26         printf("\n");
 27         printf("TABS = %d\n", tab_count);
 28         printf("SPACES = %d\n", space_count);
 29         printf("NEWLINES = %d\n", nl_count);
 30 
 31         return 0;
 32 }

输入和输出:

这是另一个输入,它再次正确输出换行符 3,但制表符为垃圾,空格为 32767。

(space)(space)(space)\t\t\t\n\n\n

TABS = 441446448
SPACES = 32767
NEWLINES = 3

When I initialize all vars to 0, then the program works correctly. What am I missing here?

tab_countspace_countnl_count;自动存储变量。如果您不将它们初始化为 0,它们将具有 不确定的 值。从他们那里读取在技术上是 未定义的行为 (UB)。由于您在初始化它们之前增加了它们的值,因此您正在调用 UB。 UB的一种表现就是产生看似无意义的值。

无法抗拒

When I initialize all vars to 0, then the program works correctly. What am I missing here?

您错过了必须将所有变量初始化为零的信息。

也许您真正缺少的是违反规则的 C 程序可能具有 undefined/unspecified 行为这一事实。这意味着它们可能看起来有效或部分有效,即使它们不正确。

只有外部变量和静态变量默认初始化为0。所有其他变量都有一个不确定的值,这就是为什么在使用它们之前必须将它们初始化为 0。

这里的问题是,当您定义自动局部变量时,它们不会隐式初始化为任何值。您必须 显式 初始化它们。否则,那些变量的内容就是垃圾和不确定的。

参考:C11,章节 §6.7.9,初始化

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.

接下来,如果没有 write(至少,初始化),如果您尝试 use(读取)该值,它会调用undefined behaviour.

参考:C11,附件 §J.2

The value of an object with automatic storage duration is used while it is indeterminate

然后,回答

When I initialize all vars to 0, then the program works correctly

当然可以,因为这样就没有 UB。

因此,在您的代码中,您必须更改

 int tab_count, space_count, nl_count;

 int tab_count = 0;
 int space_count = 0;
 int nl_count = 0;