C 将数组传递给函数时要使用的正确模式

C 将数组传递给函数时要使用的正确模式,c,arrays,pointers,C,Arrays,Pointers,我目前正在阅读理解c中的指针,我在作者谈到将数组传递给函数的那一部分。在所有的波纹管模式中,哪一种最适合使用?为什么,这与优化有什么关系吗 #include <stdio.h> void passAsPointerWithSize(int * arr, int size) { for ( int i = 0; i < size; i++ ) { printf("%d\n", arr[i]); } } void passAsPointerWithoutSi

我目前正在阅读
理解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);
}
#包括
空隙尺寸(内部*arr,内部尺寸){
对于(int i=0;i对于(int i=0;i在函数参数的上下文中,
int arr[]
int*arr
相同,因为当数组作为函数参数传递给函数参数时,会衰减为指向其第一个元素的指针

因此,声明如下:

void foo(int * arr, int size);
相当于:

void foo(int arr[], int size);
当涉及到是否需要
size
参数的问题时,需要它来确定数组的长度,除非:

  • 数组中存储了一个特殊值,用作数组末尾的指示符(被调用方将负责检查该指示符)
  • 调用方已经知道数组的长度
否则,您怎么可能知道数组包含多少个元素


在所有的波纹管模式中,哪一种最适合使用,为什么

考虑到以上几点,您唯一可以选择的是使用
int*
语法还是使用
int[]
语法作为函数参数

尽管这两个元素是等效的(如上所述),但有些人可能会认为使用
int*
可以表示最多有一个元素,而
int[]
可以表示至少有一个元素,并且可以有多个元素

这和优化有什么关系吗


不,或者至少不是直接的,您是否需要
size
参数实际上是一个问题,即调用方是否知道数组的大小,或者是否可以通过存储的数组结束指示符来获取数组的大小。

是的,其中一些参数不起作用(例如,您所说的条件*arr是什么意思?您是否试图返回以null结尾的字符串?不要!)

但是,实际上,如果你不关心顺序的话,最快的一个(除了一些我在实践中没有见过的疯狂的编译器优化)是向后迭代

void passAsPointerWithSize(int *arr, int size) {
  for ( int i = size - 1; i > 0; i-- ) {
    printf("%d\n", arr[i]);
  }
}
这是因为它在每个循环中都节省了一个完整的CPU时钟周期,因为在减少i(i-)之后,比较到零(i>0)的答案已经存储在寄存器中

首先查看哪个是正确的!(根据您发布的内容)
void passAsPointerWithSize(int*arr,int size){
对于(int i=0;i
这是一个调用未定义行为的而不是

使用
while
的数组不会停止,除非它们得到一个值为
0
的元素。如果数组没有
0
,那么它将访问内存之外的内容(这里就是这种情况)。也许这回想起了以前字符串末端用零标记的时候,无论如何,这是一种不好的做法


另一个for循环是循环,直到
索引那些没有
大小的
调用未定义的行为,所以不要使用那些。
那些
循环怎么会停止呢?在另一个
for
中,你访问的是越界的。到目前为止,我只看到其中一个工作正常。你是对的,第二个是你t在执行后执行3276,直到我使用
-O3
@OliverCharlesworth@coderredoc他们都被处决了fine@coderredoc:已修复,在第二次查看后…:}即使有了指示器,代码也会出错……如果你在数组的中间得到这个指示符/ @ CoDeReDoc,有人甚至会忘记存储指示器。这是C字符串后面的约定——你可以在 char < /Case>数组中嵌入<代码> \ 0代码>代码,理解所有C字符串函数将它作为字符串标记的结尾。@ dasBink KLIN。是的,但这不是字符数组,是的,我们可以有这种行为。你是对的。n yes OP的数组不包含
0
。所以确定UB.@coderredoc OP是另一个故事,他在复制文章中的代码时,成功地犯了几个拼写错误(我认为
I=1
公平,我不知道还有其他拼写,谢谢
void passAsPointerWithSize(int * arr, int size) {
  for ( int i = 0; i < size; i++ ) {
    printf("%d\n", arr[i]);
  }
}