Feri一到,编程开窍!
一、结构体指针:高效访问数据的「内存钥匙」
- 定义与赋值:
struct Person { char name[50]; int age; }; struct Person p = {"Tom", 20}; struct Person *ptr = &p; // 指针指向结构体变量
-
三种等价访问方式:
p.age
❕(*ptr).age
❕ptr->age
(推荐->
操作符,代码更简洁)
二、结构体传参:值传递 vs 指针传递
- 值传递陷阱:
函数接收副本,修改不影响原始数据(如void func(struct Person p)
)。
案例:void addAge(struct Person per) { per.age++; } // 调用后原数据不变
- 指针传递优化:
传入地址(void func(struct Person *ptr)
),直接操作原始数据,节省内存开销。
实战:void addAge(struct Person *ptr) { ptr->age++; } // 高效修改原值
三、动态数据结构:从结构体到链表/树
1. 链表结点的核心设计
struct Node {
int data; // 数据域
struct Node *next; // 指针域(指向下一结点)
};
- 创建结点:
struct Node *newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = 100; // 初始化数据域 newNode->next = NULL; // 初始化指针域
2. 二叉树结点的嵌套指针
struct BTNode {
int data;
struct BTNode *lchild; // 左子树指针
struct BTNode *rchild; // 右子树指针
};
- 动态构建树结构:
struct BTNode *root = (struct BTNode*)malloc(sizeof(struct BTNode)); root->data = 50; root->lchild = createNode(30); // 递归创建左子结点
四、malloc()与内存管理最佳实践
- 标准模板:
Type *ptr = (Type*)malloc(sizeof(Type)); // Type为结构体类型 if (ptr == NULL) exit(-1); // 必加内存分配失败检查
- 内存释放原则:
malloc与free成对出现,避免内存泄漏:free(ptr); ptr = NULL; // 释放后置空指针,防止野指针
五、程序员成长启示:从内存操控到系统设计
-
指针思维:理解结构体指针即「数据内存地址的抽象」,是操作复杂数据结构的基础。
-
动态规划:通过malloc/free实现按需分配内存,解决数组「固定长度」的局限性。
-
抽象能力:将现实中的链表、树等结构抽象为结构体+指针的组合,提升系统建模能力。
关键提醒:结构体指针是C语言「危险与高效并存」的特性,务必掌握内存分配失败处理、野指针规避等细节。下一篇将深入探讨「结构体与链表的增删改查实战」,关注我,解锁C语言数据结构的核心技能!
💡 互动问题:为什么链表结点的指针域要指向自身类型(如struct Node *next
)?欢迎在评论区留下你的思考~