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

            久久综合狠狠综合久久| 97久久久精品综合88久久| 久久影视综合亚洲| 久久亚洲高清综合| 久久人人爽人人爽人人av东京热| 一级女性全黄久久生活片免费 | 18岁日韩内射颜射午夜久久成人| 2021久久国自产拍精品| 品成人欧美大片久久国产欧美| 色偷偷91久久综合噜噜噜噜| 人妻丰满AV无码久久不卡 | 久久免费美女视频| 国产精品99久久不卡| 国产精品久久久久久久久软件| 国产精品国色综合久久| 久久无码AV中文出轨人妻| 亚洲伊人久久综合中文成人网| 久久亚洲私人国产精品vA| 久久亚洲AV永久无码精品| 国产99久久精品一区二区| 亚洲国产精品成人AV无码久久综合影院 | 久久精品亚洲男人的天堂| 一本一本久久a久久综合精品蜜桃| 久久精品国产免费| 久久精品国产亚洲av麻豆图片| 久久99精品久久久久婷婷| 久久久久久极精品久久久| 婷婷五月深深久久精品| 久久亚洲国产欧洲精品一| 久久天天躁狠狠躁夜夜avapp | 久久人妻无码中文字幕| 亚洲AV日韩精品久久久久| 国产亚洲色婷婷久久99精品91| 久久99国产精品尤物| 一本色道久久HEZYO无码| 久久嫩草影院免费看夜色| 久久婷婷国产麻豆91天堂| 无码任你躁久久久久久老妇App| 久久精品二区| 99久久亚洲综合精品网站| 2021精品国产综合久久|