C语言编译过程
C语言编译过程
- 1、C语言编译过程
- 2、单c文件编译实践
- 3、多c文件编译实践
- 4、define
- 4.1、不带参宏
- 4.2、带参宏
- 4.3、带参宏和带参函数的区别
- 5、选择性编译ifdef、ifndef、if
- 5.1、#ifdef
- 5.2、#ifndef
- 5.3、#if
- 6、静态库和动态链接库
- 6.1、静态库实践
- 6.1.1、将mylib.c制作成静态库
- 6.1.2、编译源程序
- 6.2、动态库实践
- 6.2.1、将mylib.c制作成动态链接库
- 6.2.2、动态链接库的使用
1、C语言编译过程
1、预编译
将 .c 中的头文件展开、宏展开。生成的文件是 .i 文件。预处理操作过程不会进行语法检查。
2、编译
将预处理之后的 .i 文件生成 .s 汇编文件。
3、汇编
将 .s 汇编文件生成 .o 目标文件。
4、链接
将 .o 文件链接成 可执行目标文件。
2、单c文件编译实践
hello.c文件
#include<stdio.h>int main() {printf("Hello World! \n");return 0;
}
Linux 下GCC 编译器编译过程
1、预处理
gcc -E hello.c -o hello.i
2、编译
gcc -S hello.i -o hello.s
3、汇编
gcc -c hello.s -o hello.o
4、链接
gcc hello.o -o hello
3、多c文件编译实践
#include<xxx.h>// 用尖括号包含头文件,在系统指定的路径下找头文件
#include "xxx.h"// 用双引号包含头文件,先在当前目录下找头文件,找不到,再到系统指定的路径下找。
注意:include 经常用来包含头文件,可以包含.c 文件,但是大家不要包含.c。
因为 include 包含的文件会在预编译被展开,如果一个.c 被包含多次,展开多次,会导致函数重复定义。所以不要包含.c 文件。
test.c文件
#include<stdio.h>
#include "max.h"
#include "min.h"int main() {int maxVal = max(1, 5);int minVal = min(1, 5);printf("最大值maxVal = %d;最小值minVal = %d \n", maxVal, minVal);return 0;
}
max.c文件
int max(int v1, int v2) {int z;if (v1>v2) {z = v1;}else {z = v2;}return z;
}
min.c文件
int min(int v1, int v2) {int z;if (v1 < v2) {z = v1;}else {z = v2;}return z;
}
max.h文件
extern int max(int v1, int v2);
min.h文件
extern int max(int v1, int v2);
gcc -E test.c -o test.i
gcc -S test.i -o test.s
gcc -c test.s -o test.ogcc -E max.c -o max.i
gcc -S max.i -o max.s
gcc -c max.s -o max.ogcc -E min.c -o min.i
gcc -S min.i -o min.s
gcc -c min.s -o min.ogcc test.o max.o min.o -o test
4、define
定义宏用 define 关键字,宏是在预编译的时候进行替换。
4.1、不带参宏
#define PI 3.1415926
在预编译的时候如果代码中出现了 PI 就用 3.1415926 去替换。
宏定义的好处:只要修改宏定义,其他地方在预编译的时候就会重新替换。
注意:宏定义后边不要加分号。
宏定义的作用范围:从定义的地方到本文件末尾。
如果想在中间终止宏的定义范围
//终止PI 的作用
#undef PI
4.2、带参宏
#define S(a,b) a*b
注意带参宏的形参 a 和 b 没有类型名:(注意歧义)
S(1,5) 即【1*5】
S(3+4,3) 即【3+4 * 3】
S((3+4),3) 即【(3+4)*3】
4.3、带参宏和带参函数的区别
带参宏: 被调用多少次就会展开多少次,执行代码的时候没有函数调用的过程不需要压栈弹栈。所以带参宏,是浪费了空间,因为被展开多次,节省时间。
带参函数: 代码只有一份,存在代码段,调用的时候去代码段取指令,调用的时候要压栈弹栈。有个调用的过程。
带参函数是浪费了时间,节省了空间。
带参函数的形参是有类型的,带参宏的形参没有类型名。
5、选择性编译ifdef、ifndef、if
选择性编译都是在预编译阶段处理的事情。
5.1、#ifdef
#ifdef AAA代码段一
#else代码段二
#endif
#include<stdio.h>
#define AAAint main(int argc, char *argv[]){
#ifdef AAAprintf("Hello World!\n");
#elseprintf("Hello China!\n");
#endifreturn 0;
}
5.2、#ifndef
#ifndef AAA代码段一
#else代码段二
#endif
#ifndef 和 #ifdef 是一种互补。这种方法,经常用在防止头文件重复包含。
5.3、#if
如果表达式为真,编译第一段代码,否则编译第二段代码。
#if 表达式程序段一
#else程序段二
#endif
6、静态库和动态链接库
一、动态编译
动态编译使用的是动态库文件进行编译,默认使用的就是动态编译。
gcc hello.c -o hello1
二、静态编译
静态编译使用的静态库文件进行编译。
gcc -static hello.c -o hello2
三、静态编译和动态编译区别
1、使用的库文件的格式不一样:动态编译使用动态库,静态编译使用静态库。
2、静态编译要把静态库文件打包编译到可执行程序中。
3、动态编译不会把动态库文件打包编译到可执行程序中,它只是编译链接关系。
=== mytest.c ====================================
#include <stdio.h>
#include "mylib.h"int main(int argc, char* argv[]) {int a = 10, b = 20, max_num, min_num;max_num = max_fun(a, b);min_num = min_fun(a, b);printf("max_num = %d \n", max_num);printf("min_num = %d \n", min_num);return 0;
}=== mylib.c ====================================
int max_fun(int x, int y) {return (x > y) ? x : y;
}int min_fun(int x, int y) {return (x < y) ? x : y;
}=== mylib.h ====================================
#ifndef __MYLIB_H__
#define __MYLIB_H__
extern int max_fun(int x, int y);
extern int min_fun(int x, int y);
#endif
6.1、静态库实践
6.1.1、将mylib.c制作成静态库
gcc -c mylib.c -o mylib.o
ar rc libmylib.a mylib.o
注意:静态库文件 起名的时候必须以 lib 开头以 .a 结尾
6.1.2、编译源程序
方法1:在同一目录下编译
编译源程序命令:
gcc -static mytest.c libmylib.a -o mytest
方法2:可以指定头文件及库文件的路径
如将 libmylib.a mylib.h 移动到 /root/staticlib 下
mv libmylib.a mylib.h /root/staticlib
编译源程序命令:
gcc mytest.c \
-static \
-o mytest \
-L /root/staticlib \
-l mylib \
-I /root/staticlib
注意:
-L 是指定库文件的路径
-l 指定找哪个库,指定的只要库文件名 lib 后面 .a 前面的部分
-I 指定头文件的路径
方法3:将库文件及头文件存放到系统默认指定路径
库文件 默认路径是 /lib 或者是 /usr/lib
头文件 默认路径是 /usr/include
mv libmylib.a /usr/lib
mv mylib.h /usr/include
编译源程序的命令
gcc mytest.c -o mytest -l mylib -static
6.2、动态库实践
6.2.1、将mylib.c制作成动态链接库
使用gcc 编译、制作动态链接库
gcc -shared mylib.c -o libmylib.so
注意:动态链接库文件 起名的时候必须以 lib 开头以 .so 结尾
6.2.2、动态链接库的使用
方法1:库函数、头文件均在当前目录下
gcc mytest.c libmylib.so -o mytest
export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH
此时就可以在执行了哦: ./mytest
方法2:库函数、头文件假设在 /opt/ 目录
mv libmylib.so mylib.h /opt
gcc mytest.c -o mytest -L/opt -lmylib -I/opt编译通过,运行 mytest 时出错,编译时找到了库函数,但运行链接时找不到库,要把链接库文件所在目录加入默认搜索路径
export LD_LIBRARY_PATH=/opt:$LD_LIBRARY_PATH
此时就可以在执行了哦: ./mytest
方法3:库函数、头文件均在系统路径下
cp libmylib.so /usr/lib
cp mylib.h /usr/include
gcc mytest.c -o mytest -lmylib
如果出现如下错误,则添加查找路径,解决问题
[root@michael cc]# ./mytest
./mytest: error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory解决方案:
export LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH
此时就可以在执行了哦: ./mytest
注:
问:此时有个问题出现了?静态库 和 动态库 都在/usr/lib下,那么默认链接的到底是动态库还是静态库呢?
答:当静态库与动态库重名时,系统会优先连接动态库,或者编译时加入-static指定使用静态库。
相关文章:
C语言编译过程
C语言编译过程1、C语言编译过程2、单c文件编译实践3、多c文件编译实践4、define4.1、不带参宏4.2、带参宏4.3、带参宏和带参函数的区别5、选择性编译ifdef、ifndef、if5.1、#ifdef5.2、#ifndef5.3、#if6、静态库和动态链接库6.1、静态库实践6.1.1、将mylib.c制作成静态库6.1.2、…...
前端学习 ---常用标签
常用标签 1,文本标签 文本标签是双标签,自带加粗效果,有自己对应的文本大小,并且独占一行,有默认间距 一级标签:< h1 > < /h1 > 二级标签:< h2 > < /h2> 三级标签:&l…...
2023年PMP考试难不难?
整个考试的考察方向转向还是比较大的,基本上以“价值传递”和“以人为本”这两个出发点来考察项目经理所需要的能力。 1}新版提纲题目数量的变化 总题量从200道减少到180道,所以答题时间上相对变的宽裕一些。考试时间230分钟,中间有十分钟休…...
Netty 入门
文章目录一、概述1.1 Netty 是什么?1.2 Netty 的地位1.3 Netty 的优势二、Hello World2.1 目标2.2 服务器端2.3 客户端2.4 流程梳理三、组件3.1 EventLoop3.2 演示 NioEventLoop 处理 io 事件3.3 演示 NioEventLoop 处理普通任务3.4 演示 NioEventLoop 处理定时任务…...
收藏|一文掌握数据分析在企业的实际流程
一、数据分析概念 1.1 数据分析 是指用适当的统计分析方法对收集来的大量数据进行分析,将他们加以汇总和理解并消化,以求最大化地开发数据的功能,发挥数据的作用。 1.2 数据分析包括 描述性数据分析(初级数据分析)…...
100ask_imx6ull 输出PWM
查看PWM对应扩展板的引脚 100ask_imx6ul通过扩展板插槽来验证pwm波,所以这里通过扩展板的原理图及芯片手册可知,gpio4_io20,gpio4_io19分别对应着PWM8和PWM7。 设置设备树 打开官方NXP的工具i.MX pins v6工具,PWM7/PWM8的配置如…...
yolov5编译安卓APP:解决图像上全是检测框
yolov5编译安卓APP:解决图像上全是检测框前言一、第一个YOLOv5 APP1.参考链接2.详细说明3.APP检测时图像上全是框的解决方法二、第二个YOLOv5 APP1.参考链接2.详细说明3.APP检测时图像上全是框的解决方法三、其他1.APK打包2.修改APP图标与名字前言 YOLOv5编译安卓A…...
为什么我们需要地图?
想一想,武侠小说里面。一张藏宝图,引来江湖腥风血雨,要么是武功秘籍,要么是绝世宝剑,要么是富可敌国的财富,只要有了藏宝图,便可曲径通幽,到达彼岸。 由此可见,地图的重…...
攻防世界1.新手练习区
4.攻防世界1.新手练习区 1.view_source 访问url: http://111.200.241.244:48855/ 鼠标点击右键不起作用,F12审查元素 得到flag为cyberpeace{0f3a3e4ab8c8664f3cf40d4240ec7b53} 2.robots 访问url: http://111.200.241.244:34362/ rob…...
Python进阶篇(二)-- Django 深入模型
上一节提到了Django是基于MVC架构的Web框架,MVC架构追求的是“模型”和“视图”的解耦合。所谓“模型”说得更直白一些就是数据(的表示),所以通常也被称作“数据模型”。在实际的项目中,数据模型通常通过数据库实现持久…...
ABAP SALV实现弹出ALV选择
问题场景 需要弹出一个ALV并获取选择的数据 实现思路 跳转屏幕弹出ALV(通过SALV)弹出ALV(通过REUSE_ALV_POPUP_TO_SELECT) 实现效果 因为这里需要的是单选,所以没有多选列 实现代码 MODULE sel_zfretype INPUT.…...
git check-pick,git patch 与 git stash 详解
大家好,我是 17。 今天和大家聊一聊 git check-pick,git patch 与 git stash 的用法。 git cherry-pick 为什么要用 cherry-pick? 不适合 merge 的场景就可以考虑 cherry-pick。 试想下面这些场景 只想同步分支的部分提交。两个分支是两上完全独立…...
OA漏洞-到处搜集整理
一米OA getfile.jsp 任意文件读取漏洞 原文链接 漏洞复现 一米OA getfile.jsp 任意文件读取漏洞 一米OA协同办公系统,集成了OA办公自动化系统、手机客户端、专业报表工具,为全国千万企业用户提供全功能、性价比高的OA软件。一米OA getfile.jsp文件存在任意文件读取漏洞&am…...
web端接收读卡器卡片信息
项目背景 通过电脑连接的读卡器读取卡片信息,并由web页面接收和处理卡片信息。 读卡器抛出卡片信息流程 卡片贴近或放置到读卡器上读卡器解析卡片信息,并形成固定格式的字符串,包括的信息有:卡片写入的数据、卡片原数据&#x…...
BUUCTF-练习场-WEB-第一部分(8道)
[极客大挑战 2019]EasySQL 1payload:1 or 11#是闭合前面的查询语句,or 11恒成立,可以使用or句子绕过判断,#用于注释,注释后面的内容不再执行,所以该sql命令会返回表内所有内容,其实就是实现一个…...
Java Reflection 实战- Class类
Java Reflection 实战 - Class Java 反射使得在运行时检查类、接口、字段和方法成为可能,而不需要在编译时知道类、方法等的名称。也可以使用反射来实例化新对象、调用方法和获取/设置字段值。 Java反射的功能相当强大,可以说是非常有用。例如ÿ…...
背包问题理解思路(01背包、完全背包、分组背包)
这两天把经典的三个背包问题看了一下,网上大多文章是以代码和公式为主,因为平时没刷过算法题所以理解起来花了些时间,固写一篇文章记录理解思路,本文不包含代码实现(理解了思路代码实现应该是小问题,网上一…...
Mr. Cappuccino的第39杯咖啡——Kubernetes之深入理解Pod
Kubernetes之深入理解PodPod相关概念Pod详细配置清单Pod核心配置Pod基本配置1. 创建yaml文件2. 创建namespace并根据yaml文件创建资源3. 查看namespace下的pod列表以及pod的详细信息Pod中多个容器的名称和端口号不能相同Pod镜像拉取策略Pod环境变量Pod端口相关设置Pod资源相关配…...
SqlSession 和 SqlSessionTemplate 简单使用及注意事项
1、SqlSession 简单使用 先简单说下 SqlSession 是什么?SqlSession 是对 Connection 的包装,简化对数据库操作。所以你获取到一个 SqlSession 就相当于获取到一个数据库连接,就可以对数据库进行操作。 SqlSession API 如下图示:…...
1. QSaveFile和QFile的简单使用
1. 说明 QSaveFile和QFile两个类都是用来操作文件的,区别在于QSaveFile在对文件进行写入时有一种保护机制,再写入出错时,不会对源文件中的内容进行操作。该类在执行写操作时,会先将内容写入到一个临时文件中,如果没有…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
