• <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
            數據加載中……

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

                    剛看了expert C中對數組和指針的詮釋,覺得很講的很精彩,尤其對這種情況引起的錯誤記憶猶新:
            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時會報錯,那是不是編譯器更新了呢?
            由此轉一篇文章詮釋數組和指針的,作者win_hate , http://bbs.chinaunix.net/viewthread.php?tid=239405

            轉本貼請把 win_hate 的名字寫上。

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

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


            一、理論分析

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

            對于指針

            int *p;

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

            .comm p, 4

            對于數組:

            int a[10]

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

            .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] */

            相比之下,數組的引用

            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ū)別是大的。

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

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

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

            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, 但在另一個模塊中,被聲明為一個數組.
            編譯器在處理 printf ("%p\n", pa) 時,認為 pa 是數組,所以直接打印符號pa的值,此值為指針pa的地址!

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

            三、總結

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


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

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

            91精品国产综合久久婷婷| 国产精品成人精品久久久 | 伊人久久成人成综合网222| 欧美久久久久久午夜精品| 欧美日韩久久中文字幕| 久久久久高潮毛片免费全部播放| 国产精品免费福利久久| 色综合合久久天天给综看| 久久精品aⅴ无码中文字字幕不卡| 日韩精品国产自在久久现线拍 | 色婷婷噜噜久久国产精品12p| 国内精品综合久久久40p| 国产精品视频久久| 久久久久久国产精品美女| 国产精品久久久久久久| 久久成人小视频| 久久无码人妻精品一区二区三区 | 女同久久| 国产精品亚洲综合专区片高清久久久 | 久久乐国产精品亚洲综合| 久久99国产精品99久久| 亚洲AV无码成人网站久久精品大| 欧美亚洲日本久久精品| 久久精品国产精品青草| 久久综合综合久久综合| 久久天天躁夜夜躁狠狠躁2022 | 久久婷婷五月综合色高清| 亚洲国产成人精品女人久久久 | 久久综合狠狠综合久久综合88| 深夜久久AAAAA级毛片免费看| 国产一区二区精品久久岳| 婷婷综合久久狠狠色99h| 69久久精品无码一区二区| 久久国产精品99精品国产| av午夜福利一片免费看久久| 香蕉久久av一区二区三区 | 国内精品欧美久久精品| 香蕉久久夜色精品国产小说| 国产福利电影一区二区三区,免费久久久久久久精 | 久久精品视频一| 一本色道久久综合|