C预处理器和C库

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jet007_007/article/details/51721022

编译程序之前,先由预处理器检查程序(因此称为预处理器)。根据程序中使用的预处理器指令,预处理器用符号缩略语所代表的内容替换程序中的缩略语。

预处理器可以根据您的请求包含其他文件,还可以选择让编译器处理哪些代码。预处理器不能理解C,它一般是接受一些文本并将其转换为其他文本。

#define

#define  所选择让的缩略语(宏macro)  替换列表(replacement list)或主体(body)
预处理器在程序中发现了宏的实例后,总会用实体替换该宏。
1、在一行结尾加反斜杠符号以使该行扩展至下一行
#define OW "Consistency is the last refuge of the unimagina\
tive.-Oscar Wilde"
注意第二行要左对齐,否则开头的空格也作为字符串的一部分。
2、类函数宏
通过使用参数,可以创建外形和作用都与函数相似的类函数宏(function-like macro)。
例如:#define MEAN(X,Y) (((X)+(Y))/2)
3、#符与预处理器的粘合剂:##运算符的使用
#符号用作一个预处理运算符,它可以把语言符号转化为字符串。例如,如果x是一个宏参量,那么#x可以把参数名转化为相应的字符串。该过程成为字符串化(stringzing)。
和#运算符一样,##运算符可以用于类函数宏的替换部分另外,##还可用于类对象宏的替换部分。这个运算符把两个语言符号组合成单个语言符号。
例如:可以定义下面的宏:#define XNAME(n)  x##n,这样,调用宏XNAME(4)会展开成下面形式:x4。
#define XNAME(n)    x##n
#define PRINT_XN(n) printf("x"#n"=%d\n",x##n)

int main(void)
{
    int XNAME(1)=14;        //变成int x1=14;
    int XNAME(2)=20;        //变成int x2=20;
    PRINT_XN(1);            //变成printf("x1=%d\n",x1);
    PRINT_XN(2);            //变成printf("x2=%d\n",x2);
    return 0;
}

条件编译

#ifdef、#else和#endif指令

#ifdef指令说明:如果预处理器已经定义了后面的标识符,那么执行所有指令并编译C代码,直到下一个#else或#endif出现为止(无论#else和#endif谁先出现)。如果有#else指令,那么,在未定义标识符时会执行#else和#endif之间的所有代码。
#ifdef #else格式非常类似于C中的if else。主要差异为预处理器不能识别标识代码块的花括号({}),因此使用#else(如果需要)和#endif(必须存在)来标记指令块。

#ifndef指令

类似于#ifdef指令,#ifndef指令可以与#else、#endif指令一起使用。#ifndef判断后面的标识符是否为未定义的,#ifndef的反义词为#ifdef。
一般地,当某文件包含几个头文件,而且每个头文件都可能定义了相同的宏时,使用#ifndef可以防止对该宏重复定义,
#ifndef指令通常用于防止多次包含统一文件。为什么会多次包含同一文件呢?最常见的原因是:许多包含文件自身包含了其他文件,因此可能显式地包含其他文件已经包含的文件。为什么这会成为问题呢?因为头文件中的有些语句在一个文件中只能出现一次(如结构类型声明)。
例如main.c文件中有下列头文件包含:
#include <head_file1.h>
#include <head_file2.h>
#include <head_file3.h>
但是如果 head_file3.c文件又有 #include <head_file1.h>,这样在main.c中就有两次#include <head_file1.h>。

#if和#elif指令

#if指令更像常规C中的if;#if后跟常量整数表达式。如果表达式为非零值,则表达式为真。在该表达式中可以使用C的关系运算符和逻辑运算符。

  








猜你喜欢

转载自blog.csdn.net/jet007_007/article/details/51721022
今日推荐