众所周知,无法分配数组名称,如:
char * array[], * point;
array = point; /* wrong */
array++; /* wrong */
但在main(int argc, char * argv[])
中,argv++
还可以,效果很好。
我错过了什么?
答案 0 :(得分:6)
在您的示例中,array
是一个真正的数组,因此是一个不可修改的l值。在main中,因为它在参数列表中声明,argv
实际上是char **
,即可以修改的指针。
这一切归结为char *array[]
意味着不同的事情,具体取决于具体情况。
答案 1 :(得分:5)
在函数参数声明的上下文中,T a[]
和T a[N]
都被解释为T *a
;在所有三种情况下,a
被声明为指针到T
,而不是T
的数组。因此,在int main(int argc, char *argv[])
中,argv
实际上被声明为char **
,或指向char
的指针,而不是指向char
的指针数组。
(编辑 - 请注意,对于函数参数声明,这只是 ;对于常规变量声明,T a[N]
和T a[]
都是将a
声明为T
的数组。
由于它是一个指针值,因此可以将其指定给它,并且可以递增。
除此之外,这是language standard所说的:
5.1.2.2.1程序启动
...
2如果声明它们,主函数的参数应遵循以下内容 限制:
...
- 参数argc
和argv
以及argv
数组指向的字符串应具有 由程序修改,并在程序之间保留它们最后存储的值 启动和程序终止。
修改强>
这是函数参数的语言:
6.7.6.3函数声明符(包括原型)
...
7参数声明为'' type ''的数组应调整为''限定指针 type '',其中类型限定符(如果有)是在[
和]
内指定的类型 数组类型推导。如果关键字static
也出现在[
和]
内 数组类型派生,然后对每个函数调用,对应的值 实际参数应提供至少与数组一样多的数组的第一个元素的访问权限 由大小表达式指定的元素。
修改 2 强>
一些例子(假设是C99编译器):
void foo(int a[], size_t len)
{
size_t i;
printf("sizeof a = %zu\n", sizeof a);
printf("sizeof (int *) = %zu\n", sizeof (int *));
for (i = 0; i < len; i++)
printf("a[%zu] = %d\n", i, *a++);
}
int main(void)
{
int a1[5] = {0};
int a2[] = {0, 1, 2, 3, 4};
printf("sizeof a1 = %zu\n", sizeof a1);
printf("sizeof a2 = %zu\n", sizeof a2);
foo(a1, sizeof a1 / sizeof a1[0]);
foo(a2, sizeof a2 / sizeof a2[0]);
return 0;
}
还有一个标准:
6.3.2.1左值,数组和函数指示符
...
3除非它是sizeof
运算符,_Alignof
运算符或运算符的操作数 一元&
运算符,或者是用于初始化数组的字符串文字,一个包含的表达式 类型'' type ''的数组被转换为类型为''指向 type ''指针的表达式 到数组对象的初始元素,而不是左值。如果数组对象有 注册存储类,行为未定义。
在函数main
中,a1
和a2
已被声明为int
的5元素数组; a2
从初始化程序中的元素数量中获取其大小。因此,表达式 a1
和a2
具有类型“{-1}}的5元素数组”,它们可能不是赋值表达式的目标,也可能不是int
或++
运算符的操作数。当这些表达式出现在对--
的调用中时,根据上述规则,它们的类型将转换为“指向foo
的指针”。因此int
接收foo
的指针值,而不是数组值(由数组参数转换为指针类型的规则所涵盖)。因此,a
中的a
表达式为foo
,或指向int *
的指针;因此,int
可能是作业的目标,它可能是a
和++
的操作数。
还有一个区别:根据上面引用的规则,当数组表达式是--
运算符的操作数时,转换为指针类型不会发生; sizeof
应评估数组sizeof a1
占用的字节数(5 * sizeof a1
)。但是,由于int
中的a
类型为foo
,而不是int *
,int [5]
应仅评估指向sizeof a
的指针的字节数}(sizeof int
)。
答案 2 :(得分:2)
main(int argc, char * argv[])
或
main(int argc, char **argv)
是相同且正确的。因为函数参数数组被衰减为指针
了解更多read this
但您显示的代码是实际的数组。并且数组的名称给出了第一个元素的地址,并且它是不可修改的,这就是为什么这样做:
array = point;
array++;
是错误的,因为你已经提到过了。