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

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

  • 相关阅读:
    汇编Ring 3下实现 HOOK API
    软件调试之INT 3讲解
    Delphi逆向
    XoftSpy 4.13的注册算法分析
    反调试技术揭秘
    jmp && call && ret 特权级转移 & 进程调度
    PHP Warning: Module 'modulename' already loaded in Unknown on line 0
    PhpStorm和PHPstudy配置调试参数(Xdebug),问题描述Error. Interpreter is not specified or invalid. Press “Fix” to edit your project configuration.
    php 安装xdebug进行调试(phpstorm)
    Windows下PHP多线程扩展pthreads的安装
  • 原文地址:https://www.cnblogs.com/liushui-sky/p/5825151.html
Copyright © 2011-2022 走看看