簡體   English   中英

將數組傳遞給函數時使用的正確模式

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM