2010-09-21 40 views
1

我對現在正在使用的另一個程序員的C程序的行爲有些困惑。我無法理解的是以下幾點:當在C中調用函數時,是否應該給變量賦予一個新地址?

1)一個變量定義這樣

typedef float (array3d_i)[3]; 
array3d_i d_i[NMAX]; 

2)一旦某值assgined所有d_i的,一個函數被調用是這樣的:

void calc(elem3d_i d_element); 

其從主使用稱爲:

calc(d_i[i]); 
在一個循環

當d_i在main中初始化時,每個元素都會在內存中獲取一個地址,我猜測是在堆棧中或其他地方。當我們調用函數「calc」時,我期望在函數內部創建一個變量的副本,並放在更新的地址中。但是我調試了程序,我可以看到在函數「calc」中,變量「d_elemt」在main中獲得的地址與d_i相同。

這是正常與否?

我甚至更困惑,因爲後來有調用另一個函數,除非現在的變量是浮點類型,並且它們的數組被初始化,而且在函數內部,變量被賦予不同的地址比主要的還要多。

這怎麼可能?爲什麼區別?代碼或調試器是否奇怪?

謝謝

+0

在第二種情況下,它是否是一個浮點數組? – 2010-09-21 10:29:16

+0

是的,它是一個花車陣列 – flow 2010-09-21 10:29:44

+0

'd_i'是'array3d_i'的數組。 'array3d_i'是一個由3個浮點數組成的數組......所以'd_i'是一個由3個浮點數組成的數組。 – pmg 2010-09-21 10:35:13

回答

3

數組通過C中的引用傳遞,而簡單的值將按值傳遞。或者,相反,數組是也是按值傳遞,但此上下文中數組的「值」是對其第一個元素的引用。這是查爾斯在評論中提到的「衰變」。

「引用」,我的意思是當然指針,因爲C沒有像C++那樣的引用。

C沒有更高級別的數組概念,這也是爲什麼您無法計算被調用函數中數組長度的原因。

+1

參考?所有東西都按'C'中的值傳遞。 – pmg 2010-09-21 10:41:00

+0

如果「放鬆」是正確的,那麼「pmg」應該是錯的,反之亦然。誰是對的?我現在說「放鬆」,我更瞭解代碼 – flow 2010-09-21 10:47:50

+1

我認爲這是描述語言如何工作的一種誤導性方式。在C參數中總是按值傳遞。每當一個函數被聲明爲將一個'X'數組作爲參數時,它的類型就會被「調整」,而不是將一個指針指向'X',否則永遠不會真正擁有一個獲取數組的函數。當在表達式中使用數組的名稱時(除與地址 - &或sizeof一起使用),它將衰減爲指向數組的第一個元素的指針。當函數被調用的時候,傳入的是一個指針,其值與C中函數調用中的任何其他類型完全相同。 – 2010-09-21 11:32:24

2

這是指針和變量之間的區別。當你將一個數組傳遞給一個函數時,你正在傳遞一個指針(按值)。當你傳遞一個浮點數時,你傳遞一個浮點數(按值)。它都是按值傳遞的,但是對於數組,值是指針的地址。

0

請注意,「傳遞數組」與傳遞指針相同,並且在C中,所有參數都按值傳遞。

你在不同的功能中看到的是指針值。指針本身(由函數收到的參數)是一個不同的每個功能(可以檢查它的地址)

想象

int a = 42, b = 42, c = 42; 

如果你看一下ab,或c在調試器你總是看到42(),但它們是不同的變量。

0

正如其他人所指出的,一切都是通過價值傳遞的。但是,這可能會導致數組誤導。雖然類似於指針,但數組不是指針。指針是保存地址的變量。數組是在特定地址處的內存塊。對於數組,沒有單獨的變量來保存地址,就像指針一樣。當你將一個數組作爲參數傳遞給一個函數,或者通過給一個指針分配名字(不帶[]索引)來獲取它的地址時,你就會知道它的地址包含在一個變量中。所以,「通過值傳遞」是一個指針,而不是一個數組,即使你用一個數組作爲參數調用該函數。所以下面是等效的:

void func1(char *const arg); 
void func2(char arg[]); 
+0

'void func1(char * arg);'''void func2(char arg []);'是等同的。 – pmg 2010-09-21 11:50:03

相關問題