Deep discussion on the usage of MACRO

see the code directly:

/* macro.c by vinco at 2011-09-15
*   i386-Red Hat-gcc-4.1.2 
*   http://blog.youkuaiyun.com/xuyunzhang/
*   Copyright: All Reserved
*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define conn(x,y) 		x##y	//xy,    (x)##(y) is not correct !!!
#define toString(x) 	#x 		//"x",   #(x) is not correct !!!
#define SWAP_INT(x,y)	({(x)^=(y)^=(x)^=(y);}) //can x,y be point !!!

/* support both struct type and basic type, but not point */
#define SWAP_GENERAL(x,y,DATA_TYPE)	do{\
	DATA_TYPE tmp;\
	memcpy(&tmp, &x, sizeof(DATA_TYPE) );\
	memcpy(&x, &y, sizeof(DATA_TYPE) );\
	memcpy(&y, &tmp, sizeof(DATA_TYPE) );\
	}while(0)
	
/* support only point/address !!! */
#define SWAP_POINT(x,y,DATA_TYPE)	do{\
	DATA_TYPE tmp;\
	memcpy(&tmp, x, sizeof(DATA_TYPE) );\
	memcpy(x, y, sizeof(DATA_TYPE) );\
	memcpy(y, &tmp, sizeof(DATA_TYPE) );\
	}while(0)

typedef struct classmate
{
	int age;
	char name[30];
}ClassMate;

void FuncTest(void);

int main(void)
{
	/*-----------------------------------------------*/
	int num= conn(123,456);
	//int num = (123##456);

	char* pStr = toString(vinco zhang);
	//char* p = #vinco;

	printf("num = %d\n", num);
	printf("pStr = %s\n", pStr);

	putchar('\n');
	/*-----------------------------------------------*/
	int x =10,y=20;
	printf("x=%d, y=%d\n", x, y);
	SWAP_INT(x,y);
	//SWAP_GENERAL( x, y, int); // is ok too !!!
	printf("x=%d, y=%d\n", x, y);

	putchar('\n');
	/*-----------------------------------------------*/
	int *px =&x,*py=&y;
	printf("*px=%d, *py=%d\n", *px, *py);

	//SWAP_INT( px, py);     // error of course !!!
	//SWAP_INT( *px, *py); //not correct, but why ???
	
	//SWAP_GENERAL( *px, *py, int); // is ok too !!!
	SWAP_POINT( px, py, int);
	printf("*px=%d, *py=%d\n", *px, *py);
	
	putchar('\n');
	/*-----------------------------------------------*/
	ClassMate classmates[2] =
	{
		{124, "vinco" },
		{24, "zhang" }
	};
	printf("classmates[0].age = %d, classmates[0].name = %s\n", classmates[0].age, classmates[0].name );
	printf("classmates[1].age = %d, classmates[1].name = %s\n", classmates[1].age, classmates[1].name );
	SWAP_GENERAL(classmates[0], classmates[1], ClassMate); 
	//SWAP_POINT(&classmates[0], &classmates[1], ClassMate); //is ok too !!!
	printf("classmates[0].age = %d, classmates[0].name = %s\n", classmates[0].age, classmates[0].name );
	printf("classmates[1].age = %d, classmates[1].name = %s\n", classmates[1].age, classmates[1].name );

	putchar('\n');
	/*-----------------------------------------------*/
	ClassMate* pClassmates[2] =
	{
		&classmates[0],
		&classmates[1]
	};
	printf("pClassmates[0]->age = %d, pClassmates[0]->name = %s\n", pClassmates[0]->age, pClassmates[0]->name );
	printf("pClassmates[1].age = %d, pClassmates[1]->name = %s\n", pClassmates[1]->age, pClassmates[1]->name );
	//SWAP_GENERAL( *pClassmates[0], *pClassmates[1], ClassMate); //is ok too !!!
	SWAP_POINT( pClassmates[0], pClassmates[1], ClassMate);
	printf("pClassmates[0]->age = %d, pClassmates[0]->name = %s\n", pClassmates[0]->age, pClassmates[0]->name );
	printf("pClassmates[1]->age = %d, pClassmates[1]->name = %s\n", pClassmates[1]->age, pClassmates[1]->name );

	putchar('\n');
	/*-----------------------------------------------*/
	FuncTest();
	/*-----------------------------------------------*/
	return 0;
}


void FuncTest(void)
{
	printf( "The %s is %s\n", toString(__FUNCTION__), __FUNCTION__ );
	printf( "The %s is %s\n", toString(__FILE__), __FILE__ );
	printf( "The %s is %d\n", toString(__LINE__), __LINE__ );
	printf( "The %s is %s\n", toString(__DATE__), __DATE__ );
	printf( "The %s is %s\n", toString(__TIME__), __TIME__ );
} 


make and run  it:

[vinco@IPPBX-Server ctest]$ make macro
cc     macro.c   -o macro
[vinco@IPPBX-Server ctest]$ ./macro
num = 123456
pStr = vinco zhang

x=10, y=20
x=20, y=10

*px=20, *py=10
*px=10, *py=20

classmates[0].age = 124, classmates[0].name = vinco
classmates[1].age = 24, classmates[1].name = zhang
classmates[0].age = 24, classmates[0].name = zhang
classmates[1].age = 124, classmates[1].name = vinco

pClassmates[0]->age = 24, pClassmates[0]->name = zhang
pClassmates[1].age = 124, pClassmates[1]->name = vinco
pClassmates[0]->age = 124, pClassmates[0]->name = vinco
pClassmates[1]->age = 24, pClassmates[1]->name = zhang

The __FUNCTION__ is FuncTest
The __FILE__ is macro.c
The __LINE__ is 111
The __DATE__ is Sep 15 2011
The __TIME__ is 17:36:13
[vinco@IPPBX-Server ctest]$ 


 

1. " #define toChar(x)#@x //'x' "
it's not support in gcc, at least in Red Hat-gcc-4.1.2 and Ubuntu-gcc-4.3.2

however, it's supported in Visual C++ 6.0 .

2.
#define conn(x,y)   (x)##(y)  //xy,
#define toString(x)   #(x)   //"x",
are not correct !!!

3. some syntax is only suitable for macro defination, it accur error once used in general place.
int i = (123##456);
char* p = #vinco;
are error !!!

4. the value of a specific macro is determined once complete compiled, otherwise compile it again.
so the value of "__DATE__" and  "__DATE__" are not changed even although execute the programm many times.

5. macro is really a good skill you can take for, especially the macro with parameter.
because it merely do some about substitution, the paremeter can be the type itself,
such as "char", "struct ClassMate".
just see "SWAP_GENERAL(x,y,DATA_TYPE)".

6. GCC support "{ any; specific; context; }" now!!! , it's equivalent to "do{any; specific; context;}while(0)",
any more , you can distribute it to several lines just by adding "\" to the end per line.
(no space charater followed any more, including ' ','\t')

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值