2009-02-27 73 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; 
} 

希望上面的措辞表明,这通常是一个坏主意。