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

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,文本标签 文本标签是双标签&#xff0c;自带加粗效果&#xff0c;有自己对应的文本大小&#xff0c;并且独占一行&#xff0c;有默认间距 一级标签&#xff1a;< h1 > < /h1 > 二级标签&#xff1a;< h2 > < /h2> 三级标签&#xff1a;&l…...

2023年PMP考试难不难?

整个考试的考察方向转向还是比较大的&#xff0c;基本上以“价值传递”和“以人为本”这两个出发点来考察项目经理所需要的能力。 1}新版提纲题目数量的变化 总题量从200道减少到180道&#xff0c;所以答题时间上相对变的宽裕一些。考试时间230分钟&#xff0c;中间有十分钟休…...

Netty 入门

文章目录一、概述1.1 Netty 是什么&#xff1f;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 数据分析 是指用适当的统计分析方法对收集来的大量数据进行分析&#xff0c;将他们加以汇总和理解并消化&#xff0c;以求最大化地开发数据的功能&#xff0c;发挥数据的作用。 1.2 数据分析包括 描述性数据分析&#xff08;初级数据分析&#xff09;…...

100ask_imx6ull 输出PWM

查看PWM对应扩展板的引脚 100ask_imx6ul通过扩展板插槽来验证pwm波&#xff0c;所以这里通过扩展板的原理图及芯片手册可知&#xff0c;gpio4_io20&#xff0c;gpio4_io19分别对应着PWM8和PWM7。 设置设备树 打开官方NXP的工具i.MX pins v6工具&#xff0c;PWM7/PWM8的配置如…...

yolov5编译安卓APP:解决图像上全是检测框

yolov5编译安卓APP&#xff1a;解决图像上全是检测框前言一、第一个YOLOv5 APP1.参考链接2.详细说明3.APP检测时图像上全是框的解决方法二、第二个YOLOv5 APP1.参考链接2.详细说明3.APP检测时图像上全是框的解决方法三、其他1.APK打包2.修改APP图标与名字前言 YOLOv5编译安卓A…...

为什么我们需要地图?

想一想&#xff0c;武侠小说里面。一张藏宝图&#xff0c;引来江湖腥风血雨&#xff0c;要么是武功秘籍&#xff0c;要么是绝世宝剑&#xff0c;要么是富可敌国的财富&#xff0c;只要有了藏宝图&#xff0c;便可曲径通幽&#xff0c;到达彼岸。 由此可见&#xff0c;地图的重…...

攻防世界1.新手练习区

4.攻防世界1.新手练习区 1.view_source 访问url&#xff1a; http://111.200.241.244:48855/ 鼠标点击右键不起作用&#xff0c;F12审查元素 得到flag为cyberpeace{0f3a3e4ab8c8664f3cf40d4240ec7b53} 2.robots 访问url&#xff1a; http://111.200.241.244:34362/ rob…...

Python进阶篇(二)-- Django 深入模型

上一节提到了Django是基于MVC架构的Web框架&#xff0c;MVC架构追求的是“模型”和“视图”的解耦合。所谓“模型”说得更直白一些就是数据&#xff08;的表示&#xff09;&#xff0c;所以通常也被称作“数据模型”。在实际的项目中&#xff0c;数据模型通常通过数据库实现持久…...

ABAP SALV实现弹出ALV选择

问题场景 需要弹出一个ALV并获取选择的数据 实现思路 跳转屏幕弹出ALV&#xff08;通过SALV&#xff09;弹出ALV&#xff08;通过REUSE_ALV_POPUP_TO_SELECT&#xff09; 实现效果 因为这里需要的是单选&#xff0c;所以没有多选列 实现代码 MODULE sel_zfretype INPUT.…...

git check-pick,git patch 与 git stash 详解

大家好&#xff0c;我是 17。 今天和大家聊一聊 git check-pick&#xff0c;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端接收读卡器卡片信息

项目背景 通过电脑连接的读卡器读取卡片信息&#xff0c;并由web页面接收和处理卡片信息。 读卡器抛出卡片信息流程 卡片贴近或放置到读卡器上读卡器解析卡片信息&#xff0c;并形成固定格式的字符串&#xff0c;包括的信息有&#xff1a;卡片写入的数据、卡片原数据&#x…...

