[英]proper pattern to use when passing an array to a function
我目前正在閱讀understanding pointers in c
,我在該部分討論了將數組傳遞給函數的問題。 在所有最好使用的波紋管模式中,為什么? ,它與優化有什么關系嗎?
#include <stdio.h>
void passAsPointerWithSize(int * arr, int size) {
for ( int i = 0; i < size; i++ ) {
printf("%d\n", arr[i]);
}
}
void passAsPointerWithoutSize(int * arr) {
while ( *arr ) {
printf("%d\n", *arr);
arr++;
}
}
void passWithoutPointerWithSize( int arr [] , int size) {
for ( int i = 0; i <= size; i++ ) {
printf("%d\n", arr[i]);
}
}
void passWithoutPointerUsingWhile(int arr []) {
int i = 1;
while ( arr[i] ) {
printf("%d\n", arr[i++]);
}
}
int main() {
int size = 5;
int arr[5] = { 1, 2, 3, 4 , 5};
passAsPointerWithSize(arr, size);
passAsPointerWithoutSize(arr);
passWithoutPointerWithSize(arr, size);
passWithoutPointerUsingWhile(arr);
}
我用-std=gnu11 -O3
編譯它
在函數參數的上下文中, int arr []
與int *arr
相同,因為當數組作為函數參數傳遞給函數參數時,它會衰減為指向其第一個元素的指針 。
所以以下聲明:
void foo(int * arr, int size);
相當於:
void foo(int arr[], int size);
當涉及到是否需要size
參數的問題時,您需要它來確定數組的長度,除非:
否則,你怎么可能知道數組包含多少元素?
在所有最好使用的波紋管模式中,為什么?
考慮到上述幾點,您可以隨時選擇的唯一事情是使用int *
語法還是int []
one作為函數參數。
盡管兩者都是等價的(如上所述),但是有些人可能會認為使用int *
可能表明最多只有一個元素,而int []
可能表明存在至少一個元素並且可能存在多個元素。
它與優化有什么關系嗎?
不,或者至少,不是直接,是否需要size
參數實際上是調用者是否知道數組的大小,或者是否可以通過存儲的數組末尾指示符獲得。
void passAsPointerWithSize(int * arr, int size) {
for ( int i = 0; i < size; i++ ) {
printf("%d\n", arr[i]);
}
}
這是不調用未定義行為的人。
使用while
的那些將不會停止,除非他們得到一個值為0
的元素。 如果數組沒有0
怎么辦? 然后它將訪問超出內存的方式(這是這里的情況)。 也許這個回聲回到了字符串過去常常用零標記的時候,無論如何,這都是不好的做法。
另一個for循環是循環,直到index<=size
訪問數組索引超出范圍時index = size
,同樣是未定義的行為。
在將1D數組傳遞給函數的上下文中,語法func(int arr[],..)
與func(int* arr,...)
相同 。 數組作為指針傳遞 - 如何指定簽名無關緊要。
循環? - 這只是一個選擇問題。
錯別字是其中一個函數中的<=
或i=1
初始化。 你不想打印第0個元素嗎? 那么i=1
然后你開始循環 - 它錯過了第0-th
元素。
一個編譯器,當傳遞一個數組時,處理指向數組的第一個元素的指針,無論你如何編寫它,所以表單無關緊要
在任何情況下 - 當您將數組作為指針傳遞給函數時 - 除非您有一些標記數組末尾的占位符,否則無法知道數組的長度。 如果不是這種情況,那么你必須明顯知道它的長度 - 這是你在函數中傳遞一個名為size
的參數時所做的。
將它寫為arr[]
可用於表達當我們處理該指針時它是一個數組的含義。 您可以瀏覽代碼並了解它作為參數獲得的內容以及可能執行的操作。 有人可能會說,評論仍然可以達到這個目的 - 這就是選擇進入圖片的地方。
是的,其中一些不起作用(你的意思是什么條件* arr例如?你試圖帶回空終止字符串嗎?不要!)
但是,實際上最快的一個(除非我在實踐中沒有看到一些瘋狂的編譯器優化)如果你不關心順序就是向后迭代
void passAsPointerWithSize(int *arr, int size) {
for ( int i = size - 1; i > 0; i-- ) {
printf("%d\n", arr[i]);
}
}
這是因為它在每個循環中節省了整個CPU時鍾周期,因為在減少i(i--)之后,比較為零(i> 0)的答案已經存儲在寄存器中
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.