2009-02-27 50 views
1
void main() 
{ 
const int * a; 
*a = 5; 
} 

GCC錯誤:只讀位置的分配。分配const int的*

那麼,如何分配給* a,而不使用其他變量? 和什麼可以使用上面的聲明?

+0

爲什麼「不使用其他變量」限制? – kmkaplan 2009-02-27 11:16:59

+0

因爲否則,它太簡單了:創建第二個int * b,賦值b = a,然後* b = 5將修改* a。 – bortzmeyer 2009-02-27 11:18:00

+0

當然很簡單。但是這是對第二個問題的回答:「可以使用上面的聲明麼?」。哦,你的「b = a」不是嚴格正確的:它將const轉換爲非常量。你寧願a = b。 – kmkaplan 2009-02-27 11:22:46

回答

10
const int * a; 

閱讀聲明從右到左[看說明]你會得到什麼? a*,即指向int的指針,即整數const,即常數。簡而言之,變量a指向一個其值不能更改的整數。至少,不通過a。指出者是否真的是不可變的是一個不同的問題。但事實依然,你不能用a來修改*a;

const是您對自己承諾:我永遠不會嘗試修改使用指向一個const指針對象。編譯器只給你支持。

如果你真的寫入指針對象,你需要一個非const指針一樣的東西:

int *a; 
*a = 42; /* this is fine */ 

而且從bortzmeyer一個非常好的評論:(我想我會跳過這保持簡單:)

你也可以把*const(如你所說,聲明應從右到左的閱讀)。

他的意思是這樣的:

const int *a; 

沒有從

int const *a; 

(記住,向左看規則的吧?) 不同而有很大的差異來自:

int * const p; 

閱讀它和我們得到:pconst(-ant)*(指針)到int(-eger)。譯文:一旦你設置p指向一個整數,你不能重置它(即寫入它使其指向另一個整數 - 讓p不變),但可以非常多地寫入指針(指針不是常量)。

注:對於迂腐傾斜這裏是Darron「的規則」:

「聲明應該由右至左讀」是一種簡化 - 如果有括號,他們應該從裏面讀出。除非括號表示函數調用。真正的規則是「把它當作表達式來對待;如果我應用這些操作符,我最終會得到這種簡單的類型」。

這個答案真的將不得不多肉少,但對於Bortzmeyer做了大量達隆 - 謝謝!

PPS:(我保證這將是最後一次編輯好了,希望!)

void main()不是C或C主要標準簽名++。直到你認識你或者(更重要的是)你的代碼永遠不需要去另一個宇宙去航行,不要使用它。

0

您不能指定給const嗎?雖然,在const指針的情況下,我不記得它指向的值是不可修改的,還是指針的地址。或兩者。我的猜測是,兩者都不能改變。

它也可以是一般的警告(或錯誤,這取決於編譯器設置),您嘗試寫入未初始化的內存。

正確的是(我認爲):

void main() 
{ 
    const int* a = new int(5); 
} 
+0

gcc拒絕識別「新」。那麼,我必須使用C++? – dharm0us 2009-02-27 11:09:13

+0

不,只需使用malloc()而不是新的。 – bortzmeyer 2009-02-27 11:15:06

-2

的問題是,你已經創建了一個指針,但它實際上犯規指向任何東西,所以當你取消對它的引用(或嘗試寫入其引用的loaction),你會得到一個錯誤。

1

您的意思是int * const,而不是const int *。在一種情況下,指針是const的,另一種指向的是const。你也可以做const int * const。閱讀一些關於const_cast的文章沒有什麼壞處,他們應該很好地覆蓋這個地方。

2

出魯本Bartelink的優秀解釋一個例子:

#include <stdlib.h> 

int main() 
{ 
    int * const a = malloc(sizeof(int)); 
    if (a == NULL) 
    return 1; 
    *a = 3; 
    free(a); 
    return 0; 
} 

這裏,是恆定的(因此必須初始化),但不是*(可能是什麼OP通緝)。

0

不回答「如何分配給* a,而不使用其他變量?」但只有「可以使用上面的聲明是什麼?」。

這是一個承諾,不要修改指向的值。正如在評論中所討論的那樣,如果你對你允許自己使用構造的方式做出限制,你可以得出它沒有用的結論。但是如果你允許自己使用整個C語言,那麼你可以找到用途。想想strcmp等的原型。

2

讓我把你的問題變成簡單的英文。

  • 如果我保證編譯器不會寫入變量a指向的值,我該如何寫入變量a指向的值?

答案:改變承諾,至少在本地。

int main() 
{ 
    const int * a; 
    *((int *) a) = 5; 
} 

希望上面的措辭表明,這通常是一個壞主意。