2012-04-03 83 views
1

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

回答

2

他們實際上沒有同類型:

  • key_valuechar *[100]型,100個char指針數組。
  • a實際上是char **類型的指針,指向char*,而不是的數組。

當傳遞key_valueurl_split它衰減到char**,這就是爲什麼key_value是的功能的有效的參數,以及爲什麼使用char**作爲意圖的功能參數的類型是的char*陣列。

增量後運算符與數組不兼容,數組不能賦值給一個新的值,但它對指針來說工作得很好,因爲它們可以被分配一個新的值。這就是爲什麼a++有效,而key_value++不是。

+0

非常感謝! – user1309502 2012-04-06 10:34:32

+0

我認爲它通過調用函數之間的指針,我的意思是它只複製地址值,因爲c通過值傳遞。 – user1309502 2012-04-06 10:37:48

3

不,它們實際上不是同一件事情:key_valuemain陣列,你不能改變(你可以改變內容而不是數組變量本身)。

當它傳遞給一個函數,它成爲一個指針到該陣列中,可以變化(以指向陣列的其它元件,例如),其中的第一個元素。

這是沒有不同:

int xyzzy[10];     // xyzzy cannot change 
int *plugh = xyzzy;    // but plugh can. 

該陣列指針的「衰變」,在絕大多數情況下的實際情況。從C11標準:

除了當它是sizeof操作者或一元&操作者的操作數,或是用於初始化數組文本的字符串,其具有鍵入一個表達式「類型的陣列」被轉換轉換爲類型爲「指向類型的指針」的表達式,該表達式指向數組對象的初始元素,並且不是左值。如果數組對象具有寄存器存儲類,則行爲未定義。

+0

謝謝我的心! – user1309502 2012-04-06 09:20:50

2

這裏是寫在Kernighan的書約這樣的:

「當一個數組名傳遞給函數,什麼傳遞是初始元素的位置在調用的函數,這種說法是局部變量,所以一個數組名 參數是一個指針,即一個包含地址的變量。「

這意味着在主要功能key_value是一個數組名,你不能修改它,因爲它只是一個synonim數組中的第一個元素。但是,當傳遞給函數時,會創建另一個指針,指向與數組的第一個元素相同的位置。

+0

非常感謝! – user1309502 2012-04-06 10:36:12