编译预处理指令

• #开头的是编译预处理指令

• 它们不是C语⾔的成分,但是C语⾔程序离不开它们  

• #define⽤来定义⼀个宏

#define

#define <名字> <值>
• 注意没有结尾的分号,因为不是C的语句
名字必须是⼀个单词,值可以是各种东⻄
• 在C语⾔的编译器开始编译之前,编译预处理程序(cpp)会把程序中的名字替换成值
• 完全的⽂本替换
• gcc —save-temps

如果⼀个宏的值中有其他的宏的名字,也是会被
替换的
如果⼀个宏的值超过⼀⾏,最后⼀⾏之前的⾏末
需要加\
• 宏的值后⾯出现的注释不会被当作宏的值的⼀部

没有值的宏

• #define _DEBUG
• 这类宏是⽤于条件编译的,后⾯有其他的编译预处理指令来检查这个宏是否已经被定义过了

预定义的宏

• __LINE__
• __FILE__
• __DATE__
• __TIME__
• __STDC__

错误定义的宏

• #define RADTODEG(x) (x * 57.29578)
• #define RADTODEG(x) (x) * 57.29578

带参数的宏的原则

• ⼀切都要括号
• 整个值要括号
• 参数出现的每个地⽅都要括号
• #define RADTODEG(x) ((x) * 57.29578)
• #define cube(x) ((x)*(x)*(x))
• 宏可以带参数

带参数的宏

• 可以带多个参数
• #define MIN(a,b) ((a)>(b)?(b):(a))
• 也可以组合(嵌套)使⽤其他宏

// 比如++i类似的自增运算符 属于是文本替换 所以在传参的时候,并没有执行一次自增运算。它只是像函数而且带参数的宏。

分号?

#define PRETTY_PRINT(msg) printf(msg);   //不要加分号,因为你在C代码中会习惯再加上一个分号的。
if (n < 10)
 PRETTY_PRINT("n is less than 10");
else
 PRETTY_PRINT("n is at least 10");

带参数的宏

• 在⼤型程序的代码中使⽤⾮常普遍
• 可以⾮常复杂,如“产⽣”函数
• 在#和##这两个运算符的帮助下
• 存在中⻄⽅⽂化差异
• 部分宏会被inline函数替代

其他编译预处理指令

• 条件编译
• error

C语言进阶——编译预处理指令的更多相关文章

  1. C语言简单编译预处理-笔记

    预处理指令 所谓预处理,是指,在编译之前对程序源码进行初步的转换,产生新的源代码提供给编译器.预处理时主要完成:包含其他源文件,定义宏,根据条件决定编译时是否包含某些代码(>防止重复包含某些文件 ...

  2. C语言系列之预处理指令、循环左移函数的使用(四)

    本章节将讲两个知识点 第一个知识点:常用的预处理指令 第二个知识点:循环左移右移函数 第一个知识点:预处理指令 一种预处理指令是#define,他把名字A定义为P0,当这个名字出现在源文件的任何地方时 ...

  3. 【C语言】15-预处理指令1-宏定义

    预处理指令简介 1.C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译 2 ...

  4. [C语言]进阶|程序结构

    ------------------------------------------------------------------------------------ 全局变量: // main.c ...

  5. c语言编译预处理和条件编译执行过程的理解

    在C语言的程序中可包括各种以符号#开头的编译指令,这些指令称为预处理命令.预处理命令属于C语言编译器,而不是C语言的组成部分.通过预处理命令可扩展C语言程序设计的环境. 一.预处理的工作方式 1.1. ...

  6. c语言学习之基础知识点介绍(九):预处理指令和多文件开发

    一:预处理指令 /* 预处理指令: 作用:在程序编译之前做一些操作. 预处理命令写法的共同特点:都是以#号开头. 文件包含指令:#include 是一个文件包含命令. 作用:把某个文件内的内容读取出来 ...

  7. C语言预处理指令的初步了解

    所谓预处理是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的工作.预处理是C语言的一个重要功能,它由预处理程序负责完成.当对一个源文件进行编译时,系统将自动引用预处理程序对源程序中的预处理部分 ...

  8. c语言的预处理指令分3种   1> 宏定义   2> 条件编译   3> 文件包含

    宏简介 1.C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译 所有的预处 ...

  9. C语言条件编译及编译预处理阶段(转)

    一.C语言由源代码生成的各阶段如下: C源程序->编译预处理->编译->优化程序->汇编程序->链接程序->可执行文件 其中 编译预处理阶段,读取c源程序,对其中的 ...

随机推荐

  1. js操作改变原数组的解决方法

    最近在开发的时候发现js中的循环操作会改变原数组,var一个变量承接也不行 甚至连map方法都会改变原数组,下面是解决方法 let a = ['a','b','c'] let b = [[2, 0, ...

  2. vue-learning:40 - Vuex - 第一篇:概念和基本使用

    vuex 第一篇 目录 vuex概念 state / mapState getter / mapGetter mutation / mapMutation action / mapAction mod ...

  3. Vasya and a Tree CodeForces - 1076E (线段树 + dfs)

    题面 Vasya has a tree consisting of n vertices with root in vertex 1. At first all vertices has 0 writ ...

  4. CF1209

    CF1209 A B 水题不管 C 因为要求最终整个序列是要单调的 所以我们就考虑枚举断点$x$ 之后把$<x$的数放到第一个集合 把$> x$的数放到第二个集合 至于$=x$的数 他能放 ...

  5. 看各类框架源码淘来的一些JavaScript技巧

    1. 创建定长的JavaScript数组,并赋空值: 出自VUE文档Render函数讲解 // 创建定长20的JavaScript数组,并把每个项的值设为null Array.apply(null, ...

  6. java_学生成绩管理系统

    //信1805-2 20183670 王云鹏 package student; import java.util.Scanner; public class ScoreManagement { sta ...

  7. 【一起学源码-微服务】Nexflix Eureka 源码十二:EurekaServer集群模式源码分析

    前言 前情回顾 上一讲看了Eureka 注册中心的自我保护机制,以及里面提到的bug问题. 哈哈 转眼间都2020年了,这个系列的文章从12.17 一直写到现在,也是不容易哈,每天持续不断学习,输出博 ...

  8. Verilog门级建模

    门级建模就是将逻辑电路图用HDL规定的文本语言表示出来,即调用Verilog语言中内置的基本门级元件描述逻辑图中的元件以及元件之间的连接关系. Verilog语言内置了12个基本门级元件模型,如下表所 ...

  9. 《图解机器学习-杉山将著》读书笔记---CH3

    CH3 最小二乘学习法 重点提炼 提出最小二乘学习法的缘故: 最小二乘学习法公式 对不同模型进行最小二乘法学习,得到最小二乘公式中的参数theta: 1.线性模型   代入3.1公式,对参数求偏导,偏 ...

  10. POJ 2456 Aggressive cows (二分)

    题目传送门 POJ 2456 Description Farmer John has built a new long barn, with N (2 <= N <= 100,000) s ...