C语言学习笔记8---预处理

来源:互联网 发布:redis in action java 编辑:程序博客网 时间:2024/06/06 00:17

宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换。

宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用# undef命令。

#include <stdio.h>

#define PI 3.1415926

void fun(void);

void main()
{    
      double s;
      int r;

      printf("Please enter the radius : ");
      scanf("%d", &r);

      s = PI * r * r;

      printf("\n\nThe area of the roundness = %g\n\n", s);     

      fun();

}

#undef PI
//在这里加上这个表示宏定义结束则后面fun函数中PI没被定义

void fun(void)
{
      printf("Now the PI = %g\n\n", PI);
      printf("PI\n\n");            // PI在引号中应该是表示常量字符串,不替换……
}

宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名。在宏展开时由预处理程序层层代换。

#define PI 3.1415926
#define S PI*r*r

可用宏定义表示数据类型,使书写方便。

例如:

#define INTEGER int

注意:宏定义表示数据类型和用typedef定义数据说明符的区别

区别:宏定义只是简单的字符串代换,是在预处理完成的,而typedef是在编译时处理的,它不是作简单的代换,而是对类型说明符重新命名。被命名的标识符具有类型定义说明的功能。

typedef后而有;  表示他是一个语句

#include <stdio.h>

#define PIN1 char*
typedef char* PIN2;

void main()
{
      PIN1  x, y;
      PIN2  a, b;

      printf("By #define : %d  %d\n\n", sizeof(x), sizeof(y));
      printf("By typedef : %d  %d\n\n", sizeof(a), sizeof(b));
}

带参数宏定义

C语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。

对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。

带参宏定义的一般形式为:

#define 宏名(形参表) 字符串

带参宏调用的一般形式为:

宏名(实参表);

例如:

#define M(y) y*y+3*y    /*宏定义*/

k = M(5);                               /*宏调用*/

在宏调用时,用实参5去代替形参y,经预处理宏展开后的语句为:

k = 5*5 + 3*5

对于带参的宏定义有以下问题需要说明:

1. 带参宏定义中,宏名和形参表之间不能有空格出现。

例如把:

#define MAX(a,b)   (a>b)?a:b

写为:

#define MAX   (a,b)   (a>b)?a:b

试试看~

 

2. 在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。

而宏调用中的实参有具体的值。

要用它们去代换形参,因此必须作类型说明。

这是与函数中的情况不同的。在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行“值传递”。

而在带参宏中,只是符号代换,不存在值传递的问题。

 

3. 在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。

如:

#define SAY(y) (y)

可以用表达式做为参数

say[i] = SAY(say[i]*1+1-1);

4. 在宏定义中,字符串内的形参通常要用括号括起来以避免出错。

#define SQ(y) (y)*(y)

sq = SQ(a+1);

就是(a+1) * (a+1)

而改成

#define SQ(y) y*y

sq = SQ(a+1);

就变成 a+1 * a+1

再变一下

sq = 160 / SQ(a+1);  就是

sq = 160 / (a+1) * (a+1);        乘除同一级从左向右运算

要再加上一个括号

#define SQ(y) ((y)*(y))

就相当于

sq = 160 / ((a+1) * (a+1));

文件包含

条件编译

预处理程序提供了条件编译的功能。可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。

条件编译有三种潜规则,下面分别介绍:

第一种形式:

条件编译

它的功能是,如果标识符已被#define命令定义过则对程序段1进行编译,否则对程序段2进行编译。

如果没有程序段2(它为空),本格式中的#else可以没有,即可以写为:

条件编译

第二种形式:

条件编译

第三种形式

条件编译

0 0
原创粉丝点击