Loading

二级指针


返回 我的技术栈(Technology Stack)



C语言允许有多级指针存在,在实际的程序中一级指针最常用,其次是二级指针。
二级指针就是指向一个一级指针变量地址的指针。
三级指针基本用不着。

二级指针

二级指针就是指向指针的指针,指向地址的地址,有点套娃...直接看下面的案例更好理解吧。


* p 、* * p、p[0]、p[0][0]

#include<stdio.h>

int main(void)
{
	int a[] = { 1,2,3 };
	int b[] = { 4,5,6 };
	int c[] = { 7,8,9 };

	//指针数组是一个特殊的二维数组模型
	//指针数组对应于二级指针
	int* arr[] = { a,b,c };    //这里不用取地址符号&,因为数组名就是数组的首地址
	 
	//指针数组和二级指针建立关系
	int** p = arr;
	printf("%p\n", a);  //输出:0xFF0000
	printf("%p\n", b);  //输出:0xFF0032
	printf("%p\n", c);  //输出:0xFF0064
	printf("%p\n", arr);  //输出:0xFF0086

	printf("%p\n", *p);  //输出:0xFF0000
	printf("%d\n", **p);  //输出:1

	printf("%p\n", p[0]);  //输出:0xFF0000
	printf("%d\n", p[0][0]);  //输出:1

	return 0;
}

image

**(p+1)、 * (*p+1)

#include<stdio.h>

int main(void)
{
	int a[] = { 1,2,3 };
	int b[] = { 4,5,6 };
	int c[] = { 7,8,9 };

	//指针数组是一个特殊的二维数组模型
	//指针数组对应于二级指针
	int* arr[] = { a,b,c };    //这里不用取地址符号&,因为数组名就是数组的首地址
	 
	//指针数组和二级指针建立关系
	int** p = arr;
	
	printf("%d\n",**(p+1));  //输出4

	return 0;
}

image

#include<stdio.h>

int main(void)
{
	int a[] = { 1,2,3 };
	int b[] = { 4,5,6 };
	int c[] = { 7,8,9 };

	//指针数组是一个特殊的二维数组模型
	//指针数组对应于二级指针
	int* arr[] = { a,b,c };    //这里不用取地址符号&,因为数组名就是数组的首地址
	 
	//指针数组和二级指针建立关系
	int** p = arr;
	
	printf("%d\n",*(*p+1));  //输出:2

	return 0;
}

image


* (*(p+1))+1)

#include<stdio.h>

int main(void)
{
	int a[] = { 1,2,3 };
	int b[] = { 4,5,6 };
	int c[] = { 7,8,9 };

	//指针数组是一个特殊的二维数组模型
	//指针数组对应于二级指针
	int* arr[] = { a,b,c };    //这里不用取地址符号&,因为数组名就是数组的首地址
	 
	//指针数组和二级指针建立关系
	int** p = arr;
	
	printf("%d\n",*(*(p+1))+1);  //输出:5

	return 0;
}

image

p[i][j]、* (p[i]+j))、* (*(p+i)+j))

#include<stdio.h>

int main(void)
{
	int a[] = { 1,2,3 };
	int b[] = { 4,5,6 };
	int c[] = { 7,8,9 };

	//指针数组是一个特殊的二维数组模型
	//指针数组对应于二级指针
	int* arr[] = { a,b,c };    //这里不用取地址符号&,因为数组名就是数组的首地址
	 
	//指针数组和二级指针建立关系
	int** p = arr;
	
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			//printf("%d    ",p[i][j]);
			//printf("%d    ",*(p[i]+j));
			printf("%d    ",*(*(p+i)+j));
		}
		puts("");  //相当于输出一个换行\n
	}

	return 0;
}

输出:
1    2    3
4    5    6
7    8    9

上面三个输出的结果一样!

image

变量的二级指针

#include<stdio.h>

int main(void)
{
	int a = 10;
	int b = 20;

	int* p = &a;
	int** pp = &p;

	printf("%p\n",&a);   //输出:0095FA7C
	printf("%p\n",&b);  //输出:0095FA70

	
	printf("%p\n",p);  //输出:0095FA7C        这里存的是a的地址
	printf("%d\n",*p);  //输出:10					这里取的是a的值
	printf("%p\n",&p);  //输出:0095FA64


	printf("%p\n",pp);  //输出:0095FA64       这里是二级指针pp存储的地址(值)
	printf("%p\n",&pp);  //输出:0095FA58    这里是二级指针pp自己的地址

	*pp = &b;  //等价于 p = &b;        把 指针的指针 pp 指向 b 的地址
	printf("%d\n", *p);  //输出:20    因为前一步指向b的地址了,所以取出的也是b的值20


	//*pp = 100;  野指针,合理修改的是地址,而不是值 
	**pp = 100;  
	// *pp 取的是 一级指针 的值(地址)0095FA70  ,这是变量b的地址,因为之前 *pp = &b; 操作了,
	//**pp 相当于 *(0095FA70)  取得是变量b的值20;截止把数值100赋值给那个地址,也就是值覆盖,变成了100


	printf("%d\n", *p);  //输出:100
	printf("%d\n", a);  //输出:10
	printf("%d\n", b);  //输出:100


	//printf("%p\n",a);


	return 0;
}

image


参考:
[1]C基础讲义2018修订版(黑马程序员)


posted @ 2021-07-21 09:21  言非  阅读(1003)  评论(0编辑  收藏  举报