2013-03-19 65 views
0

我正在讀的TCPL被K & R,當我讀一些有關數組和指針,我寫低於這個小的代碼:當我使用數組名稱作爲參數調用函數時會發生什麼?

#include <stdio.h> 
int sum(int a[]) 
{ 
    int t = 0; 
    int length = sizeof(a)/sizeof(a[0]) ; 
// printf("%d\n",length); 
    for(int i = 0; i != length; ++i) 
    { 
     t += a[i]; 
    } 
    return t; 
} 
int main() 
{ 
    int b[5] = {1, 2, 3, 4, 5}; 
    printf("%d\n",sum(b)); 
    return 0; 
} 

輸出答案是1而不是15,則我通過添加調試代碼printf("%d\n",length);輸出長度爲1而不是5 的TCPL告訴一個數組名稱轉換爲指針當數組名作爲參數,但輸出的答案是錯誤的,所以我想知道的是:

  1. 什麼時候調用happend用數組名稱作爲參數的函數?
  2. 數組a[]使用參數sum(int a[])是否有存儲?
  3. 我在調用數組時看到兩種樣式:fun(int a[]); fun(b)fun(int *a);fun(b),有什麼區別?

THX非常:-)

+1

'INT長度=的sizeof(A)/的sizeof(A [0]);'的sizeof(a)是4個字節,的sizeof( a [0])也是4個字節。如何使用length()? – Sergio 2013-03-19 07:59:39

+5

這個問題每天大概需要3-4次。 – cnicutar 2013-03-19 07:59:39

+1

加上你的'for'不正確。它應該是'for(int i = 0; i <= length; ++ i){...}' – varnie 2013-03-19 08:03:14

回答

1

你的第三個問題得到了問題的核心:就編譯器而言,這兩者之間沒有區別。關於如何傳遞參數的一切都是一樣的。

因此,在回答第二個問題時,a參數沒有存儲底層數組的存儲空間,也沒有複製該數組的成員。分配的唯一存儲空間爲int *指針,並且該指針存儲在a中。 (這也有點回答你的第一個問題。)

所以,在你的函數:

int length = sizeof(a)/sizeof(a[0]) ; 

相當於

int length = sizeof(int *)/sizeof(int); 

它在哪裏指針和整數大小相同的系統返回1。如果你在64位的Linux上運行它,你會得到2,因爲指針是64位,並且整數是32位。

+0

如果我添加'int length = sizeof(b)/ sizeof(b [0]);'並返回正確答案:5。兩種不同的'sizeof'用法? – skyline09 2013-03-19 08:39:34

+0

在'main'中?是的,因爲'main'中的'b'被聲明爲一個數組並且具有一個大小。它只是作爲一個函數參數,使數組「衰減」到指針並丟失它們的大小信息。 sizeof計算適用於聲明爲本地或全局變量而非參數的數組。 – rra 2013-03-19 08:41:33

3

不能調用一個函數,並傳遞一個整個陣列;如果使用數組名稱作爲函數參數,則它會隱式重寫爲(「衰減到」)指向其第一個元素的指針。它等同於寫

int sum(int *a) { ... } 

因此,函數,sizeof array內,不會給你的數組的大小,只有一個指向它的第一個元素的大小。

那麼如何知道陣列中有多少元素?你需要將這個數字明確地傳遞給函數(或者定義一個具有元素數量的宏,並在需要的地方使用它)。

1

調用聲明的陣列上sizeof如下

int a[5]; 

將返回數組的大小,你現在怎麼想它會(即全尺寸的數組的字節 - 在這種情況下,在20個字節我機)。當你像這樣將一個數組傳遞給一個函數時,該數組將衰減爲指向其第一個元素的指針。因此,當你在你的函數參數上調用sizeof時,你實際上是在指針類型上調用它。如果您宣佈自己的函數採用int *參數,則錯誤會更明顯,因爲您稱爲sizeof的變量的類型是顯式的。

0

沒有您的通話沒有問題,且有fun(int a[])fun(int *a)(希望這是更明顯的是,你期望一個數組,並沒有任何指針讀者)之間沒有差別。 Bot參數是一個指向int的指針。

這裏你的問題是你如何嘗試確定數組的長度。由於方括號是空的,編譯器無法知道a後面的數組有多長。例如,你可以提供數組的長度作爲第二個參數。注意:當調用函數時,sizeof(b)將提供正確的長度,因爲編譯器知道它的長度。

-1

sizeof()運算符不能用於獲取動態分配的數組長度。

Here你可以找到使用sizeof()的例子。

當你試圖做sizeof(array_ptr)它實際上是給你指針的大小

因此,必須傳遞數組長度作爲函數的參數

+0

-1,你的第一句是錯的。 – 2013-03-19 08:41:25

+0

@JensGustedt固定。 – Alex 2013-03-19 08:52:27

+0

仍然不完全正確,VLA也是動態分配的。 C看作數組,總是可以用'sizeof'。事情就是在函數中你得到一個指針而不是數組。 – 2013-03-19 12:58:43

相關問題