mysql宏参数_C语言带参数的宏定义

C语言允许宏带有参数。在宏定义中的参数称为“形式参数”,在宏调用中的参数称为“实际参数”,这点和函数有些类似。

对带参数的宏,在展开过程中不仅要进行字符串替换,还要用实参去替换形参。

带参宏定义的一般形式为:

#define 宏名(形参列表) 字符串

在字符串中可以含有各个形参。

带参宏调用的一般形式为:

宏名(实参列表);

例如:

#define M(y) y*y+3*y //宏定义

// TODO:

k=M(5); //宏调用

在宏展开时,用实参 5 去代替形参 y,经预处理程序展开后的语句为k=5*5+3*5。

【示例】输出两个数中较大的数。

#include

#define MAX(a,b) (a>b) ? a : b

int main(){

int x , y, max;

printf("input two numbers: ");

scanf("%d %d", &x, &y);

max = MAX(x, y);

printf("max=%d\n", max);

return 0;

}

运行结果:

input two numbers: 10 20

max=20

程序第 2 行定义了一个带参数的宏,用宏名MAX表示条件表达式(a>b) ? a : b,形参 a、b 均出现在条件表达式中。程序第 7 行max = MAX(x, y)为宏调用,实参 x、y 将用来代替形参 a、b。宏展开后该语句为:

max=(x>y) ? x : y;

对带参宏定义的说明

1) 带参宏定义中,形参之间可以出现空格,但是宏名和形参列表之间不能有空格出现。例如把:

#define MAX(a,b) (a>b)?a:b

写为:

#define MAX (a,b) (a>b)?a:b

将被认为是无参宏定义,宏名 MAX 代表字符串(a,b) (a>b)?a:b。宏展开时,宏调用语句:

max = MAX(x,y);

将变为:

max = (a,b)(a>b)?a:b(x,y);

这显然是错误的。

2) 在带参宏定义中,不会为形式参数分配内存,因此不必指明数据类型。而在宏调用中,实参包含了具体的数据,要用它们去替换形参,因此实参必须要指明数据类型。

这一点和函数是不同的:在函数中,形参和实参是两个不同的变量,都有自己的作用域,调用时要把实参的值传递给形参;而在带参数的宏中,只是符号的替换,不存在值传递的问题。

【示例】输入 n,输出 (n+1)^2 的值。

#include

#define SQ(y) (y)*(y)

int main(){

int a, sq;

printf("input a number: ");

scanf("%d", &a);

sq = SQ(a+1);

printf("sq=%d\n", sq);

return 0;

}

运行结果:

input a number: 9

sq=100

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

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

这与函数的调用是不同的,函数调用时要把实参表达式的值求出来再传递给形参,而宏展开中对实参表达式不作计算,直接按照原样替换。

3) 在宏定义中,字符串内的形参通常要用括号括起来以避免出错。例如上面的宏定义中 (y)*(y) 表达式的 y 都用括号括起来,因此结果是正确的。如果去掉括号,把程序改为以下形式:

#include

#define SQ(y) y*y

int main(){

int a, sq;

printf("input a number: ");

scanf("%d", &a);

sq = SQ(a+1);

printf("sq=%d\n", sq);

return 0;

}

运行结果为:

input a number: 9

sq=19

同样输入 9,但结果却是不一样的。问题在哪里呢?这是由于宏展开只是简单的符号替换的过程,没有任何其它的处理。宏替换后将得到以下语句:

sq=a+1*a+1;

由于 a 为 9,故 sq 的值为 19。这显然与题意相违,因此参数两边的括号是不能少的。即使在参数两边加括号还是不够的,请看下面程序:

#include

#define SQ(y) (y)*(y)

int main(){

int a,sq;

printf("input a number: ");

scanf("%d", &a);

sq = 200 / SQ(a+1);

printf("sq=%d\n", sq);

return 0;

}

与前面的代码相比,只是把宏调用语句改为:

sq = 200/SQ(a+1);

运行程序后,如果仍然输入 9,那么我们希望的结果为 2。但实际情况并非如此:

input a number: 9

sq=200

为什么会得这样的结果呢?分析宏调用语句,在宏展开之后变为:

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

a 为 9 时,由于“/”和“*”运算符优先级和结合性相同,所以先计算 200/(9+1),结果为 20,再计算 20*(9+1),最后得到 200。

