2015-01-11 58 views
1

在C語言編程語言中,有許多不同的方法來聲明將數組作爲參數傳遞給指針的函數的參數。函數參數中的int * vs int []與int(*)[]。我應該使用哪一個?

我準備了一個例子來向你展示我的意思。它是C++中std::accumulate函數的一個實現。它是一個函數,它執行數組中所有元素的添加並返回結果。

我可以寫這樣的:

int accumulate(int n, int *array) 
{ 
    int i; 
    int sum = 0; 
    for (i = 0; i < n; ++i) { 
     sum += array[i]; 
    } 
    return sum; 
} 

這也可以寫入到這個(這意味着同樣的事情):

int accumulate(int n, int array[]) 
{ 
    int i; 
    int sum = 0; 
    for (i = 0; i < n; ++i) { 
     sum += array[i]; 
    } 
    return sum; 
} 

我也可以寫這樣的:

int accumulate(int n, int (*array)[]) 
{ 
    int i; 
    int sum = 0; 
    for (i = 0; i < n; ++i) { 
     sum += (*array)[i]; 
    } 
    return sum; 
} 

所有這些選項都非常相似,並生成相同的可執行代碼,但它們有輕微區別在於調用者如何傳遞參數。

這是前兩個版本如何被稱爲:

int main(void) 
{ 
    int a[] = {3, 4, 2, 4, 6, 1, -40, 23, 35}; 
    printf("%d\n", accumulate(ARRAY_LENGTH(a), a)); 
    return 0; 
} 

這是THRID版本如何被稱爲:

int main(void) 
{ 
    int a[] = {3, 4, 2, 4, 6, 1, -40, 23, 35}; 
    printf("%d\n", accumulate(ARRAY_LENGTH(a), &a)); 
    return 0; 
} 

注意第三個選項要求用戶明確指定地址a&a。前兩個選項不需要這樣做,因爲數組會隱式轉換爲指向C中相同類型的指針。

我一直傾向於使用第三種方法。

這就是爲什麼:

  • 它與其他類型如何通過指針傳遞更加一致。

    int draw_point(struct point *p); 
    
    int main() 
    { 
        struct point p = {3, 4}; 
        draw_point(&p); // Here is the 'address of' operator required. 
    } 
    
  • 這使得它可以使用像ARRAY_LENGTH宏來獲取數組中元素的數量。

    #include <stdio.h> 
    #define ARRAY_LENGTH(A) (sizeof(A)/sizeof(A[0])) 
    
    void this_works(int (*array)[10]) 
    { 
        /* This works! */ 
        printf("%d\n", ARRAY_LENGTH(*array)); 
    } 
    
    void this_is_invalid_and_dangerous(int array[10]) 
    { 
        /* This does NOT work because `array` is actually a pointer. */ 
        printf("%d\n", ARRAY_LENGTH(array)); 
    } 
    

唯一的好處我int array[](和int *array)在int (*array)[]看到的是,你當你想抓住一個指數來寫的,而不是array[X](*array)[X]

但是因爲我不是專業人士,我會問你喜歡哪個版本。

你什麼時候用什麼?選擇其中一種選擇的原因是什麼?

我主要使用int (*array)[N]但我看到其他兩種方法也很常見。

+0

這是爲什麼downvoted? – wefwefa3

+0

我對任何一個答案都不滿意。它們都沒有提到'指向數組'的指針 - 這是'int array []'(在函數參數列表的上下文中有效的'int *')和'int(* array)[]'' 。 –

+0

@Jonathan如果你(或其他人)有東西要添加,你可以做出一個新的答案,我會接受,如果它更好。也許我在這個時候早些時候接受了一個答案,這阻止了新答案的出現。當我回顧這個問題時,我也意識到,對於這個Q&A網站來說,這可能太「基於觀點」,但如果您認爲其他答案缺少某些內容,請繼續並提出新答案。 – wefwefa3

回答

3

當用作功能參數時,int array[]int *array是相同的。你也可以使用。這是味道的問題。 int (*array)[]是繁瑣的,沒有被廣泛使用。

int (*array)[n]在二維數組傳遞給函數時使用最廣泛。在這種情況下,您可以訪問數組的元素array[i][j]

+0

不是一個真正的答案。你的答案的第一部分已經在問題中說明了。然後,這個問題不是關於二維數組......並且不,「int accumulate(int n,int(* array)[])'不足以能夠使用array [i] [j]'。爲此,你必須在'int(* array)[n]'中放入'n'。 –

+0

@JensGustedt;你的觀點是有效的。我做了一些更正。但是,對我來說,這個問題主要是基於意見的。 – haccks

1

我也更喜歡第三個變體,但它不是很常用。如果是這樣,與C99我會寫:在函數內部所有情況下

int accumulate(size_t n, int (*array)[n]) { .... 

這樣sizeof *array作品。

+0

你在說二維數組嗎?所以sizeof知道行長度? –

+0

@haccks,不,'[*]'僅適用於函數的原型,因爲參數的名稱不可用。要真正瞭解'sizeof * array',編譯器必須看到真實表達式,並且它是被評估的函數定義之一。 –

+0

@PaulOgilvie,不,我不是在說二維數組,這裏。這是一種將一個指針傳遞給一維數組並知道函數內數組大小的方言。 –

相關問題