C++ 默认变量值
如果我在声明变量时没有给它赋值,它是默认为零还是之前在内存中的值 e、 gC++ 默认变量值,c++,C++,如果我在声明变量时没有给它赋值,它是默认为零还是之前在内存中的值 e、 g 我认为它没有定义。我认为有些编译器在调试模式下编译时,会将其初始化为零。但也可以让它成为记忆中已经存在的东西。基本上-不要依赖任何一种行为 更新:根据注释-全局变量将初始化为零。局部变量将是任意变量 回答你的第二个问题: 谢谢-接下来,是否有一个快捷方式将零分配给以下所有值?:浮点x1、x2、x3、x4、x5、y1、y2、y3、y4、y5 你可以 float x[5] = {0,0,0,0,0}; float y[5]
我认为它没有定义。我认为有些编译器在调试模式下编译时,会将其初始化为零。但也可以让它成为记忆中已经存在的东西。基本上-不要依赖任何一种行为 更新:根据注释-全局变量将初始化为零。局部变量将是任意变量 回答你的第二个问题:
谢谢-接下来,是否有一个快捷方式将零分配给以下所有值?:浮点x1、x2、x3、x4、x5、y1、y2、y3、y4、y5 你可以
float x[5] = {0,0,0,0,0}; float y[5] = {0,0,0,0,0};
并使用
x[0]
而不是x1
C++不实例化变量。x的值是当时内存中发生的任何事情。永远不要假设它的初始值。它可以是特定于编译器的,但通常发布版本不会将变量初始化为任何特定的值,因此您可以得到内存中剩下的任何值。某些编译器在调试构建中使用某些幻数来标记内存的特定区域。这取决于具体情况。如果这是一个局部变量(具有自动存储持续时间的对象),它将被取消初始化;如果它是一个全局变量(具有静态存储持续时间的对象),它将被零初始化。同时检查。这取决于您在何处申报。全局范围中的变量初始化为0,堆栈变量未定义。这取决于变量的生存期。在程序启动之前,具有静态生存期的变量始终为零初始化:基本类型、enum
s和指针的零初始化与您分配给它的0
、适当转换为类型的情况相同。在调用构造函数之前,即使变量具有构造函数,也会发生这种情况。声明的变量可以零初始化,值初始化或默认初始化
C++03标准8.5/5恰当地定义了以下各项:
将T型对象初始化为零表示:
-如果T是标量类型(3.9),则将对象设置为0(零)的值,并转换为T-如果T是非联合类类型,则每个非静态数据成员和每个基类子对象
初始化为零
-如果T是联合类型,则对象的第一个命名数据成员初始化为零
-如果T是数组类型,则每个元素初始化为零
-如果T是引用类型,则不执行初始化 默认初始化类型为T的对象意味着:
-如果T是非POD类类型(第9条),则调用T的默认构造函数(和 如果T没有可访问的默认构造函数,则初始化是错误的)
-如果T是数组类型,则每个元素默认初始化
-否则,对象初始化为零 对值初始化类型为T的对象意味着:
-如果T是具有用户声明构造函数(12.1)的类类型(第9条),则默认 调用T的构造函数(如果T没有可访问的 默认构造函数)
-如果T是没有用户声明构造函数的非联合类类型,则每个非静态 初始化T值的数据成员和基类组件
-如果T是数组类型,则每个元素都初始化为值
-否则,对象初始化为零 例如:
#include<iostream>
using namespace std;
static int a; //Zero Initialized
int b; //Zero Initialized
int main()
{
int i; //Undefined Behavior, Might be Initialized to anything
static int j; //Zero Initialized
cout<<"\nLocal Uninitialized int variable [i]"<<i<<"\n";
cout<<"\nLocal Uninitialized Static int variable [j]"<<j<<"\n";
cout<<"\nGlobal Uninitialized Static int variable [a]"<<a<<"\n";
cout<<"\nGlobal Uninitialized int variable [b]"<<b<<"\n";
return 0;
}
编辑:正如@Kirill V.Lyadvinsky在评论中正确指出的那样,永远不应该是一个非常强的词,并且可能存在完全有效的代码,可能使用未初始化的变量,正如他在评论中指出的一个例子。因此,我可能应该说:除非您确切知道自己在做什么,否则永远不要使用未初始化的变量。在初始化之前使用任何变量的值(请注意,静态存储持续时间对象总是初始化的,因此这只适用于自动存储持续时间)会导致未定义的行为。这与包含0作为初始值或包含随机值非常不同。UB表示任何事情都有可能发生。在使用陷阱位的实现中,它可能会使程序崩溃或生成信号。在任何其他可想象(或不可想象)的行为中,多次读取也可能导致不同的不可预测值。简单地不要使用未初始化变量的值 注意:以下内容是根据评论编辑的: 请注意,这样的代码无效,除非您可以确保类型
foo\u t
没有填充位:
foo_t x;
int i;
for (i=0; i<N; i++) x = (x<<1) | get_bit();
foo_t x;
int i;
对于(i=0;i由于当前的顶级答案是在2011年编写的,并且只涉及C++03,因此我提供了一个更新的答案,以考虑C++11之后所做的更改。请注意,我正在剥离所有仅在C++03或C++11之前有效的信息,以及可以在原始源代码中看到的不必要注释。我引用了原始规范为了避免不必要的重述,可能会导致不准确的信息,请尽可能多地使用ns。如果您有兴趣深入探讨某个主题,请参阅我提供的原始资料。另外,请注意,我主要关注的是关于
*默认初始化
*未定义的行为
*零初始化
因为在我看来,这些是理解变量“默认”行为所需的最重要方面,正如问题所问的那样
:
当在没有初始值设定项的情况下声明具有自动、静态或线程本地存储持续时间的变量时
当新表达式创建具有动态存储持续时间的对象时
cc1plus: warnings being treated as errors
In function 'int main()':
Line 11: warning: 'i' is used uninitialized in this function
foo_t x;
int i;
for (i=0; i<N; i++) x = (x<<1) | get_bit();
int main()
{
int myVariable;
myFunction(myVariable); // does not change the variable
cout << myVariable << endl; // compilers might think it is now initialized
}
#include <iostream>
#include <string>
struct Coordinates {
float x, y;
};
class WithDefaultConstructor {
std::string s;
}
class WithCustomConstructor {
int a, b;
public:
WithCustomConstructor() : a(2) {}
}
int main()
{
int a; // Indeterminate value (non-class)
int& b; // Error
std::string myString; // Zero-initialized to indeterminate value
// but then default-initialized to ""
// (class, calls default constructor)
double coordsArray[2]; // Both will be 0.0 (zero-initialization)
Coordinates* pCoords; // Zero-initialized to nullptr
Coordinates coords = Coordinates();
// x: 0.0
// y: 0.0
std::cout << "x: " << coords.x << '\n'
"y: " << coords.y << std::endl;
std::cout << a.a << a.b << a.c << '\n';
WithDefaultConstructor wdc; // Since no constructor is provided,
// calls the default constructor
WithCustomConstructor wcs; // Calls the provided constructor
// a is initialized, while b is
// default-initialized to an indeterminate value
}