2014-10-30 28 views
0

因此,這裏是一個鍛鍊和,給出以下解決方案:瞭解指針和地址引用用C

假設下面的聲明已經做出:

char c = ‘A’; 
char *p = &c; 
char **p2 = &p; 
void *v = &p2; 

檢查每個以下表達式。如果該表達式是非法的,寫入ILLEGAL。如果表達式是合法的,請寫下它的類型(即int,void *等)

&p2 : char*** 
*p2: char* 
&v: char**** 
p2 + 1: char** 
v[0]: Illegal 

您能解釋我們如何得到這樣的類型嗎?我知道v [0]是非法的,因爲v指向地址,我們不能像使用數組那樣使用括號表示來訪問它。 但所有其他讓我有點困惑,尤其是1-3。

我很樂意幫忙!

+0

>我們不能使用括號表示來訪問 - 爲什麼不呢? v [0] == *(v + 0)。 – someuser 2014-10-30 04:02:12

+0

實際上,'v [0]'是不合法的,因爲'v'是一個指向'void'的指針,並且'void'的指針可能不會被解引用。要引用K&R,「無效對象的(不存在)值可能不會以任何方式使用......」 – user3386109 2014-10-30 04:04:46

+0

@ user3386109,通常我們可以使用這個表示法來訪問 - 這就是我想說的。 – someuser 2014-10-30 04:07:00

回答

0

先從基本變量

c: char 
p: char* (because p = &c) 
p2: char** (because p2 = &p) 
v: char*** (because v = &p2) 

現在,&增加了一個間接層,並*解引用,其中減去一個間接層。

&p2: char*** (because p2 is char**) 
*p2: char* (because p2 is char**) 
&v: char**** (because v is char***) 
p2 + 1: char** (same type as p2) 

注意,你可以(有些人)寫char *pchar* p它可以更容易地翻譯成「char*類型的變量p」,同爲char** p等,但char *p已經儼然成爲了慣例。當我加入遵循char *p公約的公司時,我個人很難轉換。

+0

只有'void *',沒有進一步的間接尋址,因爲'void *'實質上是指「一個指針(對任何事物)」,「一個指針指向任何事物」仍然是一個指針。你實際上可以將任何指針類型(比如'char *','char **','char ***'等)轉換爲'void *'。但是在使用'void *'之前,它通常會變成更具體的東西。 – 2014-10-30 04:14:49

+0

我認爲該慣例是爲了允許在一行上進行多個聲明,例如'char * a,* b;'。行'char * a,b;'聲明'a'爲一個指針,'b'聲明爲一個簡單的'char'。 – user3386109 2014-10-30 04:15:51

+0

@ user3386109同意。我很少在同一行上聲明變量(實際上90%的時間是用默認值初始化的)。仍然Objective-C通過了公約,所以現在我只是按照沒有問題:) – 2014-10-30 04:22:06

3

對於T類型的任何左值表達式e,表達&e具有類型T *,和表達式的值是e位置。類似地,對於類型T *的任何表達式p,表達式*p具有類型T並且表達式的值是任何p指向的值。

表達c具有類型char,所以表達式&c具有類型char *,和表達式的值是c位置。該值被分配給變量p,其中也有鍵入char *

由於p已鍵入char *,表達&p的類型爲char **和的值是p位置。這被分配給變量p2,其也具有類型char **

答案鍵有錯誤; &v 的類型是void **,而不是char ****

v[0]是非法的,因爲v的類型爲void *,並且您不允許取消引用void指針。