1. 字符映射

  键盘有多种标准规格,例如常用的IBM 104键盘标准,然而不是所有键盘都能打出像#这样的符号,因此C语言的预处理引入了字符映射机制。如果程序员要求,预处理会按照约定对源代码中的字符进行映射处理,例如将一些扩展的三元字符转换为源代码字符(??=转换为#,??/转换为\等等)。字符映射是预处理的第一步。

2. 物理行的合并

  预处理器在连续读到反斜线符和换行符时会将这两个字符删除,从而将当前所在的物理行和下一个物理行合并为一个逻辑行,例如

  printf("That's wond\
erful!\n");

  等价于

  printf("That's wonderful!\n");

  在定义一些比较复杂的宏或字符串时使用这个方法可以方便换行阅读。物理行合并是预处理的第二步。

3. 注释的替换

  在第三步,预处理器将注释替换为一个空格字符。

4. 预处理指令

  预处理器会将所有以#开头,以换行符结束的字符串作为一条预处理指令,但这个规则不受反斜线符和换行符组合的影响,因此预处理指令可以用多个物理行表示。

  4.1 #define-basic

    #define指令可以实现字符串替换,其前后分为三个部分,分别是#define、宏、替换列表。宏可以分为类对象宏或类函数宏,宏的命名方式和变量标识符一样,可以由字母、数字、下划线组成但首字符不能是数字。如果宏中出现了圆括号,那么将作为类函数宏处理,否则认为是类对象宏。例如

#define PX printf("X is %d.\n",x)
#define PR(Z) printf("The result is %d.\n", Z) int main() {
int x=0;
PX;
PR(x);
return 0;
}

    预处理后的结果为

int main() {
int x=0;
printf("x is %d",x);
printf("The result is %d.\n",x);
return 0;
}

    宏可以被重定义,代码在前面使用#define定义了一个宏MACRO之后,可以在后面再使用#define更改MACRO的定义。

  4.2 #define-##、#、...、__VA_ARGS__

    ##可以实现类函数宏中标识符的粘合。例如定义#define INT(name) x##name,则INT(1)将转换为x1。之所以这样做是因为#define的文本替换是以标识符为单位的,如果直接定义#define INT(name) xname,由于xname与name不是同一个标识符,INT(1)将不能转换为x1。

    #可以实现标识符的字符串化,这个功能配合字符串的连接特性可以解决对字符串进行文本替换的问题。之所以这样做是因为#define不对字符串的内容进行文本替换。例如#define PSQR(X) printf("The square of X is %d.\n",((X)*(X)));则替换列表中的第一个X将不会被替换。解决的办法是写为#define PSQRprintf("The square of " "#X" " is %d.\n",((X)*(X)));,这里借助了字符串的可连接性。

    ...和__VA_ARGS__可以实现可变参数宏,例如定义#define PR(...) printf(__VA_ARGS__),则使用PR即可代替printf函数。注意...只能作为最后一个参数,#define FPR(X,...,Y) fprintf(X,__VA_ARGS__,Y)是错误的。

