指令

C预处理器在程序执行之前查看程序(故称为预处理器),根据程序中的预处理器指令,预处理器把符号缩写替换成其表示的内容。预处理器可以包含程序所需的其他文件,可以选择让编译器查看哪些代码。预处理并不知道C,基本上它的工作是把一些文本转换成另外一些文本。这样描述预处理器无法体现它的真正效用和价值。

#define

#define指令来定义明示常量(manifest constant,也叫符号常量),但是指令还有许多其他用途。

#define TWO 2
#define PX printf("X is %d.\n", x)

程序有以下代码

int x = TWO;

PX;

分析具体过程
x = TWO则是变成x = 2
而PX则是变成printf("X is %d.\n", x),则会打印

X is 2.

看看下面分析

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

分三部分:

  • 第1部分是#define指令本身;
  • 第2部分是选定的缩写,像本指令行的PX,也称为宏,这些宏被称为类对象宏(object-like macro)。
  • 第3部分称为替换列表或替换休,像printf("X is %d.\n", x),一旦预处理器在程序中找到宏的示实例后,就会用替换体代替该宏。从宏变成最终替换文本的过程称为宏展开。

预处理器黏合剂: ##运算符

与#运算符类似,##运算符可用于类函数宏的替换部分,而且,##还可用于对象宏的替换部分,##运算符把两个记号组合成一个记号,比如:

#define XNAME(n) x ## n

然后,宏XNAME(4)将展开为x4。

typedef

typedef声明,简称typedef,为现有类型创建一个新的名字,比如:

struct mystruct {
    int id  
};

我们在定义一个结构变量时,可以这样

struct mystruct myvar;

其实可以更简单点,使用typedef关键字,

typedef struct mystruct {
    int id
} yourstruct;

这样就是为结构体类型struct mystruct {...} 声称一个别名类型,并没有创建一个新类型,只是为原来的结构类型声明一种别名yourstruct,以后再想定义一个结构变量,可以这样:

yourstruct yourvar;

文件包含: #include

预处理器发现#include指令时,会查看后面的文件名,并把文件的内容包含到当前文件中,即替换源文件中的#include指令。

指令#undef

#undef指令用于“取消”已定义的#define指令

条件编译

可以使用其他指令创建条件编译(conditional compilation)。也就是说,可以使用这些指令告诉编译器根据编译时的条件执行或忽略信息(或代码)块。

1.#ifdef、#else和#endif指令

看看条件编译的例子:

#ifdef MAVIS
    #include "horse.h"
    #define STABLES 5
#else
    #include "cow.h"
    #define STABLES 1
#endif

看上面,根据常量MAVIS是否定义了,则包含不同的头文件、定义常量STABLES不同的值。
这里的例子是新的编译器和ANSI标准支持的缩进格式,旧的编译器,必须左对齐所有的指令或至少左对齐#号。

2.#ifndef指令

#ifndef指令与#ifdef指令的用法类似,也可以和#else,#endif一直使用,但是它们的逻辑相反。#ifndef指令判断后面的标识符是否未定义的,常用于定义之前未定义的常量。

#ifndef SIZE
    #define SIZE 100
#endif

3.#if和#elif指令

#if指令很像C语言中的if。#if后面跟整形常量表达式,如果表达式为非零,则表达式为真,如:

#if SYS == 1
    #include "limpc.h"
#elif SYS == 2
    #include "vax.h"
#else
    #include "general.h"
#endif

当然也可以判断是否定义了常量:

#if defined (VAX)

即使用#if defined (VAX)代替#ifdef VAX

4.#line和#error

#line指令重置LINEFILE宏报告的行号和文件名。

#line 1000               // 把当前行号重置为1000
#line 10 "cool.c"        // 把行号重置为10,把文件名重置为cool.c

#error指令让预处理器发出一条错误消息,该消息包含指令中的文本,如果可能的话,编译过程应该中断,像这样:

#if __STDC_VERSION__ != 20L
#error Not C11
#endif

5.#pragma

现在编译器中,可以通过命令行参数修改编译器的一些设置。#pragma把编译器指令放话源代码中。
例如,在开发C99时,标准被称为C9X,可以使用下面的编译指示(pragma)让编译器支持C9X:

#pragma c9x on

泛型

..

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,490评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,581评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,830评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,957评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,974评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,754评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,464评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,847评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,995评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,137评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,819评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,482评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,023评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,149评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,409评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,086评论 2 355

推荐阅读更多精彩内容