• C语言编译过程


      一个C代码到一个可执行程序,其中经历了预编译、编译和链接过程,最终生成可执行程序。

      1、编辑源代码hello.c

    #include <stdio.h>
    #define HELLO "Hello World!
    "
    #define TEST
    int main(void){
    #ifdef TEST
        printf(HELLO);
    #endif
        return 0;
    }

      2、进行预编译

        预编译也叫预处理,本质上就是处理带‘#’的部分和注释,包括以下几部分:

        1)删除所有的注释。

        2)将#include包含的头文件直接拷贝到hello.c文件中。

        3)将所有的宏定义展开,也就是把所有的宏替换掉,并将#define删除。例子中是将printf中的HELLO用"Hello World! "进行了替换,最终是printf("Hello world! ");。

        4)处理所有的条件编译指令,#ifdef、#ifndef、#endif等。例子中的#ifdef TEST,在预编译的过程中会检查是否定义了TEST这个宏,如果定义了就使用printf这个语句,如果没有定义什么也不做。

        5)#pragma特殊的指令,用的很少。

        6)添加行号和文件标识(#error、#line)用于调试和编译出错时。

    //使用gcc -E hello.c -o hello.i生成预处理后的文件
    [root@localhost compile_process]# gcc -E hello.c -o hello.i
    
    //使用ls -lh看一下文件的大小
    [root@localhost compile_process]# ls -lh
    total 24K
    -rw-r--r--. 1 root root 163 Nov 20 11:12 hello.c
    -rw-r--r--. 1 root root 17K Nov 20 14:46 hello.i

      3、编译

        编译过程本质上就是把我们编写的代码翻译成机器语言的过程,这个过程都做了以下几步:

        1)词法分析

        2)语法分析

        3)语义分析

        4)优化后生成相应的汇编代码

    //使用gcc -S hello.c -o hello.s生成汇编代码
    [root@localhost compile_process]# gcc -S hello.i -o hello.s
    
    //ls -lh
    [root@localhost compile_process]# ls -lh
    total 28K
    -rw-r--r--. 1 root root 163 Nov 20 11:12 hello.c
    -rw-r--r--. 1 root root 17K Nov 20 14:46 hello.i
    -rw-r--r--. 1 root root 347 Nov 20 15:02 hello.s

      

    //使用gcc -c hello.s -o hello.o将汇编文件生成二进制文件也就是机器能识别的语言
    [root@localhost compile_process]# gcc -c hello.s -o hello.o
    //ls -lh
    [root@localhost compile_process]# ls -lh
    total 32K
    -rw-r--r--. 1 root root 163 Nov 20 11:12 hello.c
    -rw-r--r--. 1 root root 17K Nov 20 15:08 hello.i
    -rw-r--r--. 1 root root 856 Nov 20 15:15 hello.o
    -rw-r--r--. 1 root root 347 Nov 20 15:08 hello.s

      4、链接

        在编译后只是生成了二进制文件,该文件不是可执行文件,要想得到可执行文件就要把二进制文件和C标准库绑到一起,这就是链接过程了。

    //使用gcc hello.o -o hello生成可执行文件hello
    [root@localhost compile_process]# gcc hello.o -o hello
    
    //ls -lh
    [root@localhost compile_process]# ls -lh
    total 40K
    -rwxr-xr-x. 1 root root 4.6K Nov 20 15:27 hello
    -rw-r--r--. 1 root root  163 Nov 20 11:12 hello.c
    -rw-r--r--. 1 root root  17K Nov 20 15:08 hello.i
    -rw-r--r--. 1 root root  856 Nov 20 15:15 hello.o
    -rw-r--r--. 1 root root  347 Nov 20 15:08 hello.s
    
    //执行可执行文件hello
    [root@localhost compile_process]# ./hello 
    Hello World!
    
    //使用ldd查看一下可执行程序所依赖的库信息
    [root@localhost compile_process]# ldd hello
        linux-gate.so.1 =>  (0x00ad9000)
        libc.so.6 => /lib/libc.so.6 (0x003da000)
        /lib/ld-linux.so.2 (0x00572000)

      这就是我在使用gcc编译C程序是所经历的过程。当然可以在分细一点:预处理、编译、汇编、链接。还可以在分一下就是:预编译、编译、优化程序、汇编、链接。大体上就编译和链接两个阶段。

  • 相关阅读:
    我对“错排问题”的理解
    洛谷P1144 最短路计数 题解 无权图的最短路计数(广搜)
    洛谷P1714 切蛋糕 题解 单调队列
    洛谷P6040 「ACOI2020」课后期末考试滑溜滑溜补习班 题解 单调队列优化DP
    POJ2559 Largest Rectangle in a Histogram 题解 单调队列/单调栈 (直方图的最大矩形面积)
    洛谷P2947 向右看齐Look Up 题解 单调栈/单调队列
    洛谷P1725 琪露诺 题解 单调队列优化DP入门题
    洛谷P1886 滑动窗口 题解 单调队列
    洛谷P2952 牛线Cow Line 题解 双端队列deque的使用
    多线程交互,访问数据,如果访问到了就不访问了,怎么 避免重读?
  • 原文地址:https://www.cnblogs.com/coolYuan/p/7865277.html
Copyright © 2020-2023  润新知