2011-04-03 73 views
2

我不知道如何告訴C我想要一個不會移動的指針。它將始終指向相同的數組。也就是說,數組成員不是常量,但數組本身是全局的,所以它處於一個固定的位置。常量指針修復一個變量

所以,當我的代碼如下:

#include <stdio.h> 

int v[2]={0, 1}; 
const int *cpv=v; 

int main(void) 
{ 
    v[1]=2;  printf("%d\n", v[1]); 
    *(cpv+1)=3; printf("%d\n", v[1]); 
    cpv[1]=4; printf("%d\n", v[1]); 
} 

而得到這個錯誤:

constp.c: In function ‘main’: 
constp.c:9: error: assignment of read-only location '*(cpv + 4u)' 
constp.c:10: error: assignment of read-only location '*(cpv + 4u)' 

我明白,編譯器認爲我需要一個const int v[2]const int *iv使用。我如何獲得一個持續的指針來完成這項工作?

如果你看到錯誤信息,我甚至不移動指針(如pv++)。我只是解引用了一些字節。

如果我這樣做:

int *pv=cpv; 
*(pv+1)=5; printf("%d\n", v[1]); 
printf("%p == %p !?\n", cpv, pv); 

我得到這樣的警告,但它的工作原理:

constp.c:9: warning: assignment discards qualifiers from pointer target type 
pointer# ./constp 
5 
0x601020 == 0x601020 !? 

感謝, 貝喬。

回答

5

移動const限定符:

int *const cpv=v; 

說明:在C聲明的規則,這是從右側看到左開始於識別符:「cpv是常數指針int」。您的版本將被讀取爲「cpv是指向int常量」。

請注意,cpv+1仍然會給你一個指向int之後*cpv;使指針const只能防止++,--,+=-=

+0

謝謝!非常好的解釋。我的意圖就是:指針總是指向該數組的第一個元素。 ;) – 2011-04-03 22:05:23

2

您正在使用指向const的指針,而不是const指針。

const int * cpv = v;

應該變成:

INT * const的CPV = V;

1
#include <stdio.h> 

int v[2]={0, 1}; 
//const int  *  cpv=v; // cpv is a pointer to int const 
//  int const *  cpv=v; // cpv is a pointer to const int == same as above == 
     int  *const cpv=v; // cpv is a constant pointer to int 
//  int const *const cpv=v; // cpv is a constant pointer to const int 
//const int  *const cpv=v; // cpv is a constant pointer to int const == same as above == 
//const int const *const cpv=v; // == same as above == 

int main(void) 
{ 
    v[1]=2;  printf("%d\n", v[1]); 
    *(cpv+1)=3; printf("%d\n", v[1]); 
    cpv[1]=4; printf("%d\n", v[1]); 
} 
1
int * const cpv=v; 

說了這麼多,爲什麼你需要的指針呢?如果您直接訪問變量v,編譯器將能夠做得更好。如果你通過一個指針,那麼每次訪問數組時,生成的代碼都必須從內存中讀取指針。

+0

大聲笑!謝謝@林迪,我總是將問題簡化爲問題的核心。實際上,它是一個指向外部API的結構,它有很多很長的名字,我想用一個看起來像一個數組的簡化版來訪問它的成員,而指針就是這樣做的! :)好奇你是,不是嗎? ;)你可以在這裏閱讀更多:[結構就像一個數組](http://stackoverflow.com/questions/5524552/access-struct-members-as-if-they-are-a-single-array) – 2011-04-03 22:09:22

+0

當然我很好奇!但是,作爲編譯器開發人員,我有時會被要求檢查客戶項目。我見過的一種反模式是使用全局常量指針指向全局數組,迫使編譯器執行數千次額外的內存訪問,減慢程序並佔用先前的空間。 – Lindydancer 2011-04-04 08:20:45

2

指針種 「讀向後」:

const int * p; 

在這種情況下, 「p」 是一個(變量) 「指針」,以一 「const int」。從字面上看,向後讀,用'*'表示「指針」:「指針...到int const」。

奇怪的是,以下是同樣的事情:

int const * p; // same thing 

讀倒退,它說,「指針... const int的」(同樣的事情)。

所以,如果你希望你的指針是「常量」(不變量),你需要閱讀,向後和做到這一點:

int * const p; // p cannot change 

現在,「p」是一個常量指針非常量整數。不是爲了避免,而是向後讀取,「const pointer ... to int」。

使用上面的「同樣的事情」的例子,我們現在可以有一個常量指針到常量整數(以下相同):

const int * const p; 
int const * const p; 

你應該倒着讀他們,他們都說同樣的事情,「常數int的常量指針...」。

+0

+1尼斯世博會。謝謝 – 2011-04-03 22:13:13