1.#error的用法
#error用于生成一个编译错误消息,并让预编译器停止编译,这个错误消息是自己定义的。
用法:#error Message (Message不需要用双引号引起来)
2.#warming的用法
#warning用于生成一个编译警告,输出到编译器的消息窗口,编译器不会停止编译。
用法:#warning Message (Message不需要用双引号引起来)
3.#的用法
#
运算符用在预编译时期,用于将宏参数转换为字符串。
例如:
#include
#define COMMAND( x ) #x
int main()
{
printf( "%s\n", COMMAND( Hello world ! ) );
printf( "%s\n", COMMAND( 100 ) );
printf( "%s\n", COMMAND( while ) );
printf( "%s\n", COMMAND( return ) );
return(0);
}
预 编 译 后 :
int main()
{
printf( "%s\n", "Hello world!" );
printf( "%s\n", "100" );
printf( "%s\n", "while" );
printf( "%s\n", "return" );
return(0);
}
#
运算符的妙用:
#include
#define CALL( f, p ) (printf( "Call function %s\n", #f ), f( p ) )
int square( int n )
{
return(n * n);
}
int f( int x )
{
return(x);
}
int main()
{
printf( "1. %d\n", CALL( square, 4 ) );
printf( "2. %d\n", CALL( f, 10 ) );
return(0);
}
输出:
Call function square
1. 16
Call function f
2. 10
可以看到,运行结果中输出了当前调用的函数的名称,这是用函数实现不了的功能,如果用函数来实现,只能在程序中把要输出的函数名写死,没有使用宏这么通用便捷!
4.##的用法
##
运算符用于在预编译期粘连两个符号,增大了宏的使用灵活性!
例如:
#include
#define NAME( n ) name##n
int main()
{
int NAME( 1 );
int NAME( 2 );
NAME( 1 ) = 1;
NAME( 2 ) = 2;
printf( "%d\n", NAME( 1 ) );
printf( "%d\n", NAME( 2 ) );
return(0);
}
预编译后:
int main()
{
int name1;
int name2;
name1 = 1;
name2 = 2;
printf( "%d\n", name1 );
printf( "%d\n", name2 );
return(0);
}
可以看出,预编译时,宏参数n被替换,并和name连接成一个整体,然后整体替换NAME宏。
##运算符的妙用:
#include
#define STRUCT( type ) typedef struct _tag_##type type; \
struct _tag_##type
STRUCT( Student )
{
char * name;
int id;
};
int main()
{
Student s1;
Student s2;
s1.name = "s1";
s1.id = 0;
s2.name = "s2";
s2.id = 1;
printf( "%s\n", s1.name );
printf( "%d\n", s1.id );
printf( "%s\n", s2.name );
printf( "%d\n", s2.id );
return(0);
}
预编译后:
typedef struct _tag_Student Student; struct _tag_Student
{
char * name;
int id;
};
int main()
{
Student s1;
Student s2;
s1.name = "s1";
s1.id = 0;
s2.name = "s2";
s2.id = 1;
printf( "%s\n", s1.name );
printf( "%d\n", s1.id );
printf( "%s\n", s2.name );
printf( "%d\n", s2.id );
return(0);
}