2011-11-18 28 views
3

是什麼這兩個涉及指針算術的語句有什麼區別?

char cur_byte=*((char *)(buf+i)); 

char *b=(char *)(buf); 
char cur_byte=*(b+i); 

之間的差假設: BUF是作廢//指針無效* buf中;和 我被用作for循環中的迭代器 我在一個生成rabin指紋的c源代碼中發現了這段代碼(第一行),並且由於VC2010 express將它報告爲錯誤,我不得不用第二行代替它。我不確定它是否能達到預期目的。另外,如果任何人都可以給我一個提示,說明如何獲得一個可用於C++源代碼的內容定義分塊和指紋生成,我將不勝感激。

+0

不會在第一行給出運行時異常嗎? – Ankit

+0

VC2010表示這是一個錯誤 – John

回答

5

在您的第一條語句中,您將一個整數(i是一個整數類型,對嗎?)添加到void*,之後再鑄造爲char*。由於編譯器無法知道應該增加指針多少,所以C標準沒有定義帶空指針的指針算術。但是,一些編譯器定義了sizeof(void) == 1。在這種情況下,你的兩個片段是相同的,這就解釋了爲什麼這個代碼可能與另一個編譯器(感謝Steve Jessop指出這個)

你在你的第一個片段中的含義可能是 char cur_byte=*(((char *) buf) + i);,該字符指向的地址位於i之後的字符。

在以下架構中,將爲i==4cur_byte分配值r

Memory: |a| |w|o|r|d 
     ^ ^
     buf  buf+i 

在你的第二個聲明:

char *b=(char *)(buf); 
char cur_byte=*(b+i); 

首先要將bufb,再b + i內容分配給cur_bytebchar*類型,所以加入i會給後的地址i個字符。

Memory: |a| |w|o|r|d| 
     ^ ^
     buf   
     b  b+i 

最後這兩條語句是等價的(除了賦值b)。

+0

但你能告訴我爲什麼第一個選項是錯誤的VC2010 – John

+0

我剛剛編輯我的帖子,以反映你的編輯。 – Antoine

+2

「帶空指針的指針算術不是由C標準定義的」 - 但是GCC允許它作爲非迂迴模式的擴展,這可能是爲什麼首先寫出引發錯誤的代碼的原因。 GCC的擴展實際上表示,僅用於指針運算的目的是「sizeof(void)== 1」。因此,所有這些代碼片段在GCC中都是相同的。 –

1

區別在於表達式(buf + i)(b + i)

bchar*的類型,因此(b + i)將指向b + sizeof(char) * i

buf可能是不同的類型,所以(buf + i)將指向buf + sizeof(BUFS_TYPE) * i

+0

正確(+1)。現在,在John給出'buf'類型之後,你應該擴展你的答案。 –