根据“Difference between passing array and array pointer into function in C”,这两种声明参数的方式之间没有语义差异,因为“数组参数被视为被声明为指针”。
void f1(int a[]) { /* ... */ }
void f2(int* a) { /* ... */ }
然而,处理数组和指针之间存在很大差异。例如,可以使用sizeof(some_array)
找出数组的大小。但是,在处理指针时,这只会显示指针本身的大小。 (旁注:This是关于这个问题的一个非常巧妙的解决方法。)
这就是为什么我发现声明这样的参数会引起误导:f1(int a[])
。正如 djechlin 在“Difference between array and pointer as a function's argument in c”中所指出的那样,我认为它可以欺骗人们认为一个人实际上是在处理数组而不仅仅是指针:“因此我总是喜欢指针形式,因为数组形式可能会引起微妙的混淆。“
话虽如此,我想知道为什么人们继续使用“阵列形式”,因为似乎没有理由这样做。我在这里错过了什么?在他的书Learn C The Hard Way中,Zed Shaw实际上混合了两种方式:
void print_arguments(int argc, char *argv[]) { /* ... */ }
他们也在K& R2中这样做。
为什么呢?我熟悉不这样做的原因,但有哪些优点呢?
答案 0 :(得分:3)
从技术上讲,我没有意识到任何原因,但在语义上意义更清晰。
如果我看到一个函数接受指向某个东西的指针,我希望它是一个单独的项目,除非变量名称(和/或可能的函数名称)清楚地表明它将预期一个数组。
然而,如果它被标记为采用数组,那很明显。多个**
尤其如此 - 请参阅char *argv[]
示例。这显然是指向char*
的数组(即字符串)的指针。 char **argv
可能是那个,但它也可能是一个可变指针(例如,用于释放)。虽然char argv[][]
意味着二维数组(char *argv[]
没有)。
答案 1 :(得分:2)
哪一个更容易理解:
char *argv[] is intended to be an array of pointers to chars
或
char **argv is a pointer to a pointer to a char
是的,您可以用非直观的方式编写C代码,但为什么会这样?
您更喜欢哪个:
a[2]
*(a + 2)
*(2 + a)
2[a]
都具有相同的效果。为什么当它只是语法糖时使用[]
?因为它更具可读性。与此类似:(*ps).member
不像ps->member
答案 2 :(得分:0)
虽然两个声明都相同,但是当您想要将指针传递给数组时,第一个声明更可取。人们可以很容易地理解这一点 如果是后者,则无法预测您是将指针传递给单个元素还是数组。