C Macro - the blade of the wise, the nightmare of fool!

xiaoxiao2021-03-05  24

C programmers with low levels, the most like to hang in the mouth is: C macro, the first thing, the wrong opening, should be discarded.

Please note that I have used a disrespectful modifier "level is not high". Why do you say that? Because the level is low, I will listen to the old seniors quietly. High levels, such as Bane Stroustrup old people, but also say that the C language can provide better solutions than C Macro without completely negation of C Macro. But I am afraid that I will pass it, I will go out. Over time, it is transmitted to the above sentence. In fact, it is also very funny: Java programmers often say that Java is better than C , saying that C manually releases the memory of the memory; C programmer refutes, it is that you will not use it. But talk to C macro, C programmers in low levels, actually take Java's old road - obviously it will not be used, it knows less, but shirk the responsibility to C macro. You can't manage your own stupid, but if you misunderstand, if you mislead, it's not good. :)

This article will take a few simple examples of C Macro. If these examples don't have a macro that can be better solved with C , then you must reply to blog tell me, so I will not talk about it next time. Otherwise, smiling is very angry, and the consequences are very serious. :)

For example, use C macro, write code more simple, this code writes a network program, is very familiar, and is the implementation of MBUF in Net / 3.

Struct MBUF

{

Struct M_HDR MHDR;

Union {

Struct

{

Struct Pkthdr MH_PKTHDR; / * M_PKTHDR SET * /

union

{

STRUCT M_EXT MH_EXT; / * M_EXT SET * /

CHAR MH_DATABUF [MHLEN];

} MH_DAT;

} MH;

Char m_databuf [mlen]; / *! m_pkther,! m_ext * /

} M_dat;

}

The above code, if I want to access the most milesty MH_DATABUF, then I must write m_dat.mh.mh_dat.mh_database; Is this very long, it is difficult to write? Such code is unknown. In fact, for MH_PKTHDR, MH_EXT, MH_DATABUF, although not in a structural hierarchy, if we stand outside MBUF, they are the properties of MBUF, which can be smashed into a plane. Therefore, there is such a set of macros in the source code:

#define m_next m_hdr.mh_next

#define m_len m_hdr.mh_len

#define m_data m_hdr.mh_data

...

#define m_pkthdr m_dat.mh.mh_pkthdr

#define m_pktdat m_dat.mh.mh_dat.mh_databuf

...

This is not very refined in this way of writing this code!

Example 2, using C macro, realizing the need for cross-platform and compiler, this example is too good, one fell in a big plus, from the VC's library source code coming out.

#ifndef _CRTAPI1

#iF _MSC_VER> = 800 && _m_ix86> = 300

#define _CRTAPI1 __CDECL

#ELSE / * _MSC_VER> = 800 && _m_ix86> = 300 * / # define _CRTAPI1

#ENDIF / * _MSC_VER> = 800 && _m_ix86> = 300 * /

#ENDIF / * _CRTAPI1 * /

#ifndef _size_t_defined

Typedef unsigned int size_t;

#define _size_t_defined

#ENDIF / * _SIZE_T_DEFINED * /

#ifndef _mac

#ifndef _wchar_t_defined

Typedef unsigned short wchar_t;

#define_wchar_t_defined

#ENDIF / * _WCHAR_T_DEFINED * /

#ENDIF / * _MAC * /

#ifndef _nlscmp_defined

#define _nlscmperror 2147483647 / * Currently == INT_MAX * /

#define _nlscmp_defined

#ENDIF / * _NLSCMP_DEFINED * /

Excuse me, how does these instructions replace? If you really have these macros, it's more troublesome.

Example III, using C macro, automatically generate code this example is also very much, but in view of many friends do not need many compilers, do not do embedded development, I will give an example of a Win platform. We know that the MFC implements Windows message mappings, such as:

ON_COMMAND (IDM_ABOUT, ONWABOUT)

ON_COMMAND (IDM_FileNew, Onfilenew)

How is it true of IDM_about and onabout? This is used to use several macros.

#define declare_message_map () /

PRIVATE: /

Static const AFX_MSGMAP_ENTRY _MESSAGEENTRIES []; /

protected: /

Static AFX_DATA Const AFX_MSGMAP MessageMap; /

Virtual const AFX_MSGMAP * getMessageMap () const; /

#define begin_Message_Map (Theclass, Baseclass) /

Const AFX_MSGMap * Theclass :: getMessageMap () const /

{RETURN & THECLASS :: MessageMap;} /

AFX_COMDAT AFX_DATADEF const AFX_MSGMAP THECLASS :: MessageMap = /

{& Baseclass :: MessageMap, & Theclass :: _ Messagentries [0]}; /