C语言: 预处理的更多相关文章

  1. 面试问题4:C语言预处理包括哪些

    问题描述:C语言 预处理包括哪些操作 C语言的三种预处理包括:宏定义(#define).文件包含(#include).条件编译(#if.#else.#endif). 对于宏定义的介绍: 宏定义必须写在 ...

  2. 不可或缺 Windows Native (4) - C 语言: 预处理命令,输入,输出

    [源码下载] 不可或缺 Windows Native (4) - C 语言: 预处理命令,输入,输出 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 预处理命令 输入 ...

  3. C语言预处理运算符

    转自C语言预处理运算符 预处理还需要运算符?有没有搞错? ^_^, 没有搞错,预处理是有运算符,而且还不止一个: #(单井号)    -- 字符串化运算符. ##(双井号 )-- 连接运算符 #@   ...

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

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

  5. C 语言入门第八章--C语言预处理命令

    例如:#include ,这种以#号开头的命令称为预处理命令. ===C语言宏定义(#define的用法)==== #define 叫做宏定义命令,它也是C语言预处理命令的一种.所谓宏定义,就是用一个 ...

  6. C语言预处理理论2

    C语言预处理理论1.头文件包含(1)#include <>和#include ""区别:<>专门用来包含系统提供的头文件(就是系统自带的,不是程序员自己写的 ...

  7. C语言预处理理论

    C语言预处理理论1.从源码到可执行文件的过程(1)源码.c->(编译)->elf可执行程序(2)源码.c->(编译)->目标文件.o->(链接)->elf可执行程序 ...

  8. C语言预处理编译链接各个阶段错误,分阶段的说一下

    C语言预处理编译链接各个阶段错误,分阶段的说一下 C语言预处理编译链接各个阶段错误,分阶段的说一下比如指针异常,数组下标越界什么的    我来答 1个回答 #热议# 你觉得这辈子有希望看到996消失 ...

  9. C语言 预处理三(条件编译--#if)

    //#if 条件编译 //一般用于产品各个版本的语言包 #include<stdio.h> #include<stdlib.h> //#都是预处理指令,条件表达式必须在预处理里 ...

  10. C语言 预处理二(宏定义--#define)

    //#define 宏定义(宏定义一般大写) //知识点一-->#define的作用域:从#define开始,从上往下,如果遇到#undef就到#undef处结束,如果没有就是作用于当前整个文件 ...

随机推荐

  1. yformater - chrome谷歌浏览器json格式化json高亮json解析插件

    yformater是一款chrome浏览器插件,用来格式化(高亮)服务端接口返回的json数据. 实际上小菜并不是第一个写这种插件的,但是现有的chrome json格式化插件实在是不太好用,索性小菜 ...

  2. CSharpGL(1)从最简单的例子开始使用CSharpGL

    CSharpGL(1)从最简单的例子开始使用CSharpGL 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo ...

  3. C语言 · 打印1-200之间的素数

    素数定义:除了1和本身再无其他整数可被其本身整除的数称为素数,也称质数. 举一例子打印出1-200之间所有的素数: #include<stdio.h> #include<math.h ...

  4. 《Entity Framework 6 Recipes》中文翻译系列 (41) ------ 第七章 使用对象服务之标识关系中使用依赖实体与异步查询保存

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-7  标识关系中使用依赖实体 问题 你想在标识关系中插入,更新和删除一个依赖实体 ...

  5. sleep和wait区别

    1. sleep和wait都是用来进行线程控制,他们最大本质的区别是: sleep()不释放同步锁,wait()释放同步锁.               sleep(milliseconds)可以用时 ...

  6. angularjs中的directive scope配置

    angularjs中的directive scope配置 定义directive其中重要的一环就是定义scope,scope有三种形式: 默认的scope,DOM元素上原有的scope scope: ...

  7. 【初恋】vue单页应用开发总结

    vue新人,没有高级技巧 本文主要总结了使用vue-cli脚手架安装开发环境,使用vue.js等进行单页应用开发所遇问题的总结. 技术栈: Vue v1.0.21, vue-resource v0.9 ...

  8. 创建第一个 local network(II)- 每天5分钟玩转 OpenStack(81)

    上一节通过 Web GUI 创建了 “first_local_net”,本节我们需要搞清楚底层网络结构有了哪些变化? 点击 “first_local_net” 链接,显示 network 的 subn ...

  9. 使用nginx解决跨域问题(flask为例)

    背景 我们单位的架构是在api和js之间架构一个中间层(python编写),以实现后端渲染,登录状态判定,跨域转发api等功能.但是这样一个中间会使前端工程师的工作量乘上两倍,原本js可以直接ajax ...

  10. C# PPT 为形状设置三维效果

    在PPT中,形状是非常重要的元素.3-D形状,立体多元,给人耳目一新的感觉.在幻灯片中添加3-D效果形状,必然会为PPT的整体效果增色不少.为形状设置三维格式时,可设置棱台,轮廓线,表面效果等. 本篇 ...