C++:预处理功能

 

预处理功能介绍

为有助于执行编译过程,经常可以使用一些预处理命令。每条预处理命令都具备一定的预处理功能。 常用的预处理命令有以下三项:

1.宏定义命令

2.文件包含命令

3.条件编译命令。

预处理命令具有以下特点:

1.在左边加 # 号,作为标志。

2.一般独占一行。

3.预处理命令不是编程语句,因此句末不加分号。

4.在正常编译过程之前作为预备动作而执行,编译过程结束后不占用存储空间。

宏定义命令

·简单宏定义

例如:

#define PI 3.14159

#define SIZE 80

宏定义命令被执行时,用字符串替代宏名,例如用3.14159替代PI,用80替代SIZE,等。

[例1]计算圆周长和面积。

#define PI 3.14159

void main( )

{

double circum, area, r = 3;

circum = 2 * PI * r;

area = PI * r * r;

}

宏定义命令被执行时,不作语法检查。例如,用户希望将EXEC宏替代整句语句(例如int i=5;),使用以下宏:

#define EXEC int i=5

其中遗漏了分号(int i=5;才是完整语句),但因不作语法检查,因此查不出以上错误,而直到编译系统将其它使用该宏的语句进行编译时才能发现错误。

·带参数宏定义

注意:带参数宏定义并不是函数

例如:

#define ADD(x,y) x+y

[例1]计算两数之和。

#include

#define ADD(x,y) x+y

void main( )

{

int a(40), b(50); //将a、b分别初始化为40、50

int sum = ADD(a, b); //宏替代结果为int sum = a + b;

cout<

}

运行结果:

90

宏替代的操作服从于运算符的优先级,见下例:

[例2]计算数的平方。

// macro_3.cpp

// Attention in defining macro

// From Lv's book, p.85

#define SQ(x) x*x

#include

void main()

{

int a = 2, b = 3;

cout << SQ(a+b) << endl;

//由于乘法运算符优先级高于加法运算符,所以执行a+b*a+b

}

/* Result:

should be 25, but we get

a+b*a+b=11 */

问题出在优先级,应改正如下:

// macro_1.cpp

#define SQ(x) (x)*(x)

#include

void main()

{

int a = 2, b = 3;

cout << SQ(a+b) << endl; //即(a+b)*(a+b)

}

/* Result:

25 */

请注意:宏不是函数(子程序)!

宏与函数的区别:宏节省时间但占用空间;函数节省空间但增加时间!

文件包含

如果以上所述的宏定义语句很多,则可将它们包含于一个单独的文件中,例如 "macros.h" 中。此macros.h文件内容例如可为:

// macros.h

#define MAX 32 #define sq(n) (n)*(n)

#define PI 3.14159

… …

此时用户程序可简化为只包含以下一条语句:

#include "macros.h"

即可执行以上所有宏命令。

以上macros.h称为头文件(header files)(或称包含文件,include files)。

其中系统所定义的头文件名称(例如iostream.h)使用尖括弧< >将头文件名称iostream.h包括起来,系统就根据这点到系统的文件夹中去调用;而用户自定义的头文件则用双引号" "将头文件名称包括起来,例如"macros.h"。系统就根据这点到用户程序的文件夹中去调用。请注意区别此点。

C++语言系统中有很多头文件,它们除包含宏替代定义语句外,更主要包含函数原型和类的定义或类的接口,及其所用各种数据类型的全局变量、外部静态变量和常量的定义。

条件编译

条件编译命令的功能是规定某些语句(或某个程序块)在一定条件下才参加编译,否则跳过不予理睬。

其主要用途为:防止遗漏定义或避免重复定义;以及在测试时增加某些测试语句,以实现调试跟踪的目的。本节主要讲防止遗漏定义或避免重复定义的功能。

其格式为:

#ifdef (常量表达式)(或 #if defined(常量表达式))

[条件编译语句]

#endif

#ifndef (常量表达式)(或 #if not defined(常量表达式))

[条件编译语句]

#endif

以上语句中,当常量表达式无定义时,就编译两个条件编译命令#ifdef(或#ifndef)与#endif之间的条件编译语句。

条件编译命令也可表达如:

#if (常量表达式)

[条件编译语句]

#endif

此时如常量表达式非零,则满足编译条件,编译两个条件编译命令#if与#endif之间的条件编译语句。

现在讲解其避免遗漏定义和避免重复定义的功能:

以下使用 #ifndef MAX,此即(# if not defined MAX)或(#if !defined MAX)

例题:

// test_ifndef_1.cpp

// To prevent the missing of macro definition

#include <iostream.h>

#ifndef MAX

#define MAX 32

#endif

void main()

{

cout << "MAX is " << MAX << endl;

}

/* Result:

MAX is 32 */

上例中MAX没有定义,所以执行条件编译语句#define MAX 32语句。

