五分钟搞懂预处理和程序环境

有朋友问道:我们平常写的代码(源文件),是如何变成最后可执行程序的呢?

这就要讲到C中的翻译环境

在ANSI C(标准C)中规定,

test.c(源文件 也就是我们写的代码)会通过 翻译环境 变成test.exe(可执行程序)

  • 程序的翻译环境

翻译环境由 编译 ,汇编 ,链接 三个部分组成

接下来详细介绍下这些过程

  • 编译 

编译过程 由预编译(又称 预处理)和编译 组成

  • 预编译 

在这过程中 主要做的就是些 “文本操作”

1.头文件的包含 #include

2.注释的删除

3.#define符号的转换

  • 编译

到这一步 会将test.c源文件 转变成 (也就是生成该文件) test.s

里面全是些汇编代码 

把C语言代码转换成了汇编代码 并且还会做以下工作

1.语法分析

2.词法分析

3.语义分析

4.符号汇总   <—— 在链接中会使用

  • 汇编 

在汇编阶段 

1.把汇编指令转换成二进制指令

2.形成符号表

且生成 test.o //二进制文件 obj目标文件

  • 链接

在链接阶段

1.合并段表

2.符号表的合并和重定位 

由于有符号表的存在 函数可以跨文件使用

 如果有报错(无法解析外部符号)那就是在链接阶段出现的

最后生成 test.exe 可执行程序

  • 预处理详解 

预处理符号

在C语言中 我们有各种各样的预处理符号

__FILE__      //进行编译的源文件

__LINE__     //文件当前的行号

__DATE__    //文件被编译的日期

__TIME__    //文件被编译的时间

__STDC__    //如果编译器遵循ANSI C,其值为1,否则未定义

#define 定义标识符

语法 : #define    name    stuff 

在预处理阶段 这些都会直接替换

在C语言中 允许把参数替换到文本中 这种实现称为 “宏”

#define 定义宏

#define MAX(x,y)  (x > y ? x : y)//其实这种写法有问题 我等会说

#define 宏的替换规则 (在预处理阶段 完全替换)

这样的话 在执行速度上极大提升 但会出现一些异常情况

例如 :

#define SQUARE(x) x*x

int main()
{
    printf("%d",SQUARE(5)); // 5*5
    printf("%d",SQUARE(5+1)); // 5+1*5+1
    
    return 0;
}

宏不能处理这种特殊情况 容易出bug 建议宏使用在一些简单 计算量小的工作里

我们得对宏进行修改

#define SQUARE(x) ((x)*(x))

int main()
{
    printf("%d",SQUARE(5)); // 5*5
    printf("%d",SQUARE(5+1)); // ((5+1)*(5+1))
    
    return 0;
}

所以在前面的 MAX宏 你知道该怎么修改了吗 快动手试试吧

 #define MAX(x,y)  (x > y ? x : y)

除此之外 宏还不能出现递归字符串不能被替换 ;

  • 宏VS函数 

宏和函数的功能类似 所以是宏更好 还是函数更好呢?

通常什么情况下我们会使用 宏

1.调用函数和从函数返回的代码时间大于计算时间

2. 宏通常用于执行简单运算

3.函数的参数 必须给定一个确定的类型 而宏是与类型无关的 整型,浮点型,长整型都ok

宏的缺点

1.每次使用宏 都会插入程序 (直接替换)多次使用会变复杂

2.不方便 调试

3.由于与类型无关 所以不够严谨

4.宏可能会带来运算符优先级的问题

5.宏无法进行递归操作

条件编译

什么是条件编译 满足条件的编译 不满足条件的 不参加编译 

#ifdef        #endif 这两个是一对的 

#if defined(MAX)                          #ifdef MAX

//使用                                                        //使用

#endif                                                 #endif        这两个等价

条件编译有什么用吗  在<stdio.h>这种头文件中常用 在跨平台的设计中常用

 如何避免头文件重复包含 

1.#pragma once 

2.        #ifndef _TEST_H

           #define _TEST_H

           #endif

下面来考考大家 这些预处理指令 分别都是什么意思

#pragma once

#pragma pack

#pragma comment 

总结

以上就是关于 预处理和程序环境 的全部内容啦 喜欢的朋友 记得一键三连 你的点赞就是我创作的动力

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值