1179:题目描述
从键盘输入三个字符,用空格隔开,使用带参宏定义1中SWAP,将三个字符按从大到小的顺序排序输出。
宏定义1:#define SWAP(a, b, t) { t=a; a=b; b=t; }
请尝试,如果用宏定义2中的SWAP,主函数需要如何修改才能得到正确结果?
宏定义2:#define SWAP(a, b, t) t=a; a=b; b=t;
输入三个字符,用空格隔开
输出占一行,包含三个字符,用空格隔开
答案:
#include<stdio.h>
#define SWAP(a,b,t) {t=a;a=b;b=t;}
int main()
{
char a[3];
int i,j,t;
for(i=0; i<3; i++)
{
scanf("%c",&a[i]);
if(a[i]==' ')
scanf("%c",&a[i]);
}
for(i=0; i<2; i++)
for(j=1; j<3; j++)
if(a[i]<a[j])
SWAP(a[i],a[j],t);
for(i=0; i<3; i++)
printf("%c ",a[i]);
return 0;
}
关于宏定义
简单说一下我的理解(看过一些资料后总结的,仅供参考)
简单理解为:宏定义分为无参宏定义和有参宏定义
注意:
——生效范围:从定义到文本结束
——宏定义名称一般大写,与变量区分(并非规定)
——宏定义不是c语句,不用分号结束(否则分号将被算入替换内容中),宏定义不被检查,如果有错误只能由编译程序在编译宏展开后的源程序发现
无参宏定义
#define 宏定义名称 宏定义替换内容
和定义全局变量相同,在之后使用宏名时自动替换为内容
例如:
#define PI 3.14
主函数:int main()与自己添加的调用函数都可以直接使用PI
此时PI可视为一个常数:3.14
当程序运行,遇到PI时,PI被替换内容所替换,值为3.14
ps:
1.PI已经为一个常数,再次赋值或者定义变量PI都不允许
2.宏定义不分类型,宏定义不属于c语句,因此PI不可被直接输出
有参宏定义
#define 宏名(实参表) 字符串(式子)
ps:
宏名和实参表之间不能加空格,否则计算机按照无参宏处理
宏定义实践操作:
【示例】
#include<stdio.h>
#define MM(x) x*x
int main()
{
int y;
y=MM(a);//遇到MM,调用有参宏,进行宏展开:MM,其中x=5,字符串(式子)替换MM,变为y=5*5
printf("%d",y);
}
注:替换只做符号替换,不做其他处理
#include<stdio.h>
#define MM(x) x*x
int main()
{
int y,a=9;
y=MM(a+1);//y=a+1*a+1 y=9+1*9+1
printf("%d",y);//y=19
}
为了避免上述情况,通常在参数两边加上括号
#include<stdio.h>
#define MM(x) (x)*(x)
int main()
{
int y,a=9;
y=MM(a+1);//y=(a+1)*(a+1) y=(9+1)*(9+1)
printf("%d",y);//y=100
}
对于复杂情况,还需要在宏定义外加上括号
不加括号
#include<stdio.h>
#define MM(x) (x)*(x)
int main()
{
int y,a=9;
y=200/MM(a+1);//y=200/(a+1)*(a+1) y=200/(9+1)*(9+1)
printf("%d",y);//y=200
}
加上括号
#include<stdio.h>
#define MM(x) ((x)*(x))
int main()
{
int y,a=9;
y=200/MM(a+1);//y=200/((a+1)*(a+1)) y=200/((9+1)*(9+1))
printf("%d",y);//y=2
}
当然,对于不加括号不会影响程序达到想要的效果时,可以不加
有参宏定义和调用函数类似,那么为什么不直接使用调用函数呢?
因为有参宏定义不分类型
以上述例子为示范,我写一个宏定义,可以实现所有数字(整数,浮点数,字符不行,不会自动转化ASCll码)的平方,而调用函数要考虑数据类型,宏定义可以实现通用函数功能,当然,宏定义的单个式子不能太长,会大幅的增加程序的长度。
补充:宏定义可多个调用
#include<stdio.h>
#define MM(a,b,c) a>b?GG(a,c):GG(b,c)
#define GG(x,y) x>y?x:y //与调用相同,上面的为实参,调用过来给形参x,y
int main()
{
int max,a,b,c,max2;
scanf("%d%d%d",&a,&b,&c);//读取三个数字
max=(a>b?a:b)>c?(a>b?a:b):c;//用条件语句判定最大值
printf("%d\n",max);
printf("%d",MM(a,b,c));//用有参宏常量判定最大值
/*a>b 成立 a>c?(a>b?a:b):c 成立 a>b?a:b 成立为a
不成立为b
不成立 为c
a>b 不成立 b>c?(a>b?a:b):c 成立 a>b?a:b 成立为a
不成立为b
不成立 为c
*/
}
调用函数与有参宏常量的区别:
调用有参函数时,先求出值,然后复制一份给形参
展开有参宏时,简单的置换形参
有参函数分类型,要求形参与实参类型一致
有参宏不分类型,可以实现通用函数功能
使用有参函数,不会使程序变长,但是会占用系统时间进行调用现场保护和现场恢复
使用有参宏,每引用1次,都会使目标程序变大1次,但是不会占用