1.二级指针基本概念(指针变量地址的数据类型)
这里让我们花点时间来看一个例子,揭开这个即将开始的序幕。考虑下面这些声明:
它们如下图进行内存分配:

假定我们又有了第3个变量,名叫c,并用下面这条语句对它进行初始化:
它在内存中的大概模样大致如下:

问题是:c的类型是什么?显然它是一个指针,但它所指向的是什么?变量b是一个“指向整型的指针”,所以任何指向b的类型必须是指向“指向整型的指针”的指针,更通俗地说,是一个指针的指针。
它合法吗?是的!指针变量和其他变量一样,占据内存中某个特定的位置,所以用&操作符取得它的地址是合法的。
那么这个变量的声明是怎样的声明的呢?
那么这个**c如何理解呢?*操作符具有从右想做的结合性,所以这个表达式相当于*(*c),我们从里向外逐层求职。*c访问c所指向的位置,我们知道这是变量b.第二个间接访问操作符访问这个位置所指向的地址,也就是变量a.指针的指针并不难懂,只需要留心所有的箭头,如果表达式中出现了间接访问操作符,你就要随箭头访问它所指向的位置。

2. 二级指针做形参输出特性
说明一下:a[2]和*a+2一样的
二级指针做参数的输出特性是指由被调函数分配内存,主调函数使用。
//被调函数,由参数n确定分配多少个元素内存 void allocate_space(int **arr,int n){ //堆上分配n个int类型元素内存 int *temp = (int *)malloc(sizeof(int)* n); if (NULL == temp){ return; } //给内存初始化值 int *pTemp = temp; for (int i = 0; i < n;i ++){ //temp[i] = i + 100; *pTemp = i + 100; pTemp++; } //指针间接赋值 *arr = temp; } //打印数组 void print_array(int *arr,int n){ for (int i = 0; i < n;i ++){ printf("%d ",arr[i]); } printf("\n"); } //二级指针输出特性(由被调函数分配内存) 主调函数 void test(){ int *arr = NULL; int n = 10; //给arr指针间接赋值 allocate_space(&arr,n); //输出arr指向数组的内存 print_array(arr, n); //释放arr所指向内存空间的值 if (arr != NULL){ free(arr); arr = NULL; } } |
3. 二级指针做形参输入特性
二级指针做形参输入特性是指由主调函数分配内存,被调函数使用它
| //打印数组 void print_array(int **arr,int n){ for (int i = 0; i < n;i ++){ printf("%d ",*(arr[i])); } printf("\n"); } //二级指针输入特性(由主调函数分配内存) void test(){ 栈区申请数据内存 int a1 = 10; int a2 = 20; int a3 = 30; int a4 = 40; int a5 = 50; int n = 5; int** arr = (int **)malloc(sizeof(int *) * n); arr[0] = &a1; arr[1] = &a2; arr[2] = &a3; arr[3] = &a4; arr[4] = &a5; 打印堆区数据 print_array(arr,n); 释放堆区 free(arr); arr = NULL; } |