查看: 2333|回复: 1

初始化 VS 赋值

[复制链接]
  • TA的每日心情
    慵懒
    2018-3-28 17:24
  • 签到天数: 276 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2015-8-6 14:29:50 | 显示全部楼层 |阅读模式
    分享到:
                    初始化 VS 赋值
    当你写下如下语句:

                <1>
                    int x = 1;
                <2>
                    int x;
                    x = 1;  

    它们之间可有什么区别?

    有.这是两个不同的动作.
    <1>是一个初始化操作,而<2>是一个赋值操作.前者是一个编译器动作,而后者是一个程序动作.

    需要证据?好的,看下面的程序.

                    <3>
                    int main(void)
                    {
                        static  int val0 = 0x55;
                        int val1 = 0x66;
                        int val2;
                        val2 = 0x77;
                    }
    进入调试状态,在main处停下.此时main()函数尚未执行,但val0的值已经准备妥当.
    就像前面所说的, val0是一个初始化动作, 编译器在进入main()函数之前就将val0初始化完毕.

    喔,等等.val1不也是一个初始化动作吗,那怎么它的值没有准备好.

    是的,val1仍然是一个初始化动作.不过,唔,你知道的,局部变量有点特殊,它位于堆栈中.
    从某些方面说,它具有overlay属性,所以在每次进入main()函数后(不是在之前),都需要将它初始化一次.

    或者换一种说法,更好理解:
        val1是一个全局性的变量,它的生命周期,从程序开始,直到结束,都是有效的.所以它在整BPOSThttp://bbs.21ic.com/club/bbs/SaveOwnerEdC中,只需要初始化一次就好.
        而val2是一个局部性的变量,它的生命周期,从它声明开始,到它所在的函数退出前那一刻.所以每次这个函数被调用,它都将被初始化一次.

    虽然,从汇编后的结果看来,val1和val2操作的汇编代码是相同的,但它们仍然是2个不同的动作(操作).它们的汇编代码之所以相同,那是因为你使用的是内置的数据类型(int),如果你尝试在C++下写类似的代码(看程序片断<7>),那就是另一个故事了.



    杂项:
    1) const 变量不能通过赋值动作获得一个值(废话),但可以通过初始化动作获得一个初值(还是废话).
                <3>
                const int x0 = 5;   //ok
                const int x1;
                x1 = 5;             //error

    2) 关于struct   
                <4>
                typedef struct S{int v1, int v2};
                S s0 = {1,2};       //ok, 初始化
                S s1;
                s1 = {1,2};         //error, 不能这样赋值

    3) 某种意义上,初始化动作是一个一次性的动作.
        你一定写过类似下面的程序:
                <5>
                foo(..)
                {
                    static int cnt = 0;
                    cnt ++;
                    //.....
                }
        你也一定不会粗心的写成如下程序:
                <6>
                foo(..)
                {
                    static int cnt;
                    cnt = 0;
                    cnt ++;
                    //.....
                }
        因为程序<5>是一个初始化操作,是一次性的动作.
        而程序<6)是一个赋值操作,foo()每被调用,cnt将重新被赋值,这不是你要的结果,是不?
        这再次说明:初始化操作是编译器动作,而赋值操作不是.

    4) 效率
        在C中,通常都是使用一些编译器内置的数据类型,你不大可能看到初始化动作和赋值动作的效率,也因此你不太容易看到它们之间的巨大区别.
        但是如果在C++中,你就能看到初始化和赋值是多么的不同了.
                <7>
                class X {....};
                X xx;

                X xx0 = xx; //初始化动作,它使用copy construtor直接初始化对象.
                X xx1;      //声明一个对象,对象获得内存,并调用default construtor初始化对象.
                xx1 = xx;   //使用operator= 将对象xx的值赋给xx1.

    评分

    参与人数 1与非币 +5 收起 理由
    loveeeboard + 5 三周年铜板双倍!

    查看全部评分

    回复

    使用道具 举报

  • TA的每日心情

    2023-7-25 22:49
  • 签到天数: 385 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2015-8-10 16:26:14 | 显示全部楼层
    感谢分享。。。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-11-25 10:58 , Processed in 0.133731 second(s), 21 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.