1. 二级指针基本概念
这里让我们花点时间来看一个例子,揭开这个即将开始的序幕。考虑下面这些声明:
int a = 12;int *b = &a;
它们如下图进行内存分配:
假定我们又有了第3个变量,名叫c,并用下面这条语句对它进行初始化:
c = &b;
它在内存中的大概模样大致如下:
问题是:c的类型是什么?
显然它是一个指针,但它所指向的是什么?变量b是一个“指向整型的指针”,所以任何指向b的类型必须是指向“指向整型的指针”的指针,更通俗地说,是一个指针的指针。
它合法吗?是的!指针变量和其他变量一样,占据内存中某个特定的位置,所以用&操作符取得它的地址是合法的。那么这个变量的声明是怎样的声明的呢?
那么这个**c如何理解呢?*操作符具有从右想做的结合性,所以这个表达式相当于*(*c),我们从里向外逐层求职。*c访问c所指向的位置,我们知道这是变量b.第二个间接访问操作符访问这个位置所指向的地址,也就是变量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;}
4. 强化训练_画出内存模型图
void mian(){//栈区指针数组char *p1[] = { "aaaaa", "bbbbb", "ccccc" };//堆区指针数组char **p3 = (char **)malloc(3 * sizeof(char *)); //char *array[3];int i = 0;for (i = 0; i < 3; i++){p3[i] = (char *)malloc(10 * sizeof(char)); //char buf[10]sprintf(p3[i], "%d%d%d", i, i, i);}}
5. 多级指针
//分配内存void allocate_memory(char*** p, int n){if (n < 0){return;}char** temp = (char**)malloc(sizeof(char*)* n);if (temp == NULL){return;}//分别给每一个指针malloc分配内存for (int i = 0; i < n; i++){temp[i] = malloc(sizeof(char)* 30);sprintf(temp[i], "%2d_hello world!", i + 1);}*p = temp;}//打印数组void array_print(char** arr, int len){for (int i = 0; i < len; i++){printf("%s\n", arr[i]);}printf("----------------------\n");}//释放内存void free_memory(char*** buf, int len){if (buf == NULL){return;}char** temp = *buf;for (int i = 0; i < len; i++){free(temp[i]);temp[i] = NULL;}free(temp);}void test(){int n = 10;char** p = NULL;allocate_memory(&p, n);//打印数组array_print(p, n);//释放内存free_memory(&p, n);}
