C语言基础

    返回首页    发表留言
本文作者:李德强
          第二节 宏定义与宏展开
 
 

        在本节中我们来学习C语言中一个非常强大的机制--宏定义。宏定义是允许编程者在程序代码中定义一些名字,而这些名字代表一些指定意思。语法为:
                #define MACRO_NAME MACRO_CONTENT
        例如我们来定义一个圆周率的值:

#define PI 3.14159

 

        在这里我们定义了一个叫作PI的宏,这个宏的值是3.14159。在实际使用时,当要多处使用某一个值时,就可以使用PI来表示3.14159,例如:

double a = sin(PI);
double b = cos(PI / 2.0);


        再如,我们可以定义一个用于表示某一个数组长度的宏,并在程序中循环数组时使用这个宏作为下标的范围:

#include <stdio.h>

#define SIZE 3

int main(int argc, char *argv[])
{

	int arr[SIZE];
	for (int i = 0; i < SIZE; i++)
	{
		arr[i] = i;
	}
	for (int i = 0; i < SIZE; i++)
	{
		printf("%d\n", arr[i]);
	}

	return 0;
}


        有了宏定义之后,我们如果想修改数组的大小,你如将3修改成5,源代码中就不需要将每个循环中将3修改成5,而只需要在宏定义SIZE中将其修改成5即可。

        需要明确的一个关键问题是:宏定义与变量不同,变量是实际占用内存空间的一个量,它们的值可以在程序运行中被改变;而宏定义并不是一个变量,宏定义的值会在编译器预编译时替换到程序中使用宏的地方,例如:

//源代码
#define PI 3.14159
double a = sin(PI);
double b = cos(PI / 2.0);

//预编译代码
double a = sin(3.14159);
double b = cos(3.14159 / 2.0);

        也就是说,我们编写的源代码会在预编译时将宏的内容替换到预编译代码中。而这一个过程称为:宏展开。

        其实,如果我们在宏定义时只定义一个普通的数值,就没必要叫宏展开了。定义宏,还可以定义成带参数的表达式的形式,例如,我们来定义一用于计算两个变量和的宏:

//源代码
#define ADD(x,y) x+y
int a = 3;
int b = 5;
int c = ADD(a,b);

//预编译代码
int a = 3;
int b = 5;
int c = a+b;


        实际上,编译器在对这段代码编译时,会将宏ADD的内容展开成x+y,所以我们代码c = ADD(a, b)就会在预编译时被宏展开成c = a+b。

        需要注意的是:宏展开只做代码替换工作,而不会对源代码的语法和语意做任何处理。我们来看下面一段代码:
 

//源代码
#define ADD(x,y) x+y
int a = ADD(3,5)*ADD(4,6);

//预编译代码
int a = 3+5*4+6;

        可以看到,宏ADD(3,5)*ADD(4,6)在预编译时被展开成3+5*4+6,我们在源代码中预想的结果是(3 + 5) * ( 4 + 6) = 80,而实际的宏展开的结果则是3 + 5 * 4 + 6 = 29。所以使用宏的时候通常在宏的内容部分加上小括号以保证其运算符优先级不会在宏展开之后发生变化:

 

//源代码
#define ADD(x,y) (x+y)
int a = ADD(3,5)*ADD(4,6);

//预编译代码
int a = (3+5)*(4+6);

        这样,宏展开的结果就与源代码中的结果一致了。

    返回首页    返回顶部
  看不清?点击刷新

 

  Copyright © 2015-2023 问渠网 辽ICP备15013245号