#define命令的一些高级用法

===========================================================

define中的三个特殊符号:#,##,#@

===========================================================

  1. #define Conn(x,y) x##y
  2. #define ToChar(x) #@x
  3. #define ToString(x) #x

(1)x##y表示什么?表示x连接y,举例说:

  1. int n = Conn(123,456); /*
    结果就是n=123456;*/
  2. char* str = Conn("asdf", "adf"); /*结果就是
    str = "asdfadf";*/

(2)再来看#@x,其实就是给x加上单引号,结果返回是一个const
char。举例说:

char a = ToChar(1);结果就是a=‘1‘;
做个越界试验char a = ToChar(123);结果就错了;
但是如果你的参数超过四个字符,编译器就给给你报错了!

error C2015: too many characters in constant   :P

(3)最后看看#x,估计你也明白了,他是给x加双引号

char* str = ToString(123132);就成了str="123132";

===========================================================

常用的一些宏定义

===========================================================


1 防止一个头文件被重复包含

  1. #ifndef BODYDEF_H
  2. #define BODYDEF_H
  3. //头文件内容
  4. #endif

2 得到指定地址上的一个字节或字

  1. #define MEM_B( x ) ( *( (byte *) (x) ) )
  2. #define MEM_W( x ) ( *( (word *) (x) ) )

用法如下:

  1. #include <iostream>
  2. #include <windows.h>
  3. #define MEM_B(x) (*((byte*)(x)))
  4. #define MEM_W(x) (*((WORD*)(x)))
  5. int main()
  6. {
  7. int bTest = 0x123456;
  8. byte m = MEM_B((&bTest));/*m=0x56*/
  9. int n = MEM_W((&bTest));/*n=0x3456*/
  10. return 0;
  11. }

3 得到一个field在结构体(struct)中的偏移量

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

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

  1. #define FSIZ( type, field ) sizeof( ((type *) 0)->field )

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

  1. #define B_PTR( var ) ( (byte *) (void *) &(var) )
  2. #define W_PTR( var ) ( (word *) (void *) &(var) )

6 将一个字母转换为大写

  1. #define UPCASE( c ) ( ((c) >= ‘‘a‘‘ && (c) <= ‘‘z‘‘) ? ((c) - 0x20) : (c) )

7 判断字符是不是10进值的数字

  1. #define DECCHK( c ) ((c) >= ‘‘0‘‘ && (c) <= ‘‘9‘‘)

8 判断字符是不是16进值的数字

  1. #define HEXCHK( c ) ( ((c) >= ‘‘0‘‘ && (c) <= ‘‘9‘‘) ||((c) >= ‘‘A‘‘ && (c) <= ‘‘F‘‘) ||((c) >= ‘‘a‘‘ && (c) <= ‘‘f‘‘) )

9 防止溢出的一个方法

  1. #define INC_SAT( val ) (val = ((val)+1 > (val)) ? (val)+1 : (val))

10 返回数组元素的个数

  1. #define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )

11 使用一些宏跟踪调试

在调试时,我们可以设置__DEBUG宏,也可以再Makefile中使用-D编译选项设置,

#define __DEBUG  

使用方法为,

    #ifdef __DEBUG
    printf("%s", ...);
    #endif  

另外,ANSI C标准中有几个标准预定义宏,前面几个(func...STDC)常用于printf(sprintf)等语句中:

__func__:在源代码中插入当前所在函数名;

__LINE__:在源代码中插入当前源代码行号;

__FILE__:在源文件中插入当前源文件名;

__DATE__:在源文件中插入当前的编译日期

__TIME__:在源文件中插入当前编译时间;

__STDC__:当要求程序严格遵循ANSI C标准时该标识被赋值为1;

__cplusplus:当编写C++程序时该标识符被定义。

其中__cplusplus常用于头文件中,格式如下:

    #ifndef _ZX_FUNC_H
    #define _ZX_FUNC_H  

    #ifdef __cplusplus
    extern "C" {
    #endif  

    /* functions */
    char *strdup (const char *s);  

    #ifdef __cplusplus
    }
    #endif  

    #endif  

extern"C"表示将其中的代码按照C编译方法编译,目的是实现C++与C语言的调用。

C编译与C++编译的区别是:C会将上面strdup编译成_STRDUP符号,而C++会编译成_STRDUP_CHAR,这也是C++为什么能实现函数重载的原因。extern只能出现在C++文件中,一般如上面的方式置于头文件中。

要在C中调用C++代码,需要在C代码中的函数或变量声明为extern类型,在C++中将函数或变量用extern "C"修饰。


12 简单数学计算(绝对值,三角函数等)

#define ABS( a ) ( ((a)>0) ? (a) : (-(a)) )  

13 #define 一个复杂语句

