宏定义基本用法

宏定义

不带参数

宏定义又称为宏代换、宏替换,简称“宏”。

格式:

#define 标识符 字符串

其中的标识符就是所谓的符号常量,也称为“宏名”。
预处理(预编译)工作也叫做宏展开:将宏名替换为字符串。
掌握”宏”概念的关键是“换”。一切以换为前提、做任何事情之前先要换,准确理解之前就要“换”。

例:

#define Pi 3.1415926

把程序中出现的Pi全部换成3.1415926

带参数(宏函数)

宏名之后带括号的宏被认为是宏函数。用法和普通函数一样,只不过在预处理阶段,宏函数会被展开。优点是没有普通函数保存寄存器和参数传递的开销,展开后的代码有利于CPU cache的利用和指令预测,速度快。缺点是可执行代码体积大。

和不带参数的宏定义一样,除了一般的字符串替换,还要做参数代换。

格式:

#define <宏名> (<参数表>) <宏体>

例如:

#define S(a,b) a*b

area=S(3,2);第一步被换为area=a * b; ,第二步被换为area=3 * 2;

(1)实参如果是表达式容易出问题

例如:

#define S(r) r*r

area=S(a+b);第一步换为area=r * r;,第二步被换为area=a+b * a+b;

正确的宏定义是#define S(r) ((r)*(r))

(2)带参宏一般用法

例如:

#define MIN(A, B)   A < B ? A : Bint a = 2 * MIN(3, 4);
printf("%d", a);

展开结果:

int a = 2 * MIN(3, 4);
//=> int a = 2 * 3 < 4 ? 3 : 4;
//=> int a = 6 < 4 ? 3 : 4;
//=> int a = 4;

正确如下:

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

则遇到MAX(1+2,value)则会把它替换成:
((1+2)>(value)?(1+2):(value))

(3)有参宏定义中#的用法

需要注意的是凡宏定义里有用’#’或’##’的地方宏参数是不会再展开,被当做字符串处理

#define STR(str) #str

“#”号用于把宏定义中的参数两端加上字符串的”“

