我是C编程的初学者,在我编写的这段代码中,编译器坚持认为我为变量ch2
和ch3
设置了初始值。
令我困惑的是为什么在这种情况下需要的是什么时候我需要初始化变量的值,什么时候不需要(通常)?
#include <stdio.h>
#include <conio.h>
int main(void) {
int ch, ch1 = 0, ch2 = 0, ch3 = 0;
while (1) {
ch = _getche();
ch1 = ch2;
ch2 = ch3;
ch3 = ch;
if (ch1 == 'h' && ch2 == 'e' && ch3 == 'y') {
break;
}
}
printf("\nHello !");
}
答案 0 :(得分:1)
C中唯一的约束是必须初始化对象才能读取它们的值。
具有static
存储类的全局对象和本地对象在启动进程时自动初始化,可以是您在其定义中的源代码中编写的显式初始化程序,也可以是零值(以及所有对象)如果源代码中的定义点没有初始值设定项,则为其成员和聚合元素。对于数字和字符类型,零值为0
,对于指针,零值为NULL
。联合的第一个成员初始化为零值。
默认情况下,其他本地对象未初始化,因此您必须在定义时提供初始化程序,或者在读取其值之前将值存储在其中。
在您的示例中,在while
循环中,ch2
和ch3
的值在写入之前被读取。这些必须在循环之前初始化,但是值会在ch
之前存储到ch1
和if
,因此它们不需要在循环之前初始化。您可以安全地删除ch1
的初始化程序。
编译器警告您初始化ch2
和ch3
的原因是为了避免在循环的第一次迭代期间出现未定义的行为。如果未经初始化ch2
的值为'h'
而未初始化的ch3
在第一次迭代之前的值为'e'
,那么点击y
就足以打破循环。
我建议您编译代码并启用警告,以允许编译器诊断未初始化变量的潜在用途。它并不完美,可能存在误报和漏报,但诊断通常非常有用,可以避免导致未定义行为的愚蠢错误。
将所有局部变量初始化为常量并没有什么坏处。编译器通常足够聪明,可以删除冗余存储,即:它们不生成用于将值存储到非volatile
局部变量的代码,这些变量在接收另一个值或超出范围之前未使用。
请注意,您的代码可以通过这种方式减少一个变量来简化:
#include <stdio.h>
#include <conio.h>
int main(void) {
int ch = 0, ch1 = 0, ch2;
for (;;) {
ch2 = ch1;
ch1 = ch;
ch = _getche();
if (ch2 == 'h' && ch1 == 'e' && ch == 'y') {
break;
}
}
printf("\nHello !\n");
return 0;
}
答案 1 :(得分:0)
什么时候我需要初始化变量的值,什么时候不需要(通常)?
当变量自动初始化为零(例如,静态全局变量)时,可能会出现一些特殊情况。
但是根据经验,在使用之前初始化所有变量总是很好的做法(并且没有坏处)。
所以在你的情况下,将它们全部初始化:
int ch = 0, ch1 = 0, ch2 = 0, ch3 = 0;
答案 2 :(得分:0)
真正有趣的问题是何时在C 中初始化变量。
在 uninitialize 变量保证初始化为零(外部和静态变量), auto 和 register 变量 undefined (即垃圾)初始值。
实际上, auto 变量的初始化只是赋值语句的简写。更喜欢哪种形式主要是品味问题。我们通常使用显式赋值,因为声明中的初始化器更难以查看并且远离使用点。
有关详细信息,请阅读storage class in C。