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

C语言从头学51—多文件项目

       不论是从方便编辑还是方便阅读两个方面看,单个源码文件的长度总是会受到限制的。如何解决这个问题?多文件项目就是解决这个问题的钥匙,将两个、或多个源码文件一起编译,生成一个可执行文件,这种项目组织形式称为多文件项目。如何处理多文件项目,本文将以VS这一编译环境为基础,进行简要介绍。
1、自定义函数头文件
       自定义函数头文件由我们自己编辑,由头文件部分、全局变量的声明、全局结构体的声明、自定义函数的声明组成。自定义函数头文件的后缀使用".h"。
2、自定义函数实现文件
      包括:对自定义头文件的包含语句、全局变量赋初值、自定义函数实现。实现文件的后缀使用".c"。包含自定义函数头文件使用双引号,不使用尖括号。
      说明:如果程序代码不是太长,头文件和实现文件可以合二为一,统一放到头文件中即可。
3、主文件
      所谓主文件就是包含main函数的文件。主文件由头文件部分、主函数本体(含系统函数和自定义函数的调用)组成。在这个文件的头部,除了包含必须的系统头文件外,还要包含我们自定义函数文件。包含自定义函数文件的格式为:#include "自定义函数名"。主文件只能有一个,主文件的后缀为".c"。
4、防止重复加载
       由于主文件要包含自定义函数头文件,自定义函数文件中也会包含其它自定义函数文件,这就存在着一种可能性,有些自定义函数文件会被重复包含,或称重复加载;重复加载可能引起程序运行错误。防止重复加载的办法我们在学习预处理指令时已经学习过,只是没有实验的机会。具体方法是在自定义函数文件头部加一个语句:#Define 标记宏(仅有个名字即可);在准备包含它的文件头部,有关包含语句这样写:
       #ifndef  标记宏
          #include "自定义函数文件名"
       #endif
       当这个自定义函数文件已经加载过时,ifndef会发现这个宏,也就不再执行#include命令了;如没发现这个这个宏,说明还没有加载,则就会执行#include命令。这样就防止了重复加载。
 5、extern、static 说明符
       关于不同文件中全局变量的使用范围问题,前文已经介绍过这两个说明符,extern说明符是标明使用其它文件中全局变量的,static说明符是限制本文件中的全局变量不让其它文件使用的。
 6、举一个多文件项目的简单例子(VS2022编译环境),这个例子的文件组成如下:
       主文件:主文件名:myMain.c  功能:使用全局变量、全局结构体、调用自定义函数
       自定义函数头文件:mycalcu.h  功能:声明全局变量、结构体,声明自定义函数
       自定义函数实现文件:mycalcu.c 功能:实现自定义函数,为全局变量赋初值
       相关代码及注释如下:
a.主文件名:myMain.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define COUNT 0 //记录包含语句被执行次数
#ifndef MYCALCU#include "mycalcu.h" //第一次包含#undef COUNT#define COUNT 1
#endif
#ifndef MYCALCU#include "mycalcu.h" //第二次包含#undef COUNT#define COUNT 2
#endif
extern myCount; //由于使用了include语句,在VS环境下,即使没有这个语句,//在主文件也能正常使用自定义函数文件中的全局变量
int main(void)
{
//查看头文件包含次数printf("mycalau.h被包含 %d 次。\n",COUNT); //运行结果:mycalau.h被包含 1 次。//从运行结果可以看出,通过使用#ifndef...#endif检查设置在"mycalcu.h"中的宏MYCALCU//是否存在,保证了"mycalcu.h"仅加载一次
//使用自定义头文件中声明的结构体struct Person p;strcpy(p.name, "王二");p.age = 25;strcpy(p.addr, "x市x区x街x路x号");
//调用自定义头文件中函数int x = 0, y = 0;while (1){printf("请输入x:\n");if (0 == scanf("%d", &x))return 0;printf("请输入y:\n");if (0 == scanf("%d", &y))return 0;mySum(x, y); //调用计算合计函数myProd(x, y); //调用计算乘积函数printf("已进行加法、乘法共 %d 次\n",myCount);getchar(); //吸收输入数据时最后回车printf("输入n结束,其它继续...\n");char ch = getchar();if (ch == 'n' || ch == 'N') break;}return 0;
}

b.自定义函数头文件 mycalcu.h

#include <stdio.h>
#define MYCALCU //定义标记宏(空宏)
void mySum(int, int); //声明计算合计函数
void myProd(int, int); //声明计算乘积函数
int myCount; //声明计数全局变量
struct Person //声明一个人员结构体
{char name[12];int age;char addr[128];
};

c.自定义函数实现文件 mycalcu.c

#include "mycalcu.h"
//全局变量赋初值
myCount = 0;
//实现计算合计函数
void mySum(int x, int y)
{printf("x+y=%d\n", x + y);myCount++;
}
//实现计算乘积函数
void myProd(int x, int y)
{printf("x*y=%d\n", x * y);myCount++;
}

//运行结果:
mycalau.h被包含 1 次。
请输入x:
5
请输入y:
10
x+y=15
x*y=50
已进行加法、乘法共 2 次
输入n结束,其它继续...

请输入x:
20
请输入y:
30
x+y=50
x*y=600
已进行加法、乘法共 4 次
输入n结束,其它继续...
n

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 培训第三十八天(上传镜像,私有仓库下载镜像,跨主机容器间的通信,harbor软件包下载)
  • RK3568平台(平台总线篇)SPI驱动框架分析
  • C语言家教记录(八)
  • 豆包插件分享
  • C++系列-类模板案例
  • 最大噪音值甚至受法规限制,如何基于LBM算法有效控制风扇气动噪音
  • 数据结构之链表
  • AI辅助编码在主流IDE中的智能代码补全说明
  • 一 初识爬虫
  • 分享7款宝藏APP,用途多样,值得一试
  • centos7.9系统安装cloudpods并使用ceph存储(二)
  • kubernetes培训
  • Qt之QSS的介绍以及加载QSS
  • 阿里云私有镜像仓库配置及使用
  • 双重映射+逆向并查集+恢复
  • [ JavaScript ] 数据结构与算法 —— 链表
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • canvas绘制圆角头像
  • Golang-长连接-状态推送
  • JAVA_NIO系列——Channel和Buffer详解
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • k8s 面向应用开发者的基础命令
  • Laravel核心解读--Facades
  • Magento 1.x 中文订单打印乱码
  • MD5加密原理解析及OC版原理实现
  • PhantomJS 安装
  • Protobuf3语言指南
  • React Transition Group -- Transition 组件
  • vagrant 添加本地 box 安装 laravel homestead
  • 测试如何在敏捷团队中工作?
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 区块链将重新定义世界
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 异步
  • 再次简单明了总结flex布局,一看就懂...
  • Java性能优化之JVM GC(垃圾回收机制)
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ​TypeScript都不会用,也敢说会前端?
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • ​如何在iOS手机上查看应用日志
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #### golang中【堆】的使用及底层 ####
  • #14vue3生成表单并跳转到外部地址的方式
  • #QT 笔记一
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (2015)JS ES6 必知的十个 特性
  • (C++20) consteval立即函数
  • (HAL库版)freeRTOS移植STMF103
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (笔试题)合法字符串
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)ssm码农论坛 毕业设计 231126
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (三)Honghu Cloud云架构一定时调度平台