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

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

相关文章:

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

之前我们已经了解了C语言的基础知识部分&#xff0c;掌握这些之后&#xff0c;基本就可以开发一些小程序了。在开发时&#xff0c;就会出现合作的情况&#xff0c;C语言是如何协作开发的呢&#xff0c;将在这一篇文章进行演示。 工程项目开发 在开发过程中&#xff0c;你接到…...

【Java核心技术】第6章 接口

1 接口 接口不是类&#xff0c;而是对希望符合这个接口的类的一组需求 1.1 Comparable 接口 要对对象进行比较&#xff0c;就要实现(implement)比较(comparable)接口 注意&#xff1a; implements Comparable<Manager> Comparable接口是泛型接口 class Manager exten…...

【Java探索之旅】从输入输出到猜数字游戏

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; Java编程秘籍 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一、输入输出1.1 输出到控制台1.2 从键盘输入 二、猜数字游戏2.1 所需知识&#xff1a…...

【动态规划】【01背包】Leetcode 1049. 最后一块石头的重量 II

【动态规划】【01背包】Leetcode 1049. 最后一块石头的重量 II 解法 ---------------&#x1f388;&#x1f388;题目链接&#x1f388;&#x1f388;------------------- 解法 &#x1f612;: 我的代码实现> 动规五部曲 ✒️确定dp数组以及下标的含义 dp[j]表示容量为…...

2023 年上海市大学生程序设计竞赛 - 四月赛

A. 宝石划分 A. 宝石划分 - 2023 年上海市大学生程序设计竞赛 - 四月赛 - ECNU Online Judge 找距离N最近的M的因数q&#xff0c;输出M/q 如果是暴力所的话&#xff0c;会超时 #include <bits/stdc.h> using namespace std; int main(){ios::sync_with_stdio(false)…...

别让这6个UI设计雷区毁了你的APP!

一款成功的APP不仅仅取决于其功能性&#xff0c;更取决于用户体验&#xff0c;这其中&#xff0c;UI设计又至关重要。优秀的UI设计能够为用户带来直观、愉悦的交互体验&#xff0c;甚至让用户“一见钟情”&#xff0c;从而大大提高产品吸引力。 然而&#xff0c;有很多设计师在…...

继承【C/C++复习版】

目录 一、什么是继承&#xff1f;怎么定义继承&#xff1f; 二、继承关系和访问限定符&#xff1f; 三、基类和派生类对象可以赋值转换吗&#xff1f; 四、什么是隐藏&#xff1f;隐藏vs重载&#xff1f; 五、派生类的默认成员函数&#xff1f; 1&#xff09;派生类构造函…...

题目 2694: 蓝桥杯2022年第十三届决赛真题-最大数字【暴力解法】

最大数字 原题链接 &#x1f970;提交结果 思路 对于每一位&#xff0c;我我们都要尽力到达 9 所以我们去遍历每一位, 如果是 9 直接跳过这一位 如果可以上调到 9 我们将这一位上调到 9 &#xff0c;并且在a 中减去对应的次数 同样的&#xff0c;如果可以下调到 9&#xff0c;我…...

【C语言】- C语言字符串函数详解

C语言字符串函数详解 1、void *memset(void *dest, int c, size_t count); 将dest前面count个字符置为字符c. 返回dest的值. 2、void *memmove(void *dest, const void *src, size_t count); 从src复制count字节的字符到dest. 如果src和dest出现重叠, 函数会自动处理. 返回…...

如何实现小程序滑动删除组件+全选批量删除组件

如何实现小程序滑动删除组件全选批量删除组件 一、简介 如何实现小程序滑动删除组件全选批量删除组件 采用 uni-app 实现&#xff0c;可以适用微信小程序、其他各种小程序以及 APP、Web等多个平台 具体实现步骤如下&#xff1a; 下载开发者工具 HbuilderX进入 【Dcloud 插…...

基于SSM+Jsp+Mysql的农产品供销服务系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…...

​​​​网络编程学习探索系列之——广播原理剖析

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的网络编程系列之广播原理剖析&#xff0c;在这篇文章中&#xff0c; 你将会学习到如何在网络编程中利用广播来与局域网内加入某个特定广播组的主机&#xff01; 希望这篇文章能对你有所帮助&#xff0c;大家要是觉得我写…...

小程序开发SSL证书下载和安装

在开发小程序时&#xff0c;确保数据的安全传输至关重要&#xff0c;而实现这一目标的关键在于正确获取与安装SSL证书。以下详细介绍了从获取到安装SSL证书的完整流程&#xff0c;以助您为小程序构建可靠的加密通信环境。 一、小程序SSL证书类型选择&#xff1a; 域名验证型D…...

医疗图像分割 | 基于Pyramid-Vision-Transformer算法实现医疗息肉分割

项目应用场景 面向医疗图像息肉分割场景&#xff0c;项目采用 Pytorch Pyramid-Vision-Transformer 深度学习算法来实现。 项目效果 项目细节 > 具体参见项目 README.md (1) 模型架构 (2) 项目依赖&#xff0c;包括 python 3.8、pytorch 1.7.1、torchvision 0.8.2(3) 下载…...

蓝桥杯 每日2题 day5

碎碎念&#xff1a;哦哈呦&#xff0c;到第二天也是哦哈哟&#xff0c;&#xff0c;学前缀和差分学了半天&#xff01;day6堂堂连载&#xff01; 0.单词分析 14.单词分析 - 蓝桥云课 (lanqiao.cn) 关于这题就差在input前加一个sorted&#xff0c;记录一下下。接下来就是用字…...

[ 云计算 | AWS 实践 ] Java 应用中使用 Amazon S3 进行存储桶和对象操作完全指南

本文收录于【#云计算入门与实践 - AWS】专栏中&#xff0c;收录 AWS 入门与实践相关博文。 本文同步于个人公众号&#xff1a;【云计算洞察】 更多关于云计算技术内容敬请关注&#xff1a;CSDN【#云计算入门与实践 - AWS】专栏。 本系列已更新博文&#xff1a; [ 云计算 | …...

循环单链表算法库

学习贺老师数据结构 数据结构之自建算法库——循环单链表_循环单链表 csdn-CSDN博客​​​​​​ 整理总结出的循环单链表算法库 v1.0 : 基本实现功能 v2.0(2024.4.6): 修复Delete_SpecificLocate_CyclicList()删除节点函数bug,添加验证删除节点是否超范围判断 目录 1.主要功能…...

WPS二次开发系列:Gradle版本、AGP插件与Java版本的对应关系

背景 最近有体验SDK的同学反馈接入SDK出现报错&#xff0c;最终定位到原因为接入的宿主app项目的gradle版本过低导致&#xff0c;SDK兼容支持了android11的特性&#xff0c;需要对应的gradle插件为支持android11的版本。 现象 解决方案 将gradle版本升级至支持android11的插件版…...

绿联 安装MariaDB数据库用于Seatable服务

绿联 安装MariaDB数据库用于Seatable服务 MariaDB MariaDB 是一个流行的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它是MySQL的一个分支&#xff0c;提供了丰富的功能和性能&#xff0c;适用于各种应用场景。 核心功能 SQL支持: MariaDB完全支持SQL&a…...

Spark, Storm, Flink简介

目录 1.Spark VS Storm2.Storm VS Flink 本文主要介绍Spark, Storm, Flink的区别。 1.Spark VS Storm Spark和Storm都是大数据处理框架&#xff0c;但它们在设计理念和使用场景上有一些区别&#xff1a; 实时性&#xff1a;Storm是一个实时计算框架&#xff0c;适合需要实时…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...