1回答

0收藏

初始化 VS 赋值

STMCU STMCU 2621 人阅读 | 1 人回复 | 2015-08-06

                初始化 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 三周年铜板双倍!

查看全部评分

分享到:
回复

使用道具 举报

回答|共 1 个

倒序浏览

沙发

党国特派员

发表于 2015-8-10 16:26:14 | 只看该作者

感谢分享。。。
喜欢在构思妙想,电子产品DIY是工作,也是一种爱好。
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

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