一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

C/C++中的指針和數(shù)組(二)

 荔枝園子 2016-07-26

前面已經(jīng)討論了指針和數(shù)組的一些區(qū)別,然而在某些情況下,指針和數(shù)組是等同的,下面討論一下什么時(shí)候指針和數(shù)組是相同的。

C語言標(biāo)準(zhǔn)對(duì)此作了說明:

規(guī)則1:表達(dá)式中的數(shù)組名被編譯器當(dāng)做一個(gè)指向該數(shù)組第一個(gè)元素的指針;

          注:下面幾種情況例外

          1)數(shù)組名作為sizeof的操作數(shù)

          2)使用&取數(shù)組的地址

規(guī)則2:下標(biāo)總是與指針的偏移量相同;

規(guī)則3:在函數(shù)參數(shù)的聲明中,數(shù)組名被編譯器當(dāng)做指向該數(shù)組第一個(gè)元素的指針。

       規(guī)則1和規(guī)則2結(jié)合在一起理解,就是對(duì)數(shù)組下標(biāo)的引用總是可以寫成“一個(gè)指向數(shù)組的起始地址的指針加上偏移量”。如a[i]總是被編譯器解析為*(a+i)的形式。

 

規(guī)則1:表達(dá)式中的數(shù)組名總被編譯器解析為指針,因此如下語句int a[3];int *p=a;是可以正確編譯執(zhí)行的。在表達(dá)式中a被解析為指向數(shù)組第一個(gè)元素的指針,那么賦值符號(hào)兩邊的類型匹配,因此可以正確編譯執(zhí)行。

規(guī)則2:下標(biāo)總是和指針的偏移量相同。C語言中將數(shù)組的下標(biāo)改寫成指針偏移量的主要原因在于指針和偏移量是底層硬件所使用的基本類型。如a[i]中的i總被編譯器解析為偏移量,所以a[i]總是被改寫成*(a+i)的形式,a是指向數(shù)組第一個(gè)元素的指針,加上偏移量i,表示該指針向后移i個(gè)步長,然后取a+i所在單元的內(nèi)容。由此就可以解釋為什么C語言中數(shù)組的下標(biāo)可以為負(fù),而且在我看來,C語言中不檢查數(shù)組的下標(biāo)是否越界同樣跟這個(gè)有關(guān),如下面這段程序:


#include<stdio.h>
 main()
{
     a[]={,,};
     *p=(a+);
    printf(,p[-]);
     ;
}


程序執(zhí)行結(jié)果為3,雖然下標(biāo)為-1,但是被編譯器解析為偏移量,因此相當(dāng)于*(p-1)。

規(guī)則3:在函數(shù)參數(shù)的聲明中,數(shù)組名被編譯器當(dāng)做指向該數(shù)組第一個(gè)元素的指針。在C語言中將形參的數(shù)組和指針等同起來是出于效率的考慮。假如不這么做,將整個(gè)數(shù)組的每個(gè)元素的值都拷貝一份進(jìn)行傳遞,這樣無論在時(shí)間上還是空間上的開銷都可能是非常大的。但是又要能操作到數(shù)組中的元素,只需將數(shù)組第一個(gè)元素的地址傳遞給調(diào)用函數(shù),然后通過指針去訪問想要訪問的空間,這樣一來時(shí)空消耗將大大減少。因此在函數(shù)內(nèi)部,編譯器始終把參數(shù)中聲明的數(shù)組名當(dāng)做一個(gè)指向數(shù)組第一個(gè)元素的指針,這樣一來,編譯器可以產(chǎn)生正確代碼,并不需要對(duì)數(shù)組和指針這兩種情況作區(qū)分。因此void fun(int a[]);和void fun(int *a)兩種形式的效果完全等同,在函數(shù)內(nèi)部去引用a的話,始終都會(huì)被編譯器認(rèn)為是指針。因?yàn)関oid fun(int a[]);這種形式最終還是會(huì)被編譯器解析為void fun(int *a);這種形式告訴我們調(diào)用時(shí)必須傳遞一個(gè)指向整型數(shù)據(jù)的指針。所以下面這段代碼可以正確編譯和執(zhí)行:

