我正在阅读《C编程语言第二版》,练习1.8告诉我要编写一个计算输入中空格、制表符和空格的程序。当前的代码除了计算适当数量的空格和制表符外,其他都做得很好。下面是我的代码
#include <stdio.h>
int main() {
int c, blankCount, tabCount, newlineCount;
blankCount, tabCount, newlineCount = 0;
while((c = getchar()) != EOF) {
if(c == ' ') {
blankCount++;
} else if(c == 't') {
tabCount++;
} else if(c == 'n') {
newlineCount++;
}
}
printf("Number of blanks in input: %dn", blankCount);
printf("Number of tabs in input: %dn", tabCount);
printf("Number of newlines in input: %dn", newlineCount);
}
有了这个输入
this is a test
this is a tab
我得到这个输出
Number of blanks in input: 2078001861
Number of tabs in input: 32766
Number of newlines in input: 2
预期输出是这个
Number of blanks in input: 3
Number of tabs in input: 1
Number of newlines in input: 2
为什么我得到的是超高的数字而不是合适的数量?
您有未初始化的变量。初始化行:
int c, blankCount, tabCount, newlineCount;
实际上并没有将它们初始化为任何(a(,并且赋值行:
blankCount, tabCount, newlineCount = 0;
将简单地评估三个子表达式(b(并丢弃结果。只有第三个子组件newlineCount = 0
具有将该变量归零的副作用。
其他的仍然会有一些任意的值,这意味着它们的最终值不会正确地指示每个的数量。
相反,你应该有这样的东西:
int c, blankCount = 0, tabCount = 0, newlineCount = 0;
作为函数的初始化行,并完全去掉赋值行。
(a(覆盖于,例如C11 6.7.9 Initialization /10
:
如果具有自动存储持续时间的对象没有显式初始化,则其值是不确定的。
(b(当你更深入地了解C时,你会意识到它们是表达式。"语句"pi = 3.14159
实际上是一个导致pi
的表达式,其副作用是首先将其设置为该值。这就是为什么你可以做twopi = 2 * (pi = 3.14159)
这样的事情,也是oldi = i++
工作的原因。
它还允许一些奇怪的事情,比如能够编译语句:
42;
:-(
这里的问题是这一行:
blankCount, tabCount, newlineCount = 0;
你可能认为这是给所有变量赋值零。然而,为了实现这一点,您需要执行以下操作:
blankCount = tabCount = newlineCount = 0;
如果使用逗号,那么实际情况是对blankCount
、tabCount
、newlineCount = 0
进行求值,然后返回newlineCount = 0
的求值结果。
更改:
int c, blankCount, tabCount, newlineCount;
进入:
int c, blankCount = 0, tabCount = 0, newlineCount = 0;
你的线路[接近]:
blankCount, tabCount, newlineCount = 0;
仅将newLineCount
和归零,而不将其他两个归零(这是三个独立的语句,前两个[实际上]没有操作(。
它们相当于:
blankCount;
tabCount;
newlineCount = 0;
如果你用-Wall
编译,你会得到警告:
init.c: In function ‘main’:
init.c:6:15: warning: left-hand operand of comma expression has no effect [-Wunused-value]
blankCount, tabCount, newlineCount = 0;
^
init.c:6:25: warning: left-hand operand of comma expression has no effect [-Wunused-value]
blankCount, tabCount, newlineCount = 0;
^
在定义变量之前应该初始化,如果没有初始化,变量就会变得不确定,如果使用visualstudio,可以按F11一步一步执行。