2011-04-03 71 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