【c语言】编译原理

在ANSI C的任何一种实现中,存在两个不同的环境

  • 翻译环境,在这个环境中源代码被转化为可执行的机器指令
  • 执行环境,用于执行代码

编译+链接

翻译环境
程序编译过程如下:
程序编译过程

  • 组成一个程序的每个源文件通过编译过程分别转换为目标文件
  • 每个目标文件由链接器捆绑在一起,形成一个单一而完整的可执行程序。
  • 链接器同时也会引入标准C函数库中任何被该程序所用到的函数,而且它可以搜索程序员个人的程序库,将其需要的函数也链接到程序中。
  • 一个源文件test.c变为可执行程序的过程如下所示:
    这里写图片描述

预处理(文本操作)

gcc -E
test.c->test.i
1.#include 头文件的包含
2.注释的删除
3.#define定义符号的替换

编译

gcc -S
test.i->test.s//汇编
把c语言代码换为汇编代码
1.语法分析:保证语法正确 比如变量类型是否定义
2.语义分析:检查语法结构的含义,包括静态语义和动态语义 比如:变量值是否相等
3.符号分析
4.词法分析:判断单词是否拼写正确

汇编

gcc -c
test.s->test.o
把汇编代码转换为机器指令
形成符号表

链接

1.符号表的合并与重定义
2.合并段表

运行环境

1.程序必须载入内存中,在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
2.程序的执行变开始,接着调用函数
3.开始执行程序代码,这个时候程序将使用一个运行时堆栈,存储函数的局部变量和返回地址。程序同时也可以使用静态内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。
4.终止程序,正常终止main函数,也有可能是意外终止。

预处理详解

FILE //进行编译的源代码
LTNE //文件当前的行号
DATE //文件被编译的日期
TIME //文件被编译的时间
STDC //如果编译器遵循ANSI C,其值为1,否则未定义

eg:显示文件名与时间

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("file:%s line:%d %d\n", __FILE__, __LINE__, i);
    }
    system("pause");
    return 0;
}

条件编译

1.

#if  常量表达式
       ///....
#endif

eg:

#define  _DEGUE_  0
int   main()
{
    int arr[8];
    for (int i = 0; i < 8; i++)
    {
        arr[i] = i;
     #if   DEGUE
        printf("%d", arr[i]);
     #endif
    }
    for (int i = 0; i < 8; i++)
    {
        arr[i] = i;
    #if   DEGUE
        printf("%d", arr[i]);
    #endif
    }



    system("pause");

2.多个分支的条件编译

扫描二维码关注公众号,回复: 3298751 查看本文章
#if  常量表达式
    //..
#elif  常量表达式
   //...
#endif

3.判断是否被定义

#if  defined(symbol
#ifdef symbol

#if !defined(symbol)
#ifndef  symbol


#define  MAX 0
int  main()
{


#if defined(MAX)//if判断的是是否定义
    printf("hehe");
#endif  MAX
    system("pause");
}

#if  defined(xx)#ifdef  xx是一对
#if !defined(xx)与  #ifndef  xx是一对

4.嵌套指令

#if   defined   (OS_UNIX)
#ifdef  OPTION1
unix_version_option1();
#endif
#ifdef   OPTION2
unix_version_option2();
#endif

#elif  defined(OS_MSDOS)
#ifdef OPTION2
msdos_version_option2();
#end
#endif

文件包含

  • #include <> 库提供的,直接从库里去查找

  • #include “” 查找,先从当前工程里查找,再从库里面查找。

猜你喜欢

转载自blog.csdn.net/weixin_41892460/article/details/82713381