关于指针数组添加自身(++)

时间:2012-04-03 04:29:07

标签: c

我不明白为什么在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;
}

3 个答案:

答案 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。但是当传递给函数时,会创建另一个指针,该指针指向与数组的第一个元素相同的位置。