我经常使用指向 const 对象的指针,就像这样......
const int *p;
这仅仅意味着您不能更改p
指向 through的整数p
。但我也看到了对 const 指针的引用,声明如下......
int* const p;
据我了解,这意味着指针变量本身是恒定的——你可以整天改变它指向的整数,但你不能让它指向别的东西。
那有什么可能的用途?
当您为嵌入式系统设计 C 程序或需要引用同一内存的特殊用途程序(共享内存的多处理器应用程序)时,您需要常量指针。
例如,我有一个32 位 MIP 处理器,上面附有一个小 LCD 。我必须将 LCD 数据写入内存中的特定端口,然后将其发送到 LCD 控制器。
我可以#define 该数字,但我还必须将其转换为指针,而当我这样做时,C 编译器没有那么多选项。
此外,我可能需要它是易失的,也可以强制转换,但使用提供的语法更容易和更清晰 - 一个指向易失性内存位置的 const 指针。
对于 PC 程序,一个例子是:如果你设计 DOS VGA 游戏(网上有教程很有趣,可以学习基本的低级图形),那么你需要写入 VGA 内存,这可能被称为偏移量从 const 指针。
-亚当
它允许您保护指针不被更改。这意味着您可以保护您基于指针永远不会更改或无意修改的假设,例如:
int* const p = &i;
...
p++; /* Compiler error, oops you meant */
(*p)++; /* Increment the number */
另一个例子:如果你知道它是在哪里初始化的,你就可以避免未来的 NULL 检查。编译器保证指针永远不会改变(为 NULL)...</p>
在任何非 const C++ 成员函数中,this
指针都是 type C * const
,其中C
是类类型——您可以更改它指向的内容(即它的成员),但不能将其更改为指向 a 的不同实例C
. 对于const
成员函数,this
类型为const C * const
. 还有(很少遇到)volatile
和const volatile
成员函数,它们this
也有volatile
限定符。
一种用途是在低级(设备驱动程序或嵌入式)代码中,您需要引用映射到输入/输出设备(如硬件引脚)的特定地址。某些语言允许您链接特定地址的变量(例如 Ada has use at
)。在 C 中,最惯用的方法是声明一个常量指针。请注意,此类用法也应具有volatile
限定符。
其他时候它只是防御性编码。如果你有一个不应该改变的指针,明智的做法是声明它不能改变。这将允许编译器(和 lint 工具)检测修改它的错误尝试。
当我想避免对指针的意外修改(例如指针算术或函数内部)时,我总是使用它们。您也可以将它们用于单例模式。
'this' 是一个硬编码的常量指针。
与“const int”相同......如果编译器知道它不会改变,它可以是基于此的优化假设。
struct MyClass
{
char* const ptr;
MyClass(char* str) :ptr(str) {}
void SomeFunc(MyOtherClass moc)
{
for(int i=0; i < 100; ++i)
{
printf("%c", ptr[i]);
moc.SomeOtherFunc(this);
}
}
}
现在,编译器可以做很多事情来优化那个循环——只要它知道 SomeOtherFunc() 不会改变 ptr 的值。使用 const,编译器知道这一点,并且可以做出假设。没有它,编译器必须假设 SomeOtherFunc 会改变 ptr。
我见过一些 OLE 代码,其中你有一个从代码外部传入的对象,要使用它,你必须访问它传入的特定内存。所以我们使用 const 指针来确保函数总是操纵这些值比通过 OLE 界面进来的。
已经给出了几个很好的理由作为这个问题的答案(内存映射设备和只是简单的旧防御性编码),但我敢打赌,大多数情况下你看到这实际上是一个错误,并且意图是有to item 是一个指向常量的指针。
我当然没有数据来支持这种预感,但我仍然会打赌。
将type*和const type*视为类型本身。然后,您可以了解为什么您可能希望拥有这些类型的 const。
始终将指针视为 int。这意味着
object* var;
实际上可以认为是
int var;
所以,一个 const 指针仅仅意味着:
const object* var;
变成
const int var;
因此你也不能改变指针指向的地址,仅此而已。为防止数据更改,您必须将其设为指向 const 对象的指针。