1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > C语言学习记录:宏定义:#define

C语言学习记录:宏定义:#define

时间:2023-07-13 19:22:32

相关推荐

C语言学习记录:宏定义:#define

C预处理器:在程序执行之前查看程序。根据程序中的预处理器指令,预处理器把符号缩写替换成其表示的内容。

预处理指令示例:

#define、#include、#ifdef、#else、#endif、#ifndef、#if、#elif、#line、#error、#pragma

ANSI和后来的标准都允许 # 前面有空格或者制表符,而且还允许在 # 和指令的其余部分之间有空格。

目录

#define

记号问题

类函数宏

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

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

变参宏:...和__VA_ARGS__

#define

程序示例:

以下定义都是被允许的!

#include <stdio.h>#define TWO 2#define OW "Consistency is the last refuge of the unimagina\tive. -Oscar Wilde"//反斜杠表示切换到下一行#define FOUR = TWO*TWO#define PX printf("X is %d.\n",x)#define FMT "X is %d.\n"int main(void){ int x = TWO;PX;x = FOUR;printf(FMT,x);printf("%s\n",OW);//这里输出的是代表的字符串!printf("TWO:OW\n"); //这里输出的是:TWO:OW,而不是其代表的字符串和数组!}

拿出一个逻辑行当例子说明:

#define TWO 2

#define是预处理器指令,TWO是选定的缩写,也成为2称为替换列表或替换体。

有些宏代表值,称为类对象宏(object-like macro),还有类函数宏(function-like macro)

在宏定义中,还可以包含其他宏。

记号问题

把宏的替换体看做是记号(token)型字符串,而不是字符型字符串。

#define FOUR 2*2

只有一个记号:2*2序列

#define SIX 2 * 3

这个宏定义有三个记号:2*3

假设编译器解释为字符型字符串,将用2 * 3替换 SIX 。即额外的空格是替换体的一部分。

编译器解释为记号型字符串,则用3个的记号2 * 3(分别由单个空格分隔)来替换 SIX 。

解释为字符型字符串:把空格视为替换体的一部分。解释为记号型字符串:把空格视为替换体中各记号的分隔符。

类函数宏

在 #define 中使用参数可以创建外形和作用与函数类似的类函数宏。参数称为宏参数。

例子:

#define SQUIRE(x) x*x#define SUM(x,y) x+y//调用sum = SUM(5,7);squire = SQUIRE(9);

但是,函数宏只是替换并不是真正的函数!

//列如SQUIRE(2+7)//理想中应该是 81 ,但是实际上是 23X = 100/SQUIRE(2)//理想中应该是 25 ,但是实际上是 100

为什么出现这种状况?实际上的计算过程:

SQUIRE(2+7) = 2+7*2+7 = 23

X =100/SQUIRE(2) = 100/2*2 = 100

编程时应注意

#define SQUIRE(x) ((x)*(x))

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

引入例子:

#define PSQR(X) printf("The squire of X is %d.\n",((x)*(x)));//使用宏:PSQR(9);//输出The squire of X is 81.\n

此时 "" 中的 X 被视作普通文本,而不是可替换的符号。

字符串化(stringizing)

#define PSQR(X) printf("The squire of " #X " is %d.\n",((X)*(X)));int main(void){int y = 5;PSQR(y);PSQR(2 + 4);return 0;}

此时的输出为:

The squire of y is 25.

The squire of 2 + 4 is 36.

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

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

such as:

#define XNAME(n) x ## nXNAME(4) //被编译器解释为x4

## 作为黏合剂的使用:

#define XNAME(n) x ## n#define PRINT(n) printf("X" #n " = %d\n",x ## n);int main(void){int XNAME(1) = 14; //解释为 int x1 = 14;int XNAME(2) = 20;int x3 = 30;PRINT(1); //解释为 printf("x1 = %d\n",x1);PRINT(2);PRINT(3);return 0;}

运行结果有:

x1 = 14

x2 = 20

x3 = 30

体会一下其中的含义吧 ~

变参宏:...和__VA_ARGS__

这个还是需要多考虑一下的!!

这个以前没注意过,读别人代码才发现有这么个东西,我真是沙雕了!

一些函数支持数量可变的参数。如printf() 。

用户可自定义带可变参数的函数,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(void){double x = 48;double y; //y没定义是乱数y = sqrt(x);PR(1,"x = %g\n",x);//printf("Message 1:x = %g\n",x);PR(2,"x= %.2f, y = %.4f\n",x,y);return 0;}

输出:

Message 1: x = 48

Message 2: x = 48.00, y = 6.9282

省略符号只能代替最后的宏参数!!!!

最后,宏名中不允许出现空格!!!在嵌套循环中使用宏定义的函数有助于提高效率,单词循环看不出来效果。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。