C预处理器

一、明示常量: #define

#define预处理器指令和其他预处理器一样,以#号作为一行的开始。ANSI和后来的标准都允许#前面有空格或者制表符,二千还允许在# 和指令的其余部分有空格。旧版本的C 要求指令从一行最左边开始,而且#指令其余部分之间不能有空格。
指令可以出现在源文件的任何地方,其定义从指令出现的地方到改文件结尾有效。可以使用#define来定义明示常量(也叫符号常量)

 #include <stdio.h>

#define TWO 2	/* TWO 2 */
#define OW "I am \
chengxuy"

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

int main()
{
	int x = TWO;
	
	PX;
	x = FOUR;
	printf(FMT, x);
	printf("%s\n", OW);
	
	return 0;
}

在这里插入图片描述
每行#define(逻辑行)都有三部分组成。第一部分是#define 本身;第二部分是选定的缩写,也称为宏,有些宏代表值,这些宏被称为类对象宏,必须遵守C变量的命名规则;第三部分(指令行的其余部分)称为替换列表或替换体。一旦预处理器在程序找到宏的示实例后,就会用替换体代替该宏(有例外)。从宏变成最终替换文本的过程被称为宏展开。

1、重定义常量

假设先把LIMIT定义为20,稍后在改文件中又把它定义为25,这个过程称为重定义常量。

二、、在#define中使用参数

在#define中使用参数可以创建外形和作用域函数类似的类函数宏。带参数的宏看上去很像函数。类函数宏定义的圆括号中可以可以有一个或多个参数,随后这些参数出现在替换体中。

#include <stdio.h>

#define SQUARE(X) X*X
#define PR(X) printf("The result is %d.\n", X)

int main()
{
	int x = 5;
	int z = 0;
	
	printf("x=[%d], z=[%d]\n", x, z);
	z = SQUARE(x);
	
	printf("x=[%d], z=[%d]\n", x, z);
	PR(z);
	PR(x);

	return 0;
}

在这里插入图片描述

1、用宏参数创建字符串:#运算符

如果x是一个宏形参,那么#x就是转换为字符串“X”形参名,这个过程称为字符串化。
#include <stdio.h>

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

int main()
{
	int y = 5;

	PSQR(y);
	PSQR(2 + 4);
	
	
	return 0;
}

在这里插入图片描述

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

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

#define XNAME(n) x ## n 
#include <stdio.h>

#define XNAME(n) x ## n
#define PRINT_XN(n) printf("x " #n " = %d\n", x ## n); 

int main()
{
	
	int XNAME(1) = 14;;
	int XNAME(2) = 20;;
	int x3 = 20;
	PRINT_XN(1);
	PRINT_XN(2);
	PRINT_XN(3);
	
	return 0;
}

在这里插入图片描述

3、变参宏: … 和 _ _VA_ARGS_ _

一些函数接受数量可变的参数。stdvar.h提供了工具,让用户定义带可变参数的函数。
通过把宏参数列表最后的参数写成省略号(即三个点 …)来实现这一功能。预定义宏_ _VA_ARGS_ _可用在替换部分中,表示省略号代表什么。
#define pr(…) printf(_ _VA_ARGS_ _)

#include <stdio.h>
#include <math.h>

#define PR(X, ...) printf("Message " #X " : " __VA_ARGS__)

int main()
{
	double x = 48.0;
	double y = 9.0;
	
	PR(1, "x = %g\n", x);
	PR(2, "X = %.2f, y= %.4f\n", x, y);

	return 0;
}

在这里插入图片描述

三、文件包含:#include
四、其他指令
1、#undef指令

#undef指令用于取消已定义的#define指令。例如

#define LIMIT 400
#undef LIMIT 	// 移除上面的定义

即使原来没有定义LIMIT,取消LIMIT的定义仍然有效

2、条件编译

可以使用其他指令创建条件编译。可以使用这些指令告诉编译器根据编译时的条件执行或忽略信息(或代码块)、。
1、#ifdef、#else和#endif指令

#ifdef MAVIS
	#include "horse.h"	// 如果已经用#define定义了MAVIS,则执行下面的命令
	#define STABLES 5
#else
	#include "cow.h"	// 如果没有用#define定义了MAVIS,则执行下面的命令
	#define STABLES 5
#endif

2、#ifndef指令
#ifndef指令与ifdef指令的用法类似,也可以和#else、#endif一起使用。
#ifndef指令判断后面的标识符是否是未定义的。

3、预定义宏
含义
_ _DATE_ _预处理的日期("Mmm dd yyyy"形式的字符串字面量 ,如Nov 23 2013)
_ _FILE_ _表示当前源代码文件名的字符串字面量
_ _LINE_ _表示当前源代码文件中行号的整形常量
_ _STDC_ _设置为1是,表明遵循C标准
_ _STDC_HOSTED_ _本机环境设置为1,否则设置为0
_ _STDC_VERSION_ _支持C99标准,设置为199901L;支持C11标准,设置为201112L
_ _TIME_ _翻译代码时间,格式为“hh:mm :ss”
_ _func_ _代表函数名的字符串(是预定义标识符)
4、#pragma

#pragma把编译器指令放入源代码中。例如在开发C99时,标准被称为C9X,可以使用下面的编译指示让编译器支持C9X:

#pragma c9x on
5、内联函数
inline static void asd()
{
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值