调用printf()时,* b的值是否未定义?
void foo(int *a) {
const int *b = a;
int *c = a;
*c = 2;
printf("%d\n", *b); // what must be *b? 1, 2 or undefined?
}
int d = 1;
foo(&d);
答案 0 :(得分:11)
它将打印2. const int *b
字面意思是:
指向不能为其值的整数的指针 通过其去歧视改变了。
这并不意味着指针指向的值可能不会改变。事实上,改变是完全有效的。使用它的一种可能方案是保持对某些大型结构的只读引用的结构。引用可能会更改,但使用该结构的函数可能不会更改指针后面的内容。
想象一个驱动程序或类似程序,它发出设备传送的任何数据的只读内存映射:映射的地址不是常量,但由于这是一个只读映射,因此用户程序可能无法写入它。 OTOH当设备更新数据时,缓冲区的内容将发生变化,但不一定是映射地址。
答案 1 :(得分:2)
标准所说的是(重点是我的)
6.7.3 / 5
如果尝试修改使用的定义的对象 一个const限定类型通过使用非左值 const限定类型,行为未定义。
这不适用于您的情况(只是相反)
有问题的对象是用普通(int
)类型定义的。
在您的情况下,只有b
对象的更改才是非法的;通过a
或c
进行的更改完全合法
答案 2 :(得分:0)
由于b
指向与a
相同的内存,因此值当然会发生变化。不确定为什么你也引入了c
,但它没有添加任何东西。它将打印2
。
答案 3 :(得分:0)
*b
为2,因为设置值的printf
之前的最后一行是*c = 2
。
a
,b
和c
都指向相同的整数值。所以设置它的最后一个将决定它的当前值。
答案 4 :(得分:0)
b应该是printf()中的2。你总是在b和c中处理一个指针。
答案 5 :(得分:0)
声明const int *b = a;
表示b
引用常量int值。也就是说它将其价值视为一个恒定值。
因此,
*b = 10;
不正确,但是:
a = 10;
很好,因为a不是常数值,但是当解除引用b时,我们将其视为常量。
因此,当你更改了它所指向的值时,肯定定义了b
:
c = 2;
与上面的例子相同。简单地说,指向const值的指针不能通过解除引用来修改该值,但是它指向的值可以以其他方式改变。