AFX_COMDAT const AFX_MSGMAP_ENTRY THECLASS :: _ MessageEntries [] = /

{/

#define on_command (id, memberfxn) /

{WM_COMMAND, 0, (Word) ID, (Word) ID, AFXSIG_VV, (AFX_PMSG) MEMBERFXN},

#define end_message_map () /

{0, 0, 0, 0, AFXSIG_END, (AFX_PMSG) 0} /

}; /

#define declare_message_map () /

PRIVATE: /

Static const AFX_MSGMAP_ENTRY _MESSAGEENTRIES []; / protected: /

Static AFX_DATA Const AFX_MSGMAP MessageMap; /

Virtual const AFX_MSGMAP * getMessageMap () const; /

#define begin_Message_Map (Theclass, Baseclass) /

Const AFX_MSGMap * Theclass :: getMessageMap () const /

{RETURN & THECLASS :: MessageMap;} /

AFX_COMDAT AFX_DATADEF const AFX_MSGMAP THECLASS :: MessageMap = /

{& Baseclass :: MessageMap, & Theclass :: _ Messagentries [0]}; /

AFX_COMDAT const AFX_MSGMAP_ENTRY THECLASS :: _ MessageEntries [] = /

{/

#define on_command (id, memberfxn) /

{WM_COMMAND, 0, (Word) ID, (Word) ID, AFXSIG_VV, (AFX_PMSG) MEMBERFXN},

#define end_message_map () /

{0, 0, 0, 0, AFXSIG_END, (AFX_PMSG) 0} /

}; /

Hey, just a few macros, construct a message array.

Example four, with C macro, the spark of the wise thinking said for a long time, the mouth is dry, and everyone is easy - to see how people do happhoot how to use macro. This example is taken from "C Expert Program". The graphic icon (ICON) or graphics (GLYPH) is built according to the bit mode, which is a small bit mode mapped to the image generated by the screen. A bit represents a pixel on the image. If a bit is set, then the pixels it represent is "bright". If a bit is cleared, the pixels he represent is "dark". Therefore, a series of integer values ​​can be used to encode image. Tools like IconEdit are used for drawing, and they are output is an ASCII file containing a series of integer, which can be included in a window program. The problem it exists is that the icon in the program is just a string of hexadecimal numbers. In C language, the typical 16x16 black and white graphics may be as follows:

Static unsigned short stopwatch [] = {

0x07c6,

0x1ff7,

0x383b,

0x600c,

0x600c,

0xC006,

0xC006,

0xDF06,

0xC106,

0xC106,

0x610c,

0x610c,

0x3838,

0x1ff0,

0x07c0,

0x0000

}

As seen, these C language constants do not provide any clues to the actual mode of graphics. Here is an elegant collection of an amazing #define definition, allowing the program to establish constants to make them look like a graphic on the screen.

#define x) * 2 1

#define _) * 2

#define s (((((((((((((((((((((((((((((((((,,,,,,,

After defining them, as long as the icon or graphics you need, the program will automatically create their hexadecimal mode. Using these macros, the self-description ability of the program is greatly enhanced, and the above example can be converted to:

Static unsigned short stopwatch [] =

{

s _ _ _ _ _ x_,

S _ __X x x_ x,

S _ x _ _ _ _ _ _ _ _ _ X _ _,

S _ x _ _ _ _ _ _ _ _ _ X _ _,

S x x _ _ _ _ _ _ _ _ _ _ _ X _,

S x x _ _ _ _ _ _ _ _ _ _ _ X _,

S x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x_____

S x x _ _ _ _ _ x _ _ _ _ _ X _,

S x x _ _ _ _ _ x _ _ _ _ _ X _,

S _ x _ _ _ _ X _ _ _ _ X _ _,

S _ x _ _ _ _ X _ _ _ _ X _ _,

S _ _ x x _ _ _ _ _ x x _ _ _,

s _ __X__ x__

s _ _ _ _ _ x x x x _ _ _ _ _ _,

s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

}

Obviously, it means more obvious compared to the previous code. The standard C language has an octal, decimal and hexadecimal constant, but there is no binary constant, otherwise it is a more simple way to draw graphics mode.

If you seize the upper right corner of your book, you will see this page, you may guess this is a "Cursor Busy" small second table graphic for popular window systems. I learned this skill from the USENET COMP.lang.c News Group a few years ago.

Don't forget to clear these macro definitions after the drawing, no, this is likely to bring you unpredictable consequences later.

Ok, today's nonsense is here. Water can boat, can also take the boat, grasp the double-edged sword in his hands, let it serve you, don't cut your hands. :)

转载请注明原文地址:https://www.9cbs.com/read-33195.html

New Post(0)