Kee*_*oek 4 c arrays parameters parameter-passing
在 stackoverflow 上的其他地方(例如,此处,不幸的是,目前接受的答案是不正确的——但至少最高投票的答案是正确的),C 标准规定,在几乎所有情况下,数组char my_array[50]都将隐式转换为char *when它被使用,例如通过传递给一个函数 as do_something(my_array),给定一个声明void do_something(char *stuff) {}。也就是说,代码
void do_something(char *my_array) {
// Do something
}
void do_something_2(char my_array[50]) {
// Do something
}
int main() {
char my_array[50];
do_something(my_array);
do_something_2(my_array);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
由 gcc 编译,没有任何严格级别的警告。
然而,C11的第6.3.2.1.3规定,此转换不发生特别是如果一个写操作&my_array,或sizeof(my_array)(而且这些是唯一次时,不会发生这种转换)。后一条规则的目的对我来说很明显——sizeof数组等于指向第一个元素的指针的大小是非常混乱的,所以应该避免。
但是这条规则的第一部分的目的(与写作有关&my_array)完全没有让我明白。看,该规则使类型为&my_array(在 C 标准的表示法中)char (*)[50],而不是char *。这种行为什么时候有任何用处?确实,除了 - 目的之外sizeof,为什么该类型根本char (*)[50]存在?
例如,在 stackexchange(例如这里)上也解释了任何声明的函数数组参数,例如char my_array[50]在do_something_2上面的定义中,在所有方面的行为都与char *my_array在声明中编写的完全相同,甚至char my_array[0]或char my_array[5]!更糟糕的是,这意味着do_something(my_array)在任何这些情况下编写编译都不会出现任何类型错误,而do_something(&my_array)(即将正确大小的数组类型传递给声明为准确接受该数组类型的函数)是一个错误!
综上所述,&C11 6.3.2.1.3的“ -part ”到底有没有用?如果是,那是什么?
(我能想到的唯一原因是为了使sizeof(&my_array)评估与 相同sizeof(my_array),但由于其他 C 标准规则,这甚至不会发生!---前一个sizeof(&my_array)结构“按预期”确实报告了指针的大小,而不是数组本身。请参见此处。)
事实上,除了 sizeof-目的之外,为什么 char 类型
(*)[50]存在呢?
给定char x[100][50],自动转换为x指针会产生一个指向其第一个元素的指针。它的第一个元素是 a char [50],因此指向它的指针是char (*)[50]。所以这是转换必须产生的类型。
当我们将一些二维数组(比如int x[100][50])传递给一个声明了参数的数组时int x[100][50],该参数将自动调整为int (*x)[50]。然后该函数将使用诸如x[i][j]. 如果x已经调整为其他类型,这将不起作用——我们需要x成为一个指针,char [50]以便x[i]正确计算 50 个元素的子数组的元素,并生成这样的子数组作为结果,然后可以与[j].
有时我们可能希望函数只在x. 为此,我们将传递该部分的起始地址。例如,我们可能会通过它&x[n], 从数组的第n行开始。和以前一样,调整后的函数参数是,所以我们需要给我们类型为 的子数组的地址。传递 a不是参数的正确类型。char (*)[50]&x[n]x[n]char (*)[50]char *
| 归档时间: |
|
| 查看次数: |
108 次 |
| 最近记录: |