Linux——gcc编译过程详解与ACM时间和进度条的制作

gcc编译过程详解与ACM时间和进度条的制作

1. 编译详细过程与ACM时间

我们知道编译分为四大步:预处理、编译、汇编、链接,但是详细的情况并不像我们想的那样,因为编译器会做很多事情,比如:宏替换、头文件展开、语法检查、语义检查、代码优化、生成汇编代码、生成可执行文件等。

1.1 预处理

gcc -E main.c -o main.i

解析:

  • gcc:编译器
  • -E:将源代码文件进行预编译处理,形成.i文件
  • main.c:源代码文件
  • -o:指定目标文件的名称或者存放路径
  • main.i:预处理后的目标文件

预处理主要完成以下工作:

  1. 头文件展开
  • 处理所有#include预处理指令
  • 将头文件的内容复制到当前文件
  • 可以递归展开(头文件中包含的头文件)
  1. 宏定义替换
  • 展开所有#define宏定义
  • 处理条件编译指令(#if、#ifdef、#ifndef等)
  • 展开所有宏调用
#define Max(a, b) ((a) > (b) ? (a) : (b))
int max = Max(3, 4); //展开为:int max = ((3) > (4) ? (3) : (4))
  1. 条件编译处理

    • #if、#ifdef、#ifndef:条件判断
    • #elif、#else:分支处理
    • #endif:结束条件编译
    #ifdef DEBUG
    printf("debug info\n");
    #endif
    
  2. 删除注释

    • 删除所有//和/* */格式的注释
    • 每个注释都替换为一个空格
  3. 添加行号和文件名标识

    • 使用#line指令标记行号和文件名
    • 用于编译器产生调试信息和编译错误提示
  4. 处理特殊预处理指令

    • #pragma:编译器指令
    • #error:产生编译错误
    • #warning:产生编译警告
  5. 保留所有的换行符

    • 确保错误提示的行号正确
    • 方便调试
  6. 字符串常量化

    • 处理#运算符,将宏参数转换为字符串
    #define STR(s) #s
    STR(hello)  // 展开为: "hello"
    
  7. 宏连接操作

    • 处理##运算符,连接两个记号
    #define CONCAT(a,b) a##b
    CONCAT(x,y)  // 展开为: xy
    

示例:

// 源文件 main.c
#include <stdio.h>
#define MAX 100
#define SQUARE(x) ((x)*(x))

int main() {
   
    int value = SQUARE(MAX);
    return 0;
}

// 预处理后 main.i(简化版)
// ... stdio.h的内容 ...
int main() {
   
    int value = ((100)*(100)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值