BUUCTF-练习场-WEB-第一部分(8道)

[极客大挑战 2019]EasySQL 1payload&#xff1a;1 or 11#是闭合前面的查询语句&#xff0c;or 11恒成立&#xff0c;可以使用or句子绕过判断&#xff0c;#用于注释&#xff0c;注释后面的内容不再执行&#xff0c;所以该sql命令会返回表内所有内容&#xff0c;其实就是实现一个…...

Java Reflection 实战- Class类

Java Reflection 实战 - Class Java 反射使得在运行时检查类、接口、字段和方法成为可能&#xff0c;而不需要在编译时知道类、方法等的名称。也可以使用反射来实例化新对象、调用方法和获取/设置字段值。 Java反射的功能相当强大&#xff0c;可以说是非常有用。例如&#xff…...

背包问题理解思路(01背包、完全背包、分组背包)

这两天把经典的三个背包问题看了一下&#xff0c;网上大多文章是以代码和公式为主&#xff0c;因为平时没刷过算法题所以理解起来花了些时间&#xff0c;固写一篇文章记录理解思路&#xff0c;本文不包含代码实现&#xff08;理解了思路代码实现应该是小问题&#xff0c;网上一…...

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 是什么&#xff1f;SqlSession 是对 Connection 的包装&#xff0c;简化对数据库操作。所以你获取到一个 SqlSession 就相当于获取到一个数据库连接&#xff0c;就可以对数据库进行操作。 SqlSession API 如下图示&#xff1a;…...

1. QSaveFile和QFile的简单使用

1. 说明 QSaveFile和QFile两个类都是用来操作文件的&#xff0c;区别在于QSaveFile在对文件进行写入时有一种保护机制&#xff0c;再写入出错时&#xff0c;不会对源文件中的内容进行操作。该类在执行写操作时&#xff0c;会先将内容写入到一个临时文件中&#xff0c;如果没有…...

工业4.0是如何优化垃圾处理行业的

如今&#xff0c;工业4.0正在影响着制造业和物流等行业&#xff0c;其发展潜力在未来还有望进一步扩大。一些全球领先的垃圾处理公司已经开始在水处理和废物回收等领域应用工业4.0。工业4.0的创新给这个领域带来了一些必要的改进。随着环境危机的加剧&#xff0c;垃圾处理行业面…...

vue 动画(transition)

一、 实现原理 在插入、更新、移除 DOM 元素时&#xff0c;在合适的时候给元素添加样式类名&#xff0c;配合 CSS 样式使用&#xff0c;实现动画效果。 通俗来讲&#xff0c;就是将要进行动画操作的 DOM 元素用 transition 标签包裹起来。在此html元素运动前&#xff0c;运动…...

Python 爬虫工程师面试经验分享,金三银四

&#x1f643; 作为一个 Python 爬虫工程师&#xff0c;我可以分享一些我在面试中的经验和建议。 首先一点是在面试中要表现自信、友好、乐于合作&#xff0c;同时对公司的业务和文化也要有一定的了解和兴趣&#xff0c;这些也是公司在招聘中看重的因素。 文章目录&#x1f55b…...

MySQL实战篇-MySQL 降配导致的实例宕机

问题描述 由于近期对服务器进行了降配&#xff0c;该mysql数据库会进行批量写入操作&#xff0c;直接导致实例宕机 查看错误日志: 2021-02-02T09:09:23.557505Z 0 [Note] InnoDB: page_cleaner: 1000ms intended loop took 16791ms. The settings might not be optimal. (fl…...

时隔多年,这次我终于把动态代理的源码翻了个地儿朝天

本文内容整理自 博学谷狂野架构师 动态代理简介 ​ Proxy模式是常用的设计模式&#xff0c;其特征是代理类与委托类有同样的接口&#xff0c;代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类&#xff0c;以及事后处理消息等。 用户可以更加结构图&#xff0…...

数据分析-深度学习 Tensorflow Day6

