我不明白为什么在url_split
函数中我可以使用a++
,但在main
函数中我不能使用key_value++
,它们具有相同的功能键入...
void url_split(char *src, char **host, char *a[])
{
char const *p1 = "?";
char const *p2 = "&";
*host = strtok(src, p1);
char *str;
while((str = strtok(NULL, p2)))
{
*a = str;
a++;
}
*a = str;
}
int main(int argc, char *argv[])
{
char *host;
char *key_value[100];
char url[] = "http://www.baidu.com/s?wd=linux&cl=3";
url_split(url, &host, key_value);
printf("host = %s\n", host);
while(*key_value)
{
printf("key-value : %s\n", *key_value);
key_value++;
}
return 0;
}
答案 0 :(得分:3)
不,它们实际上并不是一回事:key_value
中的main
是数组,您无法更改(您可以更改内容但不是数组变量本身)。
当你将它传递给一个函数时,它成为该数组的第一个元素的指针,可以更改(指向该数组的其他元素,例如)。
与以下内容没有什么不同:
int xyzzy[10]; // xyzzy cannot change
int *plugh = xyzzy; // but plugh can.
数组到指针的“衰减”实际上发生在绝大多数情况下。从C11标准:
除非它是
sizeof
运算符或一元&
运算符的操作数,或者是用于初始化数组的字符串文字,否则将转换类型为“array of array”的表达式到类型为“指向类型的指针”的表达式,它指向数组对象的初始元素,而不是左值。如果数组对象具有寄存器存储类,则行为未定义。
答案 1 :(得分:2)
他们实际上没有相同的类型:
key_value
的类型为char *[100]
,是一个包含100个char
指针的数组。a
实际上是char **
类型,指向char*
,不是数组的指针。当您将key_value
传递给url_split
时,它会衰减到char**
,这就是为什么key_value
是函数的有效参数以及为什么使用char**
的原因}作为函数参数的类型,该参数旨在成为char*
的数组。
后增量运算符与数组不兼容,不能为数组分配新值,但它对指针完全正常,因为可以为它们分配新值。这就是为什么a++
有效且key_value++
不是。
答案 2 :(得分:2)
以下是Kernighan书中关于此的内容:
“当一个数组名传递给一个函数时,传递的是初始元素的位置。在被调用函数中,这个参数是一个局部变量,所以一个数组名 parameter是一个指针,即一个包含地址的变量。“
这意味着在main函数key_value中是一个数组名,你不能修改它,因为它只是数组中第一个元素的synonim。但是当传递给函数时,会创建另一个指针,该指针指向与数组的第一个元素相同的位置。