zoukankan      html  css  js  c++  java
  • 重要: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,避免野指针现象。

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

  • 相关阅读:
    Java中的魔法类-Unsafe
    Caffeine Cache-高性能Java本地缓存组件
    mysql之innodb日志管理
    mysql之innodb存储引擎---BTREE索引实现
    myslq5.7安装以及root密码找回
    mysql之innodb存储引擎---数据存储结构
    mysql之innodb存储引擎介绍
    java字符串详解
    hadoop2.7作业提交详解之文件分片
    hadoop2.7之作业提交详解(下)
  • 原文地址:https://www.cnblogs.com/liushui-sky/p/5825151.html
Copyright © 2011-2022 走看看