2010-01-22 107 views
13

鑑於此代碼:的C指針運算

int *p, *q; 

p = (int *) 1000; 
q = (int *) 2000; 

什麼是q - p又如何呢?

+0

需要功能標籤? – 2010-01-29 11:08:02

+1

@保羅我對此表示懷疑。 – 2011-06-25 07:07:28

回答

32

它實際上未定義,根據標準。除非指針都指向同一個數組中的一個元素,否則指針算術不能保證工作。

該標準的相關部是6.5.6:9(C1X的n1362草案但這因爲C99沒有改變),其規定:

當兩個指針相減,既應指向元件相同的數組對象, 或一個過去的數組對象的最後一個元素;結果是兩個數組元素的 下標的差異。

如果您的int數據類型爲4字節但不能保證,您很有可能得到250。未定義的行爲(與實現定義的行爲不同)就是這個意思,未定義。任何事情都可能發生,甚至包括大部分時空的完全破壞。

進修課程:

  • 定義的行爲是什麼是標準的規定。實現必須做到這一點是一致的。
  • 實現定義的行爲留給實現,但它必須清楚地記錄該行爲。如果你不關心可移植性,請使用它。
  • 未定義的行爲意味着任何事情都可能發生。永遠不要這樣做!
+4

這是正確的答案,但我想每個人都希望相信答案無論如何都是1000/sizeof(int)。好吧! – 2010-01-22 22:55:20

-7

爲P指向一個int等Q,Q-p將爲1000

+1

除以sizeof(int) – 2010-01-22 13:39:16

+1

對不起,但這是錯誤的。 – 2010-01-22 13:44:44

+0

@Pascal爲什麼我們需要將它除以sizeof(int)? – NLV 2010-01-22 13:45:35

8

q - p是250

2000 - 1000 = 1000 
1000/sizeof(int) = 250 

指針運算,假定的sizeof(int)的是4


編輯: 行,以澄清。在C中,當兩個指針的類型相同時,它們之間的差別就是它們之間指向類型的事物的數量。例如,

struct foo { int ar[1000]; } big[10]; 
char small[10]; 

struct foo *fs, *fe; 
char *ss, *se; 

fs = &big[0]; fe = &big[9]; 
ss = &small[0]; se = &small[9]; 

fe - fs == se - ss; 

也就是說,在這種情況下,兩個指針之間的差是在它們之間的數組元素的數目。在這種情況下,它是0,1,... 8或9個元素。

+0

這就是我一直在尋找的東西。我不打擾我的問題-1。你爲什麼分1000/sizeof(int)? – NLV 2010-01-22 13:40:49

+0

你最好說「如果sizeof(int)是4」。這是因爲sizeof(char)*總是* 1. – paxdiablo 2010-01-22 13:47:54

+0

@paxdiablo:對。腦凍結。 – 2010-01-22 13:48:33

2

q-p應該返回多少步,你應該做的步驟是從pq。這是1000/sizeof(int)並且等於250.記住q++實際上將轉到int類型的下一個元素,而不是它的中間,所以它應該將4加到指針的實際值上。因此,結果。

2

答案: Q-P將是250,假設你是一臺機器,其中一int爲4個字節。

的計算公式是:

q - p值= 1000 1000/4(int的大小)= 250

它背後的想法

背後指針算法的思想是如果你有一個int指針指向1000和一個int指針指向2000,並且詢問有什麼區別,你是而不是問什麼是2000-1000。你問的是,有多少int我可以適應這兩者之間。

這是各種操作非常方便,例如:

int *i = 100; 
i++; // This is **not** 101, it is 104, cause you actually want the next place an int could fit in memory. 

使用數組時,這尤其是派上用場了。一個int數組(定義爲int arr[10])基本上就像一個指針一樣對待。當您編寫arr[5]時,編譯器將其翻譯爲*(arr + 5),即將5添加到名爲arrint指針中,並獲取該地址的值。

這部作品的原因,是因爲arr + 5意味着「加5 arr中的價值」,它的意思是「添加任何是neceassary arr中的價值前進5米int的」,或者更確切地說,「添加5 * sizeof(int)到ARR的值」