当前位置:网站首页>C语言程序的编译上
C语言程序的编译上
2022-07-26 23:31:00 【旧梦拾遗186】
作者:旧梦拾遗186
每日励志:
人的潜能是无限的,努力一把,才知自己真正的实力。因为树的方向,风决定。人的方向,自己决定。
前言:
今天小编带大家一起来认识c语言的底层逻辑编译及链接
目录
1. 程序的翻译环境和执行环境
第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。第2种是执行环境,它用于实际执行代码
2. 详解编译+链接
当我们写好代码,并进行变异和链接时,会弹出一个黑框框,在我们的项目目录下会生成 .exe 可执行文件,我们现在要了解的就是这个东西是怎么形成的。
2.1 翻译环境
我们大体上可以知道是,可执行文件是由编译、链接这两个部分组合产生。用文字阐述可以说:源文件(可以是多个)经过编译器编译产生目标文件,这些目标文件被送进链接库进行链接,从而产生可执行程序。
组成一个程序的每个源文件通过编译过程分别转换成目标代码(object code)。每个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。链接器同时也会引入标准C函数库中任何被该程序所用到的函数,而且它可以搜索程序员个人 的程序库,将其需要的函数也链接到程序中
2.2 编译本身也分为几个阶段:
我们需要注意一个点,编译器的编译过程不止编译这一个环节。 也就是说,编译本身也可以分为几个阶段。
因为 Visual Studio 这些编译器是一个集成开发环境,所以不方便展示各个部分的详细内容。但是在以后学习 Linux 的过程中,我们回过头来是一定可以观察的。这里我就用文字阐述。
1.在预编译阶段,编译器会将头文件的内容、define 定义的文本替换都写入 .i 文件当中,并且删除注释。也就是说,预编译产生的 .i 文件里面写的 C 语言代码,是包括头文件的所有 C 语言代码。
2.编译阶段,从这个阶段开始,就要逐渐让计算机硬件能够识别我们的代码。所以这个阶段就会把 C 语言代码翻译成汇编语言代码。比如说我们有 int max = 10; ,那么编译阶段就会把 int 看成类型生成对应的汇编指令,max 是变量名,生成对应的汇编语句, = 是赋值符号,同样也会生成汇编语句,等等……这些汇编代码存放在 .s 文件中。
3.汇编,这里就是生成目标文件的步骤。这个阶段会对汇编代码进行更加细化的拆分,生成最原始的机器指令,即二进制指令。这些指令会被放在 .obj 文件当中(Linux 环境下为 .o 文件),在 Linux 环境下可观察这些二进制指令,但我们的大脑会认为这些是乱码。
2.3 运行环境
程序执行的过程:1. 程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。2. 程序的执行便开始。接着便调用main函数。3. 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回 地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程 一直保留他们的值。4. 终止程序。正常终止main函数;也有可能是意外终止。
3. 预处理详解
3.1 预定义符号
__FILE__ //进行编译的源文件 __LINE__ //文件当前的行号 __DATE__ //文件被编译的日期 __TIME__ //文件被编译的时间 __STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义这些预定义符号都是语言内置的。
举个栗子:
#include<stdio.h> int main() { FILE* p; p = fopen("test.txt", "w"); if (p == NULL) { perror("open"); } //格式化输出 fprintf(p, "file:%s line:%d date:%s time:%s\n", __FILE__, __LINE__, __DATE__,__TIME__); fclose(p); p = NULL; return 0; }
3.2 #define
3.2.1 #define 定义标识符
语法:#define name stuff
#define MAX 1000 #define reg register //为 register这个关键字,创建一个简短的名字 #define do_forever for(;;) //用更形象的符号来替换一种实现 #define CASE break;case //在写case语句的时候自动把 break写上。 // 如果定义的 stuff过长,可以分成几行写,除了最后一行外,每行的后面都加一个反斜杠(续行符)。 #define DEBUG_PRINT printf("file:%s\tline:%d\t \ date:%s\ttime:%s\n" ,\ __FILE__,__LINE__ , \ __DATE__,__TIME__ )
提问:
在define定义标识符的时候,要不要在最后加上 ; ?
最好不要加;
比如:
#include<stdio.h> #define MAX 100; int main() { int n = 0; scanf("%d", &n); if (n > MAX) { n = MAX; } return 0; }需要注意的是,在我们定义标识符时,尽量不要在后面添加分号,因为在我们书写代码时会习惯自己加上分号,如果定义的标识符后有分号,可能会产生不易察觉的错误。
![]()
当然我们也可以使用这个功能来实现一些令人难以捉摸的骚操作,假设有一个程序员每次使用 swich 语句内的 case ,后面都要写 break,他觉得很麻烦,那么他便写出了这么一段代码:
#define CASE break;case #include <stdio.h> int main() { int n = 3; switch (n) { case 1: CASE 2 : CASE 3 : printf("hello world!\n"); CASE 4 : break; } return 0; }
边栏推荐
- As for the pit saved by serialized variables, the data added with indexer cannot be serialized
- 中断、信号、系统调用
- 蚂蚁京东新浪10位架构师424页佳作深入分布式缓存从原理到实践pdf
- Static routing experiment configuration
- go语言慢速入门——go运算符
- F8 catch traffic, F9 catch rabbits, f10turttle
- 关于序列化变量保存的坑,加了索引器的数据不能序列化
- Northeast Securities stock online account, is it safe to open an account on your mobile phone
- Hcip first day
- Sort the three integers from large to small (introduce various methods in detail)
猜你喜欢

无效的目标发行版:17 的解决办法

GoatGui邀你参加机器学习研讨班
![文章主要内容提取软件[基于NLP技术]](/img/1c/7c1b0e9bc9af62308f4124104f6110.png)
文章主要内容提取软件[基于NLP技术]
![[C language] relevant distinction between strlen and sizeof](/img/c0/c026818692a01c1867771434e90da8.png)
[C language] relevant distinction between strlen and sizeof

Witness that the "decoding 2022 strong star of China's network security" is about to set sail

Hcip OSPF interface network interface type experiment

图书馆和档案馆的职能

Multipoint bidirectional republication and routing strategy topology experiment

Full company mGRE and star topology mGRE

Solve prime numbers between 100 and 200
随机推荐
OSPF summary (mind map)
JS 数组去重(含简单数组去重、对象数组去重)
通过ensp让静态路由实现全网可达
【无标题】
swiperjs自定义宽度
After ten years of testing, I want to say to my friends who are still confused: one thing is to do a good job in personal planning
中断、信号、系统调用
Plato farm is expected to further expand its ecosystem through elephant swap
LeetCode->二分查找打卡(三)
在腾讯测试岗干了5年,7月无情被辞,想给还在划水的兄弟提个醒.....
Redis distributed lock implemented by annotation
Is it useful to lie down with your eyes closed when you can't sleep?
FormData的使用
[use SQLite3 library to realize student information management system in Visual Studio 2019]
Encyclopedia of websites commonly used by people who know current affairs
uni-app 微信小程序搜索关键字标红显示
Sort the three integers from large to small (introduce various methods in detail)
LeetCode刷题——NO.238——除自身以外数组的乘积
hcip--ospf接口网络接口类型实验
Plato Farm有望通过Elephant Swap,进一步向外拓展生态







