2016-04-02 25 views
-2

在C,我有:瞭解指針。 ?什麼是*((字符**)等於

char *p, *q; 
p = malloc(1); //for the purpose testing only 
p[0] = '!'; 
q = *((char **)p); 
printf("p=%x q=%x\n", p, q); 
printf("p=%c q=%c\n", p, q); 

目前還沒有鑄造警告,並輸出結果是:

p=1a9008 q=21 
p q=! 

的表達會發生什麼分配給q,即*((char **)p)q類型分配後改變


編輯:?有一個犯錯或者在我的代碼中。在嘗試從代碼片段中提取它時,我遇到了一個完整的工作示例,我錯誤地使用了一個類型爲char的示例值p。在檢查了更多的原始代碼之後,p被分配了一個指針值。所以p是一個指針指針。

+0

當程序員使用一個強制轉換時,他們通常做錯了什麼 –

+7

該行基本上是無意義的 - 它調用**未定義的行爲**。 –

+0

感謝所有。這是我找到的一些代碼,並試圖找出它在做什麼。 (我是C的新手) –

回答

2

首先變量的類型不能改變,如果它聲明爲char* q那麼它的類型是char*

什麼可以改變它的變量值,但在你的情況下,代碼是完全錯誤的。

首先p被聲明爲一個指向char和一個單字節通過的malloc分配的,所以你必須像

p = 0xDEADBEEF 
     | 
     ---> '!' 

然後通過你逼p投被認爲是char**,所以一個指針的指針爲char,什麼情況是,編譯器不得不考慮

p = 0xDEADBEEF 
     | 
     -----> 0x??????21 
        | 
        --------> char 

所以基本上你是強迫記憶手工分配和assig ned被解釋爲內存地址,那麼你將這個指針解引用到指針,這樣*(char**)產生一個char*這就是0x??????21,所以它沒有任何意義。

+0

試圖將非'char *'視爲char *'會導致bat(嚴格別名規則)的未定義行爲。編譯器不會被迫嘗試寫一個地址並遵循它;這只是編譯器生成相同程序集的工件,因爲它會訪問實際的'char *',並且假定您不會爲非'char *'執行此操作。 –