我目前正在阅读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
答案 0 :(得分:4)
在函数参数的上下文中,int arr []
与int *arr
相同,因为当数组作为函数参数传递给函数参数时,衰减成指针到第一个元素 。
以下声明:
void foo(int * arr, int size);
相当于:
void foo(int arr[], int size);
当涉及到是否需要size
参数的问题时,您需要它来确定数组的长度,除非:
否则,您怎么可能知道数组包含多少元素?
最好使用的所有波纹管模式以及为什么?
考虑到以上几点,您唯一可以选择的是使用int *
语法或int []
语法作为函数参数。
尽管两者都是等价的(如上所述),但有些人可能会争辩说使用int *
可能表明最多只有一个元素,而int []
可能表明存在至少一个元素并且可能有不止一个。
它与优化有什么关系吗?
不,或者至少,不是直接,是否需要size
参数实际上是调用者是否知道数组的大小,或者是否可以通过存储的阵列末尾指标。
答案 1 :(得分:3)
void passAsPointerWithSize(int * arr, int size) {
for ( int i = 0; i < size; i++ ) {
printf("%d\n", arr[i]);
}
}
这是不调用未定义行为。
使用while
的人不会停止,除非他们获得值为0
的元素。如果数组没有0
&s 39?然后它将访问超出内存的方式(这是这里的情况)。也许这个回声回到了字符串过去常常用零标记的时候,无论如何,这都是不好的做法。
另一个for循环是循环,直到index<=size
访问数组索引超出范围index = size
,同样,未定义的行为。
在将1D数组传递给函数 的上下文中,语法func(int arr[],..)
与func(int* arr,...)
相同。数组作为指针传递 - 与指定签名的方式无关。
循环? - 这只是一个选择问题。
错别字是其中一个函数中的<=
或i=1
初始化。你不想打印第0个元素吗?好i=1
然后你开始循环 - 它错过了0-th
元素。
编译器在传递数组时会处理指向数组第一个元素的指针,无论你如何编写它,所以形式并不重要
在任何情况下 - 当您将数组作为指针传递给函数时 - 除非您有一些标记数组末尾的占位符,否则无法知道数组的长度。如果情况并非如此,那么您显然必须知道它的长度 - 这是您在函数中传递名为size
的参数时所执行的操作。
将它写为arr[]
可用于表达当我们处理该指针时它是一个数组的含义。您可以浏览代码并了解它作为参数获得的内容以及可能执行的操作。有人可能会说,评论仍然可以达到这个目的 - 这就是选择进入图片的地方。
答案 2 :(得分:1)
是的,其中一些不起作用(例如,条件* 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)的答案已经存储在寄存器中