- #define
- A #define line defines a symbolic name or symbolic constant to be a particular string of characters:
#define name replacement list
Thereafter, any occurrence of name (not in quotes and not part of another name) will be replaced by the corresponding replacement text. The name has the same form as a variable name: a sequence of letters and digits that begins with a letter. The replacement text can be any sequence of characters; it is not limited to numbers. - Symbolic constant names are conventionally written in upper case so they can ber readily distinguished from lower case variable names. Notice that there is no semicolon at the end of a #define line.
- Macro Substitution
- A definition has the form
#define name replacement text
It calls for a macro substitution of the simplest kind - subsequent occurrences of the token name will be replaced by the replacement text. - The name in a #define has the same form as a variable name; the replacement text is arbitrary.
- Normally the replacement text is the rest of the line, but a long definition may be continued onto several lines by placing a \ at the end of each line to be continued.
- The scope of a name defined with #define is from its point of definition to the end of the source file being compiled. A definition may use previous definitions.
- Substitutions are made only for tokens, and do not take place within quoted strings.
- It is also possible to define macros with arguments, so the replacement text can be different for different calls of the macro.
- If you examine the expansion of max, you will notice some pitfalls. The expressions are evaluated twice; this is bad if they involve side effects like increment operators or input and output. For instance
max(i++, j++) /* WRONG */
#define max(A, B) ((A) > (B) ? (A) : (B))
x = max(p+q, r+s);
will increment the larger twice. Some care also has to be taken with parentheses to make sure the order of evaluation is preserved; consider what happens when the macro
#define square(x) x * x /* WRONG */
is invoked as square(z+1). - Names may be undefined with #undef, usually to ensure that a routine is really a function, not a macro:
#undef getchar
int getchar(void) { ... } - Formal parameters are not replaced within quoted strings. If, however, a parameter name is preceded by a # in the replacement text, the combination will be expanded into a quoted string with the parameter replaced by the actual argument. This can be combined with string concatenation to make, for example, a debugging print macro:
#define dprint(expr) printf(#expr " = %g\n", expr) - The preprocessor operator ## provides a way to concatenate actual arguments during macro expansion. If a parameter in the replacement text is adjacent to a ##, the parameter is replaced by the actual argument, the ## and surrounding white space are removed, and the result is re-scanned. For example, the macro paste concatenates its two arguments:
#define paste(front, back) front ## back
so paste(name, 1) creates the token name1. - Test Macro usage
#include <assert.h>
#include < setjmp.h>
#include <stdlib.h >
#include <stdio.h>
#include <string.h>
// Test Macro usage
//
#undef max
// Be care to define a macro
// At the end without semicolom, otherwise the semicolom will be at the end of the token
#define max(A,B) ((A) > (B) ? (A) : (B))
#define maxName(A,B) ((A) > (B) ? (#A) : (#B))
#undef square
#undef square1
#define square(a) ((a) * (a))
#define square1(a) (a * a)
// #
#undef dprintf
#define dprintf(expr) printf(#expr " =%g\n",expr)
// ##
#undef paste
#define paste(front,back) front ## back
#undef map
#define map(str) #str
void main()
{
int a,b,c;
// Testing max(a,b)
printf( "max(a,b):\n");
printf( "Please input two numbers to compare:\n");
printf( "a=");
scanf(" %i", &a);
printf( "b=");
scanf(" %i",&b);
printf( "Which is bigger, a=%i or b=%i? %s=%i is bigger.\n",a,b, maxName(a,b),max(a,b));
// Testing max(i++,j++)
printf( "max(i++,j++):\n");
printf( "Please input two numbers to compare:\n");
printf( "a=");
scanf( "%i", & a);
printf("b=");
scanf( "%i",& b);
printf("Which is bigger, a=%i or b=%i? %s=%i is bigger.\n ",a,b, maxName(a,b),max(a++,b++ ));
printf("Now the a=%i,b=%i.\n" ,a,b);
b = 2;
printf( "\nTesting #define square(a) ((a) * (a))\n" );
printf("Square(%d) = %d\n",b,square(b));
printf("Square(%d + 1) = %d\n",b,square(b + 1));
printf( "\nTesting #define square1(a) (a * a)\n");
printf( "Square1(%d) = %d\n",b,square1(b));
printf( "Square1(%d) = %d\n",b + 1,square1(b + 1));
// Testing #
double d = 1.003;
dprintf(d);
// Testing ##
// char* strd = "Testing";
// char* str = "Testing";
double str = 2.0;
double strd = 34.0;
// expected
dprintf(str);
// expected
dprintf(strd);
printf( "%e\n",paste(str,d));
// Terminate program
printf(" Please input any character to end the program:\n");
char* t;
scanf("%s ",&t);
} - Input and Output
- The % Format Specifiers:
The % specifiers that you can use in ANSI C are:
Usual variable type Display
%c char single character
%d (%i) int signed integer
%e (%E) float or double exponential format
%f float or double signed decimal
%g (%G) float or double use %f or %e as required
%o int unsigned octal value
%p pointer address stored in pointer
%s array of char sequence of characters
%u int unsigned decimal
%x (%X) int unsigned hex value
s
--
Happy day, happy life!
No comments:
Post a Comment