宏定义用法大全(可以直接考到vs2010中运行看效果)

// macro test.cpp : 定义控制台应用程序的入口点。
//宏定义是C提供的三种预处理功能的其中一种,这三种预处理包括:宏定义、文件包含、条件编译。
/*1.不带参数的宏定义:
  宏定义又称为宏代换、宏替换,简称“宏”。
    格式:
     #define标识符 字符串
     其中的标识符就是所谓的符号常量,也称为“宏名”。
     *预处理(预编译)工作也叫做宏展开:将宏名替换为字符串。
     掌握"宏"概念的关键是“换”。一切以换为前提、做任何事情之前先要换,准确理解之前就要“换”。
       即在对相关命令或语句的含义和功能作具体分析之前就要换:
  例:
   #define PI 3.1415926
   把程序中出现的PI全部换成3.1415926
   说明:
   (1)宏名一般用大写。
   (2)使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例如:数组大小常用宏定义。
   (3)预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。
   (4)宏定义末尾不加分号。
   (5)宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头。
   (6)可以用#undef命令终止宏定义的作用域。
   (7)宏定义可以嵌套。
   (8)字符串" "中永远不包含宏。
   (9)宏定义不分配内存,变量定义分配内存。
   (10)宏定义不存在类型问题,它的参数也是无类型的。
  2.带参数的宏定义:
    除了一般的字符串替换,还要做参数代换
    格式:
     #define 宏名(参数表) 字符串
     例如:#define S(a,b) a*b
    area=S(3,2);第一步被换为area=a*b; ,第二步被换为area=3*2;
    类似于函数调用,有一个哑实结合的过程:
   (1)实参如果是表达式容易出问题
    #define S(r) r*r
    area=S(a+b);第一步换为area=r*r;第二步被换为area=a+b*a+b;
    正确的宏定义是#define S(r) ((r)*(r))
   (2)宏名和参数的括号间不能有空格。
   (3)宏替换只作替换,不做计算,不做表达式求解。
   (4)函数调用在编译后程序运行时进行,并且分配内存。宏替换在编译前进行,不分配内存。
   (5)宏的哑实结合不存在类型,也没有类型转换。
   (6)函数只有一个返回值,利用宏则可以设法得到多个值。
   (7)宏展开使源程序变长,函数调用不会。
    (8)宏展开不占运行时间,只占编译时间,函数调用占运行时间(分配内存、保留现场、值传递、返回值)。*/


#include "stdafx.h"
#include
using namespace std;
//#define a(x) x*x
#define a(x) (x)*(x)
#define b(x) ((x)*(x))
#define c(x,y) (x+x-y)   //注意括号的应用,要不计算结果会出错。
#define Conn(x,y) x##y   //连接x y(可以是int,char)。
#define ToChar(x) #@x    //给x加上单引号,结果返回是一个const char。
#define ToString(x) #x   //给x加双引号
#ifndef BODYDEF_H 
#define BODYDEF_H 
 //头文件内容 


#endif                   //防止一个头文件被重复包含,防止重复定义。
#define ARR_SIZE(a) (sizeof((a))/sizeof((a[0])))  //int 和char都行。
int _tmain(int argc, _TCHAR* argv[])
{
int s[]={1,2,3,4,5,6,7,8,9};
//char s[]={"abc"};
int size=ARR_SIZE(s);
cout< int i=a(3+2);
cout< int j=b(2+2)/b(2+2);
cout< int q=c(3,2);
cout< char *r=Conn("123","123");//int r=Conn(123,123);
cout< char a = ToChar(1);
cout< char* str = ToString(123132);
cout< /*得到指定地址上的一个字节或字
#define MEM_B( x ) ( *( (byte *) (x) ) ) 
#define MEM_W( x ) ( *( (word *) (x) ) )
用法如下:
#include
#include
#define MEM_B(x) (*((byte*)(x)))
#define MEM_W(x) (*((WORD*)(x)))
int main()
{
    int bTest = 0x123456;
    byte m = MEM_B((&bTest));/*m=0x56
    int n = MEM_W((&bTest));/*n=0x3456
}
/*得到一个field在结构体(struct)中的偏移量
#define OFFSETOF( type, field ) ( (size_t) &(( type *) 0)-> field )
得到一个结构体中field所占用的字节数 
#define FSIZ( type, field ) sizeof( ((type *) 0)->field )
得到一个变量的地址(word宽度) 
#define B_PTR( var ) ( (byte *) (void *) &(var) ) 
#define W_PTR( var ) ( (word *) (void *) &(var) )
将一个字母转换为大写
#define UPCASE( c ) ( ((c) >= ''a'' && (c) <= ''z'') ? ((c) - 0x20) : (c) )
判断字符是不是10进值的数字
#define DECCHK( c ) ((c) >= ''0'' && (c) <= ''9'')
判断字符是不是16进值的数字 
#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]) ) )
ANSI标准说明了五个预定义的宏名。它们是: 
_LINE_ /*(两个下划线),对应%d
_FILE_ /*对应%s
_DATE_ /*对应%s
_TIME_ /*对应%s*/



system("pause");
return 0;
}

你可能感兴趣的:(宏定义用法大全(可以直接考到vs2010中运行看效果))