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

            无码国内精品久久综合88| 思思久久好好热精品国产| 精品国产日韩久久亚洲| 精品人妻伦九区久久AAA片69| 久久夜色精品国产噜噜噜亚洲AV | 久久亚洲AV成人无码软件| 国产精品va久久久久久久| 久久国产精品久久久| 91精品国产高清久久久久久io| 性欧美大战久久久久久久久| 无码专区久久综合久中文字幕 | 一本色道久久88加勒比—综合| 囯产极品美女高潮无套久久久| 2021国内久久精品| 性做久久久久久久久浪潮| 久久午夜无码鲁丝片秋霞| 精品久久久中文字幕人妻| 一本色道久久HEZYO无码| 久久精品久久久久观看99水蜜桃| 伊人久久大香线蕉成人| 国产色综合久久无码有码| 久久久久无码精品国产不卡| A狠狠久久蜜臀婷色中文网| 欧美亚洲另类久久综合| 国产亚州精品女人久久久久久 | 久久久久久亚洲AV无码专区| 久久成人国产精品二三区| 国产精品无码久久久久| 色播久久人人爽人人爽人人片aV| 色99久久久久高潮综合影院| 亚洲国产精品成人久久| 久久精品国产亚洲网站| 久久久久黑人强伦姧人妻| 久久久久精品国产亚洲AV无码| 久久久久人妻精品一区二区三区| 国产成人久久久精品二区三区| 亚洲综合久久久| 99国产精品久久久久久久成人热| 久久精品国产99国产精品| 色综合久久久久无码专区| 91精品久久久久久无码|