关于C语言参数化宏的问题?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于C语言参数化宏的问题?相关的知识,希望对你有一定的参考价值。

最后一个printf为什么运行出来是0.0. 函数实参那里为int ,我-3.5强制转换为整型难道不为-3吗?
求大神详解! 明天考试啦 谢谢谢谢!

int myAbs();返回值为整形,不能用float输出。
宏没有类型,只是在编译时,替换。运行时不存在宏

追问

那请问 平常情况下 整型数值用%f去输出的话会出现什么后果?
运行时会输出一个随机值吗?

参考技术A

这个和int和float 数值类型的存储方式有关;

输入-3.5 后,float 会自动转化为int ,通过myAbs(-3)宏运算得到的数值为3;

int 在内存中存储为:0B 010;

输出的时候,格式指定为float;

float 的存储格式  :

浮点数存储方式

当作float 处理时,传入一个int,相当于只提供了这个float的低4字节,而接下来的四个字节刚好是main保存寄存器的位置,一般来说刚好是0,就拼凑出了0x00000000xxxxxxxx的形态。所以printf会打印出0.0

参考技术B 用%d格式输出追问

和这个格式控制符没关系吧。
myAbs(-3.5)这个自定义函数的返回值是多少?
能详细解释下您的回答么?

追答

既然返回值是整数,那就应用%d输出他吧

追问

那请问 平常情况下 整型数值用%f去输出的话会出现什么后果?
运行时会输出一个随机值吗?

追答

我也不清楚,你试一下

本回答被提问者采纳

C语言中带参数的宏

带参数的宏定义有如下的格式:

【#define 指令----带参数的宏】 #define 标识符(x1,x2,……,xn)

其中  x1,x2,……xn是标志符(宏的参数)

注意:在宏的名字和括号之间必修没有空格。

如果有空格,预处理会认为是在定义一个简单的宏,其中(x1,x2,……,xn)是替换列表的一部分

当预处理器遇到一个带参数的宏,会将定义存储起来以便以后使用。在后面的程序中,如果任何地方出现了标识符(y1,y2……,yn)格式的宏调用(其中y1,y2, ……yn是一些列标记),预处理器会使用替换列表替代,并使用yi替换xi

e.g. 假如我们定义了如下的宏:

#define MAX(x,y)  ((x)>(y) ? (x) : (y))

#define IS_EVEN(n)  ((n)%2==0)

下面的例子是一个更加复杂的宏:

#define TOUPPER(c)  (\'a\'<=(c) && (c)<=\'z\' ? (c)-\'a\'+\'A\' : (c))

带参数的宏可以包含空的参数列表,如下所示:

#define getchar() getc(stdin)

空的参数列表不是一定确实需要,但可以使getchar更像一个函数

使用带参数的宏替代实际的函数有两个优点:

  • 程序可能会稍微快些。一个函数调用在执行时通常会有些额外开销----存储上下文信息、复制参数的值等。而一个宏的调用则没有这些运行开销
  • 宏会更“通用”。与函数的参数不同,宏的参数没有类型。因此,只要预处理后的程序依然合法的,宏可以接受任何类型的参数。 e.g.我们可以使用MAX宏从两个数中选出较大的一个,数的类型可以是:int,long int,float,double等等
  • 编译后的代码通常会变大。每一处宏调用都会导致插入宏的替换列表,由此导致程序源代码增加(因此编译后的代码变大)。宏使用得越频繁,这种效果就越明显。当宏调用嵌套时,这个问题会相互叠加从而使程序更加复杂。e.g. n=MAX(i,MAX(j,k));

下面是预处理后的这条语句:      

n=((i)>(((j)>(k)?(j):(k)))?(i):(((j)>(k)?(j):(k))));

 

  • 宏参数没有类型检查。
  • 无法用一个指针来指向一个宏
  • 宏可能会不止一次地计算它的参数。函数对它的参数只会计算一次,而宏可能会计算两次甚至更多。如果参数有副作用,多次计算参数的值可能会产生意外的结果

考虑下面的例子,其中MAX的一个参数有副作用:

n=MAX(i++, j)

下面是这条语句在预处理之后的结果:

n=((i++) >(j)?(i++):(j));

带参数的宏不仅适用于模拟函数的调用,他们特别经常被作为模板,来处理我们经常要重复书写代码段:

e.g.我们可以使用

#define PRINT_INT(x)  printf("%d\\n",x);

使得PRINT_INT(x)代替每次使用的printf("%d\\n",x);

 

转自http://www.cnblogs.com/cpoint/p/3367386.html

以上是关于关于C语言参数化宏的问题?的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp CPP的字符串化宏示例

高分求助VC中关于不定参数宏的使用

C语言宏定义字符串参数要把参数转化成字符串再加引号才是参数么? #define PRINT(FOR

C语——宏小结

如何使用一个宏的值作为参数传递给另一个宏?

C语言宏的神奇写法:语句块作为参数,算半个函数式编程?