编译流程与预处理

简介: 编译流程与预处理

前言

之前在编码方向的学习都是在非常方便的编译器上进行的,直到一次gcc -v -o我才了解到编译器在我们写完代码之后做了非常多的事情,了解了这些之后也让我对之前很多的错误理解的更加通透,希望下面对编译器的介绍能给新手们一点指导(下面以c语言展开)


一、基本的编译步骤

cc1     .c -------> DNZ4.s                普通语言------编译(操作)------汇编语言

as       DNZ4.s-------->BW16.o        汇编语言-------汇编(操作)-------机器指令集

collect2       *.o(有好多)-------->  .exe        机器指令集--------链接 确定数据地址---------可执行文件

这三步里先阶段我们的错误大部分是在第一步,也就是语法错误,但随着学习的深入我们在第三步也是会出现错误的。

二、预编译

在编译器编译代码之前,类似printf这种关键字其实编译器是不认识的,这时候我们一般都是引用头文件去让编译器“学习”到这些关键字,预处理的符号就是#,就是在编译之前让编译器提前学习到一些关键字,这里分为头文件的预处理。

通过控制台对文件实现预处理之后,可以发现产生了一个 .i 的文件,文件里面已经用define定义的宏值替换代码里的宏名

我觉得非常变态的面试题:以下写法是否正确?

int define

一般关键字是不能拿来当变量名的,但是include,define这种必须要变成#define,#include才算是关键字,所以以上的写法是正确的!

以上的预处理指令新手平时见到的会非常多,下面的条件编译对于我这种非科班来说之前是未了解过的,但是在了解了这样的方法之后感觉真的是太方便了,有一种相见恨晚的感觉。

下面我们模拟一个场景,开发过程中我们为了调试,printf了很多数据来监测后台数据,但是产品发布的时候我们要尽量的缩小运行内存,不让这些printf执行,按照我之前的习惯就是一句一句把printf注销掉,但其实我们可以通过预处理很好的解决这个问题

这句话的意思是,如果我们定义过DEBUG那我们if判断成功,未定义过则进入else里的语句

这时候我们如果想检测后台数据,可以直接在代码上加一个#define DEBUG来触发if条件,不过这不是最好的方法(动了别人的代码),最好的办法是在编译上面做操作,这时候我们不要直接使用编译器给的默认的编译,cmd打开命令提示符面板,在编译语句前的--中间插入D加上你ifdefine后面的符号(D跟后面的符号是紧挨的),像如上我就应该写成 -DDEBUG -,如果这个.c文件叫a.c的话编译语句就是如下的。  


总结

了解编译器的编译流程能在以后解决问题的时候有更多的思路,也能对之前的问题有更好的理解,预处理的很多操作给我写项目的时候带来了极大的便利,慢慢了解自己使用的工具也是学习非常重要的一部分。

相关文章
|
3月前
|
存储 自然语言处理 程序员
程序环境和预处理(1)
程序环境和预处理(1)
33 0
|
4月前
|
存储 编译器 程序员
零基础也能学会的『程序环境和预处理』
零基础也能学会的『程序环境和预处理』
|
4月前
|
安全 C语言
程序预处理:全解版-1
程序预处理:全解版
31 0
|
4月前
|
编译器 C语言
程序预处理:全解版-2
程序预处理:全解版
29 0
|
4月前
|
存储 自然语言处理 编译器
程序环境和预处理(详解)
程序环境和预处理(详解)
|
存储 编译器 程序员
【C】程序环境和预处理
在ANSI C的任何一种实现中,存在两个不同的环境。
|
编译器 Linux C++
【程序环境与预处理】(二)
【程序环境与预处理】(二)
78 0
|
4月前
【程序环境与预处理玩转指南】(中)
【程序环境与预处理玩转指南】
|
4月前
|
存储 编译器 程序员
【程序环境与预处理玩转指南】(上)
【程序环境与预处理玩转指南】
|
9月前
|
Serverless
程序环境和预处理(二)
程序环境和预处理(二)