程序预处理:全解版-2

简介: 程序预处理:全解版

程序预处理:全解版-1

https://developer.aliyun.com/article/1515706


三、#undef

用于移除#define定义的宏;我们来看这样的一个例子:


我们在上面引用define定义MAX 100 ,然后打印MAX,发现MAX可用,但是在接下来的一行使用了#undef MAX后,后面再去打印就显示语法错误----未定义标识符,可见在这个地方定义的MAX已经被移除了。


四、命令行定义

许多 C 的编译器提供了一种能力,允许在命令行中定义符号。用于启动编译过程。

例如:当我们根据同一个源文件要编译出一个程序的不同版本的时候,这个特性有点用处。(假定某个程序中声明了一个某个长度的数组,如果机器内存有限,我们需要一个很小的数组,但是另外一个机器内存大些,我们需要一个数组能够大些。)

举个例子:

#include <stdio.h>
int main()
{
    int arr [size];
    int i = 0;
    for(i = 0; i< size i ++)
        arr[i] = i;
    for(i = 0; i< size; i ++)
        printf("%d " ,arr[i]);
    printf("\n" );
    return 0;
}

在编译的时候根据不同的需求,来命令size的大小,以确保程序在不同运行环境下的稳定性。

五、条件编译(选择性编译)

在编译的时候我们可以进行选择性编译,使用一下条件编译指令

1、单分支


#if 常量表达式


  // .....


#endif


 // .....


如:

#define __DEBUG__ 1

#if __DEBUG__

//..

#endif  


2、多分支


#if 常量表达式 

//... 

#elif 常量表达式 

//...  

#else

//... 

#endif


3.判断是否被定义

#if defined(symbol)

#ifdef symbol 

#if !defined(symbol) 

#ifndef symbol  


4.嵌套指令

#if defined(OS_UNIX)

#ifdef OPTION1

unix_version_option1 ();

#endif

#ifdef OPTION2

unix_version_option2 ();

#endif

#elif defined(OS_MSDOS)

#ifdef OPTION2

msdos_version_option2 ();

#endif

#endif

单分支语句举例   运行结果为  0 1 2 3 4 5 6 7 8 9

#include <stdio.h>
#define __DEBUG__
int main()
{
 int i = 0;
 int arr[10] = {0};
 for(i=0; i<10; i++)
 {
 arr[i] = i;
 
 #ifdef __DEBUG__  //判断条件,如果表达式结果为1则参与编译
   printf("%d\n", arr[i]);
 #endif   
 }
 return 0;
}

看上面这个例子,如果__DEBUG__被定义,则编译执行printf语句,否则不编译

多分支举例    运行结果为   3;

#include<stdio.h>
#include<stdlib.h>
#define MAX 100
int main()
{
#if 1>2
    printf("1");
#elif 2>3 
    printf("2");
#elif  4>3
    printf("3");
#endif
    system("pause");
    return 0;
}

判断是否被定义: 结果为MAX has been defined

#include<stdio.h>
#include<stdlib.h>
#define MAX 100
int main()
{
#if defined(MAX)
    printf("MAX has been defined\n");
#endif
#if defined(min)  //仅仅只看你是否定义,不会显示未定义标识符
    printf("???");
#endif
    system("pause");
    return 0;
}

(也可以将#if defined (MAX)改为

#ifdef  MAX  这两者是等价的)

此外,#ifndef MAX则等价于 #if !defined(MAX)

加了一个n和!,意思就变为了:如果MAX没定义就真,执行语句就参与编译

这里的嵌套使用和我们c语言中的if else if语句用法差不多,这里不再赘述。

六、头文件包含

我们知道,工程里面的源文件通过编译器转化为目标文件后,通过链接器和链接库 链接形成可执行程序。

#include 指令可以使另外一个文件被编译。就像它实际出现于 #include 指令的地方一样

这种替换的方式很简单:

  • 预处理器先删除这条指令,并用包含文件的内容替换。
  • 这样一个源文件被包含10次,那就实际被编译10次。


1、本地文件包含

#include"filename"

先在源文件所在目录下查找,如果该头文件未找到,编译器就像查找库函数头文件一样在标

准位置查找头文件。如果找不到就提示编译错误


2、库文件包含

#include<filename.h>

查找头文件直接去标准路径下去查找,如果找不到就提示编译错误。

这样是不是可以说,对于库文件也可以使用 “” 的形式包含?

答案是肯定的

但是这样做查找的效率就低些,当然这样也不容易区分是库文件还是本地文件了


七、嵌套文件包含

一个复杂的项目往往需要很多个公共文件模块来辅助完成,这样子就避免不了重复包含而造成问价内容重复的问题。

如何解决: 用我们前面所用到的条件编译。


即每个头文件开头和结尾分别加上

#ifndef __TEST_H__

#define __TEST_H__

  //文件内容

#endif 

或者

#pragma once  //这种方法是最简洁的

目录
相关文章
|
6月前
|
编译器 程序员 Linux
C++系列九:预处理功能
C++系列九:预处理功能
|
6月前
|
编译器 C++
C 预处理器
C 预处理器。
86 10
|
1月前
|
编译器 Linux C语言
|
6月前
|
编译器 C语言
预处理深入
预处理深入
38 0
预处理深入
|
6月前
|
安全 C语言
程序预处理:全解版-1
程序预处理:全解版
38 0
|
6月前
|
编译器 C语言
c预处理器
c预处理器
39 0
|
6月前
|
编译器 C++
c++预处理器
c++预处理器
38 0
|
安全 编译器 C语言
详解预处理(1)
详解预处理(1)
79 1
|
编译器 Linux C语言
详解预处理(2)
详解预处理(2)
77 0