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

时间:2015-07-27 06:26:36

标签: c initialization getchar

在编写应该是一个非常简单的程序(在K& R C书中)时,我得到了一些我不理解的输出。如果我EOF立即nl_count,则space_count正确为0,但int始终为32767(最大tab_count范围的一半),而 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 } 是一个较大的值(通常非常高或非常低)。

当我将所有变量初始化为0时,程序正常工作。我在这里缺少什么?

TABS = 441446448
SPACES = 32767
NEWLINES = 3

输入和输出:

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

  

(空格)(空格)(空格)\吨\吨\吨\ n \ n \ n

    SparkConf sparkConf = new 
SparkConf().setAppName("Hive").setMaster("local");   
   JavaSparkContext ctx = new JavaSparkContext(sparkConf);
    HiveContext sqlContext = new 
org.apache.spark.sql.hive.HiveContext(ctx.sc());
    org.apache.spark.sql.Row[] results = sqlContext.sql("Select * from 
Tablename where Column='Value'").collect();
    org.apache.spark.sql.Row[] results = sqlContext.sql("Select * from 
Tablename where Column='Value1'").collect();

4 个答案:

答案 0 :(得分:5)

  

当我将所有变量初始化为0时,程序正常工作。我在这里缺少什么?

tab_countspace_countnl_count;自动存储变量。如果您未将它们初始化为0,则会有不确定值。从中读取技术上是未定义的行为(UB)。由于您在初始化它们之前递增它们的值,因此您正在调用UB。 UB的一个表现是产生看似荒谬的价值观。

答案 1 :(得分:3)

默认情况下,只有Extern和Static变量初始化为0。所有其他变量都有一个不确定的值,这就是为什么在使用之前必须将它们初始化为0的原因。

答案 2 :(得分:2)

我无法抗拒。

  

当我将所有变量初始化为0时,程序正常工作。   我在这里缺少什么?

您缺少必须将所有变量初始化为零。

也许您真正缺少的是违反规则的C程序可能具有未定义/未指定的行为。这意味着即使它们不正确,它们似乎也可以工作或部分工作。

答案 3 :(得分:2)

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

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

  

如果没有显式初始化具有自动存储持续时间的对象,则其值是不确定的。

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

参考文献:C11,附件§J.2

  

使用具有自动存储持续时间的对象的值   不确定

然后,回答

  

当我将所有变量初始化为0时,程序正常运行

是的,当然,因为那样,没有UB。

因此,在您的代码中,您来更改

 int tab_count, space_count, nl_count;

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