我只是在学习C语言,想知道我应该在main方法中使用哪一个。有什么不同吗?哪一种更常见?
发布于 2009-04-23 02:59:30
由于您刚刚学习C语言,因此我建议您首先尝试了解数组和指针之间的区别,而不是常见的东西。
在参数和数组方面,有一些令人困惑的规则,在继续之前应该弄清楚。首先,对你在参数列表中声明的内容进行特殊处理。在某些情况下,在C中作为函数参数是没有意义的。这些情况包括
的参数
作为参数的数组
第二个可能还不是很清楚。但是,当您考虑到数组维度的大小是C中类型的一部分时,就会明白这一点(并且没有给出维度大小的数组具有不完整的类型)。因此,如果要创建一个按值接受数组(接收副本)的函数,那么它只能对一种大小执行此操作!此外,数组可能会变得很大,而C会尽量快一些。
在C中,由于这些原因,数组值不存在。如果你想得到一个数组的值,你得到的是一个指向该数组第一个元素的指针。而这里实际上已经有了解决方案。C编译器不会预先绘制一个无效的数组参数,而是将相应参数的类型转换为指针。记住这一点,这是非常重要的。参数不是数组,而是指向相应元素类型的指针。
现在,如果您尝试传递一个数组,则传递的是指向数组的第一个元素的指针。
偏移:作为参数的函数
为了完成,因为我认为这将帮助您更好地理解问题,让我们看看当您尝试将函数作为参数时,事件的状态是什么。的确,首先它不会有任何意义。一个参数怎么可能是一个函数?嗯,我们当然想在那个地方有一个变量!所以当这种情况发生时,编译器所做的就是,把函数转换成一个函数指针,,,,,。尝试传递函数时,将会传递一个指向相应函数的指针。因此,下面的内容是相同的(类似于数组示例):
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特性。但这些功能清楚地表明,“数组”实际上不是一个数组。这是一个指针。
一句警告
请注意,只有当您将一个数组作为函数的参数时,上述所有内容才是正确的。如果你使用局部数组,数组就不是指针。它将表现为指针,因为如前所述,当读取数组的值时,数组将被转换为指针。但它不应该与指针混淆。
下面是一个经典的例子:
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;发布于 2009-04-23 01:13:00
您可以使用这两种方法之一。它们是完全等价的。请参阅litb的评论和his answer。
这真的取决于你想如何使用它(你可以在任何情况下使用它):
// echo-with-pointer-arithmetic.c
#include <stdio.h>
int main(int argc, char **argv)
{
while (--argc > 0)
{
printf("%s ", *++argv);
}
printf("\n");
return 0;
}
// echo-without-pointer-arithmetic.c
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
for (i=1; i<argc; i++)
{
printf("%s ", argv[i]);
}
printf("\n");
return 0;
}至于哪一个更常见--这并不重要。任何有经验的C程序员在阅读您的代码时都会认为这两者是可互换的(在正确的条件下)。就像一个有经验的英语演讲者读"they‘s“和”they are“一样容易。
更重要的是,你要学会阅读它们,并认识到它们有多么相似。您将阅读比编写更多的代码,并且您需要对这两种情况都感到满意。
发布于 2009-04-23 01:08:01
这没有什么区别,但我使用char *argv[]是因为它显示的是一个固定大小的可变长度字符串数组(通常是char *)。
https://stackoverflow.com/questions/779910
复制相似问题