C在程序执行之前,C预处理器会进行哪些操作?

       了解C预处理的一些操作,对C的嵌入式开发的设计,调试,应用都会有很大的帮助,因此这里对C预处理器的一些操作做了一个简单的总结,一是对我接下来的嵌入式设计有一个思路的整理,另一方面也希望对偶然逛到本文的你有帮助。

       想要深入的了解,必须解决几个问题。


1 . C预处理器负责哪些事情?

       1)将符号缩写替换成其表示的内容(ex:#define);

       2)包含程序所需的其他文件(ex:#include);

       3)选择让编译器查看或者执行哪些代码(#if    #else    #endif);

2 . 编译器进入预处理之前还会做什么操作?

    1)把源码出现的字符映射到源字符集;

       这个阶段主要是对程序做字符和字符集的映射操作;

       值得注意的是,C语言是基于美键盘而来的,但是有些键盘没有所有C的符号,这个时候怎么办?C提供了三字符序列和双字符序列解决这些问题,因此看到这些代码时,不要觉得奇怪。

例如:

// 三字符序列
??=include <stdio.h>

// 翻译过来就是
#include <stdio.h>

再例如:

 

// 双字符序列
%:include <stdio.h>  //与三字符不同的是,不会替换" "中的双字符序列;

// 翻译过来就是
#include <stdio.h>

     2) 编译器定位每个反斜杠后面跟着换行符的实例,并删除他们。 将物理行(physical line)转换成逻辑行(logic line);

#include <stdio.h>
int main()
{
	printf("physical line : my name is \    //物理行1 \表示换行            
	mashuai\r\n");                          //物理行2
	   
	printf("logical line : my name is mashuai\r\n");  //逻辑行:预处理表达式的基本单位;
 } 

 运行结果为:

physical line : my name is mashuai
logical line : my name is mashuai

  3) 编译器将注释用一个空格字符代替。

最后,程序开始准备好进入预处理阶段,预处理将查找一行中以#开始的预处理指令。

 


 3 . 程序预处理是做什么事情?

1)明示常量 #define:  包括一些对象宏和函数宏。 下面列举了一个典型的嵌入式工程宏定义;

     值得注意的是,编译器在编译期对所有的常量表达式(只包含常量)求值,所以预处理器不会进行实际的乘除运算。预处理不做计算,不对表达式求值,只是进行简单的替换。

#define	U8	unsigned char             // 做一些数据结构的定义
#define U16	unsigned short
#define U32	unsigned int

/*宏定义*/
#define	FILTERADTIMES		4		   // 定义程序运行过程中用到的固定值,便于修正和调试
#define RESADTIMES			8		
#define	BODYADTIMES			20		
#define RESSTABLECOUNT		150		
#define	BODYSTABLECOUNT		350		
#define DEFAULT_KBCOUNT		1100	
#define	RES_MIN				3000			//200ohm
#define	REF_RES				7000			//700ohm
#define	RES_MAX				10000			//1500ohm

//#define	Short_FWR_50KHz 	00110011B	// 定义寄存器配置模式,用宏定义更方便阅读和调试;
//#define	Ref0_FWR_50KHz		00010011B	
//#define	Ref1_FWR_50KHz		00100011B	
//#define	Body_FWR_50KHz		00000011B	

#define	Short_FWR_50KHz 	0x33	//内短模式
#define	Ref0_FWR_50KHz		0x13	//参考电阻0模式
#define	Ref1_FWR_50KHz		0x23	//参考电阻1模式
#define	Body_FWR_50KHz		0x03	//人体模式

/*寄存器地址定义*/
#define	ADDR_AFE_SYS		0                // 定义寄存器名,便于程序的阅读和调试;
#define ADDR_AFE_ADC0		1
#define ADDR_AFE_ADC1		2
#define ADDR_AFE_ADC2		3
#define ADDR_AFE_ADC3		4
#define ADDR_AFE_ADC4		5
#define ADDR_AFE_ADC5	 	6
#define ADDR_AFE_BIM0		7
#define ADDR_AFE_BIM1		8
#define ADDR_AFE_ADO		9
#define ADDR_AFE_ADS		10

#define ADDR_AFE_CONFIG		0x10
#define ADDR_AFE_VREFT		0x11
#define ADDR_AFE_LDOT		0x12
#define ADDR_AFE_OSCT		0x13
#define ADDR_AFE_TST1		0x14
#define ADDR_AFE_TST2		0x15
#define ADDR_AFE_TMUX		0x16
#define ADDR_AFE_OTPCON		0x59
#define ADDR_AFE_TEST		0x5A

#define TOLERANCE0	5                            // 定义有固定值通过固定关系衍生出的值,以便于修改和程序调试;
#define Z12_L0	6000-(6000 * TOLERANCE0 / 100)
#define Z12_H0	6000+(6000 * TOLERANCE0 / 100)
#define Z13_L0	5680-(5680 * TOLERANCE0 / 100)
#define Z13_H0	5680+(5680 * TOLERANCE0 / 100)
#define Z14_L0	5680-(5680 * TOLERANCE0 / 100)
#define Z14_H0	5680+(5680 * TOLERANCE0 / 100)
#define Z23_L0	5680-(5680 * TOLERANCE0 / 100)
#define Z23_H0	5680+(5680 * TOLERANCE0 / 100)
#define Z24_L0	5680-(5680 * TOLERANCE0 / 100)
#define Z24_H0	5680+(5680 * TOLERANCE0 / 100)
#endif

  2)函数宏: 

#include <stdio.h>

#define SQUARE(X)	X*X

#define PR(X)	printf("The result is %d.\n",X)      //函数宏

int main(void)
{
	int ex_para=5,ex_result;
	
	ex_result=SQUARE(ex_para);
	
	printf("Evaluating SQUARE(ex_para): %d.\n",ex_result);    
    printf("Evaluating SQUARE(“#ex_para”): %d.\n",ex_result); 
	PR(ex_result);
	
}

// 注意点:这里需要注意的是 函数宏替换时不会替换 "" 内的内容;如果想要替换,就”#ex_para“替换;

         

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值