此例中MAX已经定义过了,故不执行条件编译语句]2例[

// test_ifndef_2.cpp

// To prevent the missing of macro definition

#include <iostream.h>

#define MAX 10

#ifndef MAX

#define MAX 32

#endif

void main()

{

cout << "MAX is " << MAX << endl;

}

/* Result:

MAX is 10 */

上例中MAX已被定义为等于10,所以不执行条件编译语句#define MAX 32语句。再说,如果真是执行了条件编译语句#define MAX 32语句,必将会出现如下警告:

warning: 'MAX' : macro redefinition

test_ifndef_2.cpp(6) : see previous definition of 'MAX'

再看避免重复包含头文件的例子:

[例3]防止重复包含头文件。

设已有头文件如下:

// ifndef.h

// To avoid the duplication of include files

#if !defined(_IFNDEF_H)

#define _IFNDEF_H

int var=1; //global variable

#endif //_IFNDEF_H

用户应用程序如下:

// test_ifndef_3.cpp

// To prevent the duplication of macro definition

#include <iostream.h>

#include "ifndef.h"

#include "ifndef.h" //看似重复包含,实则不予执行

void main()

{

cout << "变量var = " << var << endl;

}

/* Result:

变量var = 1

*/

此程序中虽然多了一句#include "ifndef.h",但第二句不起作用。原因在于头文件中使用了条件编译功能。怎么知道重复包含的第二句不起作用?因为如果包含第二句的话,将会出错。如下:

// test_ifndef_4.cpp

// The error of the duplication of macro definition

#include <iostream.h>

int var=1;

int var=1;

void main()

{

cout << "变量var = " << var << endl;

}

/* Result : Not working

error C2374: 'var' : redefinition; multiple initialization

*/

在任何头文件中,都必须使用上述条件编译语句以便避免重复包含。在有些头文件中,也可能使用语句#pragma once,只要在头文件的初始部分加入这条指令,就能够保证头文件只被编译一次。有时同时使用条件编译语句#if !defined(_IFNDEF_H)和#pragma语句。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include <iom16v.h> #include <macros.h> #define RS_0 PORTD &= ~(1 << PD3) #define RS_1 PORTD |= (1 << PD3) #define RW_0 PORTD &= ~(1 << PD4) #define RW_1 PORTD |= (1 << PD4) #define EN_0 PORTD &= ~(1 << PD6) #define EN_1 PORTD |= (1 << PD6) //微秒级延时程序晶振8MHZ void delay_us(int time) { do { time--; } while (time>1); } //毫秒级延时程序晶振8MHZ void delay_ms(unsigned int time) { while(time!=0) { delay_us(1000); time--; } } /*显示屏命令写入函数*/ void LCD_write_com(unsigned char com) { RS_0; RW_0; PORTB = com; EN_1; delay_us(20); EN_0; } /*显示屏命令写入函数*/ void LCD_write_data(unsigned char data) { RS_1; RW_0; PORTB = data; EN_1; delay_us(200); EN_0; } /*显示屏清空显示*/ void LCD_clear(void) { LCD_write_com(0x01); delay_ms(5); } /*显示屏字符串写入函数*/ void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s) { if (y == 0) { LCD_write_com(0x80 + x); } else { LCD_write_com(0xC0 + x); } while (*s) { LCD_write_data( *s); s ++; } } /*显示屏单字符写入函数*/ void LCD_write_char(unsigned char x,unsigned char y,unsigned char data) { if (y == 0) { LCD_write_com(0x80 + x); } else { LCD_write_com(0xC0 + x); } LCD_write_data( data); } /*显示屏初始化函数*/ void LCD_init(void) { DDRB = 0xFF; /*I/O口方向设置*/ DDRD |= (1 << PD3) | (1 << PD4) | (1 << PD6); LCD_write_com(0x38); /*显示模式设置*/ delay_ms(5); LCD_write_com(0x38); delay_ms(5); LCD_write_com(0x38); delay_ms(5); LCD_write_com(0x38); LCD_write_com(0x08); /*显示关闭*/ LCD_write_com(0x01); /*显示清屏*/ LCD_write_com(0x06); /*显示光标移动设置*/ delay_ms(5); LCD_write_com(0x0C); /*显示开及光标设置*/ } void main(void) { unsigned char i; unsigned char *p; PORTA = 0xFF; /*打开上拉*/ DDRA = 0x00; /*方向输入*/ PORTB = 0xFF; /*电平设置*/ DDRB = 0xFF; /*方向输出*/ PORTC = 0x7F; DDRC = 0x80; PORTD = 0xFF; DDRD = 0x00; delay_ms(100); LCD_init(); while (1) { i = 1; p = "yixiangongren"; //LCD_clear(); LCD_write_str(1,0,"www.eehome.cn"); delay_ms(50); while (*p) { LCD_write_char(i,1,*p); i ++; p ++; //delay_ms(50); } delay_ms(500); } } 本文来自: 电子工程师之家http://www.eehome.cn
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值