typedef、共用体、枚举、存储类型、分文件编程详细内容

发布时间:2026/9/15 0:32:28

typedef、共用体、枚举、存储类型、分文件编程详细内容 一、类型重定义typedeftypedef是C语言中的关键字用于为已有的数据类型定义一个新的名称别名。这可以提高代码的可读性和可维护性。1.1 基本用法语法格式typedef 原类型名 类型新名字;示例typedef unsigned int size_t;这样unsigned int a;和size_t a;就是等价的声明。1.2 重定义结构体类型1先定义结构体类型再重定义#include stdio.h struct student { int id; float score; }; int main(int argc, char const *argv[]) { typedef struct student STU; // 为struct student定义别名STU STU st; // 等价于 struct student st; STU *p st; // 等价于 struct student *p st; return 0; }2定义结构体同时进行重定义#include stdio.h typedef struct student { int id; float score; } STU; // 直接定义结构体并创建别名 int main(int argc, char const *argv[]) { STU st; // 直接使用别名 STU *p st; return 0; }1.3 typedef 和结构体指针#include stdio.h typedef struct student { int id; float score; } STU, *STP; // STU是结构体别名STP是指向该结构体的指针类型别名 int main(int argc, char const *argv[]) { STU st; // 结构体变量 STP p st; // 指针变量等价于 STU *p st; p-id 1; p-score 99.9; return 0; }判断规则根据结构体定义前是否有typedef关键字来判断定义的是变量还是类型。二、共用体联合体共用体union是一种特殊的数据类型允许在相同的内存位置存储不同的数据类型。所有成员变量共用同一块内存空间。2.1 定义格式union 共用体名 { 成员列表; };2.2 定义共用体变量语法union 共用体名 变量名;访问成员变量使用.运算符示例#include stdio.h union value { int a; char b; }; int main(int argc, char const *argv[]) { union value val; val.a 10; printf(val.a %d\n, val.a); // 输出10 val.b a; printf(val.b %c\n, val.b); // 输出a printf(val.a %d\n, val.a); // 输出97因为共用内存a的值被覆盖 return 0; }2.3 共用体特性所有成员共用一块地址空间修改一个成员会影响其他成员的值内存中的实际数据以最后一次赋值为准共用体的大小 ≥ 最大成员的大小需要满足内存对齐要求应用示例测试大小端#include stdio.h union value { int a; char b; }; int main(int argc, char const *argv[]) { union value val; val.a 0x12345678; if (val.b 0x78) { printf(小端存储Little Endian\n); } else if (val.b 0x12) { printf(大端存储Big Endian\n); } return 0; }三、枚举enum枚举是用户自定义的数据类型用于声明一组命名的整数常量提高代码可读性。3.1 定义格式enum 枚举类型名 { 常量1, 常量2, // ... };3.2 示例#include stdio.h enum Weekday { MONDAY 1, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }; int main(int argc, char const *argv[]) { int day; printf(请输入星期几1-7); scanf(%d, day); switch (day) { case MONDAY: printf(今天是星期一\n); break; case TUESDAY: printf(今天是星期二\n); break; // ... 其他case default: printf(输入错误\n); break; } return 0; }注意事项如果没有显式赋值第一个枚举常量默认为0后续常量依次递增可以给每个元素单独赋值如果某个元素没有赋值则其值为上一个元素的值加1四、存储类型C语言中的存储类型决定了变量的存储位置、生命周期和作用域。4.1 auto自动类型默认的存储类型修饰局部变量通常省略不写。变量存储在栈区函数结束时自动释放。4.2 static静态类型可以修饰局部变量、全局变量和函数。存储位置静态区/全局区.data段存放已初始化的变量.bss段存放未初始化的变量初始化默认初始化为0只初始化一次生命周期修饰局部变量时延长其生命周期到程序结束作用域限制修饰局部变量限制在当前函数内使用修饰全局变量和函数限制在当前文件中使用示例#include stdio.h void fun() { static int a 0; // 只初始化一次 a; printf(a %d\n, a); } int main(int argc, char const *argv[]) { fun(); // 输出a 1 fun(); // 输出a 2 fun(); // 输出a 3 return 0; }4.3 extern外部引用类型extern用于声明在其他文件中定义的全局变量或函数使得在当前文件中可以使用这些外部定义的变量和函数。示例///////////////////////num.c/////////////////// #include stdio.h static int n 10; // static修饰后n不能被外部引用只能限制在本文件中使用 static void fun() { printf(hello\n); } /////////////////////main.c//////////////////// #include stdio.h extern int n; // 声明外部变量n extern void fun(); // 声明外部函数fun() int main(int argc, char const *argv[]) { printf(n %d\n, n); // 编译错误n在num.c中是static的无法外部引用 fun(); // 编译错误fun()在num.c中是static的无法外部引用 return 0; }编译与执行gcc num.c main.c ./a.out4.4 register寄存器类型register建议编译器将变量存储在CPU寄存器中以提高访问速度。特点不能对寄存器变量取地址操作因为寄存器没有内存地址由于寄存器数量有限编译器可能不会将所有register变量都放入寄存器中当寄存器不足时register变量会像auto变量一样存储在栈中示例#include stdio.h int main(int argc, char const *argv[]) { register int i; // 建议编译器将i存储在寄存器中 for (i 0; i 1000000; i) { // 频繁访问的循环变量适合使用register } // int *p i; // 错误不能对register变量取地址 return 0; }五、分文件编程分文件编程是C语言中组织大型项目的常用方法通过将代码分散到多个文件中提高代码的可维护性和可重用性。5.1 头文件.h文件头文件通常包含以下内容宏定义#define类型重定义typedef结构体、共用体、枚举的定义函数声明函数原型外部变量声明extern注意全局变量一般不会直接定义在头文件中以避免多重定义错误。5.2 源文件.c文件源文件包含以下内容函数的定义实现变量的定义包含main函数的文件main.c包含子函数的文件fun.c、utils.c等5.3 分文件编程示例头文件head.h////////////////////head.h///////////////////// #ifndef HEAD_H // 防止头文件被重复包含 #define HEAD_H #include stdio.h // 函数声明 int add(int a, int b); // 结构体定义 struct student { int id; float score; }; #endif // HEAD_H主文件main.c/////////////////main.c////////////////////// #include head.h // 使用双引号包含自定义头文件 int main(int argc, char const *argv[]) { int result add(3, 5); printf(3 5 %d\n, result); struct student stu; stu.id 1; stu.score 95.5; printf(学生ID%d成绩%.1f\n, stu.id, stu.score); return 0; }函数实现文件fun.c//////////////fun.c/////////////////// #include head.h // 函数定义 int add(int a, int b) { printf(计算 %d %d\n, a, b); return a b; }5.4 编译与执行编译命令gcc main.c fun.c -o program执行命令./program5.5#include引用方式区别和的区别引用方式查找顺序适用场景#include filename.h直接去系统目录编译器指定的头文件路径查找标准库头文件如stdio.h、stdlib.h#include filename.h1. 先在当前目录查找2. 如果找不到再去系统目录查找自定义头文件项目内的头文件5.6 分文件编程的优点模块化将相关功能组织在一起便于维护代码复用头文件可以被多个源文件包含编译效率修改单个文件时只需重新编译该文件团队协作不同开发者可以同时处理不同文件隐藏实现细节头文件只暴露接口保护实现细节
延伸阅读

