-
Lesson 1 - 最简单的C程序
-
Lesson 2 - 打印输出
-
Lesson 3 - 循环打印
-
Lesson 4 - 判断奇偶
-
Lesson 5 - 从1加到100求和
-
Lesson 6 - 乘法表
-
Lesson 7 - 求100以内的最大素数
-
Lesson 8 - 1到100有多少个9
-
Lesson 9 - 整型转字符串
-
Lesson 10 - 约瑟夫环
-
Lesson 11 - 求两个坐标点之间的距离
-
Lesson 12 - 判断机器存储是否小尾端
-
Lesson 13 - 对不起,你的车今天限行
-
Lesson 14 - 判断地图上某点是否有出路
-
Lesson 15 - 统计一个数二进制表示中1的个数
-
Lesson 16 - 字符串拷贝
-
Lesson 17 - 统计单词个数
-
Lesson 18 - 实现 printf
-
Lesson 19 - 命令解释器
-
Lesson 20 - 预处理器实现
-
Lesson 21 - 词法分析器实现
-
Lesson 22 - 猜数游戏
-
Lesson 23 - 五子棋
-
Lesson 24 - 超链接分析器
-
Lesson 25 - cp命令实现
-
Lesson 26 - ELF文件头分析器实现
-
Lesson 27 - 简单流处理器实现和正则表达式
-
Lesson 28 - 数学计算器实现
-
Lesson 29 - 数学计算器实现more命令实现
-
Lesson 30 - sort命令实现
-
Lesson 31 - ls -l命令实现
-
Lesson 32 - Bash项目
-
Lesson 33 - 动态数组实现
-
Lesson 34 - 约瑟夫环问题
-
Lesson 35 - 表达式求值问题
-
Lesson 36 - 广度优先解决迷宫问题
-
Lesson 37 - 词频统计器
-
Lesson 38 - 堆排序问题
-
Lesson 39 - 构造符号表
-
Lesson 40 - MyDictionary项目
-
Lesson 41 - BSearch 实现
-
Lesson 42 - QSort 实现
-
Lesson 43 - 深度优先解决迷宫问题
-
Lesson 44 - KMP 算法实现
-
Lesson 45 - 最长公共子序列(LCS)问题
-
Lesson 46 - Dijkstra 算法
-
Lesson 47 - Huffman Coding 算法
-
Lesson 48 - 地图导航项目
Lesson 20 Preprocessor 预处理器实现
delcomment.c
#include <stdio.h>
/* abcd */
// abcd
int get_input_type(char c)
{
// deal with /* */
if (c == '/')
return 1;
if (c == '*')
return 2;
// deal with //
if (c == '\n')
return 3;
// deal with '/'
if (c == '\'')
return 4;
// deal with '\\'
if (c == '\\')
return 5;
return 0;
}
#define debug(fmt, args...) fprintf(stderr, fmt, ##args)
int main(void)
{
int state = 0;
while (1)
{
char c;
int input;
c = getchar();
input = get_input_type(c);
if (c == EOF)
break;
debug("%c", c);
/* ABCD */
if (state == 0 && input == 1) // "/
{
state = 1;
}
else
if (state == 0 && input == 4) // "abc'
{
state = 5;
putchar(c);
}
else
if (state == 1 && input == 1) // "//
{
state = 4;
}
else
if (state == 1 && input == 2) // "/*
{
state = 2;
}
else
if (state == 2 && input == 0) // "/*abc
{
state = 2;
}
else
if (state == 2 && input == 2) // "/*abc*
{
state = 3;
}
else
if (state == 3 && input == 1) // "/*abc*/
{
state = 0;
}
else
if (state == 3 && input == 0) // "/*abc*abc
{
state = 2;
}
else
if (state == 4 && input == 3) // "// abcd \n
{
state = 0;
putchar(c);
}
else
if (state == 5 && input == 4) // "abc'/'
{
state = 0;
putchar(c);
}
else
if (state == 5 && input == 5) // "abc'\/
{
state = 6;
putchar(c);
}
else
if (state == 6 && input == 4) // "abc'\'
{
state = 5;
putchar(c);
}
else
if (state == 6 && input == 5) // "abc'vv
{
state = 5;
putchar(c);
}
else
if (state == 6 && input == 0) // "abc'\'
{
state = 5;
putchar(c);
}
else
if (state == 0 || state == 5)
putchar(c);
debug(" input=%d, /* abcd */ state=%d\n", input, state);
}
return 0;
}
copy
语法知识点
- 二维数组
- 函数指针
- 二维函数指针数组
- 结构体数组
- debug 调试宏
课堂讨论
- 用 if-else 的结构实现状态机有什么好处? 能否有 switch-case 来实现?
- 请讨论有多少种判别注释的例外情况,考虑有单引号,双引号,转移字符,反斜杠等因素。
课后练习
- 在C语言去注释的问题中,对于双引号字符串中的 /* */ 注释没有进行判别,请重新设计状态机实现之。
- 在宏定义替换问题中,对于带参数的宏没有进行处理,请重新设计状态机实现之。
- 在条件编译替换问题中,对于 #else 的情况没有判别,请重新设计状态机实现之。
- 预处理问题中还有一个 #include 没有实现,请参考 #if/#endif 状态机的构造方法,自行实现之。