C Programming: Macros and Typedef Explained
Advertisement
Macros - Definitions
- A macro is a fragment of code that has been given a name. Whenever the name is used, it is replaced by the contents of the macro.
- This replacement is done by the C preprocessor.
- There are two kinds of macros, differing mostly in appearance and usage:
- Object-like macros resemble data objects when used.
- Function-like macros resemble function calls.
- Macros are used to substitute repetitive values or code fragments that are unsuitable for functions, or where converting them to a function might be costly.
Macros - Object-like Macros
-
An object-like macro is a simple identifier that will be replaced by a code fragment. It is called object-like because it looks like a data object in code. They are commonly used to give symbolic names to numeric constants.
-
#define BUFFER_SIZE 1024defines a macro namedBUFFER_SIZEas an abbreviation for the token1024. -
If a C statement of the form
foo = (char *) malloc (BUFFER_SIZE);appears after this#definedirective, the C preprocessor will recognize and expand the macroBUFFER_SIZE. The C compiler will see the same tokens as if you had writtenfoo = (char *) malloc (1024); -
By convention, macro names are written in uppercase, which makes it easier to identify them in the code.
-
The macro’s body ends at the end of the
#defineline. You can continue the definition onto multiple lines using backslash-newline if necessary. When the macro is expanded, however, it will all come out on one line. For example:#define NUMBERS 1, \ 2, \ 3 int x[] = { NUMBERS }; ==> int x[] = { 1, 2, 3 };Remember that there shouldn’t be any space at the end of the
\when you continue the macro in multiple lines. The C preprocessor scans your program sequentially. -
Macro definitions take effect at the place you write them. Therefore, the following input to the C preprocessor:
foo = X; #define X 4 bar = X;produces:
foo = X; bar = 4; -
What will the value of
xbe in the following program?#define BUFSIZE (1020) #define TABLESIZE (BUFSIZE) #undef BUFSIZE #define BUFSIZE (37) int main(void) { int x = TABLESIZE; printf ("x= %d\n"); }
Macros - Function-like Macros
-
Function-like macros can take arguments, just like true functions.
-
To define a macro that uses arguments, insert parameters between the parentheses in the macro definition, making the macro function-like. The parameters must be valid C identifiers, separated by commas and optionally whitespace.
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) x = MIN(a, b); ==> x = ((a) < (b) ? (a) : (b)); y = MIN(1, 2); ==> y = ((1) < (2) ? (1) : (2)); z = MIN(a + 28, *p); ==> z = ((a + 28) < (*p) ? (a + 28) : (*p));
Macros - Concatenation
- It is often useful to merge two tokens into one while expanding macros. This is called token pasting or token concatenation.
- The
##preprocessing operator performs token pasting. When a macro is expanded, the two tokens on either side of each##operator are combined into a single token, which then replaces the##and the two original tokens in the macro expansion.
Typedef - Definition and Uses
-
A
typedefdeclaration lets you define your own identifiers that can be used in place of type specifiers such asint,float, anddouble. -
A
typedefdeclaration does not reserve storage. The names you define usingtypedefare not new data types, but synonyms for the data types or combinations of data types they represent. -
When an object is defined using a
typedefidentifier, the properties of the defined object are exactly the same as if the object were defined by explicitly listing the data type associated with the identifier. This means that:typedef unsigned char uint8; uint8 abcd;and
unsigned char abcd;are the same.
-
typedefallows users to define data types as they want. Usingtypedefcan make code easier to read and easier to port to a new machine. However, no new physical data type is created. `
Advertisement