2017-07-26 39 views
2

我學會了this question是遞增NULL指針或過去增加一個陣列的到底是不是良好定義的行爲:正在比較一個指針定義的數組末尾的一個元素嗎?

int* pointer = 0; 
pointer++; 

int a[3]; 
int* pointer2 = &a[0]; 
pointer2 += 4; 

但如果指向一個無效的位置指針僅用於比較和記憶在他的位置永遠不會被訪問?

實施例:

void exampleFunction(int arrayLen, char** strArray) 
{ 
    for(char** str = strArray; str < strArray + arrayLen; str++) //or even str < &strArray[arrayLen] 
    { 
     //here *str is always a pointer to the first char of my string 
    } 
} 

在這裏,我我的指針比較過去陣列的端部的指針的一個元素。這是明確的行爲嗎?

+0

表達式'* argv + argc'何時有意義? 'argv [0]'的長度與'argc'沒有關係。如果你的意思是'argv + argc',那麼這是很好的AIUI,因爲指針「超過數組末尾的一個元素」是明確定義的,可以與同一數組中的其他指針進行比較。 (或'argv + argc + 1',因爲正如chux提到的那樣,'argv'以'NULL'結尾)。 – Ryan

+0

@chux很高興知道!我只需要使用'<='。但原來的問題不應該考慮我的錯誤。更好的例子更新 – Winter

+0

你的第二個代碼是OK,因爲'str'總是一個有效的指針。儘管如此,它的最後價值並不是可以去引用的。 – chux

回答

4

比較指針一步過去的數組的末尾是明確的。但是,您的pointerpointer2示例未定義,即使您對這些指針完全沒有做任何操作。

指針可能指向數組末尾的一個元素。該指針可能不會被取消引用(否則這將是undefined behavior),但可以與數組中的另一個指針進行比較。

C standard的6.5.6說關於指針加法以下:

如果指針操作數和結果指向相同的數組對象的元素,或一個過去的最後兩個數組元素 對象,評估不應產生溢出; 否則, 行爲未定義。如果結果指向數組對象的最後一個元素 ,則不應將其用作被評估的一元運算符的操作數。

節6.5.8說有關指針比較:

當兩個指針進行比較,其結果取決於物體的地址空間中的相對位置指向。 如果兩個指向對象類型的指針 既指向同一個對象,又指向兩個點 一個指向同一個數組對象的最後一個元素,則它們會比較 等於。如果指向的對象是同一個聚合對象的成員,則稍後聲明的結構成員的指針會比指向結構中較早聲明的成員的指針的大 ,而指向具有較大下標值的數組元素的指針比較 大於指針相同數組的元素與下標值 。所有指向同一聯盟對象 成員的指針相等。 如果表達式P指向數組 對象的元素,並且表達式Q指向相同的 數組對象的最後一個元素,則指針表達式Q + 1將比P大。在所有其他情況下,行爲是未定義。

+1

「一個通過」規則是否也適用於非數組對象呢? 'int x; int * p = &x+1;' – chux

+1

@chux您可能是對的。第6.5.8節第4部分說*「就這些運算符而言,指向非 數組元素的對象的指針的行爲與指向 類型的長度爲1的數組的第一個元素的指針相同作爲其元素類型。*「6.5.6節第7部分具有相同的措詞。 – dbush

+0

引用6.5.8適用於'<', '<=', '> ='和'>'。給定指向對象的指針時,'=='和'!='操作符不會產生未定義行爲,指針只是「過去」對象或空指針。 「指向」一個對象的指針與「剛過去」另一個指針的指針之間的比較可以報告相等性,但這並不意味着這些指針可以互換使用。 – supercat

相關問題