当前位置:网站首页>程序的编译
程序的编译
2022-07-25 18:09:00 【刀剑侠客】
程序环境及预处理
翻译环境和执行环境
ANSI C中存在两种环境
- 翻译环境:源代码转化为可执行的机器指令。
- 执行环境:实际执行代码。
编译+链接
程序的每一个源文件通过编译转化成目标代码(.obj)。
每个目标文件通过链接器之后,组合在一起,形成可执行程序。
编译:包括预编译,编译,汇编
预编译/预处理(.c->.i)
- 头文件的包含
- #define定义符号的替换
- 注释的删除
编译(.i->.s) C语言代码转换成汇编代码
- 语法分析
- 词法分析
- 语义分析
- 符号汇总
汇编(.s->.o) 汇编代码转换成二进制指令
- 形成符号表
链接 (.o+链接库->.exe)(linux环境下是.elf)
- 合并段表
- 符号表的合并和重定位
预定义有关知识
预定义符号
__FILE__ //源文件
__LINE__ //行号
__DATE__ //编译日期
__TIME__ //编译时间
__STDC__ //遵循ANSI C,值为1(gcc, clang)
#define定义的标识符
特点:不占用内存,是一个临时的符号,预编译之后这个符号就不存在了。
举例
语法形式:
#define name stuff
#define M 10
#define unsinged int size_t
#define FOR_CYCLE for(;;)
#define CASE break;case
//stuff过长,可以分行书写,除最后一行外,每行后面需要加续行符(\)
#define DEBUG_PRINT print("file:%s\tline:%d\t \ date:%s\ttime:%s\n", \ __FILE__, __LINE__, \ __DATE__, __TIME__)
#define定义的标识符的时候,最后最好不要加上;,因为我们一条语句是以分号结尾的,一般情况下,多加的分号会被当成空语句来处理;但是特殊情况下,会导致程序出错。
#define定义的宏
把参数替换到文本中区,这种实现方式称为宏。
声明方式
#define name(parament-list) stuff
这里需要注意的是
name必须要和左括号在一起,否则就变成了#define定义的标识符。为了保证运算是按照初设的意愿进行的,必须得在宏定义和宏定义表达式两边加上一对括号。
例如
#define SQUARE(x) ((x)*(x))
#define DOUBLE(x) ((x)+(x))
#define定义符号和宏涉及到的规则
- 调用宏时,先对参数进行检查,如果有
#define定义的符号,先被替换。 - 替换的文本插入到程序原来的文本位置;对宏,参数名被值所替代。
#和##
#的作用是把一个宏参数变成字符串
举例
#define PRINT(N) printf("the value of "#N" is %d\n", N)
##的作用是把两边的符号合成一个符号(链接的标识符必须合法)
举例
#define name(list1, list2) list1##list2
int main()
{
int Goforever = 10;
printf("%d\n", name(Go, forever));
return 0;
}
带有副作用的宏参数
变量进行前置++,--
后置++,-- 都会带有副作用
宏参数在定义的时候超过一个的时候,这时如果参数具有副作用,使用宏的时候就会很危险。
宏与函数相比的优缺点
优点:
- 宏不需要进行函数栈帧的创建和销毁以及带出返回值,所以宏的速度比函数更快。
- 因为宏没有类型检查,所以宏是与类型无关的。
- 宏的参数可以出现类型,函数不行。
缺点:
- 宏没有类型检查,因此不够严谨。
- 因为宏是在预编译的时候就完成好替换的,而调试是在运行期间才可以进行,故宏是没法调试的。
- 宏定义和宏定义的表达式两边如果不加上括号,可能会有运算符优先级的问题。
#undef
#undef用于移除一个宏定义。
#define M 10//宏定义
#undef M //移除宏定义
条件编译
条件编译是当满足我们设定的条件时进行编译,不满足条件的时候则放弃一条或者一组语句。
条件编译指令
1.
#if 常量表达式
...
#end if
2.多分支条件编译
#if 常量表达式
#elif 常量表达式
#else
#endif
3.判断是否被定义
#if defined(symbol)
#ifdef symbol
#if !defined(symbol)
#ifndef symbol
文件的包含
#include指令是用来告知预处理器在该指令出现的时候包含指定文件的内容。
替换方式:
预处理器首先删除这条指令,接着用相应的文件内容进行替换。
源文件被包含几次就被实际编译几次。
头文件的包含方式:
- 本地文件的包含
文件名放在""内,查找该文件的时候,首先是在源文件所在目录下查找,未找到的话,再到标准路径下查找。
#include "filename"
- 库文件的包含
文件名放在< >内,查找该文件的时候,只去标准路径下查找。
避免头文件的重复引用的方式
- 在每个头文件开头写上
#pragma once - 在每个头文件开头写上
#ifndef __TEST_H__
#define __TEST_H__
//头文件的包含
#endif
边栏推荐
- Itextpdf realizes the merging of multiple PDF files into one PDF document
- Kendryte K210 在freertos上的lcd屏幕的使用
- Three control methods of TestNG execution sequence
- 云流化和云桌面有什么关系
- Good news! Ruiyun technology was awarded the member unit of 5g integrated application special committee of "sailing on the sea"
- Keil5 "loading PDSC debug description failed for STMicroelectronics stm32hxxxxxxx" solution
- Bl602 development environment setup
- Oracle使用impdp导入报错:ORA-39001: 参数值无效 ORA-39000: 转储文件说明错误 ORA-39088: 文件名不能包含路径说明
- 二叉树的相关操作
- C语言 cJSON库的使用
猜你喜欢

MySQL 索引优化全攻略

RedisTemplate解决高并发下秒杀系统库存超卖方案 — Redis事务+乐观锁机制

越来越成熟的Rust,都应用了哪些场景呢?

Pan domain name configuration method

为什么数字化未来取决于3D实时渲染

Oracle导入出错:IMP-00038: 无法转换为环境字符集句柄
![Why is the index in [mysql] database implemented by b+ tree? Is hash table / red black tree /b tree feasible?](/img/1f/a2d50ec6bc97d52c1e7566a42e564b.png)
Why is the index in [mysql] database implemented by b+ tree? Is hash table / red black tree /b tree feasible?

Redistemplate solves the problem of oversold inventory in the seckill system with high speed - redis transaction + optimistic lock mechanism

imx6 RTL8189FTV移植

Cloud VR: the next step of virtual reality specialization
随机推荐
Lwip之内存与包缓冲管理
Mysql database common commands
Unity 贝塞尔曲线的创建
Why is the index in [mysql] database implemented by b+ tree? Is hash table / red black tree /b tree feasible?
简述Synchronized以及锁升级
排序还需要了解的信息以及链表
Redis source code and design analysis -- 18. Analysis of redis network connection Library
List conversion problem
Auditing相关注解
使用sqldeveloper连接mysql
「数字安全」警惕 NFT的七大骗局
Basic knowledge of software testing (mind mapping)
SQL optimizer parsing | youth training camp notes
ORB_SLAM3复现——上篇
Who is responsible for the problems of virtual idol endorsement products?
实时云渲染有哪些优势
图的相关操作
LeetCode 101. 对称二叉树 && 100. 相同的树 && 572. 另一棵树的子树
Idea integrates common functions of SVN code management
C语言 libcurl交叉编译