当前位置:网站首页>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; }
边栏推荐
- 【在Visual Studio 2019中使用SQLite3库实现学生信息管理系统】
- OSPF summary (mind map)
- 【降维打击,带你深度学习CPU(上)】
- go语言慢速入门——包
- 信息收集-端口扫描工具-Nmap使用说明
- 在腾讯测试岗干了5年,7月无情被辞,想给还在划水的兄弟提个醒.....
- Hcip day 6 OSPF static experiment
- [draw rectangular coordinate system in C language]
- Make static routing accessible to the whole network through ENSP
- As for the pit saved by serialized variables, the data added with indexer cannot be serialized
猜你喜欢

F8 catch traffic, F9 catch rabbits, f10turttle

聊聊自动化测试的度量指标

f8抓交通、f9抓兔子、f10turtle

BigDecimal 的 4 个坑,你踩过几个?

多线程的具体使用

【用C语言绘制谢尔宾斯基三角形】

图书馆和档案馆的职能

Risc-v tool chain compilation notes

Area optimization of digital chips: detailed explanation of question 1 in the digital direction of the third "Huawei Cup" graduate innovation core competition
![[draw sherpinski triangle in C language]](/img/e6/9d1d088d1c7675c23725443000329b.png)
[draw sherpinski triangle in C language]
随机推荐
Encyclopedia of websites commonly used by people who know current affairs
Solve prime numbers between 100 and 200
信息收集-端口扫描工具-Nmap使用说明
面试必问 | 一个线程从创建到消亡要经历哪些阶段?
[brother Yang takes you to play with the linear table (III) - two way linked list]
【Redis】快速入门
东北证券股票网上开户,手机上开户安全吗
Greenplum【部署 08】数据库小版本升级流程及问题处理 Error: open-source-greenplum-db-6 conflicts with
go语言慢速入门——包
Go language slow start -- go operator
项目时区问题解决
[Fibonacci sequence and spiral are based on C language]
LeetCode->二分查找打卡(三)
Plato Farm有望通过Elephant Swap,进一步向外拓展生态
BigDecimal 的 4 个坑,你踩过几个?
砺夏行动|源启数字化:既有模式,还是开源创新?
创业3年,现在鹅厂,年收入百万+,作为软件测试前辈的一些建议....
Prometheus operation and maintenance tool promtool (III) debug function
[C language] relevant distinction between strlen and sizeof
平成千字文(へいせいせんじもん) (平成12年9月10日 石渡 明 作) 宇宙広遠 銀河永久 日月運行 不乱無休 地球公転 季節変移 黄道星座 太陽年周 故郷群島 南熱北冷 海洋温暖 気候順良 青空飛雲 諸野深緑 湖泉静息 谷川清流 春桜一面 新芽







