引言:



学C语言之初。一提到预处理,脑子里想到的就是#define的宏定义以及#include包括的头文件。后来随着对C的深入学习发现。预处理不止这些。比方条件编译、提前定义的宏等等。以下对此进行总结。

先给出预处理的定义:在编译程序之前,先由预处理器检查程序(因此称为预处理器),依据程序中使用的预处理器命令,预处理器用符号缩略语所代表的内容替换程序中的缩略语。

1. #define

最经常使用的预处理器命令就是define命令,该预处理器命令有三部分组成:#define本身、符号缩略语、替换列表(或称为主体)。

结构可写为:#define 宏 主体        当中宏部分不能有空格,仅仅能是数字、下划线、字母。但第一个字符不能使数字。

如:#define PX printf("x is %d.\n", x)

预处理器发现程序中的宏后,会用它的等价替换文件取代宏。假设该字符串中还包含宏。则继续替换这些宏。假设宏出如今双引號中,则不做替换。

假设在双引號中出现的宏前面有“#运算符”,则能够用宏參数创建字符串。如:

#define PSQR(X) printf("The square of X is %d.\n", ((X)*(X)))

PSQR(8)   //等价于printf("The square of X is %d.\n", ((8)*(8)))。输出The square of X is 64.

#define PSQR(X) printf("The square of "#X" is %d.\n", ((X)*(X)))

PSQR(8)   //等价于printf("The square of8 is %d.\n", ((8)*(8))),输出The square of8 is 64.

       小结:引號中的字符中中的X被看作普通文本,而不是被看作一个可替换的语言符号。#符号用作一个预处理运算符,它能够把语言符号转化为字符串。

预处理器的粘合剂:##运算符。和上面的#运算符一样。##运算符能够用于类函数宏的替换部分。

##还能用于类对象宏的替换部分,把两个符号组合成单个语言符号,如:

#define XNAME(n) x##n

XNAME(4)  //等价于x4

从宏的定义和使用能够看出,它与函数很相近,但宏与函数又有所不同,他们的选择实际上是时间和空间的权衡。

宏产生内联代码,也就是说在程序中产生语句。

假设使用宏20次,则会把20行代码插入程序中。假设使用函数20次,那么程序中仅仅有一份函数的语句拷贝,因此节省了空间。

还有一方面。程序的控制必须转移到函数中并随后返回调用程序。因此这比内联代码话费的时间多。

2.#include

预处理器发现#include指令后,就会寻找后跟的文件名称并把这个文件的内容包括到当前文件里。被包括文件的文本将替换源码文件里的#include指令。就像把被保护文件里的所有内容键入到源文件里的这个特定位置一样。

#include <name.h>    // 文件放在尖括号里,搜索系统工作文件夹

#include “name.h”     // 文件名称放在双引號中,搜索当前工作文件夹

#include "/dir1/dir2/name.h" // 搜索/dir1/dir2文件夹

头文件里一般包括的内容有:明显常量、宏函数、函数声明、结构体模板定义、类型定义

3. 其它指令

#undef指令取消前面的#define定义。

#if #ifdef #ifndef #else #elif #endif指令可用于选择什么情况下编译哪些代码。#line指令用于重置行和文件信息,#error指令用于给出错误消息。#param指令用于想编译器发出指示

4. 提前定义的宏:

__DATE__ : 进行预处理的日期

__FILE__  :代码当前源码文件名称的字符串文字

__LINE__ :代表当前源码文件里的行号的整数常量

__STDC__ :设置为1时。表示该实现遵循C标准

__TIME__ : 源文件编译时间

