• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            攀升·Uranus


            Something Different,Something New
            數(shù)據(jù)加載中……

            數(shù)組與指針 熟練c/c++ (七)

                    剛看了expert C中對數(shù)組和指針的詮釋,覺得很講的很精彩,尤其對這種情況引起的錯誤記憶猶新:
            file: 1.c
            int a[10]={0};

            file: 2.c
            int
            main ()
            {
                    extern int *a;

                    printf ("%d\n", a[0]);
                    return 0;
            }


                        但是當我運行程序在VC6上時,發(fā)現(xiàn)這個程序Link時會報錯,那是不是編譯器更新了呢?
            由此轉(zhuǎn)一篇文章詮釋數(shù)組和指針的,作者win_hate , http://bbs.chinaunix.net/viewthread.php?tid=239405

            轉(zhuǎn)本貼請把 win_hate 的名字寫上。

            略談 c 語言中指針與數(shù)組的區(qū)別

            數(shù)組與指針是兩個不同的概念,即使是從編譯的層面上來看。不過,在很多時候,兩者的用法極為相似。本文將討論兩者的區(qū)別。


            一、理論分析

            編譯器在處理指針與數(shù)組的時候,是區(qū)別對待的。

            對于指針

            int *p;

            p 是一個變量,所以編譯器要為之分配一個空間。

            .comm p, 4

            對于數(shù)組:

            int a[10]

            a 是一個地址,編譯器會為數(shù)組 a 分配一個空間,但不會為 a 本身分配空間,在使用到a的地方,會被替換為一個地址+屬性,其結(jié)果為一個"常量指針"。

            .comm a, 40

            在對一個指針變量進行 dereferance 的時候,比如 (*p)。編譯器首先要得到 p 的地址,從中取值,然后把得到的值作為地址,再取值。類似如下匯編:

            lea (p), %esi                        /* this is &p */
            mov (%esi), %edi                /* this is p */
            mov (%edi), %eax                /* this is p[0] */

            或者,更簡單的

            mov (p), %esi                        /* this is p */
            mov (%esi), %eax                /* and this is p[0] */

            相比之下,數(shù)組的引用

            int a[10];
            a[0];

            則省去了取 a 地址的過程,符號 a 代表一個地址,這個地址不存放在任何變量中!

            lea (a), %esi                    /* this is a */
            mov (%esi), %eax                 /* this is a[0] */       

            或更簡單的:

            mov (a), %esi                   /* this is a[0] */

            熟悉匯編的人,容易從看出,區(qū)別是大的。

            二、兩個例子
            第一個例子,演示 "把數(shù)組聲明為指針" 是如何使程序崩潰的。

            file: 1.c
            int a[10]={0};

            file: 2.c
            int
            main ()
            {
                    extern int *a;

                    printf ("%d\n", a[0]);
                    return 0;
            }

            運行這個程序,Segmentation fault

            在模塊1.c 中, a 被定義為一個數(shù)組,但在模塊 2.c中,a被聲明為指針。所以編譯器在處理        printf ("%d\n", a[0]) 時:
            認為 a 是一個指針,所以先取其地址&a,然而,a  實際是個數(shù)組,&a 就是 a本身,所的 &a 是 a 的首地址。
            然后編譯器取 指針a的值,這實際上是 得到的是數(shù)組的第一個元素 a[0] ,值為0!也就是,編譯器得到了一個 0 指針,最后,編譯器對其derefrence,崩潰!

            第二個例子演示“把指針聲明為數(shù)組”如何的到錯誤的數(shù)據(jù):

            file: 3.c
            int *pa = (int *)0;

            f ()
            {
                    printf ("%x\n", &pa);
            }

            file: 4.c
            int
            main ()
            {
                    extern int pa[];
                    printf ("%p\n", pa);
                    printf ("%d\n", pa[0]);
                    f ();
                           
                    return 0;
            }



            0x403010
            0
            403010

            在這個例子中, pa 被定義為一個指針,并初始化為0, 但在另一個模塊中,被聲明為一個數(shù)組.
            編譯器在處理 printf ("%p\n", pa) 時,認為 pa 是數(shù)組,所以直接打印符號pa的值,此值為指針pa的地址!

            編譯器在處理 printf ("%p\n", pa[0]) 時,認為 pa 是數(shù)組,以符號 pa 對應(yīng)的值加一個偏移0,并取其值,得到的實際上是 指針  pa 的值 即 0.

            三、總結(jié)

            我羅羅嗦嗦地講了半天,如果還不清楚,請研究一下我給出的代碼。


            [參考文獻]
            [1] Peter Van Der Linden, <<Expert C Programming --- Deep C Secrets>;>;

            posted on 2009-03-29 19:17 攀升 閱讀(2074) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            一本久久a久久精品综合香蕉| 夜夜亚洲天天久久| 婷婷国产天堂久久综合五月| 久久久免费观成人影院| 久久精品国产精品亚洲精品| 久久人人妻人人爽人人爽| 精品久久久噜噜噜久久久| 久久国产福利免费| 亚洲国产视频久久| 91精品婷婷国产综合久久| 香蕉久久夜色精品国产小说| 伊人伊成久久人综合网777| 精品无码久久久久国产| 久久久久九国产精品| 99久久人妻无码精品系列| 日本亚洲色大成网站WWW久久| 99久久精品国产高清一区二区 | 久久精品国产亚洲AV香蕉| 精品久久久久久亚洲| 午夜天堂av天堂久久久| 精品久久久久久久久久久久久久久| 久久乐国产综合亚洲精品| 国产精品九九久久免费视频| 亚洲AV乱码久久精品蜜桃| 怡红院日本一道日本久久 | 中文精品久久久久人妻不卡| 91精品无码久久久久久五月天| 人妻精品久久久久中文字幕一冢本| 久久久噜噜噜久久| 久久精品亚洲欧美日韩久久| 精品一区二区久久| 国产精品久久久久久福利漫画 | 亚洲国产精久久久久久久| 亚洲va久久久噜噜噜久久天堂| 久久噜噜久久久精品66| 久久天天躁狠狠躁夜夜av浪潮| 93精91精品国产综合久久香蕉| 99久久无色码中文字幕| 久久精品国产秦先生| 潮喷大喷水系列无码久久精品| 久久久久亚洲AV无码麻豆|