C语言学习笔记:预处理器

栏目: C · 发布时间: 6年前

内容简介:编译一个C程序包含很多步骤,其中第一个步骤被称为预处理阶段。C预处理器在源代码编译之前对其进行一些文本性质的操作。它的主要任务包括删除注释、插入被#include指令包含的文件的内容、定义和替换由#define指令定义的符号以及确定代码的部分内容是否应该根据一些条件编译指令进行编译。预处理指令的一些规则:常见形式:

编译一个C程序包含很多步骤,其中第一个步骤被称为预处理阶段。C预处理器在源代码编译之前对其进行一些文本性质的操作。它的主要任务包括删除注释、插入被#include指令包含的文件的内容、定义和替换由#define指令定义的符号以及确定代码的部分内容是否应该根据一些条件编译指令进行编译。

预处理指令的一些规则:

  • 指令都以#开始
  • 在指令的符号之间空间而已插入任意数量的空格或水平制表符。
  • 指令总在第一个换行处结束,除非明确的指明要延续。如果想要在下一行延续指令,必须在当前行的末尾加上\符号。
  • 指令可以出现在程序中的任何位置
  • 注释可以和指令放在同一行。

宏定义

无参数的宏

常见形式:

#define 宏名称 替代文字

通常用来定义常量。另外替代文本也可以为空。比如常用于条件编译的

#define DEBUG

常见错误:

  • 宏定义中使用 =
  • 宏定义中的末尾使用分号结尾

带参数的宏

也被成为函数式宏,格式为:

#define 标识符(x1,x2,..) 替换列表

要求:

  • 宏的标识符与左括号间不能有空格,否则会被认定为无参数宏
  • 替代列表最外层用括号括起来,防止替代后出现歧义。
  • 为防止歧义,替代列表中的参数也要用括号括起来。

示例:

#define MAX(x,y) (((x) > (y))?(x):(y))
#define IS_EVEN(n) ((n)%2==0)

#运算符和##运算符

我们已经知道,预处理指令以#号开始,但是#号在宏定义中还有另外的作用:

  • #:将宏的一个参数转化成字符串字面量
  • ##:可以将2个记号(如标识符)粘合在一起,成为一个记号。

示例:

#include <stdio.h>
 
#define PRINT_INT(n) printf(#n " = %d\n", n)
#define MK_ID(n) i##n
 
int main() {
    int i, j;
    PRINT_INT(i / j); /* printf("i/j" " = %d\n", n) 8? */
 
    int MK_ID(1), MK_ID(2);  /* int n1, n2 */
    return 0;
}

取消定义

#undef 宏名称

文件包含

#include指令告诉预处理器打开一个特定的文件,将它的内容作为正在编译的文件的一部分包含进来。编译器支持2种不同类型的#include文件包含:库函数文件和本地文件。事实上他们的区别很小:

  • 库函数文件包含语法:#include <filename>
  • 本地文件包含语法:#include “filename”

规避方式是使用条件编译。

条件编译

条件编译的主要指令有:#if、#ifdef、#ifndef、#elif、#else、#endif。其中#ifdef等价于#if defined(标识符),#ifndef等价于#if !defined(标识符)

其他指令

#error指令

通常与条件编译一起,用于检测正常编译过程中不应出现的情况。遇到#error指令预示程序中出现了严重错误,通常编译器会立即停止编译。

#if INT_MAX < 100000
#error int type is to small
#endif

#line指令

  • 用来改变程序行编号。
  • #line n这条指令导致后续的编号为n、n+1、n+2…
  • #line n “文件”,指令后面的行会被认为来自文件,行号由n开始。
  • #line指令使用的场景非常少,不掌握也无所谓。

#pragma指令

为要求编译器执行某些特殊操作提供一种方法。这条指令对非常大的程序或需要使用特定编译器的特殊功能的程序非常有用。#pragma中出现的命令集在不同的编译器上是不同的(需要查看各自编译器文档)。如果#pragma包含了无法识别的命令,预处理器会忽视这些指令,并且不给出出错提示。

预定义的宏

C语言提供了一些预定义宏,这些宏提供发了当前编译或编译器本身的信息:

  • __DATE__:编译的日期(格式 mm dd yyyy)
  • __TIME__:编译的时间(格式 hh:mm:ss)
  • __FILE__:被编译的文件名
  • __LINE__:被编译的文件中的行号
  • __STDC__:如果编译器遵循C标准,则值为1

以上所述就是小编给大家介绍的《C语言学习笔记:预处理器》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Software Engineering for Internet Applications

Software Engineering for Internet Applications

Eve Andersson、Philip Greenspun、Andrew Grumet / The MIT Press / 2006-03-06 / USD 35.00

After completing this self-contained course on server-based Internet applications software, students who start with only the knowledge of how to write and debug a computer program will have learned ho......一起来看看 《Software Engineering for Internet Applications》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具