在许多编程语言中,您可以声明一个变量并在初始化之前使用它。
例如,在C++中,您可以编写以下代码:
int x;
cout << x;
当然,这样做会返回不可预测的结果(除非您知道程序如何映射内存),但我的问题是,为什么编译器允许这种行为?
是否有一些应用程序或效率,可以通过使用未初始化的内存来实现?
编辑:我想到了一个点,即将初始化留给用户可以减少对具有有限寿命(写入循环)的内存介质的写入。这只是在上述“性能”标题下的一个具体示例。谢谢。
在许多编程语言中,您可以声明一个变量并在初始化之前使用它。
例如,在C++中,您可以编写以下代码:
int x;
cout << x;
我认为这只是语言早期版本的遗留问题(我的想法可能是错误的,可以问问我的妻子)。
早期的C语言版本不允许在函数中随意声明变量,它们必须位于函数的开头(或者可能是块的开头,我很难准确回忆起来,因为现在我很少这样做)。
此外,您有一个可以理解的愿望:仅在您知道变量应该是什么时才设置变量。如果下一步要做的事情只是简单地覆盖该值,那么将变量初始化为某些东西是没有意义的(这就是性能方面的考虑)。
这就是为什么需要允许未初始化变量的原因,尽管在初始化之前不应该使用它们,而且好的编译器会发出警告来提醒您。
在C ++(和后来的C版本)中,您可以在函数中任何位置创建变量,因此您确实应该同时创建和初始化它。但是在早期版本中这是不可能的。您必须使用类似以下的代码:
int fn(void) {
int x, y;
/* Do some stuff to set y */
x = y + 2;
/* Do some more stuff */
}
现在,我会选择:
int fn(void) {
int y;
/* Do some stuff to set y */
int x = y + 2;
/* Do some more stuff */
}
编程中最古老的借口:它可以提高性能!
编辑:我看了你的评论并同意——多年前,性能的重点在于CPU周期数。我的第一个C编译器是传统的C(ANSI C之前那个版本),它允许编译各种可怕的代码。在这个现代化的时代,性能与客户投诉数量有关。正如我告诉我们雇佣的新毕业生们一样:“我不关心程序多快能给出错误答案。”使用现代编译器和开发的所有工具,写少量bug,每个人都能按时下班。
一些API的设计是通过传递变量来返回数据,例如:
bool ok;
int x = convert_to_int(some_string, &ok);
这个函数可能会设置“ok”的值,因此初始化是浪费的。
(我不赞成这种API风格。)
bool ok; std::cin >> ok;
- rafakint x;
if (external_function() == 2) {
x = 42;
} else if (another_function() == 3) {
x = 49;
}
yet_another_function( &x );
cout << x; // Is this a use-before-definition?
也许在某些情况下,将内存保持未初始化状态直到需要它可能更快(例如,如果您在使用变量之前从函数返回)。我通常会初始化所有内容,我怀疑这不会对性能产生任何真正的影响。编译器肯定有自己的优化方式来消除无用的初始化。
有些语言对某些变量类型有默认值。话虽如此,我怀疑在任何语言中都没有不显式初始化的性能优势。然而,缺点是:
我的建议是始终初始化您的变量,并且一致性将为自己付出。
for循环的样式
int i;
for(i=0;i<something;++i){
.......
}
do something with i
而且您更喜欢for循环看起来像for(init;condition;inc)
这里有一个绝对必要的
bool b;
do{
....
b = g();
....
}while(!b);
具有长嵌套名称的水平屏幕房地产
更长寿的作用域,以提高调试可见性
非常偶尔的性能问题
根据变量的大小,在性能名称中未初始化值可能被视为微观优化。与广泛存在的软件类型相比,相对较少的程序会受到额外两三个周期加载双精度浮点数的负面影响;然而,假设变量非常大,则推迟初始化直到明确需要初始化可能是一个好主意。
int y = alternate()
而不必担心未初始化的y
。如果我们能够像 Python 一样声明变量就好了:if test: y = 3; else: y = 4
,这样可以有效地防止未初始化的变量而不必在各处创建单行函数。 - Matthieu M.