C 语言中的条件编译

之前我们说过,源程序需要经过预处理、编译、汇编、链接才会变成可执行程序,预处理阶段完成的是预处理操作,本质上是一种替换操作。

不带参宏

宏常量

宏常量是用 #define 定义的宏,只能在一行内表达,如果要在多行内表达,则需要加上连接符\。比如:

#define PI 3.14

宏常量很多情况下可以用来定义文件路径。但要记住:宏只是简单的替换操作

宏类型

有时候,也会用宏来定义一种合成的类型名。如:

#include CHAR_POINTER char *

但要记住:宏只是简单的替换操作,不要和 typedef 弄混

带参宏

宏函数

有时候,对于一些简单的函数也可以利用宏来实现。如:

#define MAX(a,b) a>b?a:b

宏名和参数之间不能出现空格。虽然这样可以简化代码,减少程序调用,但是编译文件会很大。

仍然要记住:宏只是简单的替换操作

取消宏

取消宏常量,宏类型,宏函数

对于已经定义的宏常量,宏类型和宏函数来说,取消宏定义都只有一句话:

#undef macroname

预定义宏

在 C 语言中,还存在着一些内置的已经定义的宏,如:

__DATE__ 进行预处理的日期
__FILE__ 代表当前源代码文件名的字符串文字
__LINE__ 代表当前源代码中的行号的整数常量
__TIME__ 源文件编译时间
__func__ 当前所在函数名

条件编译

在跨平台开发的时候,有时候会根据条件选择性的进行编译,这就是条件编译。

单双路

一般结构为:

#ifdef
    ......
#else
    ......
#endif

或者是:

#ifndef
    ......
#else
    ......
#endif

单双多路

一般结构为:

#if logical statement
    ......
#elif logical statement
    ......
#elif logical statement
    ......
#endif

#include

在 main 之前除了条件编译之外,一般都会有 #include 语句,这就是头文件包含。

包含方式

包含是指被包含的文件全部包含到当前的文件中。包含方式一般有两种:

<>

使用这种方式是指从指定路径中搜索幷包含头文件。

""

使用这种方式是指从当前工程路径中搜索幷包含头文件,当前工程路径下不存在的话,才到系统路径下搜索幷包含。

多文件编程

多文件编程会增加程序的可读性,除了方便管理之外还能够增加文件的可移植性和保密性。

这里以一个简单的图示简单说明一下:

  • C 语言是以文件为单位进行编译的,编译期间只需要进行函数声明即可
  • 链接阶段提供实现就能够生成可执行文件
  • else.h 中的条件编译语句是为了避免头文件重复包含

关于 #

利用 # 创建字符串

如果要创建类似 "str1",“str2”,"str3" 这样的字符可能就需要 # 运算符。看下边的程序:

#include <stdio.h>
#define str(x) "str"#x

int main()
{
    printf("%s\t%s\t%s",str(1),str(2),str(3));

    return 0;
}

结果为:

str1    str2    str3

以上的结果是由于类似于 “abc”"def""ghi" 这样的字符串是合理的。而 # 号作为一个预处理运算符,它能够将待替换符转化为字符串。

利用 ## 进行预处理参数粘合

看下边的程序:

#include <stdio.h>
#define SUM(a,b) (a##a+b##b)
#define XVAR(n) x##n

int main()
{
    int XVAR(1) = 1,XVAR(2) = 2;

    printf("SUM(1,2) = %d\n",SUM(1,2));
    printf("XVAR(1)  = %d,XVAR(2)  = %d\n",x1,x2);
    printf("&XVAR(1) = %p,&XVAR(2) = %p\n",&XVAR(1),&XVAR(2));
    printf("&x1      = %p,&x2      = %p",&x1,&x2);

    return 0;
}

结果为:

SUM(1,2) = 33
XVAR(1)  = 1,XVAR(2)  = 2
&XVAR(1) = 0060FEAC,&XVAR(2) = 0060FEA8
&x1      = 0060FEAC,&x2      = 0060FEA8

还可以将上边的程序改为:

#include <stdio.h>

#define XVAR(n) x##n
#define PRINT_VAR(n) printf("XVAR("#n")  = %d",x##n);
#define POINTER_VAR(n) printf("&XVAR("#n") = %p",&XVAR(n));
#define POINTER_X(n) printf("&x"#n" = %p",&x##1);

int main()
{
    int XVAR(1) = 1,XVAR(2) = 2;

    PRINT_VAR(1);
    putchar(10);
    PRINT_VAR(2);
    putchar(10);

    POINTER_VAR(1);
    putchar(10);
    POINTER_VAR(2);
    putchar(10);

    POINTER_X(1);
    putchar(10);
    POINTER_X(2);

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章