比如交换a,b的值,

    #define(a,b) do { \
        int t = 0;
        t = a; \
        a = b; \
        b = t; \
    } while(0)  

注:#define的这些高级用法在Linux源代码很多处出现,可阅读参考Linux源代码。

from:http://blog.csdn.net/xiahouzuoxin/article/details/9494503

时间: 2024-10-11 01:46:55

#define命令的一些高级用法的相关文章

sed命令基础及高级用法

sed工具:sed是文本流编辑器,逐行对文件的内容进行处理 用法:sed [option] ... 'script' inputfile... 选项: -n:静默模式,不输出模式空间的内容至屏幕 -e:实现多点的功能编辑 -f /path/from/script_file:从指定的文件读取编辑脚本 -r:支持使用扩展的正则表达式 地址界面方法: (1)不给地址:对全文进行处理 (2)一个地址(单地址) #:指定的行 /pattern/:被引用处模式所能够匹配到的每一行: (3)地址范围 #,#:

#define的高级用法

=========================================================== define中的三个特殊符号:#,##,#@ =========================================================== #define Conn(x,y) x##y #define ToChar(x) #@x #define ToString(x) #x (1)x##y表示什么?表示x连接y,举例说: int n = Conn(12

Linux tar命令高级用法——备份数据

Linux tar命令高级用法——备份数据 2015-12-31 Linux学习 Linux上有功能强大的tar命令,tar最初是为了制作磁带备份(tape archive)而设计的,它的作用是把文件和目录备份到磁带中,然后从磁带中提取或恢复文件.现在我们可以使用tar来备份数据到任何存储介质上.它是文件级备份,不必考虑底层文件系统类别,并且支持增量备份. 1.部分常用选项 ●-z, --gzip:使用gzip工具(解)压缩,后缀一般为.gz ●-c, --create:tar打包,后缀一般为.

nmap命令-----高级用法

探测主机存活常用方式 (1)-sP :进行ping扫描 打印出对ping扫描做出响应的主机,不做进一步测试(如端口扫描或者操作系统探测): 下面去扫描10.0.3.0/24这个网段的的主机 1 nmap -sP 10.0.3.0/24 这个命令可以用于探测局域网有哪些机器 1 2 3 4 5 6 7 8 9 10 11 [[email protected] ~]# nmap -sP 10.0.3.0/24 Starting Nmap 5.51 ( http://nmap.org ) at 201

C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 本文由 arthinking 发表于315 天前 ⁄ itzhai.com原创文章 ⁄ C语言 ⁄ 评论数 3 ⁄ 被围观 1,775 views+ 指针数组: 在一个数组中,如果它的元素全部都是指针类

Python爬虫的Urllib库有哪些高级用法?

本文和大家分享的主要是python爬虫的Urllib库的高级用法相关内容,一起来看看吧,希望对大家学习python有所帮助. 1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它 是一段HTML代码,加 JS.CSS,如果把网页比作一个人,那么HTML便是他的骨架,JS便是他的肌肉,CSS便是它的衣服.所以最重要的部分是存在于HTML中的,下面我 们就写个例子来扒一个网页下来. imp

GUN sed高级用法,sed脚本编写

这里举一些sed常用的高级用法例子经供参考: 一下操作都针对file.txt文件作修改 [[email protected] ~]# cat file.txt libgcc-4.4.7-4.el6.x86_64 setup-2.8.14-20.el6_4.1.noarch tzdata-2013g-1.el6.noarch jakarta-commons-collections-3.2.1-3.4.el6.noarch filesystem-2.4.30-3.el6.x86_64 mesa-dr

Git log高级用法

格式化Log输出 首先,这篇文章会展示几种git log格式化输出的例子.大多数例子只是通过标记向git log请求或多或少的信息. 如果你不喜欢默认的git log格式,你可以用git config的别名功能来给你想要的格式创建一个快捷方式. Oneline --oneline标记把每一个提交压缩到了一行中.它默认只显示提交ID和提交信息的第一行.git log --oneline的输出一般是这样的: 0e25143 Merge branch 'feature' ad8621a Fix a b

Visual Studio 宏的高级用法

我已经介绍了如何编写一个最简单的宏,本文将进一步介绍如何用宏来实现对代码编辑窗口控制.在本文结束的时候,你应该能自己实现如下两个功能,第一个用于对方法体进行 phase0 标记:第二个可以将当前窗口中的代码进行归类,将所有方法.属性.变量通过region进行分块. 动画演示:phase0 动画演示:设置 region 为什么使用宏 在计算机行业内,宏的出现由来已久,因为它能替代人们执行一些重复发生的简单但烦琐的事情,所以广受人们欢迎.在 Visual Studio 中也提供了进行宏编程的方法,从