如何用#define宏定义多行函数
在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成为宏定义。那么究竟是用函数好,还是宏定义好?这就要求我们对二者进行合理的取舍。
首先,函数调用会带来额外的开销,它需要开辟一片栈空间,记录返回地址,将形参压栈,从函数返回还要释放堆栈。这种开销不仅会降低代码效率,而且代码量也会大大增加,而使用宏定义则在代码规模和速度方面都比函数更胜一筹;其次,函数的参数必须被声明为一种特定的类型,所以它只能在类型合适的表达式上使用,我们如果要比较两个浮点型的大小,就不得不再写一个专门针对浮点型的比较函数。反之,上面的那个宏定义可以用于整形、长整形、单浮点型、双浮点型以及其他任何可以用“>”操作符比较值大小的类型,也就是说,宏是与类型无关的。
和使用函数相比,使用宏的不利之处在于每次使用宏时,一份宏定义代码的拷贝都会插入到程序中。除非宏非常短,否则使用宏会大幅度增加程序的长度。
下面一段代码的功能是显示C整数类型的长度和范围:
#include<stdio.h>
#define RANGE(type, name) \{ \type minval,maxval,bit; \unsigned bits; \char *format; \\/*Measure size of data type in bits*/ \bits=1;bit=(type)1;while(bit<<=1)bits++; \/*signed or unsigned?*/ \if ((type)(1L<<(bits-1))>0) \{ \format="%12lu";/*unsigned*/ \minval=(type)0; \} \else \{ \format="%12ld";/*signed*/ \minval=(type)1<<(bits-1); \} \\maxval=minval-1;/*roll over backwards!*/ \\printf("%20s(%2u bits):",name,bits); \printf(format,(long)minval); \printf("to"); \printf(format,(long)maxval); \printf("\n"); \} int main(){printf("\nTesting range of UNSIGNED ints...\n\n");RANGE(unsigned char,"unsigned char");RANGE(unsigned short int,"unsigned short int");RANGE(unsigned int,"unsigned int");RANGE(unsigned long int,"unsigned long int");printf("\nTesting range of SIGNED ints...\n\n");RANGE(signed char,"signed char");RANGE(signed short int,"signed short int");RANGE(signed int,"signed int");RANGE(signed long int,"signed long int");printf("\n");return 0;}
程序运行结果如下:
说明:
1、使用#define声明多行宏函数与声明单行宏函数没有本质区别;
2、多行声明时,回车换行前要加上字符‘\’,即“\[enter]”,注意字符‘\’后要紧跟回车键,中间不能有空格或其他字符。
3、另外,在Linux操作系统中 “\[enter]”称为跳脱字符,意思是一行写不完的时候可以使用跳脱字符换行,但对于操作系统而言,它认为你并没有换行。
如何用#define宏定义多行函数相关推荐
- #define宏定义形式的函数导致的bug
定义了一个宏定义形式的"函数": #define SUM8(YY)\ {\ int Y = YY>>2;\ ...\ } 然后使用的时候,传入了一个同名的变量Y: i ...
- C语言基础知识之define宏定义表达式,undef,内存对齐,a和a的区别,数组知识点,int (*)[10] p,二维数组参数与二维指针参数,函数指针数组,常见的内存错误及对策
一.用define宏定义表达式 1.定义一年有多少秒: #define SEC_A_YEAR 60*60*24*365 //上述描述不可靠,没有考虑到在16位系统下把这样一个数赋给整型变量的时候可能会 ...
- 关于C语言刷题(#define宏定义函数的常见错误)
关于C语言刷题(#define宏定义函数的常见错误) 首先我们来先看对#define的定义 define,宏定义,C语言中预处理命令一种.分为无参宏定义和带参宏定义.无参宏定义的一般形式为:#defi ...
- #define宏定义是什么?怎么写?一文搞懂。
前言 第一次接触宏定义的时候,是在学校的C++课程大作业中.当时有幸看到了大佬写的源码,里面有很多的宏定义.当时并不了解宏定义的妙用,只感觉它像是定义了一个变量一样,不好理解还有些多此一举. 这之后在 ...
- 函数式宏定义与普通函数的区别?C语言宏定义和宏定义函数 ?
http://www.jb51.net/article/41869.htm 尽管函数式宏定义和普通函数相比有很多缺点,但只要小心使用还是会显著提高代码的执行效率,毕竟省去了分配和释放栈帧.传参.传返回 ...
- C语言学习笔记--预编译/宏定义/数组/参数传递/函数指针
目录 预编译 值传递.指针传递.引用传递 数组 typedef 函数指针 预编译 预编译又叫预处理.预编译不是编译,而是编译前的处理.这个操作是在正式编译之前由系统自动完成的.#define 和 #i ...
- 用宏定义代替printf函数
问题提出 有时候我们想用宏定义来决定是编译debug版本的代码还是release的代码,dubug版本的代码会通过printf打印调试信息,release版本的代码则不会.我们总不能对每一条print ...
- define宏定义中的#,##,@#及\符号
define宏定义中的#,##,@#及\符号 在#define中,标准只定义了#和##两种操作.#用来把参数转换成字符串,##则用来连接两个前后两个参数,把它们变成一个字符串. 1.# (string ...
- c语言数组宏定义标识符,C语言学习笔记--预编译/宏定义/数组/参数传递/函数指针...
目录 预编译 值传递.指针传递.引用传递 数组 typedef 函数指针 预编译 预编译又叫预处理.预编译不是编译,而是编译前的处理.这个操作是在正式编译之前由系统自动完成的.#define 和 #i ...
最新文章
- 图文解说nginx中server的匹配顺序
- Android -- 带你从源码角度领悟Dagger2入门到放弃(三)
- 正则表达式 学习笔记5.3
- mybaits二十八:逆向工程
- 百度商桥修改服务器,百度商桥 · 响应式网站编辑器使用手册 · 看云
- 红帽linux更新指令,CentOS7.0命令更新新版特性详解
- 对现有的所能找到的DDOS代码(攻击模块)做出一次分析----UDP篇
- 历久弥新 - 微软万亿市值背后的文化支撑(上)|DevOps案例研究
- JAVA入门级教学之(数据转换规则)
- 【Python】Turtle绘制科赫雪花
- dw怎么修改html框架的宽度,Dreamweaver (dw)cs6中div标签宽度和高度设置方法
- 网络爬虫基本原理(二)
- 如何查看电脑上是否安装有IIS服务
- 吴恩达机器学习编程题ex1上 单变量线性回归: (python版含题目要求、代码、注解)
- Windows 9预览版今秋发布 正式版明年推出
- Java double value_Java Double doubleValue()用法及代码示例
- matlab差值后求斜率,用三次样条插值求离散点斜率 matlab程序
- 益智java单词游戏_java实现单词搜索迷宫游戏
- html网页中圆角边框的编写,Html实现边框圆角的实例详解
- 快速了解K4B2G1646F-BYK0