> 文档中心 > 预处理指令最终篇和#和##的实例

预处理指令最终篇和#和##的实例

目录

今天我们主要学习深度理解条件编译,和其他预处理指令相关内容

希望大家今天也要心情愉悦哦。

深入理解条件编译

1.条件编译的使用

1.1 #ifdef 和 #ifndef区别。

1.2  #if 和 #ifdef的区别 

1.3 #if defined(宏)实现 #ifdef功能

1.4可以使用逻辑的形式同时判断两个宏的成立,来进一步判断条件编译的结果

1.5 条件编译可以嵌套吗?

1.6 剩下的多分支和单分支的实现在上一篇博客已经说过不在赘述。

2. 为什么要有条件编译?

深入理解文件包含

2.1 为什么这个东西可以避免头文件重复包含?

2.2文件重复包含的后果。

其他预处理指令讲解

3.1 #error 和 #pragma message ()的对比讲解

3.2 #pragme 相关的预处理指令

3.3 #line

关于 # 和 ## 的例子

#的作用:是把参数的符号转化为 "字符串"。

##的作用:把宏的参数组合形成新的符号。

下期预告:

下期主要讲解  指针相关  内容

下期更精彩哦~~~


今天我们主要学习深度理解条件编译,和其他预处理指令相关内容

希望大家今天也要心情愉悦哦。

深入理解条件编译

条件编译在上一篇博客已经讲过了,但是因为有些东西还是不够细致,所以今天做个补充。

1.条件编译的使用

上一篇博客说了写使用方法但是还有些方法没有说,下面一起看一些例子吧。

1.1 #ifdef 和 #ifndef区别。

这两个条件刚好是相反的,前者是的判断宏是否被定义,后者是对前者结果进行逻辑取反

#define MAXint main(){#ifndef MAXprintf("MAX被定义\n");#endif#ifdef MAXprintf("MAX被定义\n");#endifreturn 0; }

这通过产生了  .i  文件的形式,进行直观表达。

1.2  #if 和 #ifdef的区别 

 #if 是判断后面宏的逻辑上的真假  #ifdef只是判断宏的定义与否

#define MAX 0int main(){#if MAXprintf("MAX是真\n");#elseprintf("MAX是假\n");#endif#ifdef  MAXprintf("MAX已被定义\n");#endifreturn 0;}

这里可以看出,虽然MAX的值是0,但是MAX是被定义的(即使宏为空,依然也是被定义的)

1.3 #if defined(宏)实现 #ifdef功能

看下代码,理解下#if后必须是常量表达式,和模拟实现#ifdef。

#define MAXint main(){#if defined(MAX)printf("MAX已定义\n");#endif#ifdef MAXprintf("2.MAX已定义\n");#endif#if MAX    //因为MAX没有值,所以报错printf("MAX为假\n");#endifreturn 0;}

 可以看出来#if defined模拟实现#ifdef的效果,下面的那个#if只是起对比作用

同理,实现#ifndef的话使用 #if  !defined就可以了(本质就是对值进行逻辑取反)

1.4可以使用逻辑的形式同时判断两个宏的成立,来进一步判断条件编译的结果

如果同时有两个宏有需要判定呢?该怎么办呢?

看例子:

#define MAX 1#define MIN 0int main(){#if (defined(MIN) && defined(MAX))printf("MAX,MIN同时被定义");#elseprintf("未全部定义\n");#endifreturn 0;}

这样就可以同时判断两个宏是否被定义的情况了。(同理,逻辑或成立,逻辑与也是可以的,逻辑取反也是可以的,自己动手试试呀) 

1.5 条件编译可以嵌套吗?

就像是if语句一样是可以嵌套的。不废话,看例子:

#define MAX #define MINint main(){#if defined(MAX)#if defined(MIN)printf("MIN定义\n");#endifprintf("MAX定义\n");#elseprintf("未定义\n");#endifreturn 0;}

 这样来看,好像一个if语句的嵌套,每个#if defined(宏)是判断表达式要不要执行。(同理,你可以看下不同的宏,是否定义带来的不同的条件编译,产生的不同的结果)

1.6 剩下的多分支和单分支的实现在上一篇博客已经说过不在赘述。

单分支多分支条件编译

2. 为什么要有条件编译?

通过裁剪代码,快速实现某种目的(比如一些功能的裁剪,和一份代码的免费版和收费版维护,和一些代码的跨平台性)

深入理解文件包含

2.1 为什么这个东西可以避免头文件重复包含?

1 #ifndef __TEST_H__ 2  #define __TEST_H__ 3 //头文件的内容 4 #endif   //__TEST_H__

首先这是条件编译的知识,

第一行是判断 __TEST_H__  这个宏有没有被定义,

第二行是定义__TEST_H__ (把这个宏定义)  

第三行是头文件内容

第四行是#endif条件编译结束。

综上所述,这个东西每一个头文件都需要这样写。

所以我们推荐使用  #pragma once 来防止头文件被引用。

2.2文件重复包含的后果。

我们要知道文件重复包含,最大的后果就是很多声明文件重复了,很多的东西重复了,就导致代码的编译效率低下。

 你看,如果头文件被重复包含,那么就会导致多次声明,虽然没有出错,但是在编译效率上降低了。

其他预处理指令讲解

3.1 #error 和 #pragma message ()的对比讲解

#error就是让编译器打印一些字符,是以 "错误" 的方式

例 :

这样打印的消息是不可以通过编译的,所以叫 "错误" 的方式。

而#pragma message ()则是警告或者叫"提示"的方式。

 

 他们都可以用在条件编译中,#error是错误级别的,#pragma message ()是提示级别的。

3.2 #pragme 相关的预处理指令

#pragme once防止头文件重复包含。

#pragme pack()改变默认对齐数。

#pragme warning(4996)是VS下,接口型警告,常见的是scanf的警告。

3.3 #line

修改当前的文件名和行数。

看例子:

关于 # 和 ## 的例子

#的作用:是把参数的符号转化为 "字符串"。

看个例子,把数字转化为字符输出。

#define NUM(s) #sint main(){printf("π:"NUM(3.1415926)"\n");return 0;}

这样就可以把参数转化为字符,输出了。

##的作用:把宏的参数组合形成新的符号。

看个例子 ,用宏求一个数的科学计数法的值

这样不太直观,我们看下预处理后的结果吧。

这样看是不是就是浮点数的科学计数法了。

下期预告:

下期主要讲解  指针相关  内容

下期更精彩哦~~~

医学名词百科