青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數據加載中……

extern數組與extern指針

數組名代表了存放該數組的那塊內存,它是這塊內存的首地址。這就說明了數組名是一個地址,而且,還是一個不可修改的常量,完整地說,就是一個地址常量。數組名跟枚舉常量一樣,都屬于符號常量。數組名這個符號,就代表了那塊內存的首地址。注意了!不是數組名這個符號的值是那塊內存的首地址,而是數組名這個符號本身就代表了首地址這個地址值,它就是這個地址。這就是數組名屬于符號常量的意義所在。由于數組名是一種符號常量,它是一個右值,而指針,作為變量,卻是一個左值,一個右值永遠都不是左值,那么,數組名永遠都不會是指針!

對于這段話我是這么理解的:數組名在經過編譯之后將變成一個數值,這個數值就是該數組的首地址。由于數組名是一個地址,那么把它賦給一個指針變量也就不足為奇了。

例如有定義

char a[14];

char * p;

char * q;

void foo(char * pt)

{

};

考慮以下幾種賦值:

p=a;//合法,將一個地址賦給一個指針變量;

q=p;//合法,將一個指針變量的值賦給另一個指針變量;

a=p;//非法,a是數組名即地址,不是一個變量,不可被賦值(也就是上文中說的"數組名是右值"

再看這幾種調用:

foo(a);//將一個地址作為參數傳入函數,函數中用一個指針變量接收這個地址值

foo(p);//將一個指針變量的值傳入函數(也是一個地址),函數中用一個指針變量接收這個地址

 

可以看出許多時候數組名和指針可以等同地看待,而c也把它們看作是兼容的類型對待,這就是為什么我那個錯誤的聲明不被編譯器在語法檢查的時候“喀嚓”的原因。

 

關于extern的作用,許多地方都有說明,例如可以在c++里進行c格式函數的聲明,可以聲明一個變量或函數是外部變量或外部函數;我們這里要討論的是外部變量的聲明。被extern修飾的全局變量不被分配空間,而是在連接的時候到別的文件中通過查找索引定位該全局變量的地址。

 

有了這些基礎后,我們現在正式開始研究extern 數組和extern 指針的問題:

 

首先在一個.c文件中有如下定義:

char a[]={1,2,3,4};

分析:這是一個數組變量的定義,編譯器將為這個數組分配4字節的空間,并且建立一個索引,把這個數組名、數組類型和它被分配的空間首地址對應起來。它被編譯之后生成一個中間文件

然后我們在另一個.c文件中分別以不同的形式進行聲明:

(1) extern char a[];

分析:這是一個外部變量的聲明,它聲明了一個名為a的字符數組,編譯器看到這個聲明就知道不必為這個變量分配空間,這個.c文件中所有對數組a的引用都化為一個不包含類型的標號,具體地址的定位留給連接器完成。編譯完成之后也得到一個中間文件,連接器遍歷這個文件,發現有未經定位的標號,于是它搜索其他中間文件,試圖尋找到一個匹配的空間地址,在此例中無疑連接器將成功地尋找到這個地址并將此中間文件中所有的這個標號替換為連接器所尋找到的地址,最終生成的可執行文件中,所有曾經的標號都應當已經被替換為地址。這是一個正常工作過程,連接出來的可執行文件至少在對于該數組的引用部分將工作得很好。

(2) extern char * a;

分析:這是一個外部變量的聲明,它聲明了一個名為a的字符指針,編譯器看到這個聲明就知道不必為這個指針變量分配空間,這個.c文件中所有對指針a的引用都化為一個不包含類型的標號,具體地址的定位留給連接器完成。編譯完成之后仍然得到一個中間文件,連接器遍歷這個文件,發現有未經定位的標號,于是它搜索其他中間文件,試圖尋找到一個匹配的空間地址,經過一番搜索,找到了一個分配過空間的名為a的地方(也就是我們先定義的那個字符數組),連接器并不知道它們的類型,僅僅是發現它們的名字一樣,就認為應該把extern聲明的標號連接到數組a的首地址上,因此連接器把指針a對應的標號替換為數組a的首地址。這里問題就出現了:由于在這個文件中聲明的a是一個指針變量而不是數組,連接器的行為實際上是把指針a自身的地址定位到了另一個.c文件中定義的數組首地址之上,而不是我們所希望的把數組的首地址賦予指針a(這很容易理解:指針變量也需要占用空間,如果說把數組的首地址賦給了指針a,那么指針a本身在哪里存放呢?)。這就是癥結所在了。所以此例中指針a的內容實際上變成了數組a首地址開始的4字節表示的地址(如果在16位機上,就是2字節)。本例中指針a的初值將會是0x0a090807little endian),顯然不是我們的期望值,所以運行會出錯也就理所應當了。

