zoukankan      html  css  js  c++  java
  • 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程序是所经历的过程。当然可以在分细一点:预处理、编译、汇编、链接。还可以在分一下就是:预编译、编译、优化程序、汇编、链接。大体上就编译和链接两个阶段。

  • 相关阅读:
    初认识AngularJS
    (imcomplete) UVa 10127 Ones
    UVa 10061 How many zero's and how many digits?
    UVa 11728 Alternate Task
    UVa 11490 Just Another Problem
    UVa 10673 Play with Floor and Ceil
    JSON对象和字符串的收发(JS客户端用typeof()进行判断非常重要)
    HTML.ActionLink 和 Url.Action 的区别
    EASYUI TREE得到当前节点数据的GETDATA方法
    jqueery easyui tree把已选中的节点数据拼成json或者数组(非常重要)
  • 原文地址:https://www.cnblogs.com/coolYuan/p/7865277.html
Copyright © 2011-2022 走看看