更多相关文章

2026/9/14 18:44:28

硬件序列器在嵌入式图像处理中的核心作用与SIMCOP实例解析

1. 项目概述与核心价值在嵌入式图像处理领域,尤其是汽车信息娱乐、高级驾驶辅助这类对实时性和能效要求极高的场景,CPU的通用计算能力常常成为瓶颈。当面对JPEG编解码、图像缩放、色彩空间转换等重复性高、计算密集的任务时,单纯依赖软件算法…

2026/9/13 7:27:21

UE5高分辨率渲染下阴影条纹问题的成因分析与系统解决方案

1. 项目概述:高分辨率下的“条纹阴影”究竟是什么? 在UE5项目里,当你把渲染分辨率拉到4K、8K甚至更高,准备截一张惊艳的展示图或渲染一段高质量影片时,屏幕上那些本该平滑的阴影区域,却突然出现了令人抓狂的…

2026/9/15 0:31:18

C语言逆向:函数参数传递与返回值识别,避开调用约定和寄存器陷阱

C语言逆向学习基础课 第7课 函数参数传递与返回值陷阱C语言逆向学习进入函数层面之后,最先拦路的就是参数传递和返回值这两件事。前面六节课我们把内存模型、栈帧、寄存器角色这些地基过了一遍,但从这节课开始,你面对的不再是单个变量怎么存&…

