当前位置: 首页 > news >正文

嵌入式 C 语言入门:多文件编程实践笔记 —— 从文件创建到调用

前言

大家好,这里是 Hello_Embed。随着项目复杂度提升,把所有代码堆在一个.c文件里会变得难以维护。多文件编程能将功能拆分到不同文件(如按模块划分),让代码结构更清晰。本文通过一个 “打印个人信息” 的实例,详细讲解多文件编程的步骤、头文件与源文件的配合,以及三目运算符的用法,帮你掌握嵌入式工程的基础组织方式。

📝 多文件编程的核心步骤

多文件编程的核心是 “将功能实现放在.c文件,声明放在.h文件,通过头文件调用”。具体步骤如下:

  1. 创建文件:新建.c(源文件,存放函数实现)和.h(头文件,存放声明);
  2. 添加文件到工程:将.c文件加入工程(.h文件无需添加,通过#include引用);
  3. 引用头文件并调用:在需要使用功能的文件中,#include对应的.h文件,即可调用.c中的函数。
🌰 实例:多文件实现 “打印个人信息”

我们通过一个简单工程演示多文件编程的全过程,目标是定义一个结构体存储个人信息,并用函数打印信息。

步骤 1:创建文件夹与文件
  • 新建person文件夹(用于存放模块相关文件),确保它与调用文件(如text.c)在同一根目录下(例如都放在User文件夹中),避免编译器找不到路径。
  • person文件夹中创建两个文件:
    • person.c:存放打印函数的实现;
    • person.h:存放结构体定义和函数声明。
步骤 2:编写.c文件(功能实现)

person.c中实现打印个人信息的函数,使用结构体存储姓名和性别:

// person.c
#include <stdio.h>
// 打印个人信息:接收结构体指针作为参数
void print_person(struct person *p)
{printf("Name : %s\n\r", p->name);  // 打印姓名// 用三目运算符判断性别(1为男性,0为女性)printf("Sex  : %s\n\r", p->sex ? "Male" : "Female");
}
步骤 3:编写.h文件(声明)

person.h中定义结构体person,并声明print_person函数,同时添加宏保护避免重复包含:

// person.h
#ifndef _PERSON_H  // 宏保护:防止重复包含
#define _PERSON_H// 定义个人信息结构体
struct person{char *name;  // 姓名int sex;     // 性别(1:男,0:女)
};// 声明打印函数
void print_person(struct person *p);#endif  // _PERSON_H
步骤 4:将.c文件添加到工程

以 Keil 为例,右键工程目录的User组,选择 “Add Existing Files to Group”,将person.c添加到工程,.h文件无需添加,后续通过#include引用即可:
请添加图片描述

步骤 5:调用函数实现功能

text.c中包含person.h,定义结构体变量并调用print_person函数:

// text.c
#include <stdio.h>
// 包含头文件(路径为"文件夹名/文件名",因person.h在person文件夹中)
#include "Person/person.h"int mymain(void)
{// 定义结构体变量并初始化(姓名"zhangsan",性别男)struct person zhangsan = {"zhangsan", 1};// 调用打印函数(传入结构体地址)print_person(&zhangsan);return 0;
}
运行结果

编译后运行,成功打印个人信息
请添加图片描述

⚠️ 多文件编程的注意事项
  1. 文件路径问题
    • .h文件在子文件夹中(如person/person.h),引用时需写明相对路径:#include "Person/person.h"
    • .h文件与调用文件在同一目录,直接引用:#include "person.h"
    • 也可通过工程设置添加文件夹路径,之后用#include <person.h>引用(类似系统头文件)。
      请添加图片描述
  2. 工程管理
    • .c文件需要添加到工程,.h文件通过#include关联;
    • 按功能划分文件(如硬件驱动放driver.c,算法放algorithm.c),提升可读性。
🔍 补充:三目运算符(?:)的用法

实例中p->sex ? "Male" : "Female"使用了三目运算符,这是一种简洁的条件判断方式,等价于if-else但代码更短。

语法
条件 ? 表达式1 : 表达式2
判断规则
  • 若 “条件” 为真(非 0 值),结果为 “表达式 1”;
  • 若 “条件” 为假(0),结果为 “表达式 2”。
实例解析

代码p->sex ? "Male" : "Female"的逻辑:

  • 条件:p->sex(结构体的sex成员);
  • p->sex != 0(真),结果为"Male"(男性);
  • p->sex == 0(假),结果为"Female"(女性)。
    等价于if-else代码:
if (p->sex != 0) {// 输出 "Male"printf("Sex  : %s\n\r", "Male");
} else {// 输出 "Female"printf("Sex  : %s\n\r", "Female");
}
结尾

本文通过 “打印个人信息” 的实例,学习了多文件编程的完整流程:创建.c.h文件、添加.c到工程、通过头文件调用函数,同时掌握了路径处理和三目运算符的用法。多文件编程是嵌入式项目开发的基础,合理拆分模块能让代码更易维护、方便多人协作。
下一篇笔记,我们将学习函数指针。Hello_Embed 会继续带你深入嵌入式 C 语言的实战技巧,敬请期待~

http://www.lryc.cn/news/609026.html

相关文章:

  • Python Seaborn【数据可视化库】 全面讲解
  • C++ 之 【模拟实现 优先级队列】
  • Java 大视界 -- Java 大数据机器学习模型在金融市场情绪分析与投资决策辅助中的应用(379)
  • 控制建模matlab练习05:比例积分控制-①系统建模
  • 【游戏比赛demo灵感】Scenario No.9(又名:World Agent)
  • 【Python✨】解决 Conda 安装 MoviePy 报错问题
  • 【Linux系统编程】进程信号
  • Rust 同步方式访问 REST API 的完整指南
  • python学智能算法(三十一)|SVM-Slater条件理解
  • Rust:如何开发Windows 动态链接库 DLL
  • 【AI编程工具IDE/CLI/插件专栏】-国外IDE与Cursor能力对比
  • 08.Redis 持久化
  • Pytorch实现一个简单的贝叶斯卷积神经网络模型
  • (一)全栈(react配置/https支持/useState多组件传递/表单提交/React Query/axois封装/Router)
  • CICD--自动化部署--jinkins
  • TV电视版软件集合分享
  • 动感按钮:如何打造交互感十足的点击动画效果
  • 【前端安全】聊聊 HTML 闭合优先级和浏览器解析顺序
  • 二叉树算法之【前序遍历】
  • 设计原则和设计模式
  • 图像、视频、音频多模态大模型中长上下文token压缩方法综述
  • 【Leetcode】2106. 摘水果
  • 【openlayers框架学习】九:openlayers中的交互类(select和draw)
  • 安卓调javaScript Not find method “forceLogout“ implementatidsignature or namesp
  • 【C语言符号单词搜索首位置及数量】2022-10-4
  • web前端React和Vue框架与库安全实践
  • 数组和指针的关系
  • 【LeetCode刷题指南】--二叉树的后序遍历,二叉树遍历
  • VUE父级路由没有内容的解决方案
  • Python自动化测试框架:Unittest 断言