当前位置: 首页 > news >正文

【让你从0到1学会c语言】程序环境和预处理指令


作者:喜欢猫咪的的程序员

专栏:《C语言》

喜欢的话:世间因为少年的挺身而出,而更加瑰丽。                                  ——《人民日报》


目录

程序的翻译环境和执行环境:

4个过程的介绍:

 编译过程中各个阶段实现的事情:

预处理详解:

预定义符号:

#define :

 #define 定义标识符

#define 定义宏 

 宏的申明方式:

宏存在的一些问题: 

#define 替换规则

 #和##

宏和函数对比 

命名规定: 

#undef

 条件编译:

常见的条件编译指令:

文件包含

本地文件包含

库文件包含



程序的翻译环境和执行环境:

在ANSI C的任何一种实现中,存在两个不同的环境。

  • 第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。
  • 第2种是执行环境,它用于实际执行代码

编译一个C语言程序是一个多阶段的过程。从总体上看,这个过程可以分成四个独立的阶段。预处理、编译、汇编和连接

我们先来看看这4个过程的流程图:


4个过程的介绍:

1.一个文件经过编译器生成对应的目标文件

2.多个目标文件与链接库一起生成链接器,最终生成可执行程序。(编译过程)

 编译过程中各个阶段实现的事情:

我们先来了解一下编译过程中各个阶段的操作指令:

1. 预处理 选项 gcc -E test.c -o test.i
预处理完成之后就停下来,预处理之后产生的结果都放在test.i文件中。
2. 编译 选项 gcc -S test.c
编译完成之后就停下来,结果保存在test.s中。
3. 汇编 gcc -c test.c
汇编完成之后就停下来,结果保存在test.o中。

我们可以通过上述的各个指令来观察各个阶段。

下图是各个阶段会做的事情以及操作指令:


预处理详解:

预定义符号:

这些预定义符号都是语言内置的。

 以上预定义符号如何使用呢?

参考下图:


#define :

 #define 定义标识符

 语法:

#define name stuff

stuff 只要合法都可以,数字 字符串甚至是一串代码

 运用如下:


#define 定义宏 

 宏的申明方式:

#define name( parament-list ) stuff
其中的 parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中

注意:

参数列表的左括号必须与name紧邻。

如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。

如何运用如下:

 


宏存在的一些问题: 

注意:能加括号尽量加括号,避免出现歧义,造成错误。

避免出现下面这种情况:

 


  • #define 替换规则

 我们都知道 #define会替换,那他替换有什么原则吗?如下:


 #和##

  • 使用 # ,把一个宏参数变成对应的字符串。
  • ##可以把位于它两边的符号合成一个符号。它允许宏定义从分离的文本片段创建标识符。

注:这样的连接必须产生一个合法的标识符。否则其结果就是未定义的。

 


宏和函数对比 

宏的优点:

  • 宏通常被应用于执行简单的运算。
  • 宏比函数在程序的规模和速度方面更胜一筹。
  • 更为重要的是函数的参数必须声明为特定的类型。
    所以函数只能在类型合适的表达式上使用。反之这个宏怎可以适用于整形、长整型、浮点型等可以用于>来比较的类型。宏是类型无关的。

宏的缺点:

  • 每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。
  • 宏是没法调试的。
  • 宏由于类型无关,也就不够严谨。
  • 宏可能会带来运算符优先级的问题,导致程容易出现错

 


命名规定: 

  • 把宏名全部大写
  • 函数名不要全部大写

#undef

这条指令用于移除一个宏定义。


 条件编译:

常见的条件编译指令:


文件包含

本地文件包含

查找策略:先在源文件所在目录下查找,如果该头文件未找到,编译器就像查找库函数头文件一样在标

准位置查找头文件。

如果找不到就提示编译错误。

库文件包含

查找头文件直接去标准路径下去查找,如果找不到就提示编译错误


相关文章:

  • k8s pod使用sriov
  • 蓝桥杯ctf2024 部分wp
  • Spark-机器学习(7)分类学习之决策树
  • 【SpringBoot】00 Maven配置及创建项目
  • Vue Canvas图片水印的绘制 图片加水印
  • VBA技术资料MF146:发出多次Beep提示声
  • Stable-Diffusion ubuntu服务器部署,报错解决方法(小白教程)
  • 预测淡水质量
  • 系统架构设计文档模版
  • Python 光速入门课程
  • C语言标准库函数qsort( )——数据排序
  • 51单片机-(定时/计数器)
  • 什么是CMMI能力成熟度模型?企业为什么要做?
  • 嵌入式 Linux 入门(十、Linux 下的 C 编程)
  • 【附源码】计算机毕业设计SSM培训中心管理系统
  • S2B2C模式有何优势?S2B2C电商系统赋能皮革企业渠道,提升供应链管理效率
  • cdq分治 学习笔记
  • MES是生产成功的因素
  • 通过ssh远程登录linux的原理过程和配置免密登录
  • 软考:信息安全工程师4(系统安全)
  • Hadoop中的Yarn的Tool接口案例、Yarn 案例实操(四)
  • 【C++】STL——string(两万字详解)
  • 浅谈Linux下的redis攻击
  • 【C++】类和对象(中)(万字详解)
  • CockroachDB架构-存储层
  • 【DDR3 控制器设计】(1)MIG IP 核的详解与配置
  • 牛客网专项练习30天Pytnon篇第26天
  • 【Golang开发面经】得物(两轮技术面)
  • Linux vmalloc原理与实现
  • 李沐论文精读系列二:Vision Transformer、MAE、MoCo、Swin-Transformer(持续更新 )
  • 【我想找一份实习】算法篇
  • uniapp 微信小程序和H5的弹窗滚动穿透解决