当前位置: 首页 > 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.dtcms.com/a/312876.html

相关文章:

  • 为何:内存数据断电即逝,硬盘数据牢笼长存
  • LangChain框架概念及简单的使用案例
  • ABP VNext + CloudEvents:事件驱动微服务互操作性
  • 计算机核心概念辨析与解析
  • 24SpringCloud黑马商城部署Java应用后浏览器访问数据库不显示数据的解决办法
  • 可持久化线段树 系列 题解
  • 【Python✨】解决 Conda 安装 MoviePy 报错问题
  • GitCode疑难问题诊疗
  • 12.Redis 主从复制
  • deep research|从搜索引擎到搜索助手的实践(一)
  • 企业自动化交互体系的技术架构与实现:从智能回复到自动评论—仙盟创梦IDE
  • 三、驱动篇-HDF驱动介绍1
  • 语义分割--Fcn
  • 回顾MDP的概念
  • RabbitMQ面试精讲 Day 8:死信队列与延迟队列实现
  • dbdiagram:一款简洁高效的免费数据库设计工具
  • 二叉树算法之【前序遍历】
  • 三生原理的“范畴语法”如何启发AI推理?
  • Spring Boot 整合 Minio 实现高效文件存储解决方案(本地和线上)
  • 个人项目介绍:语音识别小助手
  • Spring AI的英语实例
  • Nginux Rewte 相关功能
  • 基于Python实现生产者—消费者分布式消息队列:构建高可用异步通信系统
  • Rustdesk中继服务器搭建(windows 服务器)
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-56,(知识点:电源模块,DCDC电源,LDO电源,原理及其特点)
  • Java(HashMap和HashTable和Properties)
  • kafka 是一个怎样的系统?是消息队列(MQ)还是一个分布式流处理平台?
  • 哔哩哔哩招游戏内容产品运营
  • Ubuntu22.4部署大模型前置安装
  • 零确认双花攻击