C语言宏定义#define的理解与资料整理!希望你能get到!
发布网友
发布时间:2024-10-01 21:27
我来回答
共1个回答
热心网友
时间:2024-10-19 10:01
利用#define来定义数值宏常量
宏定义像一个替身演员,它可以在代码中出现任何地方,从宏定义开始,之后的代码都认识这个宏。它可以定义任何内容。编译器会在预编译时用真身替换替身,并在代码中用替身帮忙。
例如:
#define PI 3.141592654
在代码中使用PI代替数值,保持代码简洁且易于维护。修改PI的精度时,只需修改一次。
使用#define定义数值宏常量时,避免使用“魔鬼数”(如-1),以提高代码可读性。
定义数值宏常量时,推荐使用const,它能为只读变量提供类型安全校验。
使用#define定义字符串宏常量
宏定义也用于定义字符串,尤其是路径。
例如:
#define ENG_PATH_1 E:\English\listen_to_this\listen_to_this_3
使用反斜杠接续符(\)连接路径部分。
确保接续符反斜杠后不跟任何字符,以避免混淆。
路径长时,使用反斜杠接续符确保代码清晰。
使用#define定义注释符号
定义注释符号时,避免使用宏开始或结束注释。
宏定义注释符号可能与预处理指令冲突,导致错误。
使用#define定义表达式
定义表达式时,注意溢出风险。
例如:
#define SEC_A_YEAR 60*60*24*365
考虑在16位系统下可能的溢出问题。
修改为:
#define SEC_A_YEAR (60*60*24*365)UL
定义宏函数时,注意实参代换规则,避免值传送。
例如:
#define SQR (x) x * x
定义求平方的宏函数。
在使用宏函数时,确保参数正确代换。
宏定义中的空格
宏定义时,注意空格使用。在定义宏时,空格有特定作用,但在使用宏时,空格会被忽略。
例如:
#define SUM (x) (x) + (x)
定义求和宏函数时,避免空格混淆。
使用宏时,宏函数之间空格不影响。
使用#undef撤销宏定义
#undef 用来撤销已定义的宏,确保代码结构清晰。
例如:
#define PI 3.141592654
…
#undef PI
宏定义后的代码不能使用撤销宏定义的宏。
成熟软件中常用宏定义
防止重复包含头文件
#ifndef COMDEF_H
#define COMDEF_H
头文件内容
#endif
重新定义类型,方便移植
例如:
typedef unsigned char boolean;
宏定义的实践与应用
定义最大值和最小值
#define MAX( x, y ) ((x) > (y) ? (x) : (y))
#define MIN( x, y ) ((x) < (y) ? (x) : (y))
获取结构体偏移量
#define FPOS( type, field ) ((dword) &(( type *) 0)-> field)
结构体字节数
#define FSIZ( type, field ) sizeof( ((type *) 0)->field)
宏定义的应用实例
例如:
8-bit字节转换为Word
#define FLIPW( ray ) (((word) (ray)[0]) * 256 + (ray)[1])
Word转两个字节
#define FLOPW( ray, val ) (ray)[0] = ((val) / 256); (ray)[1] = ((val) & 0xFF)
获取变量地址
#define B_PTR( var ) (byte *) (void *) &(var)
#define W_PTR( var ) (word *) (void *) &(var)
字的高位和低位字节
#define WORD_LO(xxx) ((byte) ((word)(xxx) & 255))
#define WORD_HI(xxx) ((byte) ((word)(xxx) >> 8))
返回比X大的8倍数
#define RND8( x ) (((x) + 7) / 8 * 8)
大写转换
#define UPCASE( c ) (((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c))
数字检查
#define DECCHK( c ) ((c) >= '0' && (c) <= '9')
十六进制数字检查
#define HEXCHK( c ) (((c) >= '0' && (c) <= '9') || ((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f'))
防止溢出
#define INC_SAT( val ) ((val) = ((val)+1 > (val)) ? (val)+1 : (val))
数组元素计数
#define ARR_SIZE( a ) (sizeof( (a) ) / sizeof( (a[0]) ))
模运算
#define MOD_BY_POWER_OF_TWO( val, mod_by ) ((dword)(val) & (dword)((mod_by)-1))
IO空间映射处理
#define inp(port) (*((volatile byte *) (port)))
#define inpw(port) (*((volatile word *) (port)))
宏定义在调试中的应用
例如:
#ifdef _DEBUG
#define DEBUGMSG(msg,date) printf(msg); printf("%d%d%d",date,_LINE_,_FILE_)
#else
#define DEBUGMSG(msg,date)
#endif
宏定义的错误预防
使用小括号包含宏,或使用do{}while(0)语句包含多语句以避免错误。
例如:
#define ADD(a,b) (a+b)
#define DO(a,b) a+b; a++;
避免在程序中随意添加{}
使用#define DO(a,b) do{a+b; a++;}while(0)
结语
作为一名10年的老程序员,我整理了C语言和C++的学习材料和工具。作为C/C++编程爱好者的社区,我欢迎初学者和进阶者一起学习,共同成长。如果你正在寻找工作需要、对编程感兴趣、想要学习C/C++以入行或转行,欢迎与我一起学习。关注我并加入我的专栏,一起探索编程的奥秘。