2015-10-04 65 views
0

最後一行產生「無效的操作數到二進制表達式」。試圖理解爲什麼。這是否意味着「p2-p1」是位於p3右側的二進制表達式「 - 」的無效操作數?我可以在這裏遵守任何規則?因爲「3-2-1」整數是有效的,所以對我感到困惑。試圖理解:無效的操作數到二進制表達式,C

int array[3] = {1,2,3}; 
    int* p1 = &array[0]; 
    int* p2 = &array[1]; 
    int* p3 = &array[2]; 

    p3-p2-p1; 
+4

兩個指針('p3-p2')之間的差異是'ptrdiff_t',你不能從'ptrdiff_t'中減去一個指針。 C11標準草案,'6.5.6附加操作符,第3節[...]對於減法,下列情況之一應爲:[...]]兩個操作數都是指向兼容完整對象類型的合格版本或非限定版本的指針;或者左操作數是一個指向完整對象類型的指針,右操作數具有整數類型[...]'。 – EOF

+0

'p1','p2'和'p3'是指向整數但不是整數的指針。但下面的表達式是有效的:'p1 - (p2 - p3)' –

回答

3

你正在做地址算術。給定運營商優先級,它將評估p1-p2-p3(p1-p2)-p3p1-p2不是地址而是整數。然後你試圖從一個整數中減去一個無效的地址。你可以做p1-(p2-p3),然後取p2-p3,產生一個整數,然後把它作爲一個整數偏移量從一個地址(p1)中減去,它將被編譯。但是,[在他的評論中感謝@EOF作爲這個參考]這樣的減法(來自指針的整數)只有在它指向p1的分配內的某個地方時纔有效。它是受第6.5.6具體描述的標準C11,摘錄如下:

當具有整數類型的表達式添加到或從一個指針減去 ,其結果具有指針操作數的類型。如果 指針操作數指向數組對象的元素,並且數組 足夠大,則結果指向與原始元素偏移的元素,以使得結果數組元素和原始數組元素的下標之差等於整數表達式。換句話說,如果表達式P指向數組對象的第i個元素,則表達式(P)+ N(等效地,N +(P))和(P)-N其中N具有值n)分別指向數組對象的第i + n個和第n-n個元素,只要它們存在。此外,如果 表達式P指向數組對象的最後一個元素,則表達式(P)+1將指向數組對象的最後一個元素 ,如果表達式Q指向一個超過數組 對象,表達式(Q)-1指向數組 對象的最後一個元素。如果指針操作數和結果指向相同數組對象的元素 ,或者指向數組 對象的最後一個元素,則評估不應產生溢出;否則, 行爲未定義。如果結果指向數組對象的最後一個元素 ,則不應將其用作被評估的一元運算符的操作數。

+0

謝謝 - 有道理。它會允許我儘快接受:) –

+0

實際上,在這種情況下'p1-(p2-p3)'的行爲將是不確定的:'p2-p3'將是'-1',並且'&p1 [-1] '不指向有效的對象。 – EOF

+0

@EOF有趣。 'gcc'喜歡'p1-(p2-p3)'。指針減去整數應該給出確定性的結果不應該嗎? – lurker

2

在你的代碼,p1p2p3指向整數,不是整數。

爲了得到你想要的東西,你可能想:

*p3 - *p2 - *p1; 

其中*運算符是dereference operator。它取消引用指針,所以在這種情況下,*p3等是int類型。您可以將其視爲& address-of運算符的反函數。

相關問題