2013-08-20 43 views
2

下面的代碼無法編譯:交換2個字符串指針與它的參數是一個函數void **

void swap(void **p, void **q) { 
    void *tmp; 
    tmp = *p; 
    *p = *q; 
    *q = tmp; 
} 

int main(void) { 
    char *s[] = {"help" , "please"}; 
    swap(&s[0], &s[1]); 
    return 0; 
} 

儘管此代碼編譯並運行就好:

void swap(void **p, void **q) { 
    void *tmp; 
    tmp = *p; 
    *p = *q; 
    *q = tmp; 
} 

int main(void) { 
    char *s[] = {"help" , "please"}; 
    swap((void **) &s[0], (void **) &s[1]); 
    return 0; 
} 

爲什麼鑄造必要?

+4

了'字符**'是不一樣的'無效**'。 –

+4

因爲指向'void *'的指針不具有指向任何其他指針類型的指針(如指向'char *'的指針)。一個'void **'是一個指向特定類型的指針:'void *'。 – WhozCraig

+1

http://c-faq.com/ptrs/genericpp.html – FatalError

回答

3

呀,所以除了那指出,void **不如char **同已有的答案:你的代碼調用,因爲不兼容的指針類型的未定義行爲。這裏是你真正想要的東西:

void swap(void *p1, void *p2, size_t size) 
{ 
    unsigned char buf[size]; 
    memcpy(buf, p1, size); 
    memcpy(p1, p2, size); 
    memcpy(p2, buf, size); 
} 

,並調用它是這樣的:

const char *s[] = { "help", "please" }; // also note the use of `const' for string literals 
swap(&s[0], &s[1], sizeof(s[0])); 
+0

我刪除了我的答案(我覺得沒有正確回答問題)。我也覺得你應該解釋一下WhozCraig的OP點。 –

+0

+1不僅用於查看代碼的問題,還可以看到OP正試圖解決問題。我希望我能再次投票表決未定義的行爲。 – WhozCraig

+1

@WhozCraig和Grijesh:謝謝你們倆! – 2013-08-20 17:29:16

1

您在第一個代碼中有不兼容的指針分配錯誤。在C字符串中,字面量是char[N]其中N是字符數。注意,在大多數表達式char[N]容易衰變成char*

根據你的宣言char *s[] = {"help" , "please"};類型的s[i]char*(actaully char[N]衰變成char*)。

當你通過&s[i]那麼你通過char**是不符合void**。第二個代碼可以工作,因爲你在函數調用中輸入了void**

void*可以分配任何地址類型,但它的void**必須分配地址void*類型變量。

如果你只有一串字符串,那麼在第一個版本的交換功能中,你可以用代替void,那麼你都可以不使用類型轉換。

0

由於傳遞函數的原因,該投射使示例編譯。

char *var[];在許多方面是相同char **var;

有了這樣說,要傳遞的功能的基準/地址陣列(s[0])的成員之一。

另一個更加突出的問題是,該函數接受void指針,並傳遞字符指針(沒有投射)。

+0

作爲OP的函數聲明它不接受void指針;它接受*指針*來void指針。它們不相同(儘管實際上可以將指針傳遞給一個void指針指向一個將void指針作爲參數的函數)。 – WhozCraig

+0

對,我也試圖不要在指針指針區域指針vs指針數組等指針區域混淆...名單繼續... – Shade

相關問題