【C语言天天练(二)】预处理的更多相关文章

  1. 【C语言天天练(二四)】内存分配

    引言: 对于C语言程序,了解它执行时在内存中是怎样分配的对于我们理解它的执行机制是很实用的.以下就总结一下C语言程序的一些内存分配知识. 一 一段C程序.编译连接后形成的可运行文件一般有代码段.数据段 ...

  2. 【C语言天天练(二一)】内联函数

            引言:调用函数时,一般会由于建立调用.传递參数.跳转到函数代码并返回等花费掉一些时间,C语言的解决的方法是使用类函数宏.在C99中,还提出了第二种方法:内联函数.         内联 ...

  3. 【C语言天天练(二)】statickeyword

    引言:                 statickeyword不仅能够修饰变量.并且能够修饰函数.了解它的使用方法,不仅对阅读别人的代码有帮助,也有助于自己写出更加健壮的程序. 使用方法:     ...

  4. 【C语言天天练(二二)】位操作

    C的位运算符 1.二进制反码或按位取反:~ ~(10011010) = (01100101). 假设val是一个unsigned char,~val不改名原来val的值. 2.位与:& 二进制 ...

  5. 【C语言天天练(十一)】深入理解指针

    引言:在C语言中.指针的地位是不言而喻的,要想非常好的掌握C语言,掌握指针是必须的,这也是C语言不同于其它语言的地方. (一)指针的指针 样例: int i; int *pi;/*把pi初始化为指向变 ...

  6. 【C语言天天练(二三)】errno变量

    引言: 在C编程中,errno是个必不可少的变量.特别是在网络编程中. 假设你没实用过errno,那仅仅能说明你的程序不够健壮. 为什么会使用errno呢?这是系统库设计中的一个无奈之举.他很多其它的 ...

  7. 【C语言天天练(九)】动态内存分配

    引言:数组的元素存储于内存中连续的位置上.当一个数组被声明时.它所须要的内存在编译时就被分配. 可是,我们能够使用动态内存分配在执行时为它分配内存. 一块内存的生命周期能够分为四个阶段:分配.初始化. ...

  8. 【C语言天天练(十五)】字符串输入函数fgets、gets和scanf

    引言:假设想把一个字符串读到程序中.必须首先预留存储字符串的空间.然后使用输入函数来获取这个字符串. 读取字符串输入的第一件事是建立一个空间以存放读入的字符串. char *name; scanf(& ...

  9. 【C语言天天练(三)】typedef具体解释

    引言: typedef能够看作type define的缩写,顾名思义就是类型定义,也就是说它仅仅是给已有的类型又一次定义了一个方便使用的别名.并没有产生新的数据类型. typedef与define的不 ...

随机推荐

  1. android源代码分析 android toast使用具体解释 toast自己定义

    在安卓开发过程中.toast使我们常常使用的一个类.当我们须要向用户传达一些信息,可是不须要和用户交互时,该方式就是一种十分恰当的途径. 我们习惯了这样使用toast:Toast.makeText(C ...

  2. Unable to locate package错误

    W: GPG error: http://nginx.org precise Release: The following signatures couldn't be verified becaus ...

  3. 点滴积累【C#】---序列化和反序列化

    序列化和反序列化效果图: 序列化和反序列化代码: 需要添加两个命名空间: using System.IO; using System.Runtime.Serialization.Formatters. ...

  4. Error: Could not find or load main class org.apache.flume.tools.GetJavaProperty

    问题: [root@master conf]# flume-ng version Error: Could not find or load main class org.apache.flume.t ...

  5. [sj系统] phabricator系统升级

    sj是公司产品bug管理 wiki一体化系统 ,很刁. 安装: http://www.cnblogs.com/chorulex/p/5381558.html 升级: https://phabricat ...

  6. HTTP Basic auth认证

    Basic 概述 Basic 认证是HTTP 中非常简单的认证方式,因为简单,所以不是很安全,不过仍然非常常用. 当一个客户端向一个需要认证的HTTP服务器进行数据请求时,如果之前没有认证过,HTTP ...

  7. 85. Insert Node in a Binary Search Tree【easy】

    Given a binary search tree and a new tree node, insert the node into the tree. You should keep the t ...

  8. python学习之os.walk()

    os.walk(top,topdown = True,onerror = None,followlinks = False) 参数 top -- 根目录下的每一个文件夹(包含它自己), 产生3-元组 ...

  9. 基于libmemcached,php扩展memcached的安装

    基于libmemcached,php扩展memcached的安装 张映 发表于 -- 分类目录: php 标签:libmemcached, memcached, php, 安装 一,为什么要装memc ...

  10. Qt pro文件语法

    在Qt下做开发的时候.pro文件就是工程的配置文件,虽然很多时候里面的选项是工具自动生成的,但是难免会需要手动修改的时候,下面就记录一下它的基本语法 #:在.pro文件中表示注释,注释当前行 TEMP ...