C语言二级指针和指针数组

1.定义二级指针

1. 定义二级指针变量的格式
数据类型  **二级指针变量名;

2. 二级指针变量的初始化:
二级指针变量指向的是一个一级指针变量,
因此对二级指针变量赋值时,赋值的是一级指针变量的地址。

数据类型   普通变量名 = 初始值;
数据类型  *一级指针变量名 = &普通变量名;
---> 一级指针变量指向普通变量对应的地址空间

2.1> 定义二级指针变量的同时进行初始化
数据类型  **二级指针变量名 = &一级指针变量名;
---> 二级指针变量指向一级指针变量对应的地址空间

2.2> 先定义二级指针变量,后对二级指针变量进行初始化
数据类型  **二级指针变量名 = NULL;
二级指针变量名 = &一级指针变量名
int a=100;
int *p = &a;
int **pp=&p;
//p=&a;    *p=a=100;   pp=&p;  *pp=p=&a;     **pp=*p=a=100;

image-20231226103445090

int a = 100;
int *p = &a;
int **pp = &p;
--------------------
a 		---> 变量a对应地址空间的值 
*p      ---> 指针变量p指向的地址空间的值,及变量a对应的地址空间的值
**pp    ---> *pp : 二级指针变量pp指向的一级指针变量对应地址空间的值
		---> 一级指针变量对应地址空间存放的是变量a的地址
		---> *(*pp) ---> 指向变量a对应的地址空间的值,及变量a对应的地址空间的值
------------------------
&a 		---> 变量a的地址
p       ---> 取指针变量p中存储的地址,及变量a的地址
*pp     ---> 取二级指针变量pp指向的地址空间的值,
			及指针变量p对应地址空间的存储的变量a的地址
----------------------
&p		---> 取指针变量p对应的内存地址
pp      ---> 取二级指针变量pp中存储的指针变量p的地址
-----------------------
&pp     ---> 取二级指针变量pp对应的内存地址

2.二级指针和指针数组的关系

研究二级指针变量名:
int a = 100;
int *p = &a;
int **pp = &p;

pp : 二级指针变量名, 
pp+1 : 偏移int *类型的大小 32位系统和偏移4个字节 64位系统偏移8个字节

*pp : 取二级指针变量pp指向的地址空间的值,及一级指针变量p存放的数据,及&a
*pp <=等价=> p
*pp+1 <=等价于=> p+1 : 偏移int类型的大小    *pp是&a   *pp+1等价于  p+1 偏移a的类型大小  4个字节

研究指针数组名含义:
int a = 100, b = 200, c = 300, d = 400, e = 500;
int *p_arr[5] = {&a, &b, &c, &d, &e};

p_arr : 指针数组名,数组的每个元素都是int *类型
表示指针数组的首地址
p_arr+1:偏移指针数组元素的大小,及偏移int *类型的大小 

p_arr[下标] <=等价=> *(p_arr+下标)  : 取指针数组某个元素的值  数组元素都是地址
p_arr[下标]+1 <=等价=> *(p_arr+下标)+1  : 指针数组每个元素的类型为int *类型    表示的是数组元素的值&a &b ....所以偏移的是变量a b...的类型大小
偏移int类型的大小

可以使用二级指针指向一个指针数组,及使用指针数组名对二级指针变量名赋值。

二级指针变量名和指针数组名的区别:
二级指针变量名是一个变量,可以被修改,改变二级指针的指向。
指针数组名是一个常量,不可以被修改。
二级指针指向指针数组
int a = 100, b = 200, c = 300, d = 400, e = 500;
int *p_arr[5] = {&a, &b, &c, &d, &e};
int **pp=p_arr;

p_arr[下标] <=等价=> *(p_arr+下标)<==>*(pp+下标) : 取指针数组某个元素的值  元素的值也是地址是指向的其他变量的地址
p_arr[下标]+1 <=等价=> *(p_arr+下标)+1<==>*(pp+下标)+1  : 指针数组每个元素的类型为int *类型偏移int类型的大小

编写代码:验证二级指针变量名和指针数组名的关系。
#include <stdio.h>

int main(int argc, const char *argv[])
{
	// 1. 验证二级指针变量名 
	int a = 100;
	int *p = &a;
	int **pp = &p;

	// pp : 取二级指针变量中存放的一级指针变量的地址 
	// pp + 1 : 二级指针变量的运算,加1偏移int *类型的大小
	printf("pp = %p\n", pp);
	printf("pp + 1 = %p\n", pp+1);
	
	// *pp <==> p : 取二级指针变量指向的一级指针变量对应的内存空间的值 
	// *pp + 1 <==> p + 1: 一级指针变量的运算,加1偏移int类型的大小 
	printf("&a = %p\n", &a);
	printf("p = %p\n", p);
	printf("*pp = %p\n", *pp);
	printf("p+1 = %p\n", p+1);
	printf("*pp+1 = %p\n", *pp+1);
	

	// 2. 指针数组名的验证
	int  b = 200, c =300, d = 400, e = 500;

	int *p_arr[5] = {&a,&b,&c,&d,&e};
	
	printf("p_arr = %p\n", p_arr);	// 指针数组的首地址
	printf("p_arr + 1 = %p\n", p_arr + 1);	// 偏移int *类型的大小 
							// 指针数组的每个元素都是int *类型 
	
	printf("p_arr[0] = %p\n", p_arr[0]);	// 取指针数组第0个元素的值
							// 指针数组的每个元素都是int *类型 
	printf("*(p_arr+0) = %p\n", *(p_arr+0));	// 取指针数组第0个元素的值
							// 指针数组的每个元素都是int *类型 
							
	printf("p_arr[0]+1 = %p\n", p_arr[0]+1);  // 偏移int类型的大小 
	printf("*(p_arr+0)+1 = %p\n", *(p_arr+0)+1);  // 偏移int类型的大小
	return 0;
}

 

  • 31
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值