3 宏定义
3.1 定义格式:#define 变量名 变量值,例如#define PI 3.145
预处理程序对它不做任何检查。如有错误,只能在编译已被宏展开的源程序发现
宏定义不用加分号分隔,因为分号会被当成宏替换掉
3.2 宏可以嵌套
#define PI 3.14
#define S PI*r*r
3.3 宏定义数据类型和typedef定义数据类型区别:
宏定义只是简单的字符串替换,是在预处理的时候完成的
typedef是在编译的时候处理的,不是简单的替换,而是对类型的重新说明,被命名的标识符有定义数据类型的功能。
例如:
#define PIN1 char*
typedef char* PIN2;
3.4 带参宏调用的一般形式:宏名(实参表)
例如:#define M(y) y*y+3*y
注意点:宏名和形参之间不能有空格#define M(y) 错误改成:#define M (y)
3.5 宏定义一般要注意括号,不然替换的时候会出现错误
例如:
#define SQ(y) y*y;
......
int a,b=1;
a=SQ(b+1);//此处替换后变为:b+1*b+1,出现错误结果。所以宏定义时要定义为:#define SQ(y) (y)*(y)
假如为下列代码:
int a=166,b=2;
float f;
f=a/SQ(b+1);//此处替换为:a/(2+1)*(2+1),此处有问题。所以此时宏定义应该为:#define SQ(y) ((y)*(y))
3.6 头文件
#include "stdio.h":表示在当前源码重查找
#include <stdio.h>:表示在包含文件目录去查找(包含目录是用户在定义环境变量时设置的)
3.7 条件编译
3.7.1 第一种形式
如果标识符被定义则执行程序段1,否则执行程序段2
#ifdef 标识符
程序段1
#else
程序段2
#endif
3.7.2 第二种形式
#ifndef 标识符
程序段1
#else
程序段2
#endif
3.7.3 第三种形式
#if 常量表达式
程序段1
#else
程序段2
#endif
举例:如果为0,则程序段1不会编译,程序段2会被编译
#if 0
程序段1
#else
程序段2
#endif
#define PI 3.1415926
#define S PI*r*r
#define PIN1 char* //这里不需要分号
#define MAX(a,b) (a>b)?a:b
typedef char* PIN2;//定义typedef要加分号
#define CORRECT "WWW.SINA.COM"
void main2()
{
printf("--------------------------------打印宏定义-----------------------------------------------\n");
printf("宏定义PI:%g:\n", PI);
double s;
int r;
printf("--------------------------------打印宏定义嵌套-------------------------------------------\n");
printf("输入半径:");
scanf("输入半径:%d:", &r);
s = S;
printf("面积为:%g:", s);
}
void main3()
{
PIN1 x, y;
PIN2 a, b;
//这里x为四个字节,但是y为一个字节。因为宏替换后为:char* x,y;y没有定义数据类型
printf("By define:%d %d \n\n", sizeof(x), sizeof(y));
//这里替换后为:char *a,char*b;
printf("By typedef:%d %d \n\n", sizeof(a), sizeof(b));
}
void main4()
{
int x ,y ,max;
printf("输入两个整型数字:\n");
scanf("%d %d", &x, &y);
max = MAX(x, y);
printf("最大的数字:%d",max);
}
void main()
{
#ifndef CORRECT1
#define CORRECT1 "WWW.BAI.DOM"
#endif // !CORRECT
char *s;
s = &CORRECT;
printf("%s", s);
printf("%s", CORRECT1);
}