• <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上時,發現這個程序Link時會報錯,那是不是編譯器更新了呢?
            由此轉一篇文章詮釋數組和指針的,作者win_hate , http://bbs.chinaunix.net/viewthread.php?tid=239405

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

            略談 c 語言中指針與數組的區別

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


            一、理論分析

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

            對于指針

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

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

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

            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 攀升 閱讀(2081) 評論(0)  編輯 收藏 引用

            久久午夜福利电影| 国产激情久久久久久熟女老人| 97久久香蕉国产线看观看| 精品国际久久久久999波多野| 久久九九全国免费| 2021国内久久精品| 国产激情久久久久影院老熟女免费| 久久久久国产一区二区三区| 狠狠色婷婷久久一区二区 | 亚洲国产精品综合久久网络| 国产成人精品综合久久久久| 精品久久久久久久久久中文字幕 | 久久国产成人午夜aⅴ影院 | 精品久久久久中文字幕日本| 日韩电影久久久被窝网| 中文精品久久久久国产网址| 亚洲午夜久久久久久噜噜噜| 久久久精品国产亚洲成人满18免费网站 | 亚洲午夜久久久| 激情综合色综合久久综合| 国产亚洲精久久久久久无码| 久久久久久久久久久精品尤物 | 亚洲午夜久久久久久久久久| 欧美久久天天综合香蕉伊| 久久996热精品xxxx| 国产精品欧美久久久天天影视| 亚洲人成网亚洲欧洲无码久久 | 久久久久久亚洲AV无码专区| 综合久久一区二区三区 | 91精品国产91久久久久福利| 婷婷久久香蕉五月综合加勒比| 久久笫一福利免费导航| 亚洲七七久久精品中文国产| 亚洲日韩欧美一区久久久久我| 久久无码人妻精品一区二区三区| 久久亚洲天堂| 超级97碰碰碰碰久久久久最新| 久久久久se色偷偷亚洲精品av| 亚洲av伊人久久综合密臀性色| 亚洲AV无码1区2区久久| 国产精品99久久99久久久|