为了得到正确答案,应该在宏定义中的整个字符串外加括号:

#include

#define SQ(y) ((y)*(y))

int main(){

int a,sq;

printf("input a number: ");

scanf("%d", &a);

sq = 200 / SQ(a+1);

printf("sq=%d\n", sq);

return 0;

}

由此可见,对于带参宏定义不仅要在参数两侧加括号,还应该在整个字符串外加括号。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/453660.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自定义过滤器

首先在web.xml中对过滤器的监听 1 <!-- 自定义过滤器 -->2 <filter>3 <filter-name>AscFilter</filter-name>4 <filter-class>com.llh.filter.AscFilter</filter-class>5 </filter>6 <filter-mapping>7 …

[MS Sql Server术语解释]预读,逻辑读,物理读

在MSSQL中使用 SET STATISTICS IO ON 打开IO统计功能之后&#xff0c;每次执行完一个查询就会在下面的【消息】面板中显示本次查询IO的统计信息。 (0 行受影响) 表 demo。扫描计数 1&#xff0c;逻辑读取 622 次&#xff0c;物理读取 0 次&#xff0c;预读 0 次&#xff0c;lob…

mysql 数据库查询测试_MySQL查询测试经验

测试表geoinfo,整个表超过1100万行&#xff0c;表结构&#xff1a;CREATE TABLEgeoinfo (objectidint(11) NOT NULLAUTO_INCREMENT ,latitudedouble NOT NULL,longitudedouble NOT NULL,occupancybit(1) NOT NULL,timedatetime NOT NULL,cabidvarchar(16) NOT NULL,PRIMARY KEY…

更改阿里云域名解析台里某个域名绑定的IP之后不能解析到新IP

1.由于要撤销一组负载均衡&#xff0c;所以需要更改阿里云域名解析台里某个域名由原来绑定的负载均衡公网IP换到服务器公网IP 2.在服务器上nginx指定了域名访问&#xff0c;开启nginx服务 3.暂时关闭该组负载均衡服务 4.实现通过服务器IP可以访问项目&#xff0c;域名访问不了 …

秒懂数据类型的真谛—Python基础前传(4)

一切编程语言都是人设计的&#xff0c;既然是人设计的&#xff0c;那么设计各种功能的时候就一定会有它的道理&#xff0c;那么设计数据类型的用意是什么呢&#xff1f; (一) 基本数据类型 基本数据类型&#xff1a; 数字 int字符串 str布尔值 bool列表 list元组 tuple字典 dic…

Linux 系统命令及其使用详解(大全)

Linux 系统命令及其使用详解(大全) (来源: 中国系统分析员) cat cd   chmod chown   cp cut   名称&#xff1a;cat   使用权限&#xff1a;所有使用者   使用方式&#xff1a;cat[-AbeEnstTuv] [--help] [--version] fileName   说明&#xff1a;把档案串连…

wordpress配置SMTP服务发送邮件

使用SMTP服务发送邮件&#xff0c;需要使用一个插件&#xff1a;http://wordpress.org/extend/plugins/wp-mail-smtp/ 下载完成以后解压到plugin目录&#xff0c;然后在插件中启用这个插件。 配置SMTP服务 SMTP的选项 发送一封测试邮件吧 >>> 本文转自齐师傅博客园博客…

使用rpm包安装mysql_centos下利用rpm包安装mysql

安装mysql步骤&#xff1a;第一、 http://www.mysql.com/downloads/mysql-4.0.html下载MySQL-client-5.0.96-1.glibc23.x86_64.rpm和MySQL-server-5.0.96-1.glibc23.x86_64.rpm第二、安装服务端&#xff1a;[rootlfl01 mysql]# rpm -ivh MySQL-server-5.1.73-1.glibc23.i386.rp…

maxN - 返回数组中N个最大元素 minN - 返回数组中N个最小元素

从提供的数组中返回 n 个最小元素。如果 n 大于或等于提供的数组长度&#xff0c;则返回原数组&#xff08;按降序排列&#xff09;。 结合使用Array.sort() 与展开操作符(...) &#xff0c;创建一个数组的浅克隆&#xff0c;并按降序排列。 使用 Array.slice() 以获得指定的元…

Linux 常用命令

