在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]
但我看到其他兩種方法也很常見。
這是爲什麼downvoted? – wefwefa3
我對任何一個答案都不滿意。它們都沒有提到'指向數組'的指針 - 這是'int array []'(在函數參數列表的上下文中有效的'int *')和'int(* array)[]'' 。 –
@Jonathan如果你(或其他人)有東西要添加,你可以做出一個新的答案,我會接受,如果它更好。也許我在這個時候早些時候接受了一個答案,這阻止了新答案的出現。當我回顧這個問題時,我也意識到,對於這個Q&A網站來說,這可能太「基於觀點」,但如果您認爲其他答案缺少某些內容,請繼續並提出新答案。 – wefwefa3