2010-02-07 83 views
37

我的理解是int变量会自动初始化为0;但是,事实并非如此。下面的代码打印一个随机值。C++中的变量初始化

int main() 
{ 
    int a[10]; 
    int i; 
    cout << i << endl; 
    for(int i = 0; i < 10; i++) 
     cout << a[i] << " "; 
    return 0; 
} 
  • 什么规则,如果有的话,适用于初始化?
  • 具体来说,变量在什么条件下自动初始化?

回答

62

将自动初始化,如果

  • 它是一个类/结构实例中的默认构造函数初始化所有基本类型;像MyClass instance;
  • 你使用数组初始值设定语法,例如int a[10] = {}(所有零)或int a[10] = {1,2};(所有零除第一两个项目:a[0] == 1a[1] == 2
  • 同样适用于非集合类/结构,例如MyClass instance = {}; (更多相关信息,可以发现here
  • 这是一个全局/外部变量
  • 变量定义static(无论在函数内部或全局/命名空间范围) - 感谢杰里

永远不要相信自动初始化的普通类型(int,long,...)的变量!它可能发生在C#等语言中,但不在C++中。

+7

第一点是有点不准确。如果它是非POD类型,它将自动初始化。 :) – jalf 2010-02-07 21:34:17

+0

对,改变了;)thx – AndiDog 2010-02-07 21:49:47

+2

“简单类型”的静态存储持续时间的变量也被初始化为零(或者在指针的情况下为空指针)。这可以是在函数内部声明为'static'的东西,或者是在命名空间范围内声明的东西(即在任何函数之外)。 – 2010-02-07 23:22:16

12

int不初始化为零。当你说int i;时,你所做的只是为整数保留空间。该位置的值未初始化。这只会在您说int i = 0;(或int i = 5;,在这种情况下,该值初始化为5)完成。无论如何,将变量初始化为某个已知值是一种很好的做法。否则,i保留任何随机值在该空间为其保留时在该内存位置。这就是为什么cout打印出一个随机值。

默认值取决于语言的实现。有些语言会将其初始化为一些“理智”的值(比如0)。作为一个经验法则,我总是将一个变量初始化为一个合理的值(除非我知道在我使用它之前我将它初始化为肯定是)。正如我之前提到的,假设这个值是理智的。它可能会也可能不会(取决于语言,或者该语言的解释器/编译器的实现)。

2

除非您自己做,否则局部变量不会被初始化。你看到的是在你的方法被调用之前堆栈中的垃圾。

4

这个职位的最佳说它:http://www.velocityreviews.com/forums/showpost.php?p=1528247&postcount=10

有没有“默认”构造函数 非类的类型,但默认 (零)的初始化。不幸的是,对于 使用C新空房禁地的兼容性, 默认的初始化是不是在以下 情况进行 为POD类型:

裸(即不宣布初始化 )局部变量的 类或函数。

动态分配的实例。

然而,在其他地方(尤其是 静态变量)和中给出的空初始化 paramters 任何东西的情况下(当是有效的),得到 默认的(零)的初始化。

+1

我不会说这是由于“对C的敏感程度”,我认为它更多地与C++的“不支付你不使用的”哲学有关。 – Manuel 2010-02-08 20:10:29

3

在C++中,自动变量是未定义的,直到它们被明确赋予一个值。也许你正在考虑C#或其他.Net语言或Java。

5

请参见4.9.5 C++编程语言的初始化。

取决于您的变量是否是本地的,可能会发生静态,用户定义或常量默认初始化。

因为您正在使用POD(普通旧数据类型),所以自动变量未初始化为任何默认值。

4

要强制POD的初始化(这int是),你可以使用复制初始化语法:

#include <iostream> 

int main() { 
    int i = int(); 
    int j; 

    std::cout << "i: " << i << std::endl; 
    // warning: undefined behavior 
    std::cout << "j: " << j << std::endl; 
} 

这是属于在“只付你使用什么”。如果你打算随后给变量赋值,或者根本不使用它,那么没有理由去完成初始化它的工作。要做到这一点,你必须明确地要求完成这项工作。

+1

这对'unsigned int's或'long long'或类似的类型在GCC中包含多个单词不起作用,但它可以在MSVC中工作,相关问题:http://stackoverflow.com/questions/2144012式/显式型转换和 - 多简单型说明符 – smerlin 2010-02-08 19:42:10

0

尽管您最近的发现可能不受欢迎(因为您可能需要初始化其他语言将要处理的某些变量),但这可能意味着更少的cpu周期,从而代码更快。

2

如果没有为对象指定初始值设定项,则该对象将被默认初始化;如果不执行初始化,则具有自动或动态存储持续时间的对象具有不确定的值。

Par。 8.5,最近的C++ 0x N3092.pdf草案的部分11,

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/

3

不同的操作系统(即OS X与Ubuntu Linux操作系统)将不同的反应,未初始化与在C++中初始化变量。根据我的经验,OS X版本的gcc将为以下两个版本的代码编译并打印出2。就像我在Ubuntu Linux机器上工作一样,第一个代码块将打印出发生在内存位置的变量引用(循环后的+2)。

int c; 

    for(int i = 0; i < 3; i++) 
    { 
     c++; 
    } 

    cout << c << endl; 

凡为,他们都会给你同样的结果:

int c = 0; 

    for(int i = 0; i < 3; i++) 
    { 
     c++; 
    } 

    cout << c << endl; 
-1

这里int i;是一个自动变量必须手动初始化。自动变量不会在c和C++中自动初始化。

如果你想编译器进行初始化,然后你需要使用下面的东西,

声明i为静态变量。

static int i; //零由编译器分配给i。

声明i作为全局变量[在main()外部)。