重要:C/C++变量的自动初始化

对于内置变量的自动初始化

代码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);
}
按 Ctrl+C 复制代码

输出:

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,避免野指针现象。

注:所以变量尽量做到初始化

原文地址:https://www.cnblogs.com/liushui-sky/p/5825151.html