对于内置变量的自动初始化
代码1:
#include<stdio.h> #define CONST 100 int *p1; int a[2]; int b; static int c; main() { int d; static int e; int f[2]; int *p2; printf("CONST=%d ",CONST); printf("a[0]=%d ",a[0]); //printf("*p1=%d ",*p1); printf("b=%d ",b); printf("c=%d ",c); printf("d=%d ",d); printf("e=%d ",e); printf("f[0]=%d ",f[0]); printf("*p2=%d ",*p2); }
输出:
CONST=100
a[0]=0
b=0
c=0
d=2514932
e=0
f[0]=1307813
*p2=457819009
数据区存放已初始化的全局变量,静态变量(包括全局和局部的),常量。
未初始化数据区(uninitializeddata segment,BSS)存放全局未初始化的变量。BSS的数据在程序开始执行之前被初始化为0或NULL。BSS段的变量在目标文件中只占一个符号位,编译器并没有给变量分配空间,所谓的“初始化为0”是指要链接阶段才申请了空间,并随即初始化为0。而已初始化的全局变量要占用目标文件的大小。
换句话说全局变量,静态变量(包括全局和局部的),常量未显式初始化被默认地初始化时0或NULL。故打印*p1出错,因为p1指向NULL地址。
如果试图打印*p1则会发生段错误,因为p1指向的是一个NULL地址。
而局部的非静态变量未显式初始化时是一个随机的数,一般是个很大的数。
对于类类型变量的自动初始化
不论是在全局还是局部作用域,类类型变量都会调用“默认构造函数”进行初始化。
所谓“默认构造函数”就是指空参数的构造函数。
代码2:
class A{ public: int value; A(){ cout<<"Intitialize A"<<endl; value=3; } }; A a1; int main(){ A a2; cout<<a1.value<<endl; cout<<a2.value<<endl; return 0; }
输出:
Intitialize A
Intitialize A
3
3
如果类没有显式地定义任何构造函数,则编译器会自动为其生成空参数的构造函数,称为“合成默认构造函数”。“合成默认构造函数”初始化成员的规则有3条:
1.对象在全局作用域或为静态局部对象时,则类的内置成员变量被初始化为0.
2.对象在局部作用域定义时,则类的内置成员变量不被初始化为0.
代码3:
class A{ public: int value; }; A a1; int main(){ A a2; static A a3; cout<<a1.value<<endl; cout<<a2.value<<endl; cout<<a3.value<<endl; return 0; }
输出:
0
2510836
0
3.对于类类型成员按照其自身的(合成)默认构造函数进行初始化。——重要
代码4:
class A{ public: int value; A(){ value=5; } }; class B{ public: int value; A a; }; B b1; int main(){ B b2; cout<<b1.value<<" "<<b1.a.value<<endl; cout<<b2.value<<" "<<b2.a.value<<endl; return 0; }
输出:
0 5
134514784 5
代码5:
class A{ public: int value; }; class B{ public: int value; A a; }; B b1; int main(){ B b2; cout<<b1.value<<" "<<b1.a.value<<endl; cout<<b2.value<<" "<<b2.a.value<<endl; return 0; }
输出:
0 0
134514736 -1081710584
如果类显式提供了带参数的构造函数,则编译器不会再为其生成空参数的构造函数。这时候就不能用空参数来定义类类型变量。下面的代码是错误的:
class A{ public: int value; A (int i):value(i){} }; class B{ public: int value; A a;//调用的是空参数的构造函数 }; int main(){ A a; return 0; }
转自:http://www.cnblogs.com/zhangchaoyang/articles/2671551.html
4.对于指针成员,如果不在构造函数里显式初始化,则自动会有有个地址,非NULL,故最好把不显式初始化的指针在构造函数里赋值为NULL,避免野指针现象。
注:所以变量尽量做到初始化