typedef struct nodes {
int da;
struct nodes *ptr;
} node;
node init;
printf("%d %d %d\n", &init, &init-2 ,6295648-2);
當
6295648 6295616 6295646
如何來自一個地址中減去2減去32(因此從地址減去1減去16),使用在地址動作怪異的表達?
typedef struct nodes {
int da;
struct nodes *ptr;
} node;
node init;
printf("%d %d %d\n", &init, &init-2 ,6295648-2);
當
6295648 6295616 6295646
如何來自一個地址中減去2減去32(因此從地址減去1減去16),使用在地址動作怪異的表達?
當你做指針算術你的基本單位是基本類型。例如,如果您對指向int
的指針(即int*
)執行指針運算,則以sizeof(int)
爲單位執行指針運算。
讓我來說明吧:假設我們有
int *pi = malloc(...); // Actual size doesn't matter for this example
在內存方面它像
+-------+-------+-------+-------+ | pi[0] | pi[1] | pi[2] | ..... | +-------+-------+-------+-------+ ^ ^ ^ ^ | | | | pi+0 pi+1 pi+2 pi+3
上圖應該有希望也解釋了指針和數組之間的關係之間的一個小,尤其是爲什麼表達式pi[x]
與*(pi + x)
相同。這些表達式對於指針和數組都是相同的。
現在,通過從一個指針減去,你將有一個指針什麼指針指向前。只需打印指針即可,但在大多數情況下,您無法對其進行取消引用(獲取它指向的值)。
因爲16是init
指向的大小。
下面三者是等價的:
ptr[offset]
*(ptr + offset)
offset[ptr]
(但不這樣做)所以,當你從init
加上或減去東西時,計算出的地址取決於init
指向的類型的大小。如果大小爲16,每一個偏移計算將是16
'8'是任何'init'指向的大小(因爲OP減去2,而不是1) –
不是我的DV,但我想問題是這個問題不使用下標,而且你不直接解釋你寫的如何適用於這個問題。 –
@TomKnapen我相信他在減去1時減去16而在減去2時減去32。 – Kusalananda
首先的倍數,打印地址,你應該使用%p
格式說明,並投了參數(void *)
所要求的printf()
。否則,對提供的格式說明符使用錯誤類型的參數會調用undefined behavior。
這就是說,關於指針運算,引用C11
,章§6.5.6
當具有整數類型的表達式被加到或減去一個指針, 結果具有的類型指針操作數。如果指針操作數指向數組對象的元素,並且該數組足夠大,則結果指向原始元素的偏移量 ,從而使得結果數組元素和原始數組元素的下標之差等於整數表達式。 [...]
這意味着,指針運算會對指針的數據類型表示支持。用指針加整數(或相減)的結果不是,而是另一個數,它是另一個(可能)元素的地址,只要存在。
分別換句話說,如果表達式
P
指向 陣列對象的i
個元素,表述(P)+N
(等同於N+(P)
)和(P)-N
(其中N
具有值n
)指向, ,數組對象的i+n
thth和i−n
-第 個元素,只要它們存在。 [...]
當您對指針進行算術運算時,地址的加法或減法是以指針指向的數據類型爲單位完成的。這是允許的等價:
&arr[n] = arr + n;
所以,如果sizeof init = 8
,然後&init - 2
將減去地址16個字節。
在C中,將2減去int
或者指針是不一樣的。這是pointer arithmetic。 使用int
指針,減去2將使指針位置移動2*sizeof(int)
。 如果您在減量之前將指針指向int
,您將檢索相同的值。
首先,init是什麼?其次,要打印一個指針,你應該使用''%p''格式來打印'void *'(需要強制轉換)。 –
'init'是一個「長雙」嗎?還是某種結構類型?大多數其他內置類型不是16個字節長。 –