#define命令(转)

#define命令(转)

http://www.neu.edu.cn/cxsj/pointchart/c11/.define.html


TAG: 预编译和宏定义,ANSI C,#define命令
TEXT:
#define 命令主要可以实现两种功能:
1)  符号常量定义
2)  宏定义
REF:.txt, 符号常量定义.txt,宏定义.txt
 
 符号常量定义
TAG: 预编译和宏定义,ANSI C,#define命令
TEXT:
在介绍符号常量定义之前,首先分析如下的程序。
例11-1 输入全班20个同学的C语言成绩,并计算出最高分同学的姓名和成绩,并计算出全班C语言成绩的平均分。
#include "stdio.h"
void main()
{
float fAvg; /* 平均成绩 */
float fMax; /* 最高成绩 */
int iMax;
float fSum;
int i;
/*C 语言成绩(20人) */
float fCScore[20]={78.5,65,89,65,45,62,89,99,85,85, 100,58,98,86,68,66,85.5,89.5,75,76};
/* 全班同学的姓名(20人) */
char chNames[][20]= { "Maofen","LiuTao","Wangyu","Songbou", "Liyang", "Wangming","Renhon", "Wuyong","Luming","Sunce","Zhangjie","Yuanquan", "Yangjing","Yubing","XingWen","Huangxing","Dingwen","Quyang","Liufeng","Hanhan"
};
/* 计算总分*/
fSum=0;
for(i=0;i<20;i++)
fSum=fSum+fCScore[i];
/* 计算平均分*/
fAvg =fSum/20;
/* 计算最高分*/
fMax = fCScore[0];
iMax=0;
for(i=0;i<20;i++)
{
if(fMax<fCScore[i])
{
iMax=i;
fMax= fCScore[i];
}
}
/* 输出信息*/
printf("/nThe Score of C Programming Language/n");
printf("The first is %10s /n",chNames[iMax]);
printf("The Score is %10.2f /n",fCScore[iMax]);
printf("The Average is %10.2f /n",fAvg);
}
在上面的程序中,20是一整型常量,代表全班同学的总人数。根据求解问题的需要,20出现了多次。如果将此程序修改,以便处理一个具有25个同学的班级,则需要进行多处的改动。在实际的软件开发中,一个简单的常量可能在整个软件的不同部分出现上百次或上千次,并可能代表不同的信息。在移植过程中,采用手工修改,十分容易出现错误。因此C语言中引入了符号常量,形式如下:
#define  符号常量名称 替换文本
其中#define 为预编译命令,“替换文本”为“符号常量”所代表的字符序列集合,可以为任意字符的组合。在程序代码被编译之前,编译系统自动将所有符号常量出现的位置,被其代表的“替换文本”无条件的替换,然后再进行语法检查和编译。因此利用符号常量,例11-1可改写为
#include "stdio.h"
#define STUDENT_COUNT 20
void main()
{
……
/*C 语言成绩(20人) */
float fCScore[STUDENT_COUNT ]={ …};
char chNames[][STUDENT_COUNT ]={  …};
fSum=0;
for(i=0;i<STUDENT_COUNT;i++)
fSum=fSum+fCScore[i];
fAvg =fSum/STUDENT_COUNT ;
for(i=0;i<STUDENT_COUNT ;i++)
{
……
}
}
为了节省空间,上述程序仅仅显示了修改后的部分。结合例11-1,将所有20用STUDENT_COUNT替换即可。其中
#define STUDENT_COUNT 20
是定义符号常量STUDENT_COUNT,其替换文本为20,代表20这样一个字符序列集合,在程序编译时,所有STUDENT_COUNT出现的位置均被20 无条件的替换。
如果将上述程序修改为处理具有30位同学的班级,只需修改定义
#define STUDENT_COUNT 30
即可。从上面的分析可以看出,恰当的使用符号常量可以增强程序的可移植能力。
提示 符号常量出现的位置,最终将无条件替换为其代表的字符序列集合,并不做语法检查。在编译程序时再进行语法检查。另外,符号常量定义的末尾不能有分号,与普通的程序语句不同。
符号常量的所带代表字符序列集合,可以为空,形式如下:
#define  编译标志
此命令的主要用途是引入编译标志,根据不同的编译标志,编译系统可以完成对不同代码段的编译。例如下面的程序
例11-2 在Windows系统中int 为32位数,在Dos中long为32位数。为了程序在两个系统中移植,可以定义INT32,保证在两种系统中利用INT32声明的变量为32位整型数。
#include "stdio.h"
#ifdef MY_DOS
#define INT16 int
#define INT32 long
#endif
#ifdef MY_WIN32
#define INT16 short
#define INT32 int
#endif
void main()
{
INT32 a;
a=32;
printf("%ld",a);
}
其中MY_WIN32和MY_DOS为编译标志,本段程序的主要目的是保证INT32类型数总是32位的整型数,在DOS系统中编译的时候增加代码
#define MY_DOS
此时INT32代表long。
在Windows系统下编译的时候,修改为
#define MY_WIN32
此时INT32代表int。
提示 符号常量与变量常常混淆。符号常量是一个有名字,因此其与变量相似,但是其值在程序运行过程中不能更改,与常量类似。
一般符号常量的名称采用大写字母,用于区分变量。
将常用的常量定义为符号常量是一种良好的设计习惯。
REF:.txt
 
 宏定义
