//Example 1
const double pie = 3.14; //const object
const double *cptr = &pie; //pointer-to-const to const object
double *ptr = &pie; //ERROR - non-pointer-to-const to const object
//Example 2
double pie = 3.14; //non-const object
const double *cptr = &pie; //non-pointer-to-const to non-const object
double *ptr = &pie; //non-pointer-to-const to non-const object
最初我虽然允许指向非const对象的指针,因为它只是意味着 指向const的指针不会改变非const对象。
但我刚读完c ++书 因为没有,所以允许指向非const对象的指针的原因 指针到const指针的方式真正知道它指向的对象是否为const, 所以它将它指向的对象视为const 但是通过相同的逻辑,非指针指向const会将const对象视为非const对象 但是编译器会在编译时抛出错误。
我在这里错过了什么吗?
答案 0 :(得分:5)
声明一个const说,"此变量的值不应该改变。"
声明指向const的指针,"我无意更改我指向的变量"。
问题1:为什么在为变量指针指定了const的地址时会出现错误?
// Example 1
const int i = 0;
int * p = &i; /* Error */
答案:因为第一行显示,"请保证i
的值不会改变",但在第二行中编译器不能再保证 - 指针p
上的类型信息不够严格,不足以告诉编译器不允许更改指向的值i
。
问题2:为什么当指向const的指针被赋予变量的地址时,你不会得到错误?
// Example 2
int j = 0;
const int * q = &j; /* No error */
答案:因为指向const的指针显示,"请保证j
的值不会通过q
更改 &#34 ;.请注意, via q
很重要,因为指向const声明的指针并不意味着指向的值必须是常量,只有使用指针的人不能使用指针来改变值。
答案 1 :(得分:2)
指向const的指针
const double *p
将它指向的对象视为常量对象,即它不允许您更改它。只要你取消指向指针
*p
你正在处理一个常量对象。如果您尝试修改它,
*p = 1.0;
您将收到编译器的错误消息。
另一方面,指向非常量指针,
double *p
将它指向的对象视为非const,因此允许您修改其值:
*p = 1.0;
变得合法。但是,如果在任何给定时间你有一个恒定的对象
const double d = 1.0;
您将无法创建指向它的指向非const的指针:
double *p = &d;
编译器不接受。所以,是的,编译器启用指向非const的指针来修改它指向的对象。但是它不能让你创建一个指向常量对象的指向非const的指针。因此,您不会遇到可以使用指向非const的指针来修改常量对象的情况。
关于标题中的问题:这主要是语言设计决策。但是,编译器可以依赖某些对象永远不会更改值的事实意味着可以进行各种优化。例如,如果同一指针在两个解除引用之间的其他代码的函数中被解除引用两次,并且如果该指针是指向const的指针,则编译器将假设它实际上不必从内存中获取值两次,因为在第一次和第二次去分化之间不允许改变该值。