C语言的二级指针

本文深入浅出地解析了一级指针和二级指针的概念,通过实例代码详细解释了二级指针如何保存指针的地址,并阐述了其在不同场景下的应用价值。

一个初学者对于二级指针的个人分析,如果有错希望给与批评和指正

个人对于指针的理解就是其实指针就是一个变量,一个保证着地址的变量。

一级指针非常容易理解,如下:

#include<stdio.h>


void main()
{
    int num =100;  //一个普通的num变量
    
    int *p = &num;  //一个int类型的指针变量,保存着变量num的地址 ,变量名前加个*就是指针了  
                    //(指定类型就是告诉指针往前走4个字节就好了,因为int是占用四个字节的类型)
                    // &变量名   就是取出该变量的地址编号
  

    printf("num和*p是等价的:num=%d == *p=%d \n", num, *p); //*指针 是根据指针保存的地址取出值
    printf("&num和p是等价的:&num=%p == p=%p \n", &num, p); //&变量 是根据变量取出值所在的地址

    getchar(); 

}

执行结果:

num和*p是等价的:num = 100 == *p = 100
&num和p是等价的:&num = 001AF76C == p = 001AF76C

理解了普通指针,接下来就是二级指针:

一级指针p保存的是变量num在内存里的地址,那一级指针p在内存里的地址呢???

指针p的地址也用指针保存啊,那么保存指针p地址的指针就是二级指针了...........

看代码:

#include<stdio.h>


void main()
{
	int num = 100;  //一个普通的num变量

	int *p = &num;  //一个int类型的指针变量,保存着变量num的地址 ,变量名前加个*就是指针了  
					//(指定类型就是告诉指针往前走4个字节就好了,因为int是占用四个字节的类型)
					// &变量名   就是取出该变量的地址编号


	printf("num和*p是等价的:num = %d == *p = %d\n\n", num, *p); //*指针 是根据指针保存的地址取出值
	printf("&num和p是等价的:&num = %p == p = %p\n\n", &num, p); //&变量 是根据变量取出值所在的地址


	int **PP = &p;  // 加多一个* 两个**就是二级指针le....  &p 取出指针 p 的地址给 pp 保存

	printf("*p 和 **pp 是等价的 *p = %d == **pp =%d\n\n",*p, **PP);
	printf("p 和 *pp 是等价的 p = %p == *pp = %p\n\n", p, *PP);
	printf("pp和&p是等价的:pp = %p, &p = %p", PP, &p);
	//通过上面的代码已经知道:
	//p   保存的是 num 的地址, *p  根据地址取出 num 的值是100
	//pp  保存的是 p   的地址, *pp 根据地址取出 p 的值是 num的地址 
	//pp  保存的是 p   的地址  &p 取出p的地址
							

	getchar();

}

 

执行结果如下:

num和*p是等价的:num = 100 == *p = 100

&num和p是等价的:&num = 010FFE28 == p = 010FFE28

*p 和 **pp 是等价的 *p = 100 == **pp =100

p 和 *pp 是等价的 p = 010FFE28 == *pp = 010FFE28

pp和&p是等价的:pp = 010FFE1C, &p = 010FFE1C

问:pp 保存的是啥? 

答:p 的地址啊

问:为什么*pp的值是和 p 是等价的?

答:因为pp保存的是 p 的地址,* 号是根据地址取出值,*pp 取出 p 的地址里面保存的值,也就是num的地址. 取出num的地址后,在加一个*号,就是根据num的地址取出值,所以 **pp == 100;

内存中的逻辑大概如下图(原谅我画的丑--_--||):

 

问: 为什么要使用二级指针保存指针的地址?难道一级指针就不能保存一级指针的地址了吗???

答:windows32位操作系统的指针变量是占四个字节,这就跟指针说明了,从首地址开始,往后要读四个字节,不能多也不能少。如果读少或者读多了,读出来的数据讲是不正确的。如果需要保存的值是地址,那么必须确保有四个字节的空间来保存。这才能保证数据的完整性。但是指针的类型又是多样的,定义int *P = &num;因为int类型占四个字节空间,所以int类型的指针会从首地址开始往后读四个字节。如果定义的是char 类型的指针,char 只占一个字节,这时候char,类型的指针就只会读取这一个字节,当指针类型为double是,指针便会往前读取包括首地址在内的8个字节。32位系统指针只占4个字节,这时读取的是地址的话便全都是错的,二级指针很好的规避了这个问题,二级指针,无论什么类型的指针都只会读取四个字节。

 

问:那如果要保存PP的地址呢?

答:那就再定义一个指针变量,用三个*。当然你也可以用两个或者int类型指针的一个*。但是这样你就取不出100的值了。定义的指针变量用两个*号,最多只能取出num的地址。 这是为什么呢?你自己做一下试验就知道咯哦,勤动手,多练习^-^  

### 三级标题:C语言二级指针的概念 在C语言中,二级指针是指指向指针的指针。这意味着,二级指针存储的地址是另一个指针变量的地址。一级指针通常用于指向实际的数据,而二级指针则用于指向这些一级指针[^1]。 ### 三级标题:使用二级指针的原因 二级指针的主要用途是在函数内部修改指针本身。由于C语言中的函数调用是按值传递的,这意味着函数内部对指针的任何修改都不会影响到函数外部的指针。为了能够在函数内部修改指针,就需要传递指针的地址,即使用二级指针。此外,二级指针也常用于动态分配多维数组[^2]。 ### 三级标题:二级指针的使用方法 二级指针的声明和使用与一级指针类似,但需要额外的间接层。声明一个二级指针通常涉及到两次使用`*`符号。例如,声明一个指向`int`类型的指针的指针可以写成`int **pptr;`。然后,可以通过`malloc`函数来分配内存,以便存储指向其他指针的指针。 ### 三级标题:二级指针的示例代码 下面是一个简单的示例,演示了如何在C语言中定义和使用二级指针: ```c #include <stdio.h> int main() { int num = 10; int *ptr = &num; // 一级指针,指向int类型变量 int **pptr = &ptr; // 二级指针,指向一级指针 printf("num的值: %d\n", num); printf("通过一级指针访问num的值: %d\n", *ptr); printf("通过二级指针访问num的值: %d\n", **pptr); return 0; } ``` 在这个例子中,`ptr`是一个一级指针,它指向`num`变量的地址;`pptr`是一个二级指针,它指向`ptr`指针的地址。通过`pptr`,我们可以间接访问到`num`的值。 ### 三级标题:手动开辟空间示例 当需要在程序中动态地创建二维数组时,可以使用二级指针配合`malloc`函数来分配内存。以下是一个使用二级指针动态分配内存的例子: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char **buf = NULL; buf = (char **)malloc(sizeof(char*) * 3); // 分配三个char指针的空间 for (int i = 0; i < 3; i++) { buf[i] = (char *)malloc(sizeof(char) * 5); // 每个char指针分配五个字符的空间 sprintf(buf[i], "%d%d%d", i + 1, i + 2, i + 3); // 格式化字符串 } // 使用完动态分配的内存后,应该释放它们 for (int i = 0; i < 3; i++) { free(buf[i]); // 释放每个char指针分配的空间 } free(buf); // 释放char指针数组的空间 return 0; } ``` 在这个例子中,`buf`是一个二级指针,它首先被分配了足够的空间来存储三个`char`指针。接着,每个`char`指针又被分配了足够的空间来存储五个字符。最后,使用`free`函数释放了所有分配的内存[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值