void fun(int a[])

{

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

}

int main(void)

{

    int a[3]={1,2,3};

    int *p1,*p2;

    int b=4;

    p1=a;

    p2=&b;

    fun(a);

    fun(&a[1]);

    fun(p1);

    fun(p2);

    fun(&b);

    return 0;

}

區(qū)分幾個(gè)表達(dá)式的含義:

&p,p,a,&a

&p:表示取存儲(chǔ)指針變量p的內(nèi)存單元的地址;  sizeof(&p)=4;

p:表示取指針變量p存儲(chǔ)的地址;                     sizeof(p)=4;

a:表示取數(shù)組第一個(gè)元素的地址;                    sizeof(a)=3*4=12;

&a:表示取整個(gè)數(shù)組的首地址;                        sizeof(&a)=4(在VC++6.0中該值為12,我認(rèn)為是錯(cuò)誤的,因?yàn)槠漕愋褪菙?shù)組指針)

雖然a和&a的值相同,但是所表達(dá)的含義完全不同,a表示取數(shù)組第一個(gè)元素的地址,而&a表示取數(shù)組的首地址。它們所代表的類型也完全不同,a是一個(gè)int型指針,而&a是一個(gè)int (*p)[]型指針,即數(shù)組指針(在后續(xù)文章中會(huì)作解釋)。所以a+1和&a+1得到的結(jié)果不同,a+1表示將指向該數(shù)組的第一個(gè)元素的指針向后移一個(gè)步長(這里的步長為數(shù)組元素類型所占的字節(jié)數(shù));而&a+1表示將指向該數(shù)組的指針向后移動(dòng)一個(gè)步長(而此處的步長為數(shù)組元素個(gè)數(shù)*元素類型所占的字節(jié)數(shù))。

#include<stdio.h>
 main()
{
     a[]={,,};
     *p=a;
    printf(,&p);
    printf(,p);
    printf(,&p+);
    printf(,p+);
    printf(,a);
    printf(,&a);
    printf(,a+);
    printf(,&a+);         ;
}


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    美女被后入视频在线观看| 美女露小粉嫩91精品久久久| 国产欧美高清精品一区| 亚洲一区二区欧美在线| 欧美午夜一级艳片免费看| 欧美精品在线观看国产| 日韩精品视频高清在线观看| 久久精品国产熟女精品| 九九蜜桃视频香蕉视频| 欧美午夜一区二区福利视频| 欧美国产日产在线观看| 日韩一本不卡在线观看| 亚洲乱妇熟女爽的高潮片| 日韩日韩欧美国产精品| 亚洲黄色在线观看免费高清 | 欧美中文字幕日韩精品| 蜜桃传媒在线正在播放| 亚洲天堂精品在线视频| 国产传媒免费观看视频| 亚洲中文字幕高清乱码毛片| 韩国日本欧美国产三级| 人妻一区二区三区在线| 99久只有精品免费视频播放 | 韩日黄片在线免费观看| 两性色午夜天堂免费视频| 成人午夜视频在线播放| av国产熟妇露脸在线观看| 欧美亚洲另类久久久精品| 国产乱久久亚洲国产精品| 国产精品不卡一区二区三区四区| 中文字幕av诱惑一区二区| 色好吊视频这里只有精| 国产一区二区三区四区免费| 欧美日韩乱一区二区三区| 国产日韩精品欧美综合区| 国产精欧美一区二区三区久久| 国产精品一区二区三区欧美 | 少妇福利视频一区二区| 暴力三级a特黄在线观看| 大香蕉精品视频一区二区| 欧美成人精品国产成人综合|