编译、链接过程简介

目录

1、编译过程简介

2、链接过程简介

3、小结


1、编译过程简介

初识编译器

你不知道的事。。。

预编译 

                -处理所有的注释,以空格代替 

                -将所有的#define删除,并且展开所有的宏定义 

                -处理条件编译指令#if, #ifdef, #elif, #else, #endif 

                -处理#include, 展开被包含的文件 

                -保留编译器需要使用的#pragma指令 

                -预处理指令示例: gcc -E file.c -o file.i 

19-1.h

/* 
    This is a header file.  
*/   
  
const char* p = "Nyist";  
  
int i = 0;  

19-1.c

#include "19-1.h"  
  
// Begin to define macro  
  
#define GREETING "Hello world!"  
  
#define INC(x) x++  
  
// End  
  
int main()  
{     
    p = GREETING;  
      
    INC(i);  
      
    return 0;  
}  

 

  

                                        #信息用于传给后续编译器

编译 

                -对预处理文件进行词法分析,语法分析和语义分析 

                        词法分析:分析关键字,标示符,立即数等是否合法 

                        语法分析:分析表达式是否遵循语法规则 

                        语义分析:在语法分析的基础上进—步分析表达式是否合法 

                -分析结束后进行代码优化生成相应的汇编代码文件 

                          编译指令示例: gcc -S file.i -o file.s 

 

  

现在版本的GCC把预编译和编译两个步骤合并成一个步骤,使用一个叫做ccl的程序来完成这两个步骤

所以也可以直接调用ccl test.c完成预编译编译过程

 

汇编 

                -汇编器将汇编代码转变为机器的可以执行指令 

                -每条汇编语句几乎都对应—条机器指令 

                        汇编指令示例: gcc -c file.s -o file.o

 

 

                                  不是可执行程序,需要链接器连接

  

2、链接过程简介

问题

                工程中的每个C语言源文件被编译后生成目标文件,这些目标文件如何生成最终的可执行程序?

链接器的意义

      链接器的主要作用是把各个模块之间相互引用的部分处理好,

      使得各个模块之间能够正确的衔接。

 

                       模块链接可分为静态链接动态链接

静态链接 

                    -由链接器在链接时将库的内容直接加入到可执行程序中

 

Linux下静态库的创建和使用 

                    -编译静态库源码: gcc -c lib.c -o lib.o 

                    -生成静态库文件: ar -q lib.a lib.o 

                    -使用静态库编译: gcc main.c lib.a -o mian.out

编程实验

//slib.c
char* name()  
{  
    return "Static Lib";  
}  
  
int add(int a, int b)  
{  
    return a + b;  
}
//20-1.c
#include <stdio.h>  
  
extern char* name();  
extern int add(int a, int b);  
  
int main()  
{  
    printf("Name: %s\n", name());  
    printf("Result: %d\n", add(2, 3));  
  
    return 0;  
}  

 

                

                                目标文件和静态库文件完全被链接到可执行文件

动态链接 

                    -可执行程序在运行时才动态加载库进行链接 

                    -库的内容不会进入可执行程序当中 

 

Linux下动态库的创建和使用 

                    -编译动态库源码: gcc -shared dlib.c -o dlib.so (gcc -shared -fPIC dlib.c -o dlib.so )

                    -使用动态库编译: gcc main.c -ldl -o main.out 

                    -关键系统调用 

                            dlopen : 打开动态库文件 

                            dlsym : 查找动态库中的函数并返回调用地址 

                            dlclose: 关闭动态库文件

编程实验

//dlib.c
char* name()  
{  
    return "Dynamic Lib";  
}  
 
int add(int a, int b)  
{  
    return a + b;  
}  
//20-2.c 
#include <stdio.h>  
#include <dlfcn.h>  
  
int main()  
{  
    void* pdlib = dlopen("./dlib.so", RTLD_LAZY);  //指针指向加载到内存的地址
  
    char* (*pname)();  
    int (*padd)(int, int);  
  
    if( pdlib != NULL )  //动态库加载成功
    {  
        pname = dlsym(pdlib, "name");  //到动态库查找name函数,返回函数入口地址
        padd = dlsym(pdlib, "add");  
   
        if( (pname != NULL) && (padd != NULL) )  //都找到了,调用
        {  
            printf("Name: %s\n", pname());  
            printf("Result: %d\n", padd(2, 3));  
        }  
  
        dlclose(pdlib);  //关闭动态库
    }  
    else  
    {  
        printf("Cannot open lib ...\n");  
    }  
  
    return 0;  
}

           删除创建的dlib.so(动态库文件)后

                       说明程序运行时库文件被动态的加载到内存里

3、小结

编译过程分为预处理,编译,汇编和链接四个阶段 

     -预处理:处理注释,宏以及已经以#开头的符号 

     -编译:进行词法分析,语法分析和语义分析等 

     -汇编:将汇编代码翻译为机器指令的目标文件 

            链接是指将目标文件最终链接为可执行程序 

            根据链接方式的不同,链接过程可以分为: 

                -静态链接:目标文件直接链接进入可执行程序 

                 - 动态链接:在程序启动后才动态加载目标文件

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值