C 为什么指向常量的指针所指向的位置可由其他变量赋值?

C 为什么指向常量的指针所指向的位置可由其他变量赋值?,c,pointers,C,Pointers,我已经写了这段代码 #include <stdio.h> int main() { int b = 15; const int *foo = &b; //b = 20; *foo = 20; printf("%d", *foo); return 0; } 如果*foo即b是只读位置,为什么我可以更改它的值b=20?怎么办 int b=15; const int* foo=&b; 什么意思 这意味

我已经写了这段代码

#include <stdio.h>
int main() {
     int b = 15;
     const int *foo = &b;
     //b = 20;
     *foo = 20;
     printf("%d", *foo);
     return 0;
}
如果
*foo
b
是只读位置,为什么我可以更改它的值
b=20

怎么办

 int b=15;
 const int* foo=&b;   
什么意思

这意味着

  • b
    是可修改的
    int
    对象
  • &b
    具有类型
    int*
    foo
    的声明将
    &b
    转换为类型
    const int*
    。这是一个有效的资格转换
  • int
    foo
    指向的对象不能使用
    foo
    修改
上述资格转换不会使
b
的声明无效,即它仍然是可修改的
b
仍可用于更新其值,但不能使用
*foo


将const视为承诺。您向编译器承诺不会更改
foo
所指位置的值,但没有人阻止您通过其他方式更改该位置的值来违背承诺。

no,
const int*foo=&b
并不意味着您不能更改
b
,它意味着您不能像这样取消引用此指针并更改取消引用的指针的值

*foo = 20;

你不能用
const
说某段内存对所有人来说都是不可修改的。您可以说,只有
const
变量不能更改这段内存,因此即使常量指针指向
b
,此操作(如果
b
hasnt
const
修饰符)也是完全有效的

 b=20;

如果需要指向非常量对象的常量指针,请声明它:

 T * const ptr = &t

其中,
T
是对象的类型,
T
是对象本身

我认为chqrlie说错误消息“分配只读位置“*foo”具有误导性是正确的。实际上,
const int*foo
(即定义为指向
const int
的指针)并不意味着指针寻址的内存本身是或变得不可变的;这仅仅意味着指针寻址的内存不能通过该指针改变;然而,它可能会以其他方式改变。例如,您可以定义第二个指针
int*foo2=&b
,通过它可以更改
foo2
所寻址的值

因此,您可以将指针视为指向特定内存地址上的值的单独视图,并且可以将该视图声明为只读或非只读。但是,这并不影响特定内存地址本身的值是否不可变:

int main()
{
    int b=15;  // b is mutable
    const int* foo=&b; // *foo is immutable; b remains mutable
    int *foo2=&b; // *foo2 is mutable
    b=20;  // allowed, since b is mutable
    *foo=20; // not allowed, since "*foo" is immutable, even if the value to which it points (i.e. b) would be mutable
    *foo2=20; // allowed, since "*foo2" is mutable

    return 0;
}
虽然没有被问到,但反过来说,你实际上可以将一个值定义为不可变的,并且这个值不能以任何方式被改变;如果您以某种方式通过写入其内存地址来操纵该值,则该行为未定义:

const int c = 15; // c is immutable
int* bar = &c; // warning: discards const qualifier
printf("%d\n", c);
*bar = 20;  // undefined behaviour from here on; modifying a const value is not allowed.
printf("%d\n", c); // undefined behaviour; good chance that it still prints 15, because a compiler might have relied on the fact that c is 15 and immutable
printf("%d\n", *bar); // undefined behaviour; probably printing 20?

希望有帮助。

此问题的答案是在将指针声明为

const int *foo = &b;
不能将*foo用作L值,因为此代码也会给出相同的错误

#include <stdio.h>
int main() {
     int a=10,b = 15;
     const int *foo = &b;
     foo=&a; //assigning foo the address of a
     *foo=30; // Again here you cant use *foo
     printf("%d", *foo);
     return 0;
}
#包括
int main(){
INTA=10,b=15;
常量int*foo=&b;
foo=&a;//为foo分配
*foo=30;//同样,这里不能使用*foo
printf(“%d”,*foo);
返回0;
}

这就是问题所在。福指着b。我可以把它设为b=20,我没有得到任何错误!您不能使用
foo
更改它指向的内容。没有什么能阻止你改变其他合法机制所指向的东西。使用
b
是修改
foo
指向的位置的合法机制。b只是为存储在内存中的值(内存中的位置)指定的名称。错误显示为只读。那么我们如何改变它的价值呢?对不起,我不明白@PradeepKumar:我们可以看出你没有得到它。困难的是找出你为什么得不到它。
foo
是指向常量值的指针,这意味着您不能使用
foo
更改它指向的内容。但是
b
不是常数。它可以改变。使用
foo
@PradeepKumar无法更改它;我改变了答案,并作了进一步解释。再读一遍,这不是我要问的!请库马尔停止喊叫:DSo学习如何提问<代码>常量指针表示常量指针,而不是指向常量对象的指针。责备自己,感激有人浪费时间回答你的问题我承认我的错误。但是你应该阅读整个问题并建议编辑。无论如何谢谢你@在我看来,这是“T”字question@PradeepKumar:错误消息显示
*foo
为只读位置,因为
foo
被定义为指向不应通过此指针更改的位置。错误消息有点令人困惑。@chqrlie:很好,错误消息具有误导性,可能是OP误解代码含义的根本原因。指针声明和对象声明之间存在差异。指针不能用于更改引用的对象。对象本身可以更改,但不能通过常量指针。这里的要点是,指向非常量的指针可以无缝地转换为指向相同类型常量的指针。这被解释为不通过该指针修改值的意图。当然,原始左值不会受到向其添加新指针的影响,并且保持可写状态。请看一看我相信会帮助您理解为什么它会这样做。您不能使用
foo
来更改它所指向的内容。没有什么能阻止你改变其他合法机制所指向的东西。使用
b
是修改
foo
所指位置的合法机制。可能重复的请阅读整个问题@PradeepKumar是否存在的写保护区域
#include <stdio.h>
int main() {
     int a=10,b = 15;
     const int *foo = &b;
     foo=&a; //assigning foo the address of a
     *foo=30; // Again here you cant use *foo
     printf("%d", *foo);
     return 0;
}