C语言程序与设计——工程项目开发

之前我们已经了解了C语言的基础知识部分,掌握这些之后,基本就可以开发一些小程序了。在开发时,就会出现合作的情况,C语言是如何协作开发的呢,将在这一篇文章进行演示。

工程项目开发

在开发过程中,你接到任务开发A和B两个功能模块,但是能在B中又存在一个功能模块C,C这一部分是另一个人开发的,那么我们如何将这两部分整合到一起呢?

#include<stdio.h>void funcA(int n){if(!n) return ;printf("funcA:%d \n", n);funcB(n - 1);
}
void funcB(int n){if(!n) return ;printf("funcB:%d\n", n);funC(n - 1);
}int main(){funcA(10);return 0;
}

以上就是你开发的内容,如何把C模块置入进来?我们知道一个C语言程序的声明周期是:
编辑 − > 预编译 − > 编译 − > 汇编 − > 链接 − > 执行 编辑->预编译->编译->汇编->链接->执行 编辑>预编译>编译>汇编>链接>执行
作为一个独立的功能模块,一定是可以独立运行的程序里,所以应该是在编译后,也就是链接的时期,我们把两个源程序程序链接起来

当前呢已经完成了两个文件,一个主程序一个功能模块C,主程序包括功能模块A和B,然后从图中可以看到我进行了编译,编译之后报了很多警告,因为两个程序中调用了本身没有的函数。但是还是生成了对象文件。下面就可以将两个对象文件进行链接,看一下可不可以正常运行。
在这里插入图片描述
可以看到进行连接之后,生成了可执行程序a.out,尝试运行得到了我们想要的结果。这就是一个基本开发的思路。

未声明和未定义
我们可以发现在编译过程中,报出的警告是未声明函数,而不是未定义,当我们对对象文件进行编译的时候才会出现未定义的错误。也就是说在编译前,计算机检查的是语法和语义的错误,在编译后,报出未定义,也恰恰说明了,在链接过程中,程序开始进行组合。
在这里插入图片描述

头文件与源文件

源文件: xxx.c
头文件: xxx.h

我们在编辑的文件就是源文件,而我们在写程序时,第一行总会有一个#include <stdio.h>这个<stdio.h>就是头文件。在工程项目开发规范当中,头文件中放声明,源文件中放定义。那么如果不遵循这个规范又会出现什么问题呢,我们来演示一下。
在这里插入图片描述
我们现在把刚刚的main.c程序中函数部分全部放到了head1.h文件当中,下面我们编译一下。
在这里插入图片描述
可以看到这里出现了一个错误main.c:9:9: fatal error: head1.h: No such file or directory,大致意思是没有当前文件或目录也就是说没有找到我们的头文件。为什么会找不到呢。我们不难思考出问题所在,我们在引入<stdio.h>时运行是完全没有问题的,但是我们自己写的就有问题了,而且错误原因是文件或目录不存在,不难猜出应该是查找路径的问题。

在C语言中头文件的引入中有两种形式

  • 双引号形式:双引号形式编译器是从当前目录查找头文件
  • 尖角号形式:尖角号形式编译器则是从系统路径下查找文件

我们换成双引号,再编译一下试试看:
在这里插入图片描述


这样看似都定义在头文件中也都是可以正常运行的,下面我们就复杂一点,多加入几个头文件看看是不是也可以。

我们现在的程序的每次编译还需要链接一下func.c文件太麻烦了,所以我们也可以把func.c改写成一个head2.h的头文件,。


现在呢我们发现head2.h的头文件功能很好,其它程序也需要调用,但是head2.h有funA()的函数调用,所以我们只需要在head2.h中引入head1.h的头文件即可。但是当引入后会发现我们写的main.c程序无法编译
在这里插入图片描述
可以看到报错内容出现了重定义,我们可以通过gcc -E main.c 查看预编译期发生了什么。太长这里就不贴图了,原因是因为在宏展开的时候,head1.h优先展开,而后展开head2.h时因为head2.h中已经有了head1.h所以被展开了两次,可以看到报错问题就是funA()和funB()发生了重定义,因为head1.h被展开了两次也就定义了两次。
如何解决这个问题呢,在之前我们已经学了条件式编译,只要保证一个头文件只展开一次就够了,已经展开过了就不需要再展开了。只需要再head1.h中加入这三行代码
在这里插入图片描述
可以看到程序正常运行了。应该在每一个头文件中都加入这三行命令这样就可以保证在引入头文件的时候不会出现问题。后面定义的宏的名字建议与所属头文件名字相关,这样可以保证不会重名,也可以如果出现问题了第一时间发现在哪里。

#ifndef _HEAD_H
#define _HEAD_H
#endif

使用条件式编译就可以很好的规避掉重定义的问题了
在这里插入图片描述

