铜仁市论坛

首页 » 分类 » 分类 » 基于C99规范,最全C语言预处理知识总结
TUhjnbcbe - 2021/3/26 9:58:00
北京普通治疗白癜风多少钱         https://m-mip.39.net/disease/mipso_5416226.html
00.前言

面试官:请简单描述下编译器将C语言从源代码到可执行文件的过程。

应聘者:呃……就是……在IDE里写代码,然后点编译啊……

面试官:那你知道预处理命令这个东西吗,平时用过有哪些?

应聘者:这个我懂,不就是宏定义那些嘛,我平时用#define来定义某些数值,还有用#ifdef来做选择性编译,这些挺简单的啊。

面试官:嗯,好,今天先聊到这,回去等通知吧。

不知道这个问题的,有可能你一直都是用IDE做开发,而没思考过IDE里面经历了什么。如果你用过GCC,你应该大概知道这是一个怎样的过程:

这个过程里面有个Pre-processing,很不起眼,但是非常关键,如果用得好,你的代码也会变得很奇妙。

以下是基于C99标准,总结C语言预处理的知识点以及其相关用法和问题剖析。

注:本文所有案例测试都是基于Windows上的GCC(gccversion6.3.0(MinGW.orgGCC-6.3.0-1))

抛开大脑里零零散散的几个概念,我们直接参考C99标准(ISO/IEC:(E)),简单汇总有以下命令或用法:

分类命令解释简单示例01.条件包含Conditionalinclusion#if,#else,#elif,#endif,#ifdef,#ifndef,#undef即平时理解的条件编译#ifdefidentifier02.源文件包含Sourcefileinclusion#include头文件/源文件包含#includeh-char-sequencenew-line03.宏替换Macroreplacement#define,#,##宏替换A##B04.行控制Linecontrol#line行控制。一般很少用#linedigit-sequencenew-line05.错误指示Errordirective#error出错指示。做预处理检查,可以输出错误提示信息。#errorpp-tokensoptnew-line06.空指令Nulldirective#空指。看起来没什么用令#new-line07.预定义宏名Predefinedmacronames__DATE__,__FILE__,__LINE__,__STDC__,__TIME__预定义宏名08.Pragma命令/操作Pragmadirective/operator_Pragma,#pragmapragma指令#pragmalistingon"..\listing.dir"

以上内容,大部分都很常见,如果要说用得好,那是个艺术活。

1.语法形式

预处理有以下语法形式:

preprocessing-file:

groupoptgroup:

group-partgroupgroup-part

group-part:  

if-section

control-line  

text-line  

#non-directive

if-section:  

if-groupelif-groupsoptelse-groupoptendif-line

if-group:  

#ifconstant-expressionnew-linegroupopt  

#ifdefidentifiernew-linegroupopt  

#ifndefidentifiernew-linegroupopt

elif-groups:  

elif-group  

elif-groupselif-group

elif-group:  

#elifconstant-expressionnew-linegroupopt

else-group:  

#elsenew-linegroupoptendif-line:  #endifnew-linecontrol-line:  #includepp-tokensnew-line  #defineidentifierreplacement-listnew-line  #defineidentifierlparenidentifier-listopt)  replacement-listnew-line  #defineidentifierlparen...)replacement-listnew-line  #defineidentifierlparenidentifier-list,...)  replacement-listnew-line  #undefidentifiernew-line  #linepp-tokensnew-line  #errorpp-tokensoptnew-line  #pragmapp-tokensoptnew-line  #new-linetext-line:  pp-tokensoptnew-linenon-directive:  pp-tokensnew-linelparen:  a(characternotimmediatelyprecededbywhite-spacereplacement-list:  pp-tokensoptpp-tokens:  preprocessing-token  pp-tokenspreprocessing-tokennew-line:  thenew-linecharacter

2.描述

预处理指令由一系列预处理令牌组成,这些预处理令牌以#预处理令牌开头,它是源文件中的第一个字符或紧跟着包含至少一个换行符的空白,并在下一个换行符结束。

文本行不要以#开头,非指令内容也不要用“语法形式”中的内容作为开头

3.约束

在预处理指令中的预处理标记之间(从引入#预处理标记之后到结束换行符之前),唯一出现的空白字符是空格和水平制表符(包括替换了注释或可能的空格)

/*

1
查看完整版本: 基于C99规范,最全C语言预处理知识总结