?

幾點細節:我們發現,使用extern修飾的變量在連接的時候只找尋同名的標號,不檢查類型,例如如果我們定義的甚至不是一個變量而是一個全局的函數,比如去掉定義

char a[]={....};

代之以

void a(){};

連接器居然也會連接通過。

實例如下:

比如在a.c文件中有這樣一段代碼

 

int g_i[] = {1, 2, 3, 4};

extern void testdotp();

 

void main(void)

{

   int i = 0;

   int num = 0;

   num = sizeof(g_i) / sizeof(int);

   for (i = 0; i < num; i++)

   {

      printf("g_i[%d] = %d ", i, g_i[i]);

   }

   printf("\n");

   testdotp();

}

 

而在b.c中的代碼如下:

extern int *g_i;

 

void testdotp()

{

   printf("*(&g_i + 2) = %d\n", *(&g_i + 2));

   printf("&g_i = %d\n", &g_i);

   printf("&g_i + 1= %d\n", &g_i + 1);

   printf("g_i = %d\n", g_i);

   printf("g_i + 1 = %d\n", g_i + 1);

}

運行結果為

g_i[0] = 1 g_i[1] = 2 g_i[2] = 3 g_i[3] = 4

*(&g_i + 2) = 3

&g_i = 4344368

&g_i + 1= 4344372

g_i = 1

g_i + 1 = 5

 

分析如下:

因為b.c文件中g_i變量的地址是a.c文件中g_i數組的首地址,故g_i的值為g_i[0]的值,&g_i的值為g_i地址的首地址。

 

*(&g_i + 2)的值:&g_i的值為g_i數組的首地址,(&g_i + 2)就為數組g_i3個元素的地址,*(&g_i + 2)就為第2個元素的值,即3

 

&g_i + 1:由于&g_i的值為g_i數組首地址,由于在32位機上運行,故&g_i + 1&g_i基礎上加上4個字節

g_i + 1:由于g_i是一個指針變量,g_i變量內存放的是地址,又因為g_i的值為1,而g_i + 1就為1 + 4的單元的內存空間(32位機上),故g_i + 15

 

