2013-11-25 56 views
0

我碰到一些很奇怪的(至少對我來說),而我在讀一個C教程:爲什麼在傳遞數組作爲參數時使用一個自由維?

void foo(char arr[]){ 

} 


void main(){ 

    char old_buffer[100]; 

    foo(old_buffer);   //Working??! 
    char arr2[] = old_buffer; //Error! 


} 

與錯誤註釋的行我很清楚,old_buffer被當作一個地址,所以這個可以不起作用,因爲數組缺少應該分配多少內存的信息。但是,爲什麼這是在一個函數的頭部工作? 感謝您的支持:)

+0

你的意思是,它爲什麼在'void foo(char arr [])'中工作? –

+0

是的,正好:) – user2352375

+0

'char * arr2 = old_buffer'和'char * arr2 [] = {old_buffer};'都可以工作... –

回答

2

帶有錯誤註釋的行在我看來很清楚,old_buffer被視爲一個地址,所以這不能工作,因爲數組缺少信息應該分配多少內存。

這已經很接近,但它不完全發生的事情:有錯誤的行不是語法正確的 - 如果你將其更改爲

char *arr2 = old_buffer; 

它會奏效。但是,這不會是一個數組,它將是一個指針。這將允許類似數組的訪問,但它不會給你在sizeof中的正確值。

但是,爲什麼這是在一個函數的頭部工作?

因爲當您將數組傳遞給函數時,大小總是被忽略。據說數組衰減爲一個指針。換句話說,您的聲明與此相同:

void foo(char *arr) 
+0

正確,但爲什麼我可以在聲明函數(頭)時雙向寫它?即使(數組=指針)不起作用的功能(正文)? – user2352375

+0

@ user2352375這是原始C規範的編程人員所允許的,並沒有改變(事實上,他們允許的東西非常接近今天的語法,因爲參數是在函數的頭部之外聲明的,但是空括號在那裏回到K&R的語言版本)。儘管如此,它們從來不允許它用於本地和靜態,只能用於函數參數。 – dasblinkenlight

+0

@ user2352375如果我是你,我會清除你認爲C如何工作的任何先入爲主的觀念。在定義變量時,在函數聲明中寫入'arr []'與編寫'arr []'不同。當數組傳遞給函數時,會傳遞一個指向數組中第一個元素的指針。原來,函數聲明中的arr []和arr是相同的。 – Justin

1

old_bufferold_buffer[0]的地址,也就是&old_buffer[0]char arr[]相當於char *arr

0

c/C++中的數組用作MEM中順序指針的列表。 數組名稱是變量,它保存數組中第一個元素的地址。 當我們使用索引達到存儲在這個索引位置的值 編譯器知道,該值存儲在MEM位置,等於 存儲在數組名稱中的地址存儲在索引值中。 例如:

A[0] ='v' 
A = 0x000000 
A[4] = 'c' 

//it is location at 0x000000 + 4 
//so the 
&A[4] = 0x000004 

char * arr2 = old_buffer;將在你的代碼中工作,並且你可以將arr2作爲一個數組 處理,因爲它保存了MEM中預定位數組的第一個元素的地址。這種編譯器方式是讓你的代碼在函數頭部工作的原因。

相關問題