C语言中#define在多行宏定义出错的原因及分析
更新时间:2023年2月27日 17:43 点击:778 作者:倒在路上的羊
C语言中#define在多行宏定义出错的原因
1.第一种错误
#include<stdio.h> #define echange(a,b) {\/*宏定义中允许包含多行命令的情形,此时必须在最右边加上"\"*/ int t;\ t=a;\ a=b;\ b=t;\ } main() { int c, d; c = 2; d = 3; printf("%d %d\n", c, d); echange(c,d) printf("%d %d\n", c, d); return 0; }
在用#define进行多行宏定义时,注释要放在"\"之前
2.第二种错误
#include<stdio.h> #define echange(a,b) {/*宏定义中允许包含两道衣裳命令的情形,此时必须在最右边加上"\"*/\ int t;\ t=a;\ a=b;\ b=t;\ }/*在最后一行多加了一个"\"*/\ main() { int c, d; c = 2; d = 3; printf("%d %d\n", c, d); echange(c,d) printf("%d %d\n", c, d); return 0; }
在用#define进行多行宏定义时,在最后一行加上"\“,我们使用#define进行多行定义时,默认最后一个”\“的下一行也属于宏定义范围,去掉最后一行的”\"即可
以下是代码的正确形式
#include<stdio.h> #define echange(a,b) {/*宏定义中允许包含两道衣裳命令的情形,此时必须在最右边加上"\"*/\ int t;\ t=a;\ a=b;\ b=t;\ } main() { int c, d; c = 2; d = 3; printf("%d %d\n", c, d); echange(c,d) printf("%d %d\n", c, d); return 0; }
使用#define宏定义的几个小技巧
1.调试开关
有时候编写程序时为方便查找错误,会在很多地方加上串口打印语句直观查看程序哪里出错。
但是,串口的输出是需要时间的,在项目基本完成时,就需要将这些打印关闭,但是一行一行的注释掉费时费力,不现实。
这时可以使用宏来当做一个"开关",直接操作这个宏就可以实现打印的开关,例如:
//#define DEBUG(...) #define DEBUG printf
另外,还可以使用几个预定义的宏进行辅助:
__FILE__ // 文件 __FUNCTION__ // 函数 __LINE__ // 行号 DEBUG("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
2.条件编译
当程序为了适配更多不同的环境时,还可以使用条件宏来选择不同的代码模块:
#if 1 printf("Hello!\n"); #else printf("Hi!\n"); #endif
3.宏实现函数
交换两个数:
#define swap(a,b) ((a)=(a)+(b);(b)=(a)-(b);(a)=(a)-(b))
比较两个数并且返回最小的数:
#define MIN(a,b) ((a)<(b)?(a):(b))
求数组元素个数:
#define LENGTH(array) (sizeof(array) / sizeof(array[0]))
4.跨行宏定义
#define SWAP(a,b) do { \ int t = 0;\ t = a; \ a = b; \ b = t; \ } while(0)
细心的你可能已经注意到以上宏末尾都没有带分号“;”
5.防止头文件被重复包含
#ifndef __TEST_H #define __TEST_H // 头文件内容 #endif
6.带参宏与带参函数的区别
- 1.宏会在编译器在对源代码进行编译的时候进行简单替换,不会进行任何逻辑检测,即简单代码复制而已;
- 2.宏进行定义时不会考虑参数的类型;
- 3.参数宏的使用会使具有同一作用的代码块在目标文件中存在多个副本,即会增长目标文件的大小;
- 4.参数宏的运行速度会比函数快,因为不需要参数压栈/出栈操作;
- 5.参数宏在定义时要多加小心,多加括号;
- 6.函数只在目标文件中存在一处,比较节省程序空间;
- 7.函数的调用会牵扯到参数的传递,压栈/出栈操作,速度相对较慢;
- 8.函数的参数存在传值和传地址(指针)的问题,参数宏不存在;
7.注意事项
- 1.宏定义不会对引号内的参数进行替换;
- 2.若要替换,可以在参数前面加上’#’转换成“字符串”,如:
#define dprint(expr) printf(#expr " = %d\n", expr)
使用dprint(x/y)就被替换成:
printf("x/y" " = %g\n", x/y);
即
printf("x/y = %g\n", x/y);
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。
原文出处:https://blog.csdn.net/qq_45158026/article/details/104025617
相关文章
- 这篇文章主要为大家详细介绍了C语言实现放烟花的程序,有音乐播放,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-23
- 本篇文章主要介绍C语言中char的知识,并附有代码实例,以便大家在学习的时候更好的理解,有需要的可以看一下...2020-04-25
- 这篇文章主要介绍了详解如何将c语言文件打包成exe可执行程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-25
- free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
- 这篇文章主要介绍了C语言中计算正弦的相关函数总结,包括正弦和双曲线正弦以及反正弦的函数,需要的朋友可以参考下...2020-04-25
详解C语言中的rename()函数和remove()函数的使用方法
这篇文章主要介绍了详解C语言中的rename()函数和remove()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25- 这篇文章主要介绍了C语言中求和、计算平均值、方差和标准差的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-10
- 本篇文章主要讲解C语言 基本语法,这里提供简单的示例和代码来详细讲解C语言的基本语法,开始学习C语言的朋友可以看一下,希望能够给你带来帮助...2021-09-18
- 这篇文章主要介绍了C语言中send()函数和sendto()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25
- 今天小编就为大家分享一篇C语言实现从文件读入一个3*3数组,并计算每行的平均值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要介绍了使用C语言操作文件的基本函数整理,包括创建和打开以及关闭文件的操作方法,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C语言中memcpy 函数的用法详解的相关资料,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C语言中查找字符在字符串中出现的位置的方法,分别是strchr()函数和strrchr()函数的使用,需要的朋友可以参考下...2020-04-25
- 很多同学在学习c语言的时候是不是会碰到a++和++a都有甚么作用啊。今天我们就来探讨下...2020-04-25
- 下面小编就为大家带来一篇C语言实现时间戳转日期的算法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要对C语言中const关键字的用法进行了详细的分析介绍,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C语言之整数划分问题(递归法)实例代码的相关资料,需要的朋友可以参考下...2020-04-25
- 本文给大家简单介绍下c实现linux下的数据库备份的方法和具体的源码,十分的实用,有需要的小伙伴可以参考下。...2020-04-25
C语言正则表达式详解 regcomp() regexec() regfree()用法详解
C语言处理正则表达式常用的函数有regcomp()、regexec()、regfree()和regerror(),这里就为大家介绍一下,需要的朋友可以参考一下啊...2020-04-25- 这篇文章主要介绍了c语言实现找最大值最小值位置查找,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-04