二级指针正确使用方式

二级指针理解

第一次的代码 (低级错误)
int init(Node *phead)
{
    phead = (Node *)malloc(sizeof(Node));//只是改变了副本的值 毫无malloc的意义
    phead->next = NULL;
    phead->val = NULL;
}
int main(){
    Node *phead;
    init(phead); 
// 为什么传入不了值呢?
//  因为phead是拷贝副本,malloc分配空间后phead值有改变但是这里并没有带回,仍然是拷贝副本
第二次改进代码(中级错误)
int init(Node **phead)
{
    phead = (Node **)malloc(sizeof(Node));
     (*phead)->next = NULL; //这里会运行报错 malloc后的*phead仍然没有值
     (*phead)->val = NULL;
// 为什么二级指针报错?
//  malloc是给指针分配空间,二级指针已经有空间存地址了,需要给一级指针分配存放Node节点的空间,所以next会报错。
}
int main(){
    Node *phead;
    init(phead);
最后的正确代码
int init(Node **phead)
{
    *phead = (Node *)malloc(sizeof(Node)); //表示意义是给*phead分配空间,因为这里存放的是节点数据, 这里既不能是**phead也不可以是phead!!
     (*phead)->next = NULL; //这里会运行报错
     (*phead)->val = NULL;
// 为什么二级指针报错?
//  malloc是给指针分配空间,二级指针已经有空间存地址了,需要给一级指针分配存放Node节点的空间,所以next会报错。
}
int main(){
    Node *phead;
    init(&phead);
PS:

// 根据二级指针再写点内容:二级指针要指向两次才能找到最终的指向的内存块
二级指针 有效的内存地址开始位置 p2->p1->data
一级指针 有效的内存地址开始位置 p1->data

一级指针中 p 表示指针内容的有效地址
一级指针中 *p 表示指针内容
一级指针中 &p 表示指针变量地址

二级指针中 p 表示指针内容的有效地址
二级指针中 **p 表示指针内容
二级指针中 &p 表示指针变量地址
二级指针中 *p表示的一个中间值 没有什么太大意义

引用一个图 更形象的表示指针:
在这里插入图片描述

### C/C++ 中二级指针使用方法 #### 什么是二级指针? 在C/C++中,二级指针是指指向另一个指针变量的地址的指针。这意味着它存储的是一个指针变量的地址而不是普通数据类型的地址。声明形式如下: ```c type **pointer_name; ``` 这里`type`表示所指向的数据类型。 #### 如何初始化和操作二级指针? 当定义了一个二级指针之后,通常需要先给这个二级指针赋值为某个一级指针的地址才能安全地对其进行解引用操作。例如: ```c int a = 10, b = 20; int *p = &a; // p 是指向 int 类型的一级指针 int **q = &p; // q 是指向 int* 类型(即一级指针) 的二级指针 printf("Value of 'a' using secondary pointer is %d\n", **q); // 输出: Value of 'a' using secondary pointer is 10 *p = b; // 修改 p 所指向的内容(也就是修改了'a') printf("New value of 'a': %d\n", a); // 输出: New value of 'a': 20 ``` 上述例子展示了如何通过二级指针对原始变量进行间接访问并改变其值[^3]。 #### 安全注意事项 需要注意的是,在处理多层嵌套的指针时要格外小心,因为任何一层未被正确初始化都可能导致程序崩溃或者产生不可预测的行为。特别是对于动态分配内存的情况更是如此。因此建议开发者始终确保每一级别的指针都被适当地设置了有效地址后再尝试读取或写入它们指向的位置[^4]。 #### 实际应用场景举例 考虑这样一个场景——传递二维数组到函数中作为参数。由于C语言不允许直接传整个数组而只允许传送首元素地址的方式实现按引用调用的效果;而对于二维乃至更高维度矩阵而言,则可以借助于二级甚至更多层次别的指针完成这一目标。比如下面这段用于打印整数列表片段的代码就是利用了这一点: ```c void printArray(int **arr, int len) { for (int i = 0; i < len; ++i) { printf("%d ", (*arr)[i]); // 正确方式应该是(*arr+i),此处为了简化理解采用这种表达形式 } } // 调用此函数前需保证已构建好相应的结构体关系链表 ``` 以上实现了遍历由多个一维向量组成的集合,并依次输出各成员项的功能[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值