news 2026/4/28 9:22:15

C 语言函数:从 0 到 链表封装 --> 一次真正理解“数据 + 行为”的过程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C 语言函数:从 0 到 链表封装 --> 一次真正理解“数据 + 行为”的过程

很多人学 C 语言时,都会在「函数、指针、结构体、链表」之间来回卡壳。
真正的难点并不是语法,而是不知道如何用函数去“组织数据的行为”

本文将从C 函数最基础用法出发,逐步引入指针、结构体、动态内存,最终用函数完整封装一个单链表,让你真正理解:

👉C 语言的工程本质:结构体 = 数据,函数 = 行为

一、为什么「函数」是 C 语言的核心?

在 C 语言中:

  • 结构体:只负责描述数据

  • 函数:负责对数据进行操作

如果你只会写结构体,而不会用函数去操作它,那么你写的代码永远只能停留在「演示级」。

一个反例:没有函数的 C 代码

struct Student { int id; int score; }; int main() { struct Student s; s.id = 1; s.score = 100; printf("%d\n", s.score); }

问题是:

  • 所有逻辑堆在main
  • 完全无法复用
  • 一旦复杂就失控

👉解决方案:用函数封装行为

二、C 语言函数的最基础形态

1️⃣ 函数的定义与调用

int add(int a, int b) { return a + b; } int main() { int result = add(3, 5); printf("%d\n", result); return 0; }

函数由三部分组成:

  • 返回值类型
  • 参数列表
  • 函数体

2️⃣ 函数的本质:一段可复用的逻辑

你可以把函数理解为:

“给一组输入,产生一个结果的逻辑单元”

但在 C 语言里,这还远远不够。

三、为什么 C 语言函数必须配合「指针」?

1️⃣ 值传递的局限

