`
BestUpon
  • 浏览: 284000 次
  • 性别: Icon_minigender_1
  • 来自: 兰州
社区版块
存档分类
最新评论

带参数 宏-使用括号将参数扩起来

C 
阅读更多

 

#define SQ(y) (y)*(y)
main(){
int a,sq;
printf("input a number: ");
scanf("%d",&a);
sq=SQ(a+1);
printf("sq=%d\n",sq);
}

 上例中第一行为宏定义,形参为y。程序第七行宏调用中实参为a+1,是一个表达式,在宏展开时,用a+1代换y,再用(y)*(y) 代换SQ,得到如下语句:

sq=(a+1)*(a+1);

这与函数的调用是不同的,函数调用时要把实参表达式的值求出来再赋予形参。而宏代换中对实参表达式不作计算直接地照原样代换。

 

#define SQ(y) y*y
main(){
int a,sq;
printf("input a number: ");
scanf("%d",&a);
sq=SQ(a+1);
printf("sq=%d\n",sq);
}

 运行结果为:

input a number:3

sq=7

同样输入3,但结果却是不一样的。问题在哪里呢? 这是由于代换只作符号代换而不作其它处理而造成的。宏代换后将得到以下语句:

sq=a+1*a+1;

由于a为3故sq的值为7。

 

 

#define SQ(y) (y)*(y)
main(){
int a,sq;
printf("input a number: ");
scanf("%d",&a);
sq=160/SQ(a+1);
printf("sq=%d\n",sq);
}

 本程序与前例相比,只把宏调用语句改为:

sq=160/SQ(a+1);
运行本程序如输入值仍为3时,希望结果为10。但实际运行的结果如下:
input a number:3
sq=160
为什么会得这样的结果呢?分析宏调用语句,在宏代换之后变为:
sq=160/(a+1)*(a+1);
a为3时,由于“/”和“*”运算符优先级和结合性相同,则先作160/(3+1)得40,再作40*(3+1)最后得160。为了得到正确答案应在宏定义中的整个字符串外加括号,程序修改如下:
#define SQ(y) ((y)*(y))
main(){
int a,sq;
printf("input a number: ");
scanf("%d",&a);
sq=160/SQ(a+1);
printf("sq=%d\n",sq);
}

或者
#define SQ(y) ((y)*(y))
main(){
int a,sq;
printf("input a number: ");
scanf("%d",&a);
sq=160/(SQ(a+1));
printf("sq=%d\n",sq);
}
 

 

分享到:
评论

相关推荐

    C++出错提示英汉对照表

    Macro argument syntax error -------------------宏参数语法错误 Macro expansion too long ----------------------宏的扩展以后太长 Mismatched number of parameters in definition ---------------------定义...

    常用C/C++预处理指令详解

    预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。...在带参数的宏定义,宏名和参数的括号间不能有空格。  宏定义不分配内存,变量定义分配内存。  宏展开不占运行时间,

    课件c语言 大学教材 很好的资源

    实验中熟悉了宏定义的使用、函数的声明,要注意宏定义中括号的使用,很容易丢掉了。在重复调用时,较小的函数可以用带参数的宏替换来提高程序的效率。 此外,通过实验还了解到自己的许多不足,还需多加练习编写...

    cmd操作命令和linux命令大全收集

    date /t 、 time /t 使用此参数即“DATE/T”、“TIME/T”将只显示当前日期和时间,而不必输入新日期和时间 set 指定环境变量名称=要指派给变量的字符 设置环境变量 set 显示当前所有的环境变量...

    make和Makefile详解 一起写Makefile

     如果在执行command命令时返回了一个非"0"的出错信号,例如makefile文件中出现了错误的目标文件名或者出现了以连字符打头的命令字符串,make操作一般会就此终止,但如果make后带有"-i"参数,则make将忽略此类出错...

    EditPlus 2整理信箱的工具

    【4】 正则表达式应用——替换带有半角括号的多行 【5】 正则表达式应用——删除空行----------------------------江德华 软件技巧类 ------------------------------------------------------ 【6】 软件技巧——...

    Editplus 3[1].0

    【4】 正则表达式应用——替换带有半角括号的多行 【5】 正则表达式应用——删除空行----------------------------江德华 软件技巧类 ------------------------------------------------------ 【6】 软件技巧——...

    (二)就业模拟测试题-LINUX应用开发工程师职位

    ) #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)2)懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。...

    2009 达内Unix学习笔记

    把前一命令的输出作为后一命令的输入,把几个命令连接起来。 |经常跟tee连用,tee 把内容保存到文档并显示出来。 三、通用后接命令符 -a 所有(all)。 -e 所有(every),比a更详细。 -f 取消保护。 -i 添加...

    Sublime-JS-Auto-Semicolon:添加数组或函数参数时,自动在行的末尾添加分号

    您将使用匿名函数(或命名的,因为这样也很好)作为参数。 Sublime可以有效地合上括号,但是您必须记住输入关键点并在末尾添加分号。 另一个用例 如果您的参数是对象或数组(基本上是括号内的任何块)也将起作用。 ...

    freemarker总结

    上面的代码中的逻辑表达式用括号括起来主要是因为里面有>符号,由于FreeMarker会将>符号当成标签的结束字符,可能导致程序出错,为了避免这种情况,我们应该在凡是出现这些符号的地方都使用括号. Pythons are ...

    图像处理的 相关资料

    带参数的宏和函数调用看起来有些相似。看一个例子: #define Cube(x) (x)*(x)*(x) 可以时任何数字表达式甚至函数调用来代替参数x。这里再次提醒大家注意括号的使用。宏展开后完全包含在一对括号中,而且参数也...

    C/C++常用预处理指令

    预处理是在编译之前的处理,而编译工作的任务之一是语法检查,预处理不做语法检查。预处理命令以符号“#”开头。  常用的预处理指令包括: ...在带参数的宏定义,宏名和参数的括号间不能有空格。  宏定义不分配内存

    编程修养,是关于写C程序的

    22、宏的使用 23、static 的使用 24、函数中的代码尺寸 25、typedef 的使用 26、为常量声明宏 27、不要为宏定义加分号 28、||和&&的语句执行顺序 29、尽量用for 而不是while 做循环 30、请sizeof ...

    sassy:受sas宏启发,用于文本插值的简单但功能强大的模板语言

    宏看起来很像一个函数,并且必须在括号内被赋予名称和参数列表(无参数时为空): %macro (, ...); 宏使用%exec标记执行,引用宏名称,并传递所需的参数(如果有) 运行时,宏将在其主体内插参数和标签,并输出...

    C C++ 编程修养

     22、宏的使用  23、static的使用  24、函数中的代码尺寸  25、typedef的使用  26、为常量声明宏  27、不要为宏定义加分号  28、||和&&的语句执行顺序  29、尽量用for而不是while做循环  30、请...

    浅谈内联函数与宏定义的区别详解

    2.编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数),而宏定义则不会; 3.内联函数可以访问类的成员变量,宏定义则不能; 4.在类中声明同时定义的成员函数,自动转化为内联函数。文章(一)内联...

    单片机C语言入门-以最为流行的80C51 单片机为例来学习单片机的C 语言编程技术

    mDelay 后面有一个小括号,小括号里有数据(1000),这个1000 被称之“参数”,用它 可以在一定范围内调整延时时间的长短,这里用1000 来要求延时时间为1000 毫秒,要做到 这一点,必须由我们自己编写的mDelay 那段...

    redmine_wiki_todos:允许您将简单的任务列表嵌入到 Redmine 的 wiki 的宏

    添加宏,允许您将带有可点击复选框的简单任务列表嵌入到 Redmine 的 wiki 安装 只需将redmine_wiki_todos文件夹放入 Redmine 的plugins文件夹并重新启动 Redmine。 用法 将这样的内容添加到您的 wiki 页面或问题描述...

    Excel-Tournament-Assistant:具有宏的Excel电子表格,用于将循环组阶段的锦标赛安排和组织到种子淘汰赛主要阶段中。 我的VBA代码混乱

    当拖延考试准备时,我开始使用自动Excel电子表格进行工作,该电子表格利用宏动态地生成锦标赛括号,用于我和我的朋友们在季节性的Super Smash Brothers锦标赛中聚会时的感受。 运行工作表 运行工作表需要您确保启用...

Global site tag (gtag.js) - Google Analytics