gcc编译流程、printf、ctype、const的简单介绍

GCC(GNU Compiler Collection)的编译过程主要包括以下几个阶段:

  1. 预处理(Preprocessing)

    • 处理源文件中的预处理指令,如 #include#define 等。
    • 展开宏定义,将包含的头文件内容插入到源文件中。
  2. 编译(Compilation)

    • 将预处理后的源文件转换为汇编语言代码。
  3. 汇编(Assembly)

    • 将汇编语言代码转换为机器语言的目标文件(.o 文件)。
  4. 链接(Linking)

    • 将多个目标文件以及所需的库文件链接在一起,形成可执行文件或共享库等最终产物。
    • 解决目标文件之间的符号引用等问题。

在实际编译过程中,可以通过指定不同的参数来控制各个阶段的具体行为和优化选项等。例如,可以指定优化级别、目标架构等。

举例来说,使用 gcc -o

以下是一个简单的 PL/0 独立词法分析程序,它从标准输入中读取 PL/0 源程序,将其转换为单词符号的序列,并在标准输出中显示单词种别和单词的值(对于标识符和无符号整数),或者仅显示单词种别(对于其他单词符号)。 ``` #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #define MAX_IDENT_LEN 32 #define MAX_NUM_LEN 10 enum { SYM_NULL, SYM_IDENTIFIER, SYM_NUMBER, SYM_PLUS, SYM_MINUS, SYM_TIMES, SYM_SLASH, SYM_ODD, SYM_EQU, SYM_NEQ, SYM_LES, SYM_LEQ, SYM_GTR, SYM_GEQ, SYM_LPAREN, SYM_RPAREN, SYM_COMMA, SYM_SEMICOLON, SYM_PERIOD, SYM_BECOMES, SYM_BEGIN, SYM_END, SYM_IF, SYM_THEN, SYM_WHILE, SYM_DO, SYM_CALL, SYM_CONST, SYM_VAR, SYM_PROCEDURE }; static char ch = ' '; static int sym; static char ident[MAX_IDENT_LEN + 1]; static int num; static void next_ch(void) { ch = getchar(); } static void error(const char *msg) { fprintf(stderr, "%s\n", msg); exit(1); } static void get_sym(void) { while (isspace(ch)) next_ch(); if (isalpha(ch)) { int i = 0; do { if (i < MAX_IDENT_LEN) ident[i++] = ch; next_ch(); } while (isalnum(ch)); ident[i] = '\0'; if (strcmp(ident, "odd") == 0) sym = SYM_ODD; else if (strcmp(ident, "begin") == 0) sym = SYM_BEGIN; else if (strcmp(ident, "end") == 0) sym = SYM_END; else if (strcmp(ident, "if") == 0) sym = SYM_IF; else if (strcmp(ident, "then") == 0) sym = SYM_THEN; else if (strcmp(ident, "while") == 0) sym = SYM_WHILE; else if (strcmp(ident, "do") == 0) sym = SYM_DO; else if (strcmp(ident, "call") == 0) sym = SYM_CALL; else if (strcmp(ident, "const") == 0) sym = SYM_CONST; else if (strcmp(ident, "var") == 0) sym = SYM_VAR; else if (strcmp(ident, "procedure") == 0) sym = SYM_PROCEDURE; else sym = SYM_IDENTIFIER; } else if (isdigit(ch)) { num = 0; do { num = num * 10 + (ch - '0'); next_ch(); } while (isdigit(ch)); sym = SYM_NUMBER; } else { switch (ch) { case '+': sym = SYM_PLUS; next_ch(); break; case '-': sym = SYM_MINUS; next_ch(); break; case '*': sym = SYM_TIMES; next_ch(); break; case '/': sym = SYM_SLASH; next_ch(); break; case '=': sym = SYM_EQU; next_ch(); break; case '<': next_ch(); if (ch == '=') { sym = SYM_LEQ; next_ch(); } else if (ch == '>') { sym = SYM_NEQ; next_ch(); } else { sym = SYM_LES; } break; case '>': next_ch(); if (ch == '=') { sym = SYM_GEQ; next_ch(); } else { sym = SYM_GTR; } break; case '(': sym = SYM_LPAREN; next_ch(); break; case ')': sym = SYM_RPAREN; next_ch(); break; case ',': sym = SYM_COMMA; next_ch(); break; case ';': sym = SYM_SEMICOLON; next_ch(); break; case '.': sym = SYM_PERIOD; next_ch(); break; case ':': next_ch(); if (ch == '=') { sym = SYM_BECOMES; next_ch(); } else { error("invalid symbol"); } break; default: error("invalid symbol"); break; } } } int main(void) { while (ch != EOF) { get_sym(); switch (sym) { case SYM_IDENTIFIER: printf("%d %s\n", SYM_IDENTIFIER, ident); break; case SYM_NUMBER: printf("%d %d\n", SYM_NUMBER, num); break; default: printf("%d\n", sym); break; } } return 0; } ``` 可以将上述代码保存为 `pl0lex.c`,并使用 C 编译器进行编译,例如: ``` $ gcc -o pl0lex pl0lex.c ``` 然后,可以使用以下命令运行该程序: ``` $ ./pl0lex < input.pl0 ``` 其中 `input.pl0` 是 PL/0 源程序的文件名。程序将输出单词符号的序列,每个单词符号占一行,其中标识符和无符号整数的值也将被显示出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会C、Java多种开发语言的金哥

您的鼓励是我创作的动力源泉!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值