只是在学习C,并且想知道在我的主要方法中应该使用哪一个。有什么区别吗? 问题来源于stack overflow
当您刚刚学习C时,我建议您首先真正地尝试理解数组和指针之间的差异,而不是普通的事物。
在参数和数组方面,有一些令人困惑的规则应该在继续之前弄清楚。首先,您在参数列表中声明的内容是特殊的。在某些情况下,将事情作为C中的函数参数没有意义。
用作参数 数组作为参数 数组作为参数 第二个也许还不清楚。但是,当您考虑到数组维的大小是C语言中的类型的一部分时(而未给出维大小的数组具有不完整的类型),这一点就变得很清楚。因此,如果您要创建一个函数,该函数需要一个按值作为数组的值(接收一个副本),那么它只能对一个大小执行此操作!另外,数组可能会变大,并且C会尝试尽可能快。
由于这些原因,在C中,不存在数组值。如果要获取数组的值,则获取的是指向该数组第一个元素的指针。解决方案实际上已经在这里。C编译器不会预先绘制无效的数组参数,而是将各个参数的类型转换为指针。记住这一点,这非常重要。该参数不是数组,而是一个指向相应元素类型的指针。
现在,如果您尝试传递数组,则传递的是指向数组第一个元素的指针。
游览:用作参数 为了完整起见,并且因为我认为这将帮助您更好地理解问题,所以让我们看看尝试将函数用作参数时的事务状态。确实,首先这没有任何意义。参数如何成为函数?嗯,我们当然想要那个地方的变量!那么,当这种情况发生的编译器所做的是,再次,要转变功能为函数指针。尝试传递一个函数将改为传递一个指向该函数的指针。因此,以下内容相同(类似于数组示例):
void f(void g(void)); void f(void (*g)(void)); 请注意,g需要用括号括起来。否则,它将指定一个returning函数void,而不是一个指向returning函数的指针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”-它已成为const指针。不过,只有少数C编译器支持这些C99功能。但是这些功能清楚地表明“数组”实际上不是一个。这是一个指针。
一句警告 请注意,仅当您将数组作为函数的参数时,上述所有内容才是正确的。如果您使用本地数组,则数组将不是指针。这将表现为指针,因为当读出其值如前面所述阵列将被转换为一个指针。但这不应与指针混淆。
以下是一个经典的示例:
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;
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。