那么现在回到开始的问题,似乎可以声明和定义都放到头文件中。但是别急,现在我们知识解决了一个源文件中一次编译链接的重定义问题,我们尝试多个源文件的编译连接过程。


当前的main.c函数是在协作开发过程中我们开发的功能,完成任务后我们发个另一个人去使用,但是在使用过程中,发现再添加一个funD()功能会让程序运行的更流畅,所以我们再现在基础上加入这个新功能。文件以及代码改动情况如下:
在这里插入图片描述
我们还是先编译再链接,我们发现最终没有可执行文件生成。在其中呢,不同的源文件中也是发生了重定义
在这里插入图片描述
那么我们把头文件和源文件全部拆开,然后按照之前的步骤,先编译在链接,在这里我就不一一截图了,具体的代码仓库地址分享在文末。可以看到一一编译完成之后生成了四个对象文件然后链接之后程序也是成功运行了。
在这里插入图片描述
以上就是工程项目开发的内容了。


头文件查找路径

我们在引入自己的头文件时,使用的是双引号,如果也想要使用尖角号的话就需要把我们的目录加到系统目录中去,在命令行执行下面一行代码即可

gcc -I./ -c file.c

下面我们就需要标准化我们的开发目录,如下。include目录放入头文件,src目录放入我们的源文件。bin目录存放我们最终生成的可执行程序在这里插入图片描述

makefile

makefile是一个多文件编译链接的工具,可以帮助我们更快捷完成工作。具体细节内容可以自行搜寻,这里只是简单演示
在这里插入图片描述

在这里插入图片描述
文件名要取makefile,编辑后输入make执行,然后会按照我们我们编辑的内容执行,可以看到下方的执行结果是我们的预期结果。在bin目录下生成了output
在这里插入图片描述


在实际开发过程中我们也要考虑我们自己代码的私密性,所以协作开发的时候不会把源文件发给其他人,但是这个时候需要用到你的功能应该怎么办呢。我们可以打包成一个静态链接库供别人调用。不同的环境呢会有不同的指令,这里就不作演示了,以上就是全部内容

代码仓库https://gitee.com/xingyexiakong/c-practice.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/811187.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法每日一练]-图论(lca) 最近公共祖先LCA,货车运输

目录 P3379&#xff1a;最近公共祖先LCA 思路&#xff1a; 货车运输 P3379&#xff1a;最近公共祖先LCA 思路&#xff1a; 首先进行的预处理&#xff0c;将所有点的深度和p数组求出来 设置&#xff1a;p[i][j]存的从i向上走2的j次方那么长的路径到的父节点 更深的点走到和…

PostgreSQL入门到实战-第二十二弹

PostgreSQL入门到实战 PostgreSQL中表连接操作(六)官网地址PostgreSQL概述PostgreSQL中self-join命令理论PostgreSQL中self-join命令实战更新计划 PostgreSQL中表连接操作(六) 使用PostgreSQL自联接技术来比较同一表中的行 官网地址 声明: 由于操作系统, 版本更新等原因, 文…

内存函数memcpy、mommove、memset、memcmp

1、memcpy函数 描述&#xff1a; C 库函数 void *memcpy(void *str1, const void *str2, size_t n) 从存储区 str2 复制 n 个字节到存储区 str1。 声明&#xff1a; void *memcpy(void *str1, const void *str2, size_t n)参数&#xff1a; str1 -- 指向用于存储复制内容的目标…

【电控笔记0】稳定度判断

简要概括 现控:原理虚轴,稳定度越高 自控:相位裕度PM 增益裕度GM 开环传函 不稳定条件判断

期望阻抗(Zd/s或Yd*s)的nyquist、bode与rlocus

在机器人控制领域中&#xff0c;针对具体的阻抗参数特性&#xff08;如质量、阻尼和刚度&#xff09;&#xff0c;Nyquist图、Bode图和根轨迹&#xff08;rlocus&#xff09;可以提供深入的分析和设计工具。 Nyquist图&#xff1a; 应用于阻抗参数&#xff1a;在机器人控制中&…

docker pull镜像的时候指定arm平台

指定arm平台 x86平台下载arm平台的镜像包 以mysql镜像为例 docker pull --platform linux/arm64 mysqldocker images查看镜像信息 要查看Docker镜像的信息&#xff0c;可以使用docker inspect命令。这个命令会返回镜像的详细信息&#xff0c;包括其元数据和配置。 docker i…

Fast-lio2运行时如何显示轨迹线

修改对应设备的.yaml文件&#xff0c;以velodyne为例&#xff1a; 将 path_en参数改为true即可&#xff0c;运行其他设备&#xff0c;修改对应的参数

四、SpringBoot3 整合 Druid 数据源

本章概要 创建程序引入依赖启动类配置文件编写编写 Controller启动测试问题解决 4.1 创建程序 4.2 引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://ww…

【C++ STL序列容器】deque 双端队列