比如,这里 STR(my#name) 会被替换成”my#name”

(4)有参宏定义中##的用法

例如:

#define WIDE(str) L##str

则会将形参str的前面加上L

比如:

WIDE(“abc”)就会被替换成L”abc”

如果有:

#define FUN(a,b) vo##a##b()

那么FUN(id ma,in)会被替换成void main()

多行宏定义

每一次换行都必须要有 “ \ ”结尾,末尾行不需要“ \ ” 结尾。

例如:

#define doit(m,n) for(int i=0;i<(n);++i)\
    {\
    m+=i;\
    }
#define WARN_IF(EXP) \do { if (EXP) \fprintf (stderr, "Warning: " #EXP "\n"); } \while (0)

WARN_IF (x == 0);会被扩展成:

do 
{ if (x == 0)fprintf (stderr, "Warning: " "x == 0" "\n"); 
}
while (0);
#define VAR_TO_STR(var)\({\std::string name = (#var);\int pos = 0;\int length = 0;\length = name.length();\pos = name.find_last_of(':',length);\if ( pos == -1 )\{\pos = 0;\name = name.substr(pos,length);\}\else\{\name = name.substr( pos + 1,length);\}\(name);\})

std::string str = VAR_TO_STR(VDAD::RRR) 展开后:

int main()
{std::string ss =({std::string name = ("VDAD::RRR");int pos = 0;int length = 0;length = name.length();pos = name.find_last_of(':',length);if ( pos == -1 ){pos = 0;name = name.substr(pos,length);}else{name = name.substr( pos + 1,length);}(name);});cout << ss<< endl;return 0;
}

输出为:

相关链接

1.C语言宏的特殊用法和几个坑
2.C/C++ 宏定义

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

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

相关文章

广度优先搜索练习之神奇的电梯

广度优先搜索练习之神奇的电梯 Time Limit: 1000ms Memory limit: 65536K 题目描述 有一座已知层数为n的高楼&#xff0c;这座高楼的特殊之处在于只能靠电梯去上下楼&#xff0c;所以要去到某一层要非常耽误时间&#xff0c;然而更悲哀的是&#xff0c;这座高楼的电梯是限号…

ubuntu安装proxychains及自动补全

proxychains ProxyChains是本人目前为止用到的最方便的代理工具。 inux下代理一般是通过http_proxy和https_proxy这两个环境变量&#xff0c;但是很多软件并不使用这两个变量&#xff0c;导致流量无法走代理。在不使用vpn的前提下&#xff0c;linux并没有转发所有流量的真全局…

快速幂讲解

快速幂的目的就是做到快速求幂&#xff0c;假设我们要求a^b,按照朴素算法就是把a连乘b次&#xff0c;这样一来时间复杂度是O(b)也即是O(n)级别&#xff0c;快速幂能做到O(logn)&#xff0c;快了好多好多。它的原理如下&#xff1a; 假设我们要求a^b&#xff0c;那么其实b是可以…

如何查询资料

如何查询资料技术资料及问题查询查询方法分类查找提取关键字GitHub项目优先使用Google搜索引擎Copy Paste论文查找询问主管 测试修改使用总结分享 公司信息查询国内公司国外公司 如何查询资料 技术资料及问题查询 查询方法 资料与解决办法的查询大致分为7大类。 1.分类查…

山东省第八届 ACM 省赛 sum of power(SDUT 3899)

Problem Description Calculate ∑ni1im mod (10000000007) for given n&#xff0c;m. Input Input contains two integers n,m(1≤n≤1000,0≤m≤10). Output Output the answer in a single line. Example Input 10 0 Example Output 10 方法&#xff1a;快速幂和大数求和 …

Ubuntu主题更换

Ubuntu主题更换 目前的Ubuntu有Unity和Gnome两个比较流行的版本&#xff0c;以下为Gnome桌面环境的主题更换&#xff0c;其他桌面环境类似。 主题的下载地址&#xff0c;点击 Theme 将在网络上下载的主题文件进行解压&#xff0c;然后拷贝到 /usr/share/themes/ 目录下&…

awk简单使用

awk 用于在linux/unix下对文本和数据进行处理,支持用户自定义函数和动态正则表达式等先进功能。 命令格式&#xff1a; awk BEGIN{ print “start” } pattern { commend } END{print "end"} file awk "BEGIN{ print “start” } pattern { commend } END{pr…

Ubuntu 14.04 下 Virtual Judge 的搭建

前期准备工作 1.1 一个Linux系统 因为现场赛的缘故&#xff0c;我一直使用的都是ubuntu。 这里我测试用的是Ubuntu14.04 Desktop 64bit ,当然选择Server会更好一些. 系统的安装不再赘述&#xff0c;作为服务器请选用Server版本。1.2 更新源 在搭建环境之前&#xff0c;请确保…

BitMap的原理介绍与实现

BitMap 位图&#xff08;bitmap&#xff09;是一种非常常用的结构&#xff0c;在索引&#xff0c;数据压缩等方面有广泛应用。位图是通过将数组下标与应用中的一些值关联映射&#xff0c;数组中该下标所指定的位置上的元素可以用来标识应用中值的情况&#xff08;是否存在或者数…

MySQL与PHP连接

1、mysql_connect()-建立数据库连接 格式&#xff1a; resource mysql_connect([string hostname [:port] [:/path/to/socket] [, string username] [, string password]]) 例&#xff1a; $conn mysql_connect("localhost", "username", "pa…

QML Profiler性能优化教程

QML Profiler 2018年1月26日 vincent 对于一个程序的开发&#xff0c;性能优化是开发中的一个重要步骤。 我们肯定不希望开发出来的程序表现出卡顿&#xff0c;最好是处处流畅&#xff0c;丝滑般的体验。 对于C程序&#xff0c;我们有很多方法可以做性能优化&#xff0c;例如…

uburntu在不能自动获取网络时的联网设置

一&#xff1a;网络基础配置 1. eth0设置不正确&#xff0c;导致无法正常启动&#xff0c;修改eth0配置文件就好 ubuntu 12.04的网络设置文件是/etc/network/interfaces&#xff0c;打开文件&#xff0c;会看到 auto lo iface lo inet loopback 这边的设置是本地回路。在后…

计算机显卡知识普及

显卡知识普及 一、什么是显卡&#xff1f; 显示接口卡&#xff08;Video card&#xff0c;Graphics card&#xff09;、显示器配置卡简称为显卡&#xff0c;是个人电脑基本组成部分之一。 用途是将计算机系统所需要的显示信息进行转换驱动&#xff0c;并向显示器提供信号&…

整除的尾数

Problem Description 一个整数&#xff0c;只知道前几位&#xff0c;不知道末二位&#xff0c;被另一个整数除尽了&#xff0c;那么该数的末二位该是什么呢&#xff1f; Input 输入数据有若干组&#xff0c;每组数据包含二个整数a&#xff0c;b(0<10000,10<b<100)&…

QML 控件大全

QML TypeContainerDelayButtonDialDialogButtonBoxDialogDrawerMenuMenuBarOverlayPageIndicatorRangeSliderScrollViewSpinBoxStackViewSwipeViewSwitchTabBarToolBarToolSeparatorToolTipTumbler QML Type 本篇主要介绍QtQuick Controls 2,Qt Creator 5.10 1.Container im…

斐波那契的整除

Description 已知斐波那契数列有如下递归定义&#xff0c;f(1)1,f(2)1, 且n>3,f(n)f(n-1)f(n-2)&#xff0c;它的前几项可以表示为1&#xff0c; 1&#xff0c;2 &#xff0c;3 &#xff0c;5 &#xff0c;8&#xff0c;13&#xff0c;21&#xff0c;34…&#xff0c;现在的…

Qt与QML的枚举绑定(C++枚举)

Qt到QML的枚举绑定 QML中是不支持c的枚举类型的&#xff0c;所以我们可以使用Qt的元对象系统&#xff0c;即MOS,来帮助我们实现。 进行绑定的好处就是&#xff0c;以后数据发生变化的时候&#xff0c;就是枚举发生增加修改&#xff0c;添加等的时候&#xff0c;不需要在QML中…

深入理解Qt的.pro文件

深入理解Qt的pro文件模板变量生成目录生成的应用程序名编译选项目标文件目录包含头文件包含源文件包含资源文件附加头文件包含链接库预编译宏平台相关性处理指定来自ui文件位置指定界面翻译文本列表指定图标 深入理解Qt的.pro文件 一般Qt项目我们是使用Qt Creator自动生成的&…

Ubuntu 用vsftpd 配置FTP服务器

最近开学&#xff0c;有好多课程结束后都需要将文件考到优盘里&#xff0c;而本人又有健忘的毛病&#xff0c;经常忘记带优盘&#xff0c;所以就搭建了自己的ftp服务器&#xff0c;也算是用技术放松自己吧。闲话少叙&#xff0c;进入正题&#xff1a; 网上关于ftp搭建的文章很…

linux的程序打包deb

deb安装包 deb是Unix系统(其实主要是Linux)下的安装包&#xff0c;基于 tar 包&#xff0c;因此本身会记录文件的权限(读/写/可执行)以及所有者/用户组。 由于 Unix 类系统对权限、所有者、组的严格要求&#xff0c;而 deb 格式安装包又经常会涉及到系统比较底层的操作&#…