指针常量和常量指针(无师自通)
常量指针不能用于改变它指向的值;而指针常量在初始化之后就不能改变。
图 1 常量指针
由于 rates 是一个指向 const 的指针,所以编译器不会允许程序员编写代码来改变 rates 指向的内容。
在将常量的地址传递到指针变量中时,该变量必须已定义为指向常量的指针。如果在 rates 形参的定义中没有使用 const 关键字,则会产生编译器错误。
除此之外,还有一种使用 const 关键字定义的 const 指针,称为指针常量。常量指针和指针常量在中文里面听起来像是绕口令,但其实它们不是一回事。以下就是"指向const的指针"和"const指针"之间的区别:
下面的代码显示了一个 const 指针的示例:
图 2 指针常量
在该代码中,ptr 是用 value 变量的地址初始化的。因为 ptr 是一个常量指针,所以如果编写使 ptr 指向其他任何内容的代码,都会导致编译器错误。但是,如果使用 ptr 来改变 value 的内容,则不会产生错误。这是因为 value 并不是常量,并且 ptr 也不是一个指向常量的指针。
指针常量必须使用起始值进行初始化,如以上示例代码所示。如果将一个指针常量用作函数形参,则该形参将使用传递进来的实参地址进行初始化,并且在函数执行时不能被修改为指向任何其他地方。以下就是一个试图违反这个规则的示例:
例如,来看下面的代码示例:
图 3 指向常量的指针常量
在以上代码中,ptr 是用 value 的地址初始化的。因为 ptr 是一个指针常量,所以不能编写使 ptr 指向其他任何东西的代码;又因为 ptr 是一个常量指针,所以也不能用它来改变 value 的内容。
以下代码显示了一个指向常量的指针常量的另一示例:
常量指针
前面已经介绍了如何将一个项目的地址传递到一个指针形参中,并且该指针可以用来修改作为实参传递的项目。有时需要将 const 项目的地址传递给指针。在这种情况下,必须把指针定义为指向 const 项的指针。例如,来看以下数组定义:
const int SIZE = 6;
const double payRates[SIZE] = { 18.55, 17.45, 12.85, 14.97, 10.35, 18.89 };
void displayPayRates(const double *rates, int size) { // Set numeric output formatting cout << setprecision(2) << fixed << showpoint; // Display all the pay rates for (int count = 0; count < size; count++) { cout << "Pay rate for employee " << (count + 1)<< "is $" << *(rates + count) << endl; } }在函数头中,请注意 rates 形参被定义为一个指向 const double 的指针。应该指出的是,const 这个单词适用于 rates 指向的东西,而不是 rates 本身,如图 1 所示。
图 1 常量指针
由于 rates 是一个指向 const 的指针,所以编译器不会允许程序员编写代码来改变 rates 指向的内容。
在将常量的地址传递到指针变量中时,该变量必须已定义为指向常量的指针。如果在 rates 形参的定义中没有使用 const 关键字,则会产生编译器错误。
指针常量
在前面的章节中,我们讨论了指向 const 的指针,即指向 const 数据的指针。所谓“指向 const 的指针”其实就是“指向常量的指针”,即常量指针。除此之外,还有一种使用 const 关键字定义的 const 指针,称为指针常量。常量指针和指针常量在中文里面听起来像是绕口令,但其实它们不是一回事。以下就是"指向const的指针"和"const指针"之间的区别:
- 指向 const 的指针指向一个常量项目。指针指向的数据不能改变,但指针本身可以改变。
- 而对于 const 指针来说,指针本身就是常量。一旦指针使用了某个地址进行初始化,那么它就不能指向除此地址之外的任何其他东西。
下面的代码显示了一个 const 指针的示例:
int value = 22;
int *const ptr = &value;
图 2 指针常量
在该代码中,ptr 是用 value 变量的地址初始化的。因为 ptr 是一个常量指针,所以如果编写使 ptr 指向其他任何内容的代码,都会导致编译器错误。但是,如果使用 ptr 来改变 value 的内容,则不会产生错误。这是因为 value 并不是常量,并且 ptr 也不是一个指向常量的指针。
指针常量必须使用起始值进行初始化,如以上示例代码所示。如果将一个指针常量用作函数形参,则该形参将使用传递进来的实参地址进行初始化,并且在函数执行时不能被修改为指向任何其他地方。以下就是一个试图违反这个规则的示例:
void setToZero(int *const ptr) { ptr = 0; //错误,不能更改ptr的内容 }这个函数的形参 ptr 是一个 const 指针。它不会被编译,因为在函数中不能有改变 ptr 内容的代码。但是,ptr 并不指向 const,所以可以使用代码来改变 ptr 指向的数据。以下示例就完全可以编译:
void setToZero(int *const ptr) { *ptr =0; }虽然该形参是指针常量,但是程序员也可以使用不同的实参多次调用函数。以下代码即可成功地将 x、y 和 z 的地址传递给 setToZero 函数:
int x, y, z; //将x、y和z设置为0 setToZero(&x); setToZero(&y); setToZero(&z);
指向常量的指针常量
到目前为止,在一起使用 const 和指针时,我们既认识了常量指针,也认识了指针常量。但其实还存在着第 3 种结合,即“指向常量的指针常量”。例如,来看下面的代码示例:
int value = 22;
const int *const ptr = &value;
图 3 指向常量的指针常量
在以上代码中,ptr 是用 value 的地址初始化的。因为 ptr 是一个指针常量,所以不能编写使 ptr 指向其他任何东西的代码;又因为 ptr 是一个常量指针,所以也不能用它来改变 value 的内容。
以下代码显示了一个指向常量的指针常量的另一示例:
void displayValues(const int *const numbers, int size) { // Display all the values. for (int count = 0; count < size; count++) { cout << * (numbers + count) << " "; } cout << endl; }在这段代码中,形参 numbers 是一个指向 const int 的 const 指针。虽然可以使用不同的实参来调用函数,但函数本身不能改变 numbers 指针的指向,也不能使用 numbers 指针来改变实参的内容。
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算