[英]const and pointers in C
通过将const与指针一起使用,可以通过使用有问题的指针对它进行解引用来使pointee不可修改。 但是,为什么我不能修改指针未直接指向的内容呢?
例如:
int a = 3;
const int* ptr = &a;
*ptr = 5;
将无法编译。 但是为什么
*(ptr + 2) = 5;
还不能编译? 我没有更改指针指向的内容。
那么,我们是否必须说以这种方式将const与指针一起使用,不仅不能修改指针指向的内容(通过取消对指针的引用),还可以修改使用指针获得的地址的其他任何内容?
我知道在该示例中,我尝试访问未分配的内存,但这只是为了讨论。
ptr +2
与ptr
具有相同的类型,即指向const
对象的指针。
指针算法假定所指向的对象是所有相同基本类型的数组。 此类型包括const
限定符。
const
引入的不可修改性取决于const
的写入位置。
如果你写
const int * ptr = &a;
(或int const * ptr = &a;
),则const
指向对象,因此禁止使用指针写入目标。
(OTOH,如果你写
int * const ptr = &a;
您无法修改ptr
。)
在您的情况下,所有涉及写入目标的操作都是禁止的。
这包括*ptr
和ptr[0]
(它们是等效的),还包括涉及目标地址修改的所有内容,例如*(ptr + 2)
或ptr[2]
。
尽管其他答案解释了为什么它不起作用的技术性,但我想提供一个更笼统的理由:这是唯一有意义的事情。
问题在于,编译器没有通用的方法来确定p + something
是否与p
相同,因为something
可以任意复杂。 诸如“ p
和p + 0
所指向的值不可修改,但其他值仍可修改”之类的规则在编译时无法检查:假设您编写了以下内容:
*(p + very complex expression) = ...
您的编译器是否应该能够确定very complex expression
是否为零? 关于什么
int s;
scanf("%d", &s);
*(p + s) = ...
在这种情况下,编译器应该做什么?
这里唯一合理的选择是使通过p
访问的任何值均不可修改。
由于指针也可以用作数组(请考虑argv
),因此编译器会限制指针所涉及的每次访问。 这样,整个数组都是只读的。
让我们考虑一下表达式的类型。
const int* ptr = &a;
ptr
的类型为const int*
。
因此*ptr
的类型为const int
。 不可修改。
(ptr + 2)
的类型仍然是const int*
因此*(ptr + 2)
的类型仍然是const int
,这也是不可修改的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.