我们需要解决的问题&#xff1a;1&#xff1a; 什么是bp 神经网络&#xff1f;2&#xff1a;理解bp神经网络需要哪些数学知识&#xff1f;3&#xff1a;梯度下降的原理4: 激活函数5&#xff1a;bp的推导。1.什么是bp网络&#xff1f;引用百度知道回复&#xff1a;“我们最常用的…...

leaflet 设置多个marker,导出为一个geojson文件(066)

第066个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中使用L.marker设置多个markers, 通过数据重组,导出为geojson文件。 这里面 ayer instanceof L.Marker 是一个很重要的判断条件,可以灵活地去运用。 直接复制下面的 vue+openlayers源代码,操作2分钟即可…...

企业与第三方供应商合作时,会存在哪些安全风险?

随着现代社会的发展&#xff0c;企业供应链、产业供应链已日渐成熟。其中&#xff0c;供应商与企业的关系也由最初的纯粹买卖关系发展成了合作伙伴关系。在整个供应链体系中&#xff0c;供应商与其受众承担着供应链中环环相扣的责任&#xff0c;可以说&#xff0c;企业安全的薄…...

技术源自洛克希德·马丁,光场XR眼镜FYR解析

专注于医疗场景的一家XR眼镜厂商FYR&#xff08;全称&#xff1a;FYR Medical&#xff09;近期亮相&#xff0c;并宣布完成了260万美元A轮融资&#xff0c;本轮融资由NuVasive领投&#xff0c;资金将用于开发世界上第一个XR光场“放大镜”类产品。据青亭网了解&#xff0c;NuVa…...

剑指 Offer 10- II. 青蛙跳台阶问题(LeetCode 70. 爬楼梯)(动态规划打表)

题目&#xff1a; 链接&#xff1a;剑指 Offer 10- II. 青蛙跳台阶问题&#xff1b;LeetCode 70. 爬楼梯 难度&#xff1a;简单 相关博文&#xff1a;剑指 Offer 10- I. 斐波那契数列&#xff08;动态规划打表&#xff09; 一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上…...

seo网站推广优化/中文域名查询官网

2019独角兽企业重金招聘Python工程师标准>>> UDP是一种高速&#xff0c;无连接的数据交换方式&#xff0c;他的特点是&#xff0c;即使没有连接到&#xff08;也不许要连接&#xff09;接收方也可以封包发送&#xff0c;就像在一个多人使用的步话机环境中&#xff0…...

网站如何做质保系统/semicircle

异常描述 在对HDFS格式化&#xff0c;执行hadoop namenode -format命令时&#xff0c;出现未知的主机名的问题&#xff0c;异常信息如下所示&#xff1a; Java代码[shirdrnlocalhost bin]$ hadoop namenode -format 11/06/22 07:33:31 INFO namenode.NameNode: STARTUP_MSG: …...

好享管家安卓下载/广州seo代理

欢迎关注专栏&#xff1a;Java架构技术进阶。里面有大量batj面试题集锦&#xff0c;还有各种技术分享&#xff0c;如有好文章也欢迎投稿哦。 微信公众号&#xff1a;慕容千语的架构笔记。欢迎关注一起进步。 Spring Cloud微服务架构介绍 Spring Cloud的目标是为Spring开发人员提…...

阿里网站制作需要多少钱/谷歌竞价推广教程

单击服务和应用程序&#xff0c;右边的配置服务或应用程序选择分配给文件服务器的存储磁盘&#xff0c;GDNS自动生成A记录查看修改后台打印文件夹修改打印机服务器属性返回故障转移集群查看状态正常如下图主节点为PRT-02手动切换主节点部署集群打印机此处按正常打印机部署设置&…...

企业网站建设基本流程/重庆seo服务

1、禁止复制文本html页面增加<style>*{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;} </style>复制代码2、禁止img标签增加样式<img style"pointer-even…...

网站建设与管理策划书/搜索引擎优化需要多少钱

恩智浦半导体公司(NXP Semiconductors)推出了号称全世界体型最小、能耗最少的64位物联网ARM处理器&#xff0c;名为“QorIQ LS1012A”。 QorIQ LS1012A芯片拥有64位ARMv8处理器&#xff0c;配置网络包加速器&#xff0c;内置安全系统。这款芯片尺寸为9.6平方毫米&#xff0c;潜…...