网站备案被拒,市场价格查询,做贷超网站 前期需要什么分析,毕设做系统好还是做网站好文章目录 在#define中使用参数参考资料 在#define中使用参数
在#define中使用参数可以创建外形和作用与函数类似的类函数宏。带有 参数的宏看上去很像函数#xff0c;因为这样的宏也使用圆括号。类函数宏定义的圆 括号中可以有一个或多个参数#xff0c;随后这些参数出现在替… 文章目录 在#define中使用参数参考资料 在#define中使用参数
在#define中使用参数可以创建外形和作用与函数类似的类函数宏。带有 参数的宏看上去很像函数因为这样的宏也使用圆括号。类函数宏定义的圆 括号中可以有一个或多个参数随后这些参数出现在替换体中如图所 示。
下面是一个类函数宏的示例
#define SQUARE(X) X*X在程序中可以这样用
z SQUARE(2);这看上去像函数调用但是它的行为和函数调用完全不同。程序示了类函数宏和另一个宏的用法。该示例中有一些陷阱请仔细阅读。
/* mac_arg.c -- 带参数的宏 */
#include stdio.h
#define SQUARE(X) X*X
#define PR(X) printf(The result is %d.\n, X)
int main(void)
{
int x 5;
int z;
printf(x %d\n, x);
z SQUARE(x);
printf(Evaluating SQUARE(x): );
PR(z);
z SQUARE(2);
printf(Evaluating SQUARE(2): );
PR(z);
printf(Evaluating SQUARE(x2): );
PR(SQUARE(x 2));
printf(Evaluating 100/SQUARE(2): );
PR(100 / SQUARE(2));
printf(x is %d.\n, x);
printf(Evaluating SQUARE(x): );
PR(SQUARE(x));
printf(After incrementing, x is %x.\n, x);
return 0;
}这里SQUARE 是宏标识符SQUARE(X)中的 X 是宏参数X * X 是替 换列表。程序清单 16.2 中出现SQUARE(X)的地方都会被X * X替换。这与前 面的示例不同使用该宏时既可以用X也可以用其他符号。宏定义中的 X由宏调用中的符号代替。因此SQUARE(2)替换为2 * 2X实际上起到参数 的作用。 然而稍后你将看到宏参数与函数参数不完全相同。下面是程序的输 出。注意有些内容可能与我们的预期不符。实际上你的编译器输出甚至与 下面的结果完全不同。
x 5
Evaluating SQUARE(x): The result is 25.
Evaluating SQUARE(2): The result is 4.
Evaluating SQUARE(x2): The result is 17.
Evaluating 100/SQUARE(2): The result is 100.
x is 5.
Evaluating SQUARE(x): The result is 42.
After incrementing, x is 7.前两行与预期相符但是接下来的结果有点奇怪。程序中设置x的值为 5你可能认为SQUARE(x2)应该是 7 * 7即 49。
但是输出的结果是 17这不是一个平方值导致这样结果的原因是我们前面提到过预处理器不做计算、不求值只替换字符序列。预处理器把出现x的地方都替换成x2。因此x * x变成了x2*x2。如果x为5那么该表达式的值为
52*52 5 10 2 17该例演示了函数调用和宏调用的重要区别。函数调用在程序运行时把参 数的值传递给函数。宏调用在编译之前把参数记号传递给程序。这两个不同 的过程发生在不同时期。是否可以修改宏定义让SQUARE(x2)得36 当然可以要多加几个圆括号
#define SQUARE(x) (x)*(x)现在SQUARE(x2)变成了(x2)*(x2)在替换字符串中使用圆括号就得 到符合预期的乘法运算。
但是这并未解决所有的问题。下面的输出行
100/SQUARE(2)将变成
100/2*2根据优先级规则从左往右对表达式求值 (100/2)2即502得100。把SQUARE(x)定义为下面的形式可以解决这种混乱
#define SQUARE(x) (x*x)这样修改定义后得100/(2*2)即100/4得25。 要处理前面的两种情况要这样定义
#define SQUARE(x) ((x)*(x))因此必要时要使用足够多的圆括号来确保运算和结合的正确顺序。
尽管如此这样做还是无法避免程序中最后一种情况的问题。 SQUARE(x)变成了x*x递增了两次x一次在乘法运算之前一次 在乘法运算之后
x*x 6*7 42由于标准并未对这类运算规定顺序所以有些编译器得 76。而有些编 译器可能在乘法运算之前已经递增了x所以77得49。在C标准中对该表 达式求值的这种情况称为未定义行为。无论哪种情况x的开始值都是5虽 然从代码上看只递增了一次但是x的最终值是7。 解决这个问题最简单的方法是避免用x 作为宏参数。一般而言不 要在宏中使用递增或递减运算符。但是x可作为函数参数因为编译器 会对x求值得5后再把5传递给函数。
参考资料
《C Primer Plus》