define 的深度剖析

本文介绍了C语言中的预处理标识符(__FILE__,__LINE__,__DATE__,__TIME__)的应用,探讨了宏与函数的区别,展示了宏在简单计算中的优势及其可能带来的副作用,并概述了C程序从源代码到可执行文件的编译链接过程。

1.预处理标识符的使用:

#include<stdio.h>

#define __FILE__    //进行编译的源文件
#define __LINE__    //文件当前的行号
#define __DATE__    //文件被编译的日期
#define __TIME__    //文件被编译的时间
int main()
{
	printf("file:%s\n", __FILE__);
	printf("line:%d\n", __LINE__);
	printf("date:%s\n", __DATE__);
	printf("time:%s\n", __TIME__);
	return 0;
}



执行结果:

<img src="https://img-blog.youkuaiyun.com/20161018185101086?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

这样可以输出当前编译文件的相关信息,使用非常方便。


2.了解宏和函数的区别

使用宏的语法和使用函数的语法是完全一样的,所以语言本身不能区分这两者,一般情况下,我们将宏的名字全部用大写来区分。

宏可以非常频繁的用于执行简单的计算,比如:

#define MAX(a,b)     ((a)>(b)?(a):(b))             //求两个数中较大的一个

为什么不用函数来完成,有两个原因:

1)用于调用和函数返回的代码很可能比实际执行这个小型计算工作的代价大,所以使用宏比使用函数在程序的规模和速度更胜一筹。

2)但是更重要的是,函数的参数必须申明为一种特定的类型,所以函数只能在类型合适的表达式上使用。反之,宏可以用于整形、长整形......以及其他任何可以使用>操作符

比较大小的类型。

宏是和类型无关的。

和函数相比,使用宏的不好处在于每次使用时,都要将宏定义的代码拷贝到程序中,除非宏非常短,否则使用宏可能会大幅度增加程序的长度。

还有一些任务函数无法实现,比如:

#include<stdio.h>
#define MALLOC(n,type) ((type*)malloc((n)*sizeof(type)))

int main()
{
	int *pi = MALLOC(25, int);
	return 0;
}

这个程序经过预处理后得到:

int main()
{
 int *pi = ((int*)malloc((25)*sizeof(int)));
 return 0;
}

这个宏的第二个参数是一种类型,它无法作为函数参数进行传递。


3.宏参数的副作用

当宏参数在宏定义中出现次超过一次时,如果这个参数具有副作用,那么使用时就有可能导致不可预料的结果。比如

x++;

#include<stdio.h>
#define MAX(a,b)   ((a)>(b)?(a):(b))
int main()
{
	int x = 2;
	int y = 8;
	int z = MAX(x++, y++);
	printf("x=%d\n", x);
	printf("y=%d\n", y);
	printf("z=%d\n", z);
	return 0;
}


得到结果:



在这个程序中较小值计算了一次,但是较大值却计算了两次。


4.编译链接的整个过程

1)预处理过程

  (1)宏替换

  (2)头文件展开

  (3)取消注释

  (4)条件编译

          在编译一个程序时,如果我们可以选择某条语句或某组语句进行翻译或者被忽略,就会很方便,条件编译就是用于实现这个目的的。

2)编译过程(c程序代码到汇编)

3)汇编过程(汇编到二进制)

4)链接过程(将二进制生成可执行程序的过程)

比如:

#include<stdio.h>
#define DEBUG 1                  //DEBUG被定义则执行语句,值为1时执行,为0时不执行
#define REALSE 1
int main()
{
#if DEBUG
      printf("hello.\n");
	  printf("happy.\n");
#elif REALSE
	printf("wwww\n");
#else 
	printf("aaa\n");
#endif
	return 0;
}

执行结果:

可以通过更改定义的值DEBUG,REALSE来选择执行哪条语句,可以起到很好的调试作用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值