調用printf()時,* b的值是否爲undefined?在相同的存儲器中作爲a
const和普通指針的指針可以混合使用嗎?
void foo(int *a) {
const int *b = a;
int *c = a;
*c = 2;
printf("%d\n", *b); // what must be *b? 1, 2 or undefined?
}
int d = 1;
foo(&d);
調用printf()時,* b的值是否爲undefined?在相同的存儲器中作爲a
const和普通指針的指針可以混合使用嗎?
void foo(int *a) {
const int *b = a;
int *c = a;
*c = 2;
printf("%d\n", *b); // what must be *b? 1, 2 or undefined?
}
int d = 1;
foo(&d);
它將打印2. const int *b
字面意思是:
指向一個整數,其值不能通過其dereferentiation被 改變。
這並不意味着指針指向的值可能不會改變。事實上,改變是完全有效的。一個可能的情況是使用這個結構,它保留對某個大型結構的只讀引用。引用可能會改變,但使用該結構的函數可能不會改變指針後面的內容。
設想一個驅動程序或類似的東西,它發出設備交付的任何數據的只讀存儲器映射:映射的地址不是恆定的,但由於這是隻讀映射,用戶程序可能無法寫入它。 OTOH當設備更新數據時緩衝區的內容將會改變,但不一定是映射地址。
*b
將是2,因爲printf
之前設置值的最後一行是*c = 2
。
a
,b
和c
都指向相同的整數值。所以最後一個設置它將決定它的當前值。
b在printf()中應該是2。你在b和c中一直處理一個指針。
聲明const int *b = a;
意味着b
引用一個常量int值。也就是說它把它的價值看作一個不變的價值。
因此,
*b = 10;
是不正確的,但:
a = 10;
是罰款,因爲一個是不是一個恆定值,但是提領b當我們把它當作常量。
c = 2;
這是一樣的上面的例子:
所以b
,因爲你改變了它指向的值肯定是定義。簡而言之,指向const值的指針不能通過解引用來修改該值,但是指向的值可以另外進行更改。
標準說什麼是(重點是我的)
6.7。3/5
如果試圖修改通過使用與非 const限定型的左值與 一個常量限定類型定義的對象,該行爲是未定義。
這不適用於您的情況(只是相反的方式)。
有問題的對象是用普通的(int
)類型定義的。
在你的情況只有通過b
更改對象是非法的;通過a
或c
更改是完全合法的
非常可靠的解釋是,你必須考慮一個事實,即指針對象本身就是一個地址。 – 2011-05-03 14:19:42
這是我的情況:結構中的項目定義爲指向const的指針,以便可以由其他函數更改數據。這是我第一次在這裏,所有的答案都太快了! – misianne 2011-05-03 14:44:09
@misianne:的確,當用這種方式指針時,「const」這個詞有點讓人誤解,因爲它讓你思考const性(不變性),而它更像「readonly」。關鍵是,當你說'const int * p'時,你正在講述**指針**(即它不能用於寫入),而不是關於**指向的對象**(這可能不是不變)。 – 6502 2012-01-07 09:52:01