void change(int x) { x = 10; } int main() { int a = 5; change(a); printf("%d\n", a); // 仍然是 5 }

原因:

  • 函数拿到的是变量的拷贝
  • 外部变量不会被修改

2️⃣ 使用指针修改外部变量(关键)

void change(int* p) { *p = 10; } int main() { int a = 5; change(&a); printf("%d\n", a); // 10 }

👉C 的函数想要“产生副作用”,必须使用指针

四、函数 + 结构体:工程代码的起点

1️⃣ 定义一个结构体

typedef struct { int id; int score; } Student;

2️⃣ 通过函数操作结构体

void print_student(Student* s) { printf("id=%d, score=%d\n", s->id, s->score); }

注意:

  • 永远传结构体指针,而不是结构体本身
  • 避免拷贝,提高效率

五、从结构体走向链表

1️⃣ 链表节点的结构体定义

typedef struct Node { int data; struct Node* next; } Node;

链表的本质:

结构体中,包含指向同类型结构体的指针

六、用函数一步步封装一个链表

1️⃣ 创建节点(返回指针)

Node* create_node(int value) { Node* node = (Node*)malloc(sizeof(Node)); if (node == NULL) { return NULL; } node->data = value; node->next = NULL; return node; }

这里你第一次看到:

  • 函数返回指针
  • 动态内存分配

2️⃣ 尾插节点(修改头指针)

void append(Node** head, int value) { Node* newNode = create_node(value); if (*head == NULL) { *head = newNode; return; } Node* cur = *head; while (cur->next != NULL) { cur = cur->next; } cur->next = newNode; }

⚠️ 重点:

  • 为什么是Node** head
  • 因为函数内部要修改head本身

Node** head 是二级指针

3️⃣ 遍历链表

void print_list(Node* head) { Node* cur = head; while (cur != NULL) { printf("%d -> ", cur->data); cur = cur->next; } printf("NULL\n"); }

4️⃣ 删除节点

void remove_node(Node** head, int value) { Node* cur = *head; Node* prev = NULL; while (cur != NULL) { if (cur->data == value) { if (prev == NULL) { *head = cur->next; } else { prev->next = cur->next; } free(cur); return; } prev = cur; cur = cur->next; } }

5️⃣ 释放整个链表(非常重要)

void destroy_list(Node* head) { Node* cur = head; while (cur != NULL) { Node* next = cur->next; free(cur); cur = next; } }

七、完整测试示例

int main() { Node* head = NULL; append(&head, 1); append(&head, 2); append(&head, 3); print_list(head); remove_node(&head, 2); print_list(head); destroy_list(head); return 0; }

输出:

1 -> 2 -> 3 -> NULL
1 -> 3 -> NULL

八、从链表到 MessageQueue 的思想迁移

你会发现:

  • 链表 = 存数据

  • 函数 = 操作数据

  • 头指针 = 队列入口

这和 Android 的 MessageQueue / Looper 在思想层面是完全一致的

九、总结一句话(非常重要)

C 语言不是“语法语言”,而是“内存 + 行为设计语言”

当你学会用函数封装结构体行为,你才真正开始写 C 的工程代码。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/27 0:59:56

10、系统安全配置强化指南

系统安全配置强化指南 1. 概述 入侵者常采用多种技术来隐藏自己的踪迹并确保对受害主机的持续root访问,从清理日志文件到安装后门和rootkit等。检测高级黑客的存在往往十分困难,因此,强化主机的策略和配置至关重要。以下将详细介绍如何对系统的默认设置和常用服务进行加固…

作者头像 李华
网站建设 2026/4/28 3:05:57

14、夏普 Zaurus PDA 黑客工具介绍

夏普 Zaurus PDA 黑客工具介绍 在网络安全和渗透测试领域,有许多工具可以用于不同的目的,如端口扫描、建立安全隧道、测试防火墙规则等。本文将介绍一些可用于夏普 Zaurus PDA 的工具及其功能、下载地址和使用方法。 1. BING Bing 是一个简单的脚本,可自动执行端口扫描。…

作者头像 李华
网站建设 2026/4/27 12:35:56

15、Zaurus PDA安全工具与相关技术解析

Zaurus PDA安全工具与相关技术解析 1. Perl与Zaurus PDA 许多安全工具,如Nikto和Whisker Web漏洞扫描器,都是用Perl语言编写的。由于Perl是一种解释型语言,因此无需重新编译现有的Perl脚本,就可以在Zaurus上运行它们。你可以在http://zaurus.frontgarden.net/perl.html获…

作者头像 李华
网站建设 2026/4/26 20:33:20

晨控CK-GW04S-EIP与基恩士KV-X520系列PLC配置EtherNetIP通讯连接手册

晨控CK-GW04S-EIP与基恩士KV-X520系列PLC配置EtherNetIP通讯连接手册CK-GW04S系列是晨控为工业多通道需求研制的一款网关控制器,方便用户集成到PLC等控制系统中,系统集成了4路读写接口,并且支持大部分工业协议ModbusTCP、Profinet、EtherNet/lP、EtherCa…

作者头像 李华
网站建设 2026/4/25 13:26:20

21、Iptables与Snort规则模拟及Fwsnort部署

Iptables与Snort规则模拟及Fwsnort部署 1. Iptables状态匹配与规则应用 Iptables的状态匹配扩展提供了强大的数据包过滤功能。通过 iptables -m state -h 命令可以查看状态匹配的选项,其版本为v1.3.7,支持的状态选项包括 INVALID 、 ESTABLISHED 、 NEW 、 RELATE…

作者头像 李华
网站建设 2026/4/26 23:50:18

29、实用的 awk 程序集合

实用的 awk 程序集合 在文本处理和自动化任务中,awk 是一个强大且灵活的工具。下面将介绍多个实用的 awk 程序,涵盖文件分割、输出复制、去重、计数等多个方面。 1. for 循环测试 在 PROCINFO 数组中,任何补充组的索引为 “group1” 到 “groupN”(N 为补充组的总数),…

作者头像 李华