C言語マクロ定義のテクニック
8690 ワード
出典:http://blog.chinaunix.net/uid-14022540-id-2849095.html
1.マクロの中の「萼」と「菗33751;」の使い方
一、一般的な使い方
私たちはマクロパラメータを使って文字列に変えて、二つのマクロパラメータを一緒にくっつけます。
1、'33852;'と'璢33751;'の場合ではなく、自然に展開されます。
萼デfine TOW (2)
_defineMUL(a,b)(a*b)
printf(「%d*%d=%d」、TOW、TOW、MUL(TOW、TOW);
この行のマクロは次のように展開されます。
printf('%d*%d=%d",(2),((2)*(2)))))));
MULのパラメータTOWは(2)に展開されます。
2,「萼」または「菗菗」があるときは、「葃」または「\ӗ〹〹〹」のローカルマクロパラメータは再展開されません。
湖南省にある地名 (2)
〹define CONS(a,b) (int)(a〓〓〓〓〓〓〓〓〓〓〓〓〓〓))
printf("%s",CONS(A,A)); // comple error
この行は:
printf(“%s”、int(AeA);
しかし、この問題を解決する方法はとても簡単です。マクロの中間変換を多くします。
1,ヘッダファイルが重複して含まれることを防止する
ヽoo。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。H
ハデfine COMDEF_H
//ヘッダファイルの内容
湖南省にある地名
2,いくつかのタイプを再定義し、様々なプラットフォームとコンパイラの違いによるバイト数の違いを防止し、移植を容易にする。
typedef unsigned char book; /* Boolean value type.*/
typedef unsigned long int uint 32; /* Unisigned 32 bit value*/
typedef unsigned shart uint 16; /* Unisigned 16 bit value*/
typedef unsigned char uint 8 /* Unisigned 8 bit value*/
typedef signed long int int 32; /* Signed 32 bit value*/
typedef signed shart int 16 /* Signed 16 bit value*/
typedef signed char int 8; /* Signed 8 bit value*/
typedef unsigned char byte; /* Unisigned 8 bit value type.*/
typedef unsigned shart word; /* Unisinged 16 bit value type.*/
typedef unsigned long dword; /* Unisigned 32 bit value type.*/
3,指定されたアドレスのバイトまたはワードを取得します。
同前 MEMB(x) (*(((byte*)(x))
同前 MEMW(x) (*((word*)(x))
4,最大値と最小値を求める
#define MAX(x,y)((x)>(y))?(x):(y)
#define MIN(x,y)((x)<(y)))?(x):(y)
7,LSB形式によって、二つのバイトをワードに変換する。
#define FLIPW(ray)(((((word)[0]*256)+(ray)[1])
8,LSB形式で一つのWordを二バイトに変換する
#define FLOW(ray,val)\
(ray)[0]=(val)/256);\
(ray)[1]=(val)&0 xFF)
12、1文字を大文字に変換します。
#define UPCSE(c)(((((c)>='a'&(c)='0'&((c)='0'&((*)='A'&(c)='a'&((c) (val)?(val)+1:(val)
20、マクロ定義の使用防止はエラーです。
括弧で含める
do{}while(0)の文で複数の語句を含んでエラーを防止します。
eg:((zhi define ADD(a,b)do{a+b;)
a++;}while(0)
1.マクロの中の「萼」と「菗33751;」の使い方
一、一般的な使い方
私たちはマクロパラメータを使って文字列に変えて、二つのマクロパラメータを一緒にくっつけます。
#include <stdio.h>
#define CONS(a,b) ((int)(a##e##b))
#define STR(s) #s
int main()
{
printf("%s
",STR(ABC));
printf("%d
",CONS(2,3));
return 0;
}
/*
root@oucaijun:/work/dcc# gcc *.c; ./a.out
ABC
2000
*/
二、マクロパラメータが別のマクロの場合: 注意しなければならないのは、凡宏の定義において、「〓」や「〓〓」というところのマクロパラメータが展開されないことです。1、'33852;'と'璢33751;'の場合ではなく、自然に展開されます。
萼デfine TOW (2)
_defineMUL(a,b)(a*b)
printf(「%d*%d=%d」、TOW、TOW、MUL(TOW、TOW);
この行のマクロは次のように展開されます。
printf('%d*%d=%d",(2),((2)*(2)))))));
MULのパラメータTOWは(2)に展開されます。
2,「萼」または「菗菗」があるときは、「葃」または「\ӗ〹〹〹」のローカルマクロパラメータは再展開されません。
湖南省にある地名 (2)
〹define CONS(a,b) (int)(a〓〓〓〓〓〓〓〓〓〓〓〓〓〓))
printf("%s",CONS(A,A)); // comple error
この行は:
printf(“%s”、int(AeA);
しかし、この問題を解決する方法はとても簡単です。マクロの中間変換を多くします。
#include <stdio.h>
#define _GET_FILE_NAME(f) (#f)
#define GET_FILE_NAME(f) _GET_FILE_NAME(f)
int main()
{
// GET_FILE_NAME(f) , #, , 。
static char FILENAME[] = GET_FILE_NAME(__FILE__);//"test.c"
printf("%s
", FILENAME);
// _GET_FILE_NAME(f) , __FILE__
// _GET_FILE_NAME , , ,
static char FILENAME2[] = _GET_FILE_NAME(__FILE__);//__FILE__
printf("%s
", FILENAME2);
return 0;
}
/*
root@oucaijun:/work/dcc# gcc *.c; ./a.out
"test.c"
__FILE__
*/
2.マクロトラッキングデバッグ#include <stdio.h>
#include <time.h>
int main()
{
time_t t;
time(&t);
printf("file:%s, line:%d, function:%s, msg:%s, date:%s
", \
__FILE__, __LINE__, __FUNCTION__,"hello", ctime(&t));
return 0;
}
/*
root@oucaijun:/work/dcc# gcc *.c; ./a.out
file:1.c, line:11, function:main, msg:hello, date:Tue Jul 21 17:03:01 2015
*/
_DEBUG,
#include <stdio.h>
#include <time.h>
#define _DEBUG
#ifdef _DEBUG
#define DEBUGMSG(msg, date) \
do{\
printf("msg: %s; file:%s, line:%d, date:%s
",msg, __FILE__, __LINE__, date);\
}while(0)
#else
#define DEBUGMSG(msg,date)
#endif
int main()
{
time_t now;
time(&now);
DEBUGMSG("hello",ctime(&now));
return 0;
}
/*
root@oucaijun:/work/dcc# gcc *.c; ./a.out
msg: hello; file:1.c, line:22, date:Tue Jul 21 17:05:44 2015
*/
3.以下にソフトウェアでよく使われるマクロ定義を挙げます。1,ヘッダファイルが重複して含まれることを防止する
ヽoo。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。H
ハデfine COMDEF_H
//ヘッダファイルの内容
湖南省にある地名
2,いくつかのタイプを再定義し、様々なプラットフォームとコンパイラの違いによるバイト数の違いを防止し、移植を容易にする。
typedef unsigned char book; /* Boolean value type.*/
typedef unsigned long int uint 32; /* Unisigned 32 bit value*/
typedef unsigned shart uint 16; /* Unisigned 16 bit value*/
typedef unsigned char uint 8 /* Unisigned 8 bit value*/
typedef signed long int int 32; /* Signed 32 bit value*/
typedef signed shart int 16 /* Signed 16 bit value*/
typedef signed char int 8; /* Signed 8 bit value*/
typedef unsigned char byte; /* Unisigned 8 bit value type.*/
typedef unsigned shart word; /* Unisinged 16 bit value type.*/
typedef unsigned long dword; /* Unisigned 32 bit value type.*/
3,指定されたアドレスのバイトまたはワードを取得します。
同前 MEMB(x) (*(((byte*)(x))
同前 MEMW(x) (*((word*)(x))
4,最大値と最小値を求める
#define MAX(x,y)((x)>(y))?(x):(y)
#define MIN(x,y)((x)<(y)))?(x):(y)
7,LSB形式によって、二つのバイトをワードに変換する。
#define FLIPW(ray)(((((word)[0]*256)+(ray)[1])
8,LSB形式で一つのWordを二バイトに変換する
#define FLOW(ray,val)\
(ray)[0]=(val)/256);\
(ray)[1]=(val)&0 xFF)
12、1文字を大文字に変換します。
#define UPCSE(c)(((((c)>='a'&(c)='0'&((c)='0'&((*)='A'&(c)='a'&((c) (val)?(val)+1:(val)
20、マクロ定義の使用防止はエラーです。
括弧で含める
do{}while(0)の文で複数の語句を含んでエラーを防止します。
eg:((zhi define ADD(a,b)do{a+b;)
a++;}while(0)