C语言的#define用法

C语言的#define用法

1. 简单的宏定义

#define MAXSIZE 1000
// 有点像简单的文本替换

2. define的函数定义

// 同样类似简单文本替换
#define Add(a,b) a+b
// 要注意可能会出现运算优先级的问题,比如
c*Add(a,b)*d;
// 本意是c*(a+b)*d,但是计算机可能理解为:c*a+b*d

3. 宏的单行定义和多行定义

宏定义中允许包含两行以上命令的情形,此时必须在最右边加上\且该行\不能再有任何字符,连注释部分都不能有,下面的每行最后的一定要是\,\后面加一个空格都会报错,更不能跟注释。

#define max(a,b) \
(((a)>(b))?(a):(b))\

4. 条件编译

在大规模的开发过程中,特别是跨平台和系统的软件里,define最重要的功能是条件编译。

#ifdef WINDOWS
...
#endif
#ifdef LINUX
...
#endif

5. 取消定义宏

//定义宏
#define [MacroName] [MacroValue]
//取消定义
#undef [MacroName]

6. 重复包含(定义)

由于头文件包含可以嵌套,那么C文件就有可能包含多次同一个头文件,就可能出现重复定义的问题的。通过条件编译开关来避免重复包含(重复定义)

#ifndef __headerfileXXX__
#define __headerfileXXX__

//头文件内容

#endif

7. 重新定义类型

重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。

补充:关于unsiged char和char

首先在内存中,char与unsigned char没有什么不同,都是一个字节,唯一的区别是,char的最高位为符号位,因此char能表示-128~127,unsigned char没有符号位,因此能表示0~255,这个好理解,8个bit,最多256种情况,因此无论如何都能表示256个数字。

在实际使用过程种有什么区别呢?主要是符号位,但是在普通的赋值,读写文件和网络字节流都没什么区别,反正就是一个字节,不管最高位是什么,最终的读取结果都一样,只是你怎么理解最高位而已,在屏幕上面的显示可能不一样。

二者的最大区别是:但是我们却发现在表示byte时,都用unsigned char,这是为什么呢?首先我们通常意义上理解,byte没有什么符号位之说,更重要的是如果将byte的值赋给int,long等数据类型时,系统会做一些额外的工作。如果是char,那么系统认为最高位是符号位,而int可能是16或者32位,那么会对最高位进行扩展(注意,赋给unsigned int也会扩展)而如果是unsigned char,那么不会扩展。最高位若为0时,二者没有区别,若为1时,则有区别了。同理可以推导到其它的类型,比如short, unsigned short,等等。

typedef unsigned char boolean;     /* Boolean value type. */

8. 一些常用用法

1. 得到一个field在结构体中的偏移量

#define OFFSETOF(type, field)  ((size_t)&(((type *)0)->field))

(type*)0表示把0地址当成type类型的指针 ((type *)0)->field表示对于

域的变量。前面加上&表示取得地址(也就是相对于0的偏移量),然后将该偏移量转换为size_t类型的数据

2. 得到一个结构体中field所占用的字节数

#define FPOS( type, field ) ( (dword) &(( type *) 0)-> field )

3. 按照LSB格式把两个字节转化为一个Word

#define  FLIPW( ray ) ( (((word) (ray)[0]) * 256) + (ray)[1] )

4. 得到一个变量的地址(word宽度)

#define  B_PTR(var) ((byte*)(void *) &(var))

#define  W_PTR( var )  ((word *)(void *) &(var))

5. 得到一个字的高位和低位字节

#define  WORD_LO(xxx)  ((byte) ((word)(xxx) & 255))

#define  WORD_HI(xxx)  ((byte) ((word)(xxx) >> 8))

9. 使用一些宏跟踪调试

五个预定义的宏名:

__LINE__ 及 __FILE__ //宏指示,#line指令可以改变它的值,简单的讲,编译时,它们包含程序的当前行数和文件名。

__DATE__ 宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。

__TIME__ 宏指令包含程序编译的时间。时间用字符串表示,其形式为:分:秒

__STDC__ 宏指令的意义是编译时定义的。一般来讲,如果__STDC__已经定义,编译器将仅接受不包含任何非标准扩展的标准C/C++代码。如果实现是标准的,则宏__STDC__含有十进制常量1。如果它含有任何其它数,则实现是非标准的。;

// 定义_DEBUG
#ifdef _DEBUG

#define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_)

#else

#define DEBUGMSG(msg,date)

#endif

10. 一些特殊的标识符

## 是简单的连接符,#@用来给参数加单引号,#用来给参数加双引号即转成字符串。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值