有些程序员说你应该首先在C语言的序列(函数)的开头声明所有变量,尽管从C99起不再需要了。在开始时初始化所有变量或者是否浪费处理器时间是一个好主意吗?
答案 0 :(得分:3)
有些程序员说你应该首先在C中首先在序列(函数)的开头声明所有变量......
我发现声明变量接近于首先使用的变量更好。 @pm100
然而,这是一个风格问题。最好遵循您小组的编码标准。
最初初始化所有变量还是浪费处理器时间也是个好主意?
使用简单变量,这不是“浪费处理器时间”。
使用长阵列时,很有可能出现明显的延迟。
#define N 4096
char buf[N];
// or
char buf[N] = { 0 };
if (fread(buf, sizeof buf[0], N, ...
根据您组的编码标准执行“不需要的”初始化。
考虑4例:3例有潜在的UB
// No initialization
char buf1[N];
fgets(buf1, sizeof buf1, stdin);
fputs(buf1, stdout);
// Initialization
char buf2[N] = {0};
fgets(buf2, sizeof buf2, stdin);
fputs(buf2, stdout);
// No initialization, early assignment
char buf3[N];
buf3[0] = '\0';
fgets(buf3, sizeof buf3, stdin);
fputs(buf3, stdout);
// No initialization, test function result that populates buf4
char buf4[N];
if (fgets(buf4, sizeof buf4, stdin)) {
fputs(buf4, stdout);
}
只有
if (fgets(buf4, sizeof buf4, stdin))
才能正确防止读取错误,该错误以“数组内容不确定”结尾。
我既不批评也不反对不必要的初始化1)编译器经常(并不总是)检测并警告缺少初始化/分配2)我看到的编码问题往往存在于不检查错误状态和3)与圣战问题一样就像Indent style这样,我遵循我的小组的编码标准 - 不管它是什么。
答案 1 :(得分:2)
通常,是的,在定义时初始化变量(本地范围,自动存储,特别是)总是更好的选择。这样做可以避免使用单位化值的可能性,可能会导致未定义的行为。
例如,一个简单的案例,
int x;
//...after some code
if (/*some options*/) x = 0;
//after some more code
if (x == 5) {....
如果if
评估为false,则上述代码段肯定会导致UB。但是,在定义x
时,如果我们初始化,就像
int x = -1;
然后,至少,我们可以避开UB。
注意:这并不能证明忽略编译器警告(可能使用单位化变量),这只是一个例子。
也就是说,启用适当的优化后,对于编译器而言,定义变量的位置并不重要,但出于可读性的目的,您应该始终在其使用之前/之前定义变量。这又是推荐,而不是规则。
softwareengineering SE上有一个不错的Q& A,请阅读。
答案 2 :(得分:1)
您将初始化与声明混淆了。初始化是给变量一个初始值,如果可以的话,它是初始化变量的好方法。 必须在使用之前为变量赋值。
但您的问题似乎是关于在哪里声明变量。普遍接受的最佳做法是尽可能接近使用。
使用C89,必须在块的开头声明变量。我能想到坚持这个规则的唯一原因(不能与一个非常旧的标准兼容)是它鼓励你保持你的功能和阻塞。但我并不赞成这样的论点,因为你仍然可以保持函数和块的简短(绝对是好的做法),而只有在实际使用它们时才声明变量,这使得代码的可读性稍差。
答案 3 :(得分:1)
编译器足够聪明,可以优化代码,无论您是在代码范围的开头还是中间定义变量都无关紧要。
在许多情况下,在您需要的时候定义一个变量看起来更具可读性,因为您可以轻松地追溯变量的类型以及用于的变量(特别是使用非常长的代码片段)。
但是,定义变量后立即初始化变量是一种很好的行为,因为它有助于避免由于访问未初始化的变量而导致未定义的行为。
答案 4 :(得分:1)
只是指出一个不和谐的观点(我同意初始化是好的)。
当变量将用作for
循环中的计数器时,我发现初始化它看起来比赋值更差
int i = 0; // initialization
for (; i < 100; i++) {
// code, code, code
if (foo == bar) i = 999;
// code, code, code
}
if (i == 999) exit(EXIT_FAILURE);
int i;
for (i = 0; i < 100; i++) { // assignment
// code, code, code
if (foo == bar) i = 999;
// code, code, code
}
if (i == 999) exit(EXIT_FAILURE);