C++_3种预处理功能

1.文件包含#include

作用:把指定的源文件或头文件的全部内容包含到当前文件中。
形式1:#include<文件名>,直接按系统标准方式检索文件目录。
形式2:#include"文件名",在当前的源文件的目录中寻找,找不到再按照系统标准方式检索其他文件目录。

2.宏定义#define命令

#include<iostream>
using namespace std;
#define name1 北京邮电大学;
#define name2 "北京邮电大学";

int main()
{
//    char n1[] = name1;//预处理后为 char n1[] = 北京邮电大学,非法语句
    char n2[] = name2;//预处理后为 char n1[] = "北京邮电大学",合法语句
    cout << n2 <<endl;
    return 0;
}
(1)带参数的宏定义
作用:除了进行字符序列替换外,在进行参数替换。
形式:#define 宏名(参数列表) 字符序列。
宏替换过程:用指定的字符序列替换宏名,然后用实参替换参数列表中的形参。
#include<iostream>
#include <stdio.h>
#define sq(x) ( (x) * (x) )
using namespace std;
int main()
{
	int i = 3, j;
	j = sq(i++);//j = ((i++) * (i++));
//	j = sq(++i);//结果:25 5
	printf("%d  %d", j, i);
    return 0;
}
注意:<1>不能忽视宏定义中的空格,如:#define f  (x) ((x)-1) 被理解为不带参数的宏替换;
   <2>“实参”与“形参”应一一对应,无类型而言,仅替换;“实参” 如果是表达式,并不进行运算;
   <3>与函数的形参和实参有本质上的区别:不分配内存、参数无类型、表达式不求值、宏展开在预编译时进行(函数调用在运行时进行);
   <4>宏替换不占运行时间,只占编译时间;
   <5>在定义宏时最好把每个参数都括起来,整个结果表达式也括起来,括号多用于在复杂表达式中遇到的优先级问题:define abs(x)  (((x) >= 0) ? (x) : -(x)),如果定义成define abs(x)  x > 0 ? x : -x ,abs(a-b)得到a - b > 0 ? a - b : - a - b错误结果 。
(2)宏并不是类型定义
宏的一个常见用途是:使多个不同变量的类型可在一个地方说明,只需要改变一行代码,就能改变f1和a的类型。
<pre name="code" class="cpp">#define FTYPE struct f
FTYPE f1;
FTYPE a;
 
 
但是最好使用类型定义:typedef struct f FTYPE。比如:
#define  T1  struct   f *
typedef  struct   f   *T2;
以上T1,T2都是指向结构体 f 的指针类型,用它们声明多个变量时 ,将出错:
T1   a,b;   //展开 struct  f *a,b,出错,a定义为指向结构体的指针,b被定义为一个结构体 
T2   a,b;   //正确
(3)在替换中使用参数
C语言还专门提供了一个特殊的符号作为参数标识,被称为符号参数。符号参数用“#”和“##”表示。“#”是在引用处用参数字符串直接替换,”##”是在引用处的符号参数续接。
#include <iostream>
#include <stdio.h>
using namespace std;
#define pr(x) printf(#x"\n")
#define PI 3.14
#define PI2 6.28
#define PIOut(x) printf("%f\n",PI##x)
int main()
{
    pr(abc);
    PIOut(2);
    return 0;
}

3.条件编译命令

作用:对满足条件的部分程序内容进行编译,否则不参与编译。
功能:便于调试 。
(1)判断符号常量,进行条件编译:
形式1:#ifdef 标识符
                程序段
                # endif
作用:如果标识符被定义过(一般用#define命令定义),则编译程序段,否则不编译。
形式2:#ifdef 标识符
                  程序段1
                  #else
                  程序段2
                  # endif
作用:如果标识符被定义过,则编译程序段1,否则编译程序段2。
形式3:#ifndef 标识符
                 程序段
                 # endif
作用:如果标识符没有被定义过,则编译程序段,否则不编译。
形式4:#ifndef 标识符
                    程序段1
                  #else
                 程序段2
                 # endif
作用:如果标识符没有被定义过,则编译程序段1,否则编译程序段2 。

(2)判断表达式,进行条件编译:
形式1:#if(表达式)
                 程序段
                  # endif
作用:如果表达式成立(表达式为“真”)则编译程序段,否则不编译。
形式2:#if(表达式)
                 程序段1
                #else
                  程序段2
                # endif
作用:如果表达式成立则编译程序段1,否则编译程序段2 。
说明:
①只对在判断范围内的程序段进行条件编译,其它的程序部分均不编译;
②不编译=不可能执行;
③省编译时间,减少目标程序的长度,便于程序移植。
#include <iostream>
#include <stdio.h>
using namespace std;
#define Student 1
int main()
{
    #ifdef Student
    printf("处理学生信息\n");
        #if(Student)
            printf("处理大学生信息\n");
        #else
            printf("处理小学生信息\n");
        #endif
    #else
         printf("处理教师信息\n");
    #endif // Student
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大师兄电子工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值