• <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中對(duì)數(shù)組和指針的詮釋,覺得很講的很精彩,尤其對(duì)這種情況引起的錯(cuò)誤記憶猶新:
            file: 1.c
            int a[10]={0};

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

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


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

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

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

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


            一、理論分析

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

            對(duì)于指針

            int *p;

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

            .comm p, 4

            對(duì)于數(shù)組:

            int a[10]

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

            .comm a, 40

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

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

            或者,更簡(jiǎn)單的

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

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

            int a[10];
            a[0];

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

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

            或更簡(jiǎn)單的:

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

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

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

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

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

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

            運(yùn)行這個(gè)程序,Segmentation fault

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

            第二個(gè)例子演示“把指針聲明為數(shù)組”如何的到錯(cuò)誤的數(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

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

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

            三、總結(jié)

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


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

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


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


            久久综合综合久久狠狠狠97色88| 国产精品久久久久久福利漫画| 办公室久久精品| 欧美日韩中文字幕久久久不卡| 久久亚洲AV成人无码软件 | 精品久久久久久国产牛牛app| 欧美精品福利视频一区二区三区久久久精品| 久久亚洲国产精品123区| 亚洲欧美日韩久久精品第一区| 色综合久久综精品| 一本一本久久a久久综合精品蜜桃 一本一道久久综合狠狠老 | 久久久久人妻精品一区三寸蜜桃| 久久精品国产久精国产果冻传媒| 久久国产精品久久精品国产| 久久SE精品一区二区| 久久AⅤ人妻少妇嫩草影院| 久久精品国产久精国产思思 | 亚洲婷婷国产精品电影人久久| 99热成人精品热久久669| 色天使久久综合网天天| 欧美国产精品久久高清| 91久久精品国产91性色也| 久久精品国产亚洲av麻豆小说| 久久99这里只有精品国产| 国产女人aaa级久久久级| 久久99精品综合国产首页| 久久精品国产亚洲AV嫖农村妇女| 伊人久久大香线蕉亚洲五月天 | 99久久无码一区人妻a黑| 欧洲精品久久久av无码电影| 久久久久波多野结衣高潮| 精品无码久久久久国产动漫3d | 国产精品久久婷婷六月丁香| 九九久久精品无码专区| 国产精品久久久久一区二区三区 | 亚洲国产天堂久久综合| 一本大道久久香蕉成人网| 老男人久久青草av高清| 成人久久免费网站| 97久久久久人妻精品专区| 99精品久久精品|