文章目录 【 1. 基本原理 】【 1. deque 的创建 】1.1 创建一个空的 deque1.2 创建一个 n 个默认值的 deque1.3 创建一个 n 个指定值的 deque1.4 通过一个 deque 初始化另一个 deque1.5 通过基础容器来初始化 queue 容器适配器 【 3. deque 支持的成员函数 】 【 1. 基本原理 】…

不惑之年,反思我如何成为一个程序员

不惑之年&#xff0c;反思我如何成为一个程序员 文章目录 不惑之年&#xff0c;反思我如何成为一个程序员01/偶然掉入码河02/现实撕碎理想03/发展选择方向04/时代成就向往05/幸运装饰未来 在这个充满生机与希望的季节&#xff0c;博主有幸收到一家国企邀约面试&#xff0c;并顺…

通俗易懂HTTP和HTTPS区别

HTTP&#xff1a;超文本传输协议&#xff0c;它是使用一种明文的方式发送我们的内容&#xff0c;没有任何的加密&#xff0c;例如我们要在网页上输入账号密码&#xff0c;如果使用HTTP协议&#xff0c;账号密码就可能会被暴露&#xff0c;默认端口是80. HTTPS&#xff1a;是HT…

护眼台灯品牌哪个好?2024五大护眼台灯排行榜分享

​护眼台灯作为家庭中常见的照明工具&#xff0c;其存在几乎成为了现代生活的标配。家长们往往会为孩子购置一台&#xff0c;供学习和阅读使用&#xff1b;同时&#xff0c;它也是学生和办公人员在夜晚工作学习的必备之物。然而&#xff0c;市面上的一些普通台灯可能存在着种种…

Springboot使用教程

二、配置文件 SpringBoot使用一个全局的配置文件&#xff0c;配置文件名是固定的&#xff1b; •application.properties •application.yml 1.配置文件的作用&#xff1a; 修改SpringBoot自动配置的默认值&#xff1b;SpringBoot在底层都给我们自动配置好&#xff1b; Y…

OpenHarmony的C/C++三方库的适配

简介 本仓库主要用于存放已经适配OpenHarmony的C/C三方库的适配脚本和OpenHarmony三方库适配指导文档、三方库适配相关的工具。 三方库适配 本仓库的三方库主要是通过OpenHarmony SDK进行交叉编译适配的&#xff0c;并集成到应用端进行使用。 在使用OpenHarmony的SDK进行交…

智能合约:未来数字经济的基石

智能合约是一种自动执行交易的计算机协议&#xff0c;它以代码形式规定了交易双方的权利和义务&#xff0c;具有高度的可靠性和安全性。随着数字经济的发展&#xff0c;智能合约的重要性日益凸显&#xff0c;将成为未来数字经济的基石。 首先&#xff0c;智能合约在金融领域的应…

【目标检测数据集】城市街道垃圾堆相关数据集

一、GarbageOverflow&#xff1a;城市街道垃圾堆数据集 该垃圾堆数据集是通过爬虫从网上进行爬取得到的&#xff0c;一共包含1188张图片&#xff0c;有2个类别&#xff0c;分别为[overflow, No Overflow]&#xff0c;两个标签的数量分别为1734个标签和414个标签。部分数据集及…

23年坚守,只为打造高品质立秀膨体,索康让品质为中国说话

2024年3月23日&#xff0c;第二十三届上海国际整形美容外科大会&#xff08;以下简称“大会”&#xff09;在上海召开&#xff0c;本次大会由张涤生整形外科发展基金会主办&#xff0c;上海交通大学附属第九人民医院整复外科、Chinese Journal of Plastic and Reconstructive S…

阿里云2核2G服务器这么便宜,能用来做什么?

阿里云2核2G服务器这么便宜&#xff0c;能用来做什么&#xff1f;阿里云2核2G云服务器可以用来搭建网站、爬虫、邮件服务器、接口服务器、个人博客、企业官网、数据库应用、大数据计算、AI人工智能、论坛、电子商务、AI、LLM大语言模型、测试环境等&#xff0c;阿里云2核2G服务…

Uniapp+基于百度智能云完成AI视觉功能(附前端思路)

本博客使用uniapp百度智能云图像大模型中的AI视觉API&#xff08;本文以物体检测为例&#xff09;完成了一个简单的图像识别页面&#xff0c;调用百度智能云API可以实现快速训练模型并且部署的效果。 uniapp百度智能云AI视觉页面实现 先上效果图实现过程百度智能云Easy DL训练图…

Hi3861 OpenHarmony嵌入式应用入门--鸿蒙开发环境搭建

目录 简介 准备材料 安装开发环境 配置开发工具和sdk 新建工程 代码编译 简介 本篇将进行hi3861开发环境的搭建&#xff0c;并能够编译默认工程。 准备材料 华为集成开发环境工具DevEco Device Tool 华为集成开发环境IDE DevEco Device Tool下载 | HarmonyOS设备开发 …