繁体   English   中英

const和C中的指针

[英]const and pointers in C

通过将const与指针一起使用,可以通过使用有问题的指针对它进行解引用来使pointee不可修改。 但是,为什么我不能修改指针未直接指向的内容呢?

例如:

int a = 3;
const int* ptr = &a;
*ptr = 5;

将无法编译。 但是为什么

*(ptr + 2) = 5;

还不能编译? 我没有更改指针指向的内容。
那么,我们是否必须说以这种方式将const与指针一起使用,不仅不能修改指针指向的内容(通过取消对指针的引用),还可以修改使用指针获得的地址的其他任何内容?

我知道在该示例中,我尝试访问未分配的内存,但这只是为了讨论。

ptr +2ptr具有相同的类型,即指向const对象的指针。

指针算法假定所指向的对象是所有相同基本类型的数组。 此类型包括const限定符。

const引入的不可修改性取决于const的写入位置。

如果你写

const int * ptr = &a;

(或int const * ptr = &a; ),则const指向对象,因此禁止使用指针写入目标。

(OTOH,如果你写

int * const ptr = &a;

您无法修改ptr 。)

在您的情况下,所有涉及写入目标的操作都是禁止的。

这包括*ptrptr[0] (它们是等效的),还包括涉及目标地址修改的所有内容,例如*(ptr + 2)ptr[2]

尽管其他答案解释了为什么它不起作用的技术性,但我想提供一个更笼统的理由:这是唯一有意义的事情。

问题在于,编译器没有通用的方法来确定p + something是否与p相同,因为something可以任意复杂。 诸如“ pp + 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM