C程序令牌统计技术咨询:预处理指令计数规则及指定代码令牌数量分析
C程序令牌统计技术咨询:预处理指令计数规则及指定代码令牌数量分析
嗨,我来帮你把C语言令牌统计的事儿说透,尤其是预处理指令的计数规则,再一步步给你数清楚你贴的代码里的令牌数量~
首先得明确两个核心概念:预处理令牌和编译阶段的普通令牌——考试里经常会在这两个点上挖坑,一定要区分开。
一、预处理指令的令牌计数规则
- 预处理指令开头的
#是一个单独的预处理令牌,不能和后面的include/define合并。 include、define这些预处理关键字,也是单独的预处理令牌。- 宏定义里的宏名、宏参数、替换内容,都会被拆分成独立的令牌:比如
#define PI 3.14159里,PI是标识符令牌,3.14159是浮点常量令牌;宏的参数x是标识符令牌,替换里的(、)、*也都是单独的标点/运算符令牌。 - 注意:当预处理完成后,所有的预处理指令(
#、include、define这些)都会被移除,宏会被展开成对应的内容,这时候统计的就是给编译器的普通令牌了——很多题目会特意问这两种情况的数量,别搞混!
二、你的代码令牌统计分析
先把你给出的代码贴出来方便对照:
#include <stdio.h> #define PI 3.14159 #define SQUARE(x) ((x) * (x)) int main() { float radius = 5.0; float area = PI * SQUARE(radius); printf("Area of circle: %.2f\n", area); return 0; }
1. 预处理前(含预处理指令)的令牌总数
我们逐行拆解(空白字符只用来分隔令牌,本身不算):
- 第一行
#include <stdio.h>:#、include、<stdio.h>→ 3个 - 第二行
#define PI 3.14159:#、define、PI、3.14159→ 4个 - 第三行
#define SQUARE(x) ((x) * (x)):#、define、SQUARE、(、x、)、(、(、x、)、*、(、x、)、)→ 15个 - 主函数部分:
int、main、(、)、{→ 5个float、radius、=、5.0、;→5个float、area、=、PI、*、SQUARE、(、radius、)、;→10个printf、(、"Area of circle: %.2f\n"、area、)、;→6个return、0、;→3个}→1个
把这些加起来:3+4+15+5+5+10+6+3+1 = 47个预处理+普通令牌。
2. 预处理后(编译阶段)的令牌总数
预处理完成后,#include会引入头文件(但头文件的令牌不算在你的代码里,除非题目特别说明),#define的宏会被展开,预处理指令全部被移除,你的主函数代码会变成这样:
int main() { float radius = 5.0; float area = 3.14159 * ((radius) * (radius)); printf("Area of circle: %.2f\n", area); return 0; }
现在统计这里的令牌:
int、main、(、)、{→5个float、radius、=、5.0、;→5个float、area、=、3.14159、*、(、(、radius、)、*、(、radius、)、)、;→15个printf、(、"Area of circle: %.2f\n"、area、)、;→6个return、0、;→3个}→1个
总和:5+5+15+6+3+1 = 35个编译阶段令牌。
三、考试里的注意事项
- 字符串常量(比如
"Area of circle: %.2f\n")是单个令牌,不管里面有多少字符、转义符,都算一个。 - 关键字(
int、float)、标识符(main、radius)都是单个令牌,哪怕名字很长。 - 单个的运算符、标点(
=、*、(、))每个都是独立令牌,组合运算符(比如++、<=)算一个,你这段代码里没有这种情况。
内容来源于stack exchange
相关产品推荐
相关产品推荐

