C语言07 预编译+define

阅读: 评论:0

C语言07 预编译+define

C语言07 预编译+define

一、理论

1、什么是预编译,何时需要预编译?

答: 预编译又叫预处理,指程序编译前的代码文本处理工作。

主要指用#表示的预编译指令,有三种:编译器编译前拷贝#include包含的代码,#define宏定义的替换,条件编译等等。

何时需要预编译?

1)总是使用不经常改动的大型代码体。

2)程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。

2、为什么标准头文件都有类似以下的结构?

#ifndef __INCvxWorksh
#define __INCvxWorksh       //防止该头文件被重复引用extern "C"		             //实现C++与C混合编程
{#include "cExample.h"                        
}
#endif /* __INCvxWorksh */

答:extern “C”声明实现C++与C及其它语言的混合编程。

  C++作为面向对象的语言,支持函数重载,而过程式语言C则不支持。同一函数被C++编译后在symbol库中的名字与C语言的不同。例如,假设某个函数的原型为:

        void foo(int x, int y);

  该函数被C编译器编译后在symbol库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。_foo_int_int这样的名字包含了函数名和函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。

  为了实现C和C++的混合编程,C++提供了C连接交换指定符号extern "C"来解决名字匹配问题,函数声明前加上extern "C"后,则编译器就会按照C语言的方式将该函数编译为_foo,这样C语言中就可以调用C++的函数了。

3、对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?

 答: c用宏定义,c++用inline。

二、define表达式

【1】好处:直观;帮忙计算;

【2】语法规则(无分号;使用括号;防止溢出;小心输入自加自减的参数)

1、用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)

#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL

1) #define 语法的基本知识(不能以分号结束,括号的使用)

2)懂得预处理器将计算常数表达式的值,直接写出怎么样计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。

3) 这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是无符号的长整型数。

2、写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。

#define MIN(A,B) ((A)<=(B)?(A):(B)) 
或者
#define Min((X),(Y)) ((X)>(Y)?(Y):(X))

【1】三重条件操作符使得编译器能产生比if-then-else更优化的代码。要小心地把参数和整个宏用括号括起来。

【2】MIN(*p++, b)会产生宏的副作用,指针p会作2次++自增操作。所以这个宏定义表达式不能代入自加自减。

3、已知一个数组table,用一个宏定义,求出数据的元素个数?

#define NTBL (sizeof(table)/sizeof(table[0]))

4、用宏定义写出swap(x,y)

#define SWAP(x,y) {x+=y;y=x-y;x=x-y;}  

5、一语句实现x是否为2的若干次幂的判断

#define is2*n(x) ((x & (x - 1))? 0 : 1) 
int main(void)
{int m = 512;cout << ((m & (m - 1)) ? false : true) << endl;return (0);
}

答:x为2的若干次幂即表示x中只有最高位为1。

题目转化为求一个32位数中1的位数,如果为1,则表示该数为2的若干次幂。

//这个时候 x: 0B10  0B100  0B1000  0B10000

//这个时候 x-1: 0B1 0B11    0B111       0B1111

若有两个及以上的1,则(m & (m - 1))不为0,输出0,表示不为2的若干次幂;

  同理也可以利用此规则求一个32位数中1的位数, (m & (m - 1)每次可用消除一个1,计算的次数即为1的个数 !

三、define的其他用法

1、预编译

#if    0
#elif  0
#elif  0
#elif  1
#endif

2、宏定义操作IO

#define	    digitalHi(p,i)		  {p->BSRR=i;}	 //输出为高电平
#define 	digitalLo(p,i)		  {p->BRR=i;}	 //输出为低电平
#define 	digitalToggle(p,i) 	  {p->ODR^=i;}   //输出为反转状态
#define LED1_TOGGLE		 digitalToggle(LED1_GPIO_PORT,LED1_GPIO_PIN)
#define LED1_OFF		 digitalHi(LED1_GPIO_PORT,LED1_GPIO_PIN)
#define LED1_ON		     digitalLo(LED1_GPIO_PORT,LED1_GPIO_PIN)
#define LED1(a)	if (a)	GPIO_SetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);else		GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN)

3、替代函数语句

#define IS_BLCOM_NOMAL_MODE() (g_BlcomState==EM_BLCOM_IDLE) 
if(IS_BLCOM_NOMAL_MODE()) 
{...
}

本文发布于:2024-02-04 22:52:35,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170718209160465.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:语言   define
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23