一般源程序中的所有程序行都参加编译,但有时希望对其中一部分内容只在满足一定条件下才进行编译.
#if、#elif、 #else、#endif、#ifdef、#ifndef
/*选择不同的编译范围,产生不同的代码,提供通用性。*/
/*如对8051在6MHZ与12MHZ下有*/
#ifdef cpu==8051
#define FREQ 6 /*程序段*/
#else
#define FREQ 12/*程序段*/
#endif
/*这样下面的原程序不用做任何修改便可以使用于两种时钟频率的单片机系统*/
1:开关作用,条件编程
#ifdef A
程序段
#endif
2:避免重复定义,重复包舍
#ifndef A
#defined A
程序段
#endif
#if defined(COM_DEBUG) || defined(XU_DEBUG)
//#include "xucommon.h"
#define DEBUG_PRINT UARTprintf
#elif defined(STM_DEBUG)
#define DEBUG_PRINT printf
#else
//#define DEBUG_PRINT while(0)((int (*)(char *, ...))0)
#define DEBUG_PRINT
#endif
#if defined (_10MBIT_)
write_PHY (PHY_REG_CTRL, PHY_FULLD_10M);
#elif defined (_100MBIT_)
write_PHY (PHY_REG_CTRL, PHY_FULLD_100M);
#else
write_PHY (PHY_REG_CTRL, PHY_AUTO_NEG);
for (tout = 0; tout < 0x20000; tout++) {
regv = read_PHY (PHY_REG_STAT);
if (regv & 0x0020) {
break;
}
}
#endif
//结构类型定义中也可以包含宏定义
struct http_state {
struct fs_file *handle;
char *file; /* Pointer to first unsent byte in buf. */
char *buf; /* File read buffer. */
#ifdef INCLUDE_HTTPD_SSI
char *parsed; /* Pointer to the first unparsed byte in buf. */
char *tag_end; /* Pointer to char after the closing '>' of the tag. */
u32_t parse_left; /* Number of unparsed bytes in buf. */
#endif
u32_t left; /* Number of unsent bytes in buf. */
int buf_len; /* Size of file read buffer, buf. */
u8_t retries;
#ifdef INCLUDE_HTTPD_SSI
u8_t tag_check; /* true if we are processing a .shtml file else false */
u8_t tag_index; /* Counter used by tag parsing state machine */
u8_t tag_insert_len; /* Length of insert in string tag_insert */
u8_t tag_name_len; /* Length of the tag name in string tag_name */
char tag_name[MAX_TAG_NAME_LEN + 1]; /* Last tag name extracted */
char tag_insert[MAX_TAG_INSERT_LEN + 1]; /* Insert string for tag_name */
enum tag_check_state tag_state; /* State of the tag processor */
#endif
#ifdef INCLUDE_HTTPD_CGI
char *params[MAX_CGI_PARAMETERS]; /* Params extracted from the request URI */
char *param_vals[MAX_CGI_PARAMETERS]; /* Values for each extracted param */
#endif
#ifdef DYNAMIC_HTTP_HEADERS
const char *hdrs[NUM_FILE_HDR_STRINGS]; /* HTTP headers to be sent. */
u16_t hdr_pos; /* The position of the first unsent header byte in the current string */
u16_t hdr_index; /* The index of the hdr string currently being sent. */
#endif
};
#if !NO_SYS /* don't build if not configured for use in lwipopts.h */
#endif
//对某些无用的函数不编译.
#if 0
static BOOL check_lfn_old (const char *fn) {
}
#endif
#define ETH_ENABLE 1
#if ETH_ENABLE == 1 //4.01版本之前
#if (ETH_ENABLE) //4.11版本
{ { _IP1, _IP2, _IP3, _IP4 },
/* Default Gateway IP address */
{ _GW1, _GW2, _GW3, _GW4 },
/* Subnet IP Mask */
{ _MSK1, _MSK2, _MSK3, _MSK4 },
/* Primary DNS Server IP */
{ _pDNS1, _pDNS2, _pDNS3, _pDNS4 },
/* Secondary DNS Server IP */
{ _sDNS1, _sDNS2, _sDNS3, _sDNS4 }
},
#else
{ { 0,0,0,0 }, { 0,0,0,0 }, { 0,0,0,0 }, { 0,0,0,0 }, { 0,0,0,0 } },
#endif
#if !(SLIP_ENABLE || PPP_ENABLE || ETH_ENABLE)
#error all network interfaces disabled in configuration
#endif
#if GUI_ALLOC_SIZE == 0
#error GUI_ALLOC_SIZE needs to be > 0 when using this module
#endif
//--- lgdp4535_8bit.c
#if ! defined(PORTRAIT) && ! defined(PORTRAIT_FLIP) && \
! defined(LANDSCAPE) && ! defined(LANDSCAPE_FLIP)
#define LANDSCAPE//PORTRAIT
#endif
#define SWAPB(w) ((w>>8)|(w<<8)&0xFFFF) // Swap-exchange Hi<->Lo Bytes
#define HIB(w) (U8)(w>>8) // Extract Hi byte of Word
#define LOB(w) (U8)(w) // Extract Lo byte of Word
#if interface = 0
__int16 __stdcall writecard1(short comno,int userid,int cardtype,long cardno,char *Roomno,int cardid,int pubid,uchar *stime,uchar *etime,int timecontrol,int cengno,uchar *accountno,uchar *glceng,uchar *glroom,char *roomno1,int cardid1,char *roomno2,int cardid2,char *roomno3,int cardid3,int FloorSelect)
#else
__int16 __stdcall writecard1(short comno,int userid,long cardno,char *Roomno,int cardid,uchar *stime,uchar *etime,int timecontrol,int cengno,uchar *accountno,uchar *glceng,uchar *glroom,char *roomno1,int cardid1,char *roomno2,int cardid2,char *roomno3,int cardid3,int FloorSelect)
#endif
//---- gui.h, 无os时直接定义函数名
#if !GUI_OS
#define GUI_LOCK()
#define GUI_UNLOCK()
#define GUITASK_INIT()
#define GUITASK_COPY_CONTEXT()
#else
void GUI_Lock(void);
void GUI_Unlock(void);
void GUITASK_Init(void);
void GUITASK_CopyContext(void);
#define GUI_LOCK() GUI_Lock()
#define GUI_UNLOCK() GUI_Unlock()
#define GUITASK_INIT() GUITASK_Init()
#define GUITASK_COPY_CONTEXT() GUITASK_CopyContext()
#endif
#if GUIDEMO_LARGE
r = 50;
#elif !(GUIDEMO_TINY)
r = 40;
#else
#if (LCD_YSIZE < 80)
r = 23;
#else
r = 30;
#endif
#endif
-----------------------------------------------------
#define XMK_STR(x) #x //给x加上双引号
#define MK_STR(x) XMK_STR(x) //二次展开宏
#define CONFIG_IPADDR 192.168.1.1
#define CONFIG_SERVERIP 192.168.1.2
uchar default_environment[] = {
#ifdef CONFIG_IPADDR
"ipaddr=" MK_STR(CONFIG_IPADDR) "\0"
#endif
#ifdef CONFIG_SERVERIP
"serverip=" MK_STR(CONFIG_SERVERIP) "\0"
#endif
"\0"
};
//宏在预编译时只展开一次, 如下的只用1个宏实现, 则x一定不能为宏
#define MK_STR(x) #x
#define CONFIG_BAUDRATE 115200
unsigned char a[]=MK_STR(CONFIG_BAUDRATE);
printf("a = %s\n", a); //输出: "CONFIG_BAUDRATE", 宏只展开一次, 尚未展开到其具体内容!
//举例说明如下
#define STR(x) #x
#define _STR(x) STR(x)
#define x 123
STR(x); //如果这时x本身是一个宏, 那么展开会是"x", 而不是"123"
_STR(x); //那么会展开宏定义里的宏, 结果就是"123".
#define CAT(x,y) x##y //x连接y, 字符串和数值都可以
#define TOCHAR(x) #@x //x加上单引号
int n = CAT(123,456); //n = 123456
char* str = CAT("asdf", "adf"); // str = "asdfadf"