本文主要介绍 C/C++ 编程语言中指针(pointer)的相关知识,同时通过示例代码介绍 C/C++ 编程语言中指针的常见用法。
1 What
指针,是 C/C++ 编程语言中的一个重要概念。指针通常可以理解为内存地址,而指针变量就是用来存放内存地址的变量。在同一 CPU 架构下,不同类型的指针变量所占用的存储单元的长度是相同的(而存放数据的变量因数据类型的不同,所占用的存储空间长度也不同)。例如,在 64 位操作系统(安装在 X64 CPU 架构之上)中,指针变量占用 8 字节。通过使用指针,不仅可以对数据本身进行操作,也可以对存储该数据的变量地址进行操作。
在 C/C++ 编程语言中,指针变量存储的是其指向的对象的首地址,指针指向的对象可以是变量(注意,指针变量也是变量)、数组、函数、对象等占据存储空间的实体。
下面通过一个简单的指针及其指向对象的信息关系图来进一步介绍指针。现假设有一个字符变量“c”,其内容为“A”,又有一个名称为“pChar”的指针(变量)指向该字符变量,因此字符变量“c”与指向其的指针“pChar”关系如下图所示:
?通过上图内容,可知:
- 字符变量“c”的内存地址为“0x7ffefdc3ae00”;
- 指针变量“pChar”指向的字符变量“c”对应的内存地址为“0x7ffefdc3ae00”,因此,指针变量的内容即为“0x7ffefdc3ae00”,从这里就可以知道,指针变量与其他变量不同,其存储的内容是内存地址(而其他变量通常存储用户数据);
- 指针变量也是一种变量,其也是存储在内存空间中的,在上图中未将指针变量画在内存空间中是为了便于观察指针变量及其指向对象之间的关系。
2 用法示例
在本章中,将通过示例代码来介绍 C/C++ 编程语言中指针的具体用法。
2.1 示例1
示例1的代码内容如下:
#include <iostream>
using namespace std;
int main()
{
char c = 'A';
cout << "c is: " << c << endl;
cout << "address of c is: " << (void*)&c << endl << endl;
char* pChar1 = &c;
cout << "*pChar1 is: " << *pChar1 << endl;
cout << "pChar1 is: " << (void*)pChar1 << endl;
cout << "address of pChar1 is: " << &pChar1 << endl << endl;
char* pChar2 = pChar1;
cout << "*pChar2 is: " << *pChar2 << endl;
cout << "pChar2 is: " << (void*)pChar2 << endl;
cout << "address of pChar2 is: " << &pChar2 << endl << endl;
char** pChar3 = &pChar2;
cout << "**pChar3 is: " << **pChar3 << endl;
cout << "*pChar3 is: " << (void*)(*pChar3) << endl;
cout << "pChar3 is: " << (void*)pChar3 << endl;
cout << "address of pChar3 is: " << &pChar3 << endl << endl;
return 0;
}
编译并执行上述代码,(可能的)结果如下:
通过上述代码及其执行结果,可知:
- 在 C/C++ 编程语言中,通过取地址运算符“&”可以获取到变量的内存地址;
- 指向一般变量(如本例中的字符变量 c)的指针变量(如本例中的 pChar1 和 pChar2),为一级指针,而指向一级指针的指针变量(如本例中的指针变量 pChar3),为二级指针,依此类推;
- 对指针变量进行赋值操作,需要满足指针级别的对应关系,如一级指针赋值给一级指针、二级指针赋值给二级指针,否则编译器会报错;
- 通过指针操作符“*”可以获取指针变量指向的对象的内容,如本例中通过“*pChar1”可获取指针变量 pChar1 指向的字符变量 c 的内容;
- 对于二级指针,使用一个指针操作符“*”获取到的是该指针指向的指针变量的内容,使用两个指针操作符“*”才能获取到该指针变量指向的指针变量指向的对象的内容——有点绕,具体看代码及运行结果:)
- 在 C++ 编程语言中,可通过将内存地址强转为 void* 类型的方式,来打印其内容;
本例的指针及其指向的对象的相关信息,如下图所示:
?
|