c指針和數組不同

主  題:   一道華爲面試題
作  者:   Aliens (異形們)
等  級:  
信 譽 值:   100
所屬論壇:   C/C++ C語言
問題點數:   20
回覆次數:   17
發表時間:   2007-7-30 0:07:29
     
 
     

文件1裏聲明全局變量:int array[5];
文件2裏聲明全局變量:extern int *array;
問在運行時會不會報錯,如果會,是在編譯時還是在鏈接時?

  我當時想:兩個不一樣呀,一個是數組一個是指針,可能會在編譯時出錯,面試官沒說對還是錯,接着說,我們的面試就到這兒,等通知吧。
  鬱悶呀,回家上機一試,僅僅是聲明變量,沒有給它們賦值,編譯和鏈接竟然順利通過,看了一下它們有地址,是相同的。不過還是覺得這題很詭異,於是在文件2里加了一條語句,array[0] = 1;
照舊編譯和鏈接順利通過,可是運行時發生了錯誤:

“try.exe 中的 0x004114c1 處未處理的異常: 0xC0000005: 寫入位置 0x00000005 時發生訪問衝突”

我call,這題不是人做的,誰能解釋這是怎麼回事?是編譯器和鏈接器都沒查出來的錯誤還是其他原因?
 
  回覆人:R9R9R9(豬頭餅) ( 二級(初級)) 信譽:100 2007-7-30 0:30:25 得分:0
 
 
?

樓主去看<<C專家編程.pdf>>這本書吧,這裏面關於這個問題,有很深的解釋

Top
 
  回覆人:marrco2005(高手前傳) ( 一級(初級)) 信譽:100 2007-7-30 0:55:59 得分:0
 
 
?

mark
Top
 
  回覆人:onemansdream() ( 一級(初級)) 信譽:100 2007-7-30 1:08:47 得分:0
 
 
?

int array[5];
int *array;
是一回事
因爲數組array存儲的時候就是按array的基指針存放的
所以int array[5]; = int *array;
比如array[0] = * array
array[0] = * array+1
extern在多文件中就是來聲明外部變量的
extern int *array; = extern int array[5];
聲明之後該文件就可以使用了
小概念,呵呵
Top
 
  回覆人:onemansdream() ( 一級(初級)) 信譽:100 2007-7-30 1:09:37 得分:0
 
 
?

array[1] = * array+1
應該是,寫錯了
Top
 
  回覆人:cunsh(村少) ( 一星(中級)) 信譽:96 2007-7-30 1:27:44 得分:0
 
 
?

樓上. 找個<<c專家編程.pdf>>吧
Top
 
  回覆人:Forkerl(清者自清) ( 一級(初級)) 信譽:100 2007-7-30 7:23:49 得分:0
 
 
?

三言兩語不好說,專家編程裏講了小半章呢。
大概意思就是先生命數組數組訪問array+偏移量(array本身是地址),
聲明成指針array編譯器就當作指針了,要取array裏保存的地址然後,用他保存的地址再加偏移量。而array本身就是地址,對地址再取址報錯很正常。你第二個文件裏array[0],此時的array就被當成指針了。
Top
 
  回覆人:LoveYouJustOneDay(哈哈) ( 三級(初級)) 信譽:100 2007-7-30 8:39:57 得分:0
 
 
?

//extern int array[5]; a[4]=123;
movl $123, array+16
聲明成 數組時, array是個地址,array[i]實際上就是array+i


//extern int *array; a[4]=123
movl array, %eax
addl $16, %eax
movl $123, (%eax)
聲明成指針時,需要對指針進行解引用
就是 先把指針裏存放的值+偏移 然後解引用


C語言語法給人的感覺是 數組跟指針幾乎一樣 但是內部實現是完全不同的

上面的情況跟下面的是有區別的
int a[10];
int *p=a;
p本身的地址跟a不同,p中存儲的是a的值
p[5] == (p中存儲的值 + 5*sizeof(int)) 這個地址中存儲的值 p中存儲的值是a的值

而int a[10];
extern int *a;
此處a的地址和a相等,是同一個數值
a[5]== (a中存儲的值+5*sizeof(int))這個地址存儲的值 第二個a中存儲的值 就是a[0]的值
Top
 
  回覆人:superyys(無血野人) ( 一級(初級)) 信譽:99 2007-7-30 9:18:30 得分:0
 
 
?

怎麼華爲就喜歡考這些BT問題?沒什麼實際用途!
Top
 
  回覆人:alps_008(潛水,冒泡,繼續潛水) ( 一級(初級)) 信譽:100 2007-7-30 9:33:08 得分:0
 
 
?

啊,又學到了,呵呵。樓上的講的挺明白的。
那麼最後結論是不應該這麼用還是怎麼的呢?
Top
 
  回覆人:LoveYouJustOneDay(哈哈) ( 三級(初級)) 信譽:100 2007-7-30 9:33:38 得分:0
 
 
?

華爲做底層開發 問這類問題很有實際意義
對C和彙編理解的透徹是做好底層的前提
Top
 
  回覆人:csShooter(Sharp Shooter) ( 二級(初級)) 信譽:100 2007-07-30 11:55:10 得分:0
 
 
?
好貼
Top
 
  回覆人:changke18() ( 一級(初級)) 信譽:100 2007-07-30 13:25:43 得分:0
 
 
?
回覆人:onemansdream() ( 一級(初級)) 信譽:100

回答的很好
Top
 
  回覆人:csShooter(Sharp Shooter) ( 二級(初級)) 信譽:100 2007-07-30 13:28:08 得分:0
 
 
?
《C專家編程.pdf》裏面就是有:


數組與指針是不一樣的!
Top
 
  回覆人:BEYOND_Q() ( 一級(初級)) 信譽:100 2007-07-30 14:12:19 得分:0
 
 
?
我個人認爲在文件1中的int array[5] 和 文件2中的extern int *array 沒什麼關係。
在C語言裏,如果extern 是全局變量的聲明它只是告訴編譯器,這個變量可以在外部引用。而是在一個函數內部,則是告訴編譯器這個變量是在外部定義的。總的來說就是擴張這個變量的使用範圍。
所以編譯連接都沒問題。
但是,你沒有爲你的*extern開闢內存空間。如果你使用*(array + 1)或者array[1](文件2中的指針變量)。就會出現非法內存訪問。而使用文件1中的array是沒有問題的。

呵呵。個人見解。如有錯誤還請指正。
Top
 
  回覆人:alps_008(潛水,冒泡,繼續潛水) ( 一級(初級)) 信譽:100 2007-07-30 14:13:18 得分:0
 
 
?
剛下了一個《C專家編程.pdf》
裏面第四章就是:『令人震驚的事實:數組和指針並不相同』
確實就是以這個問題爲例,講的很好
Top
 
  回覆人:linuxjackaroo() ( 一級(初級)) 信譽:100 2007-07-30 14:33:15 得分:0
 
 
?
那個我昨天看了。還沒太年懂。。。。鬱悶呢。
Top
 
  回覆人:lostinger(我終於明白了我還有好多事情不明白!) ( 一級(初級)) 信譽:100 2007-07-30 14:47:24 得分:0
 
 
?
good
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章