由于您刚刚学习C,我建议您首先真正try 理解数组和指针之间的differences,而不是common.
在参数和数组方面,有一些令人困惑的规则,在继续之前应该弄清楚.首先,在有些情况下,C中的函数参数是没有意义的
第二个可能还不清楚.但是,当您认为数组维度的大小是C中的类型的一部分(并且没有给出维度尺寸的数组具有不完整类型)时,这一点就很明显了.所以,如果你想创建一个函数,它接受一个数组的值(接收一个副本),那么它只能接受一个大小!此外,数组可能会变大,C会尽可能快.
在C中,由于这些原因,array-values是不存在的.如果你想得到一个数组的值,你会得到一个指向该数组第一个元素的指针.事实上,解决方案就在这里.C编译器不会预先绘制无效的数组参数,而是将相应参数的类型指定为指针.记住这一点,这非常重要.参数不是数组,而是指向相应元素类型的指针.
现在,如果您试图传递一个数组,那么传递的是指向数组的第一个元素的指针.
为了完成,因为我认为这将帮助您更好地理解问题,让我们看看当您try 将函数作为参数时,事件的状态是什么.的确,首先,这没有任何意义.参数怎么可能是函数呢?嗯,我们当然想在那个地方有一个变量!因此,当发生这种情况时,编译器所做的是,再次将函数transform转化为function pointer.try 传递函数将改为传递指向相应函数的指针.因此,以下内容相同(类似于数组示例):
void f(void g(void));
void f(void (*g)(void));
请注意,需要使用*g
左右的括号.否则,它将指定返回void*
的函数,而不是指向返回void
的函数的指针.
现在,我在一开始就说过,数组可能有一个不完整的类型——如果你还没有给出大小,就会出现这种情况.因为我们已经计算出数组参数不存在,但任何数组参数都是指针,所以数组的大小无关紧要.这意味着,编译器将翻译以下所有内容,所有内容都是一样的:
int main(int c, char **argv);
int main(int c, char *argv[]);
int main(int c, char *argv[1]);
int main(int c, char *argv[42]);
当然,它没有太多的意义,能够把任何大小的它,它只是扔掉.出于这个原因,C99为这些数字想出了一个新的含义,并允许其他东西出现在括号之间:
// says: argv is a non-null pointer pointing to at least 5 char*'s
// allows CPU to pre-load some memory.
int main(int c, char *argv[static 5]);
// says: argv is a constant pointer pointing to a char*
int main(int c, char *argv[const]);
// says the same as the previous one
int main(int c, char ** const argv);
最后两行表示无法在函数中更改"argv"——它已成为常量指针.不过,只有少数C编译器支持这些C99功能.但这些特性清楚地表明,"数组"实际上不是一个.是指针.
请注意,我上面所说的只有当你有一个数组作为一个函数的parameter时才是正确的.如果使用本地数组,数组将不是指针.它将behave作为指针,因为如前所述,数组在读取其值时将转换为指针.但它不应该与指针混淆.
一个典型的例子如下:
char c[10];
char **c = &c; // does not work.
typedef char array[10];
array *pc = &c; // *does* work.
// same without typedef. Parens needed, because [...] has
// higher precedence than '*'. Analogous to the function example above.
char (*array)[10] = &c;