我写了这段代码
#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
时。它没有显示任何错误,我得到输出20
。在这段代码中我得到了这个错误
main.c: In function 'main':
main.c:15:10: error: assignment of read-only location '*foo'
*foo = 20;
如果*foo
b
是只读位置,为什么我可以更改其值b = 20
?
答案 0 :(得分:7)
什么是
int b=15;
const int* foo=&b;
意思?
这意味着,
b
是一个可修改的int
对象。 &b
的类型为int *
。 foo
的声明会将&b
转换为const int *
类型。这是有效的资格转换。 int
foo
指向的对象不得使用foo
进行修改。
上述资格转换不会使b
的声明无效,即它仍然是可修改的。 b
仍可用于更新其值,但*foo
无法使用。
将const
视为承诺。您向编译器承诺,您不会更改foo
指向的位置的值,但是没有人阻止您通过其他方式更改该位置的值来打破该承诺。
答案 1 :(得分:7)
我认为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?
希望它有所帮助。
答案 2 :(得分:3)
不,const int* foo = &b;
并不意味着您无法更改b
,这意味着您无法取消引用此指针并更改取消引用指针的值,就像这样
*foo = 20;
你不能用const
说某些内存对所有人来说都是无法修改的。你可以说只有const
变量才能改变这段内存,所以这个操作(如果b
没有const
修饰符)完全有效,即使你有指针指向{{ 1}}。
b
答案 3 :(得分:0)
如果你想要一个不是常量对象的常量指针声明它:
T * const ptr = &t
其中T
是对象的类型,t
是对象本身
答案 4 :(得分:0)
这个问题的答案是在将指针声明为
之后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;
}