TAG: 预编译和宏定义,ANSI C,#define命令
TEXT:
C 语言还提供另外一种带参数的#define命令,其英文为macro,一般翻译为宏。其形式如下:
#define  宏(参数列表) 替换文本
其中一般称“替换文本”为宏定义。例如
#define Sum(a,b) a+b
中Sum为宏,a,b为参数列表,a+b为宏定义。在下面的代码中
a=Sum(2,3);
在编译阶段,被替换为
a=2+3;
然后,再编译成可执行代码。
例10-3 定义宏FAILED用于检测数据的正确性。
#define FAILED(Status) ((Status)<0)
#include "stdio.h"
void main()
{
int d;
printf ("Please input a integer number(n>0)/n");
do
{
scanf("%d" ,&d);
}while(FAILED(d));
}
其中while(FAILED(d))在编译之前被无条件替换为while(d<0)。
宏定义和调用在形式与函数比较相似,但是原理是不同。
例10-4 定义Add函数实现两个数的乘法。
double Add(int a,int b)
{
return a*b;
}
void main()
{
double a,b;
double e,f;
a=3;
b=2;
e=Add(a,2);
f=Add(b+1,2);
printf("e=%ff=%f",e,f);
}
程序的运行结果如下
e=6.000000f=6.000000
在下面代码与上面的代码类似,但是运行结果不同。
例10-5 定义Add宏实现两个数的乘法。
#define Add(a,b)? a*b
void main()
{
double a,b;
double e,f;
a=3;
b=2;
e=Add(a,2);
f=Add(b+1,2);
printf("e=%f,f=%f",e,f);
}
程序的运行结果如下
e=6.000000,f=4.000000
在编译之前,系统做如下的处理:
e=Add(a,2) 替换为e=a*2;
f=Add(b+1,2) 替换为f=b+1*2;
因此在使用宏的时候,一定要注意与函数区分。首先宏是一种预编译指令,函数为程序指令。其次宏的作用是定义一种带参数的代码替换方法,在编译之后不会形成独立的代码段;而函数在编译之后会形成相对独立的代码段。
提示 函数定义是将一块公共的代码封装成一个函数,系统编译之后,此部分的机器指令依然作为一个相对对立的代码段。宏的定义仅仅是定义一个带参数的文本替换编译指令,在编译的时候所有的宏将被其代表的信息替换,而在编译之后,对应的机器指令不独立存在。
宏的使用与函数的调用不同。宏的使用发生在程序代码编译成为机器指令之前,而函数的调用发生在程序运行的时候。函数调用会产生额外系统开销,而宏的使用会加大程序代码量,函数的使用会减少程序的代码量。使用宏可以获得更高的代码运行效率,因为其不存在函数调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值