zoukankan      html  css  js  c++  java
  • 初始化系列之零初始化(zero initialization)

    https://zh.cppreference.com/w/cpp/language/zero_initialization
    https://en.cppreference.com/w/cpp/language/zero_initialization

    零初始化

    把一个对象的初始化值设置为0

    说明

    零初始化会在下面的情况下执行:

    1. 对于任何static或者thread-local变量,没有使用const,在任何初始化之前,会进行0初始化,也就是static和thread-local修饰的变量会0初始化

    2. 如果不是类,作为数值初始化序列的一部分;如果是类,并且没有构造函数,作为数值初始化中的一员,都会进行零初始化。包括没有提供初始化器的元素聚合数值初始化。参考下面例子

    class A {
    public:
        int i;
    };
    class B {
    public:
        B() {}
        int i;
    };
    int main() {
        int t1{};
        cout << t1 << endl;
        int t2 = {};
        cout << t2 << endl;
        int* t3 = new int();
        cout << *t3 << endl;
        int* t4 = new int{};
        cout << *t4 << endl;
        int t5[2] = {};
        cout << t5[0] << "|" << t5[1] << endl;
        int t6[2]{};
        cout << t6[0] << "|" << t6[1] << endl;
        int* t7 = new int[2]();
        cout << t7[0] << "|" << t7[1] << endl;
        int* t8 = new int[2]{};
        cout << t8[0] << "|" << t8[1] << endl;
        A a1;
        cout << a1.i << endl;
        A a2{};
        cout << a2.i << endl;
        A* a3 = new A();
        cout << a3->i << endl;
        A* a4 = new A{};
        cout << a4->i << endl;
        B b1;
        cout << b1.i << endl;
        B b2{};
        cout << b2.i << endl;
        B* b3 = new B();
        cout << b3->i << endl;
        B* b4 = new B{};
        cout << b4->i << endl;
        return 1;
    };
    

    除了最后四个结果是未知,剩下的所有的结果都是0,B相关的之所以是未知,就是因为B提供了用户的构造函数,所以B内的成员不会进行零初始化。

    1. 如果是一个字符类型的数组,初始化的字符比数组的空间小,剩下的空间会默认初始化为0
    char a[10] = "test";
    

    除了开始的4个分别是test,数组a剩下的空间都是0

    零初始化的规则:

    • 如果是标准类型,就会初始化为0

    • 如果是非union的类类型,基类和非静态成员初始化为零,所有填充位初始化为零。忽略构造函数

    • 如果是union,第一个非静态的数据初始化为零,填充位初始化为零

    • 如果是数组,所有元素初始化为零

    • 如果是引用,不做任何处理

    说明

    在非局部初始化中,static和thread-local变量,如果不是const类型,会在其他初始化之前进行零初始化。如果非类类型的变量,也不是局部变量,并且没有初始化器,那么默认初始化不做任何事情,也就是由一开始初始化为0,最后结果并不会修改,还是保持原来的值-零。

    零初始化的指针是空指针,即使空指针不是零。

    非局部变量

    非局部变量,基本上遇到的就是全局变量,写在类、函数之外的变量,总结一句就是会初始化为0,数字是0,字符是,指针是null

    所有的有着静态存储期的非局部变量都会在程序起来时初始化,也就是在main函数运行之前(除非你可以延迟初始化)。所有的有着thread-local存储期的非局部变量在线程起来时初始化,顺序在执行线程函数之前。对于这两种变量,有着两个初始化阶段:

    静态初始化

    静态初始化有两种形势:

    1. 如果是左值,就进行常量初始化
    2. 否则,非局部的static和thread-local进行零初始化

    实际情况:

    • 常量初始化经常在编译期进行。将提前计算的对象作为程序的一部分存储起来。如果编译器没有这样做,那也必须保证初始化在动态初始化之前。
    • 用来零初始化的数据保存在程序的.bss段,不占用硬盘空间,在系统加载程序的时候设置为0
    class A {
    public:
        int i;
    };
    class B {
    public:
        B() {}
        int i;
    };
    enum C
    {
        C1 = 10,
        C2
    };
    int t;
    int a[2];
    A a1;
    B b1;
    C c;
    int* p;
    int main() {
        cout << t << endl;
        cout << a[0] << "|" << a[1] << endl;
        cout << a1.i << endl;
        cout << b1.i << endl;
        cout << c << endl;
        cout << p << endl;
        return 1;
    };
    

    上面的输出结果全是0,因为对于非局部变量,比如上面的全局变量,在初始化之前会全部初始化为0,并且后续默认初始化什么都不做,所以最终结果是0.

    版权声明:本文版权归作者所有,如需转载,请标明出处

  • 相关阅读:
    tf-idf sklearn
    特征工程——特征预处理
    dict 字典
    特征预处理——特征表达
    特征工程之特征选择
    机器学习技巧学习
    dataframe去重 drop_duplicates
    dataframe 转为list
    XGboost
    StratifiedShuffleSplit()函数 实现对数据集的划分
  • 原文地址:https://www.cnblogs.com/studywithallofyou/p/14548250.html
Copyright © 2011-2022 走看看