2026/9/15 0:31:18

矢量光速螺旋时空与量子统一理论解析

1. 项目背景与核心概念解析"基于矢量光速螺旋时空的归一化体系拓展:量子化闭环与四大相互作用完全统一"这个标题涉及多个前沿物理概念的交汇。让我们先拆解其中的关键术语:矢量光速螺旋时空(Vector Light-speed Helical Spacetime&…

2026/9/15 0:31:18

把 Hermes 的模型 API 地址改到 TaoToken 后,下载好的 Agent 就能跑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/15 0:31:18

基于加速度传感器与MySQL状态机的睡眠阶段检测小程序

简介:这是一套面向计算机专业本科生的毕业设计级微信小程序实战项目,聚焦睡眠健康管理场景,提供从需求分析、前后端开发到部署上线的完整技术闭环。资源包含基于uniapp或原生小程序框架开发的前端代码、Java/PHP后端服务及MySQL 5.7数据库设计…

2026/9/15 0:31:18

同一把 TaoToken Key,让 Cline 从 Claude Sonnet 3.5 切到 GPT 4o

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/15 0:26:18

解决Python ModuleNotFoundError: No module named ‘pipenv‘的全面指南

1. 问题背景与现象分析最近在Python开发社区中,ModuleNotFoundError: No module named pipenv这个错误频繁出现。作为一个长期使用Python进行项目开发的工程师,我发现这个问题特别容易出现在以下几种场景:新手开发者第一次尝试使用pipenv管理…

2026/9/14 2:17:50

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/15 0:01:16

AI英语单词APP开发:自适应学习算法与移动端优化实践

1. 项目概述 作为一名在移动应用开发领域摸爬滚打多年的老手,我最近完成了一个AI英语单词APP的开发项目。这个项目将传统单词记忆方法与现代AI技术相结合,打造了一款能够智能适应不同用户学习习惯的英语学习工具。 市面上大多数单词APP都存在一个通病&a…

2026/9/15 0:01:16

Flutter与OpenHarmony结合开发手语学习APP实战

1. 项目背景与核心价值作为一名同时接触过Flutter和OpenHarmony的开发者,最近我完成了一个基于Flutter for OpenHarmony的手语学习APP实战项目。这个项目最大的特点在于实现了跨平台框架与国产操作系统深度结合的创新实践——用Flutter开发的应用能完美运行在OpenHa…

2026/9/15 0:01:16

六个月成为机器人工程师:从ROS2到SLAM的实战路径

1. 六个月的紧迫感从哪来:先搞清楚你要成为哪种机器人工程师说实话,六个月的期限并不是一个宽松的时间线。市面上任何一本正经的机器人学教材都超过五百页,ROS2的官方文档可以翻到你怀疑人生,再加上ABB、KUKA这些工业机器人厂家动…

2026/9/14 11:59:31

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/14 13:53:59

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/14 11:22:57

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码