Linux之所以受到广大计算机爱好者的喜爱&#xff0c;主要原因有两个&#xff0c;首先它是自由软件&#xff0c;用户不用支付费用就可以使用它&#xff0c;并可根据自己的需要对它进行修改。另外&#xff0c;它具有Unix的全部功能&#xff0c;任何使用Unix系统或想要学习Unix系统…

使用Server 2008新GPO做驱动器映射

在Server 2003的时代&#xff0c;我们为用户做网络驱动器映射(以下就直接称为Map Network Drive&#xff09;, 通常可能有以下的做法. 方法一: 做一个登录脚本&#xff0c;放在DC的netlogon目录&#xff0c;接着在“Active Directory用户和计算机”控制台的用户属性的Logon S…

electron 打包后 __static_electron开发客户端注意事项(兼开源个人知识管理工具“想学吗”)...

窗口间通信的问题electron窗口通信比nwjs要麻烦的多electron分主进程和渲染进程&#xff0c;渲染进程又分主窗口的渲染进程和子窗口的渲染进程主窗口的渲染进程给子窗口的渲染进程发消息subWin.webContents.on(dom-ready, () > {subWin.webContents.send(message, {title: s…

180118 有趣的人工智能对话小程序

print(Hello world!) #输入 print(What is your name?) # ask for their name 询问名字 myName input()   #该你来回答名字了 print(It is good to meet you, myName)  #根据你的名字来给你打个招呼 print(The length of your name is:)  #然后看下一句 print(len(…

Linux 内核调试器 调试指南

Linux 内核调试器内幕 KDB 入门指南 Hariprasad Nellitheertha (nhariprain.ibm.com), 软件工程师, IBM简介&#xff1a; 调试内核问题时&#xff0c;能够跟踪内核执行情况并查看其内存和数据结构是非常有用的。Linux 中的内置内核调试器 KDB 提供了这种功能。在本文中您将了解…

学习API HOOK,编写了一个winsock 的封包抓取程序,可免费使用;

开发环境是:windows 2000 delphi 7 监视API&#xff1a;recv,recvfrom,WSARecvEx,send,sendto,accept,bind,closesocket,connect socket 版本&#xff1a;wsock32.dll/*ws2_32.dll(暂时有兼容问题) 目前还不支持修改封包&#xff1b; 当前实现针对某个进程或多个选定进程的通…

fib函数用python编写_Python中利用函数装饰器实现备忘功能

“备忘”的定义“memoization”(备忘)这个词是由Donald Michie在1968年提出的&#xff0c;它基于拉丁语单词“memorandum”(备忘录)&#xff0c;意思是“被记住”。虽然它和单词“memorization”在某种程度上有些相似&#xff0c;但它并不是该单词的错误拼写。实际上&#xff0…

MyBatis学习总结(二)——使用MyBatis对表执行CRUD操作

MyBatis学习总结(二)——使用MyBatis对表执行CRUD操作 上一篇博文MyBatis学习总结(一)——MyBatis快速入门中我们讲了如何使用Mybatis查询users表中的数据&#xff0c;算是对MyBatis有一个初步的入门了&#xff0c;今天讲解一下如何使用MyBatis对users表执行CRUD操作。本文中使…

cifs mount 挂载共享目录_安装cifsutils解决linux挂载windows共享文件夹

1、安装mount.cifs软件包yum install cifs-utils -y如果是离线环境&#xff0c;请参考我的另一篇文章https://blog.csdn.net/qq_37119960/article/details/1083313732、开始挂载mount.cifs //192.168.1.110/share /usr/local/winshare -o useradministrator,pass123456参数说明…

JFinal框架

FJinal过滤器(tomcat) 创建java类继承JFinalConfig 会实现六个方法(有一个是拦截器的方法好像是,那个我好像看的跟struts2一样但是又没看懂暂时不写) Controller层的测试方法 Entity实体类 常用方法 查询 增加 删除 修改 转载于:https://www.cnblogs.com/guanzhuang/p/8317949.…

掌握 Linux 调试技术 使用 GDB 调试 Linux 软件

简介&#xff1a; 您可以用各种方法来监控运行着的用户空间程序&#xff1a;可以为其运行调试器并单步调试该程序&#xff0c;添加打印语句&#xff0c;或者添加工具来分析程序。本文描述了几种可以用来调试在 Linux 上运行的程序的方法。我们将回顾四种调试问题的情况&#xf…