C++二级指针的用法(非常详细,附带实例)
在 C++ 程序中,指针可以指向基本数据类型,如整型或字符型,从而允许我们访问这些数据。由于指针本身也是存储在内存中的变量,它记录着数据的内存地址,因此指针也可以指向另一个指针,即指向指针的指针。
虽然这个概念初听起来有些复杂,但可以这样理解,指针本质上是一个存储内存地址的变量,当有一个指针变量存储了另一个指针变量所在内存的地址时,我们就称这个指针为“指向指针的指针”,又称为二级指针。
为了更清晰地展示这一概念,下面是一个实际的例子:
下图展示了这三个变量之间的关系。

图 1 指向指针的指针
从图 1 中可以看到,变量 N 保存在内存地址 0016FA38 这个位置,而指针变量 pN 记录的值是 N 所在的内存位置 0016FA38,同时它自己保存在内存地址 0016FA5C 这个位置。
同理,作为指向 pN 的指针,ppN 这个指针变量记录的值是 pN 所在内存地址 0016FA5C 的位置,而它自己保存在内存地址 0016FA90 这个位置。
简单来讲,普通指针指向的是一个具体的数据,而指针的指针指向的是一个指针数据,我们可以把指针数据也当作某个具体的数据,它也有自己的数据类型(例如 int*),也占用一定的内存(例如 0016FA5C),记录一定的数值(例如 0016FA37)。类比普通数据,指向指针的指针的数据类型,就是在它所指向的数据的类型之后加一个“*”。
例如,我们要定义一个指针指向另一个
在 C++ 中,可以用下面的语法格式来定义一个二级指针:
二级指针通常用来访问指针数组。数组不仅可以保存基本数据类型的数据,还可以保存指针,保存指针的数组被称为指针数组。如果要访问一个指针数组,使用二级指针最为方便。
例如:
为了利用指针偏移方便地访问数组中的各个字符串,我们需要一个可以指向这些字符串元素的指针,因为字符串元素的类型是
指针运算后得到的仍然是指针,我们需要用“*”符号取得这个指针所指向的内容,才能得到对应的字符串指针,直接输出就可以得到数字对应的月份字符串。
虽然这个概念初听起来有些复杂,但可以这样理解,指针本质上是一个存储内存地址的变量,当有一个指针变量存储了另一个指针变量所在内存的地址时,我们就称这个指针为“指向指针的指针”,又称为二级指针。
为了更清晰地展示这一概念,下面是一个实际的例子:
int N = 2; int* pN = &N; // 定义一个指针变量pN,记录变量N所在的内存地址 int** ppN = &pN; // 定义一个指针变量ppN,记录指针变量pN所在的内存地址在这段代码中,首先定义了一个整型变量 N,然后定义了一个整型指针指向这个变量 N。换句话说,这个指针的值就是整型变量 N 在内存中的地址。最后,指向指针的指针 ppN 登场了,我们用
int**
作为数据类型定义了一个指针 ppN,其中保存的就是 pN 指针变量所在内存中的地址,也就是它指向这个整型指针 pN。下图展示了这三个变量之间的关系。

图 1 指向指针的指针
从图 1 中可以看到,变量 N 保存在内存地址 0016FA38 这个位置,而指针变量 pN 记录的值是 N 所在的内存位置 0016FA38,同时它自己保存在内存地址 0016FA5C 这个位置。
同理,作为指向 pN 的指针,ppN 这个指针变量记录的值是 pN 所在内存地址 0016FA5C 的位置,而它自己保存在内存地址 0016FA90 这个位置。
简单来讲,普通指针指向的是一个具体的数据,而指针的指针指向的是一个指针数据,我们可以把指针数据也当作某个具体的数据,它也有自己的数据类型(例如 int*),也占用一定的内存(例如 0016FA5C),记录一定的数值(例如 0016FA37)。类比普通数据,指向指针的指针的数据类型,就是在它所指向的数据的类型之后加一个“*”。
例如,我们要定义一个指针指向另一个
int*
类型的指针,那么它自身的类型就是 int* 加一个“*”就成了 int**
。而这个指针的值,同样是用“&”取得被指向的指针变量的地址赋给它,于是它就成为指向这个指针的指针。在 C++ 中,可以用下面的语法格式来定义一个二级指针:
数据类型** 指针变量名其中,数据类型表示它所指向的指针的数据类型。例如:
int** ppN = &pN;这样就定义了一个指向整型指针的二级指针 ppN,它指向另一个指针变量 pN,而 pN 指针变量又指向一个整型变量。
二级指针通常用来访问指针数组。数组不仅可以保存基本数据类型的数据,还可以保存指针,保存指针的数组被称为指针数组。如果要访问一个指针数组,使用二级指针最为方便。
例如:
// 这是一个指针数组,其中保存的是各个字符串常量的首地址指针,其类型是 const char* const char* arrMonth[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; // 定义一个指向指针的指针 // 因为要指向的指针是 const char*类型,所以加上*后它自身的类型就是 const char** // 这里数组的首地址 arrMonth 就是数组的第一个元素 // 也就是指向第一个字符串 “Jan” 的指针 const char** pMonth = arrMonth; // 获取用户输入 int nIndex = 0; cout << "请输入月份对应的数字: " << endl; cin >> nIndex; // 对指针进行运算,使其指向相应的数组元素 // 也就是相应的字符串指针 const char* pCurMonth = *(pMonth + (nIndex - 1)); cout << "对应的月份是: " << pCurMonth << endl;在以上这段代码中,arrMonth 数组中保存的是多个字符串常量的指针,这些指针的数据类型是
const char*
。为了利用指针偏移方便地访问数组中的各个字符串,我们需要一个可以指向这些字符串元素的指针,因为字符串元素的类型是
const char*
,所以我们定义了一个 const char**
类型的二级指针 pMonth,并将字符串数组的首地址赋值给它,使其指向字符串数组的第一个元素。然后通过对 pMonth 进行运算,让其偏移指向数组中所对应的字符串元素。指针运算后得到的仍然是指针,我们需要用“*”符号取得这个指针所指向的内容,才能得到对应的字符串指针,直接输出就可以得到数字对应的月份字符串。