posted on 2009-11-17 10:53 肥仔 閱讀(2071) 評論(0)  編輯 收藏 引用 所屬分類: C++ 基礎

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美日韩精品不卡| 亚洲综合色网站| 亚洲一区免费网站| 亚洲一区高清| 国产一区二区av| 欧美一区高清| 久久精品夜色噜噜亚洲a∨| 国产精品欧美日韩一区二区| 亚洲综合精品四区| 久久综合999| 免费在线成人| 好看的日韩视频| 久久免费黄色| 久久精品国产综合精品| 国产精品午夜电影| 亚洲一区二区三区高清 | 亚洲人永久免费| 欧美大片在线影院| 亚洲人成在线播放网站岛国| 9色porny自拍视频一区二区| 欧美午夜不卡视频| 欧美一级片一区| 欧美α欧美αv大片| 国产精品久久九九| 91久久国产自产拍夜夜嗨| 欧美成人嫩草网站| 欧美亚洲专区| 日韩视频在线观看国产| 欧美成人69| 欧美电影在线观看完整版| 久久精品亚洲精品| 欧美在线视频二区| 久久国产加勒比精品无码| 欧美一区二区三区四区夜夜大片| 一二三区精品福利视频| 欧美成人日本| 久久国产日本精品| 性亚洲最疯狂xxxx高清| 午夜在线播放视频欧美| 午夜日韩在线| 校园激情久久| 午夜在线电影亚洲一区| 亚洲制服av| 亚洲女ⅴideoshd黑人| 娇妻被交换粗又大又硬视频欧美| 欧美少妇一区二区| 欧美在线综合视频| 国产免费亚洲高清| 亚洲国产精品电影在线观看| 免费成人小视频| 久久综合九色欧美综合狠狠| 亚洲日韩欧美一区二区在线| 免费亚洲电影在线| 美女免费视频一区| 性欧美videos另类喷潮| 欧美在线观看www| 欧美国产综合一区二区| 一区二区毛片| 午夜精品在线观看| 老司机午夜精品| 亚洲欧美综合另类中字| 欧美激情1区2区3区| 一区二区三区高清在线| 久久成人av少妇免费| 一区在线观看| 欧美色精品在线视频| 久久激情网站| 久久精品国产99| 亚洲欧美网站| 欧美剧在线观看| 亚洲欧美激情在线视频| 欧美电影在线观看| 亚洲综合日韩中文字幕v在线| 国产精品日韩欧美大师| 久久精品成人一区二区三区| 亚洲欧美在线另类| 久久综合伊人77777| 夜夜爽99久久国产综合精品女不卡| 欧美永久精品| 久久在线视频| 久久成人亚洲| 久久精品国产久精国产一老狼| 国产精品一区二区久久久| 噜噜噜噜噜久久久久久91 | 韩国精品主播一区二区在线观看| 久久亚洲欧美| 亚洲影音先锋| 亚洲三级免费电影| 亚洲三级视频在线观看| 亚洲精品一区二区网址| 久久综合精品国产一区二区三区| 久久九九精品99国产精品| 亚洲精品视频免费| 亚洲欧美日韩电影| 亚洲一区二区在| 国产精品久久精品日日| 久久精品国产精品亚洲| 老巨人导航500精品| 亚洲一区二区精品视频| 久久久久国产免费免费| 欧美与欧洲交xxxx免费观看| 亚洲精品乱码| 午夜综合激情| 久久精品一区四区| 久久久成人精品| 亚洲一级免费视频| 国产精品午夜电影| 理论片一区二区在线| 一本到12不卡视频在线dvd | 亚洲日本中文字幕区| 国产亚洲精品bv在线观看| 亚洲高清一二三区| 亚洲日本电影| 亚洲综合国产精品| 亚洲一区二区三区免费观看| 久久国产精品第一页| 午夜久久一区| 亚洲大片在线观看| 亚洲高清在线观看| 亚洲视频图片小说| 免费中文日韩| 国产日韩精品在线| 国产亚洲va综合人人澡精品| 亚洲综合欧美日韩| 99在线热播精品免费99热| 久久av资源网| 在线观看欧美日韩国产| 一本色道久久综合亚洲精品小说| 亚洲国内欧美| 国产精品伦子伦免费视频| 欧美黑人国产人伦爽爽爽| 国产精品亚洲综合一区在线观看 | 欧美高潮视频| 久久在线91| 国产精品欧美日韩| 亚洲免费观看| 亚洲美女中文字幕| 久久在精品线影院精品国产| 午夜精品短视频| 国产精品久久午夜夜伦鲁鲁| 99这里只有久久精品视频| 亚洲一区二区三区色| 国产精品私房写真福利视频| 久久综合九色综合久99| 夜久久久久久| 午夜日韩视频| 国产精品女人久久久久久| 国产综合精品| 欧美国产日韩二区| 亚洲精品视频啊美女在线直播| 欧美精品99| 欧美一级成年大片在线观看| 美女诱惑黄网站一区| 久久精品二区三区| 国产欧美精品一区二区色综合 | 亚洲一区二区欧美日韩| 在线精品观看| 国产精品久久9| 欧美激情第10页| 久久先锋影音av| 午夜精品国产更新| 欧美中文在线观看| 亚洲精品午夜| 亚洲免费网站| 亚洲一区在线观看免费观看电影高清 | 久久精品二区亚洲w码| 免费一级欧美片在线播放| 亚洲观看高清完整版在线观看| 在线视频国内自拍亚洲视频| 久久久久国产精品一区三寸| 亚洲第一精品夜夜躁人人爽| 亚洲欧洲另类| 欧美久久久久久久久| 亚洲一区欧美激情| 最新亚洲激情| 91久久精品国产91久久| 亚洲日本中文字幕| 在线综合亚洲| 亚洲欧美另类中文字幕| 欧美在线观看一区二区| 欧美一级专区| 久久久久久久久一区二区| 久久久久国产精品一区三寸| 久久视频在线视频| 欧美国产在线视频| 国产精品vvv| 国产视频在线观看一区| 国产专区一区| 91久久黄色| 亚洲午夜精品| 久久―日本道色综合久久| 欧美aⅴ99久久黑人专区| 亚洲激情校园春色| 午夜精品久久久久久99热软件| 久久久久久久999精品视频| 麻豆免费精品视频| 亚洲日本成人| 另类尿喷潮videofree| 欧美日韩精品免费观看视频| 国产精品社区|