嵌入式C语言面试相关知识——编译过程

news/2024/12/22 20:38:37/

嵌入式C语言面试相关知识——编译过程

  • 一、博客声明
  • 二、自问题目
    • 1、C语言的编译过程是什么?
    • 2、编译过程中参与的工具有哪些?
    • 3、什么是条件编译,作用是什么?
    • 4、链接环节中的静态链接和动态链接是什么,有何区别?
    • 5、什么是头文件保护符(Include Guards),为什么需要它们?
    • 6、如何创建和使用静态库和动态库?

一、博客声明

  又是一年一度的秋招,怎么能只刷笔试题目呢,面试题目也得看,想当好厂的牛马其实也不容易呀O(∩_∩)O。注意:这篇博客大部分是来自网上的资源,通过自问或者他问,然后寻找答案,为了加深印象,总结和抄一遍。


二、自问题目

1、C语言的编译过程是什么?

  C语言的编译过程分为四个主要步骤:*预处理、编译、汇编和链接。

	源文件 (source.c) ↓ 预处理器 (Preprocessor)预处理后的文件 (source.i)↓ 编译器 (Compiler)汇编代码文件 (source.s)↓ 汇编器 (Assembler)目标文件 (source.o)↓ 链接器 (Linker)可执行文件 (a.out 或 main.exe)
  • 预处理(Preprocessing): 在这一步,预处理器将对源码进行处理。它会根据以 “#” 开头的指令,如#include#define,展开头文件、宏定义,并去除注释等。生成的结果是一个经过宏替换和条件编译后的纯C代码文件,输出的扩展名为 “.i”
    gcc -E main.c -o main.i
    
  • 编译(Compilation): 在这一步,编译器将把预处理后的源代码转为汇编语言。它会将C语言代码翻译成相应的汇编指令,但还没有生成可以执行的代码。生成的结果是一个以 “.s”“.asm” 为扩展名的汇编文件。
    gcc -S main.i -o main.s
    
  • 汇编(Assembly): 在这一步,汇编器将把上一步产生的汇编语言代码转化为机器码指令,即可执行的二进制代码文件。它会将每条汇编指令翻译成机器码,并生成目标文件(通常以 “.obj”“.o” 为扩展名),其中包含了已经转换好的机器码指令。
    gcc -c main.s -o main.o
    
  • 链接(Linking): 最后一步就是链接器对目标文件进行链接操作,将所有需要用到的函数库和对象文件合并成一个可执行文件。链接器解析符号引用并确定函数和变量在内存中的地址,生成最终可执行文件(通过以 “.exe”“.out” 为扩展名).
    gcc main.o -o main
    

2、编译过程中参与的工具有哪些?

  其实上面已经说了,分别是预处理器、编译器、汇编器和链接器。

  1. 预处理器: 预处理器会处理以 # 开头的指令(如#include、#define等)和宏定义。预处理的输出是一个纯C语言代码文件。
    • 宏替换: 将所有的宏定义(如#define)替换为相应的值。
    • 头文件包含: 处理#include指令,将头文件的内容插入到源文件中。
    • 条件编译: 根据条件编译指令(如#ifdef、#ifndef)选择性地编译代码段。
    • 删除注释: 去除源代码中的注释。
  2. 编译器: 编译是将预处理后的C代码转换为汇编代码的过程。编译器会进行语法检查、语义分析和代码优化,生成目标平台的汇编代码。
  3. 汇编器: 汇编器将编译器生成的汇编代码转换为机器码(目标代码),生成目标文件(通常是.o或.obj文件)。目标文件是二进制文件,包含机器码和相关数据。
  4. 链接器: 链接器将一个或多个目标文件以及所需的库文件链接在一起,生成最终的可执行文件。链接器会解析符号引用(例如函数和全局变量),并将所有目标文件和库文件中的代码和数据整合到一个可执行文件中。
    • 静态链接: 将所有需要的库代码复制到可执行文件中。
    • 动态链接: 可执行文件在运行时加载库代码(如动态链接库DLL或共享库SO)。

3、什么是条件编译,作用是什么?

  • 条件编译(Conditional Compilation): 是指在编译过程中,根据特定的条件来决定某些代码是否被编译的技术。条件编译通过预处理指令来实现,这些指令会在预处理阶段进行解析,并根据条件来包含或排除代码块。条件编译的预处理指令主要包括:

    • #if
    • #ifdef
    • #ifndef
    • #else
    • #elif
    • #endif
  • 作用:

    1. 提高代码的可移植性: 在不同的平台或环境下编译相同的代码时,可能需要包含或排除特定的代码段。通过条件编译,可以为不同的平台或环境编写特定的代码,而无需维护多个代码版本。
    2. 调试和开发: 在开发和调试过程中,条件编译可以用来包含或排除调试代码。例如,可以在调试版本中包含调试信息和日志记录代码,而在发布版本中排除这些代码。
    3. 功能开关: 通过条件编译,可以根据需要启用或禁用某些功能。例如,可以使用条件编译来启用或禁用某些模块、特性或优化选项。
    4. 减少代码的编译时间: 在大型项目中,条件编译可以用来只编译需要测试或开发的部分代码,从而减少编译时间。

4、链接环节中的静态链接和动态链接是什么,有何区别?

  • 静态链接: 是将所有需要的库代码在编译时直接复制到可执行文件中。

    • 特点:
      1. 独特性: 生成的可执行文件包含了所有必要的库代码,不依赖于外部库文件。这使得可执行文件可以在没有相应库文件的系统上运行。
      2. 文件体积较大: 由于所有的库代码都被复制到可执行文件中,生成的可执行文件体积较大。
      3. 更新不便: 如果库文件有更新,必须重新编译所有引用该库的可执行文件。
      4. 静态链接库文件后缀名: Linux/Unix系统为 “.a” ,Windows系统为 “.lib”
  • 动态链接: 是在运行时,将库代码加载到内存中,由多个程序共享使用。动态链接使用动态链接库。

    • 特点:
      1. 节省内存和磁盘空间: 多个程序可以共享相同的动态库,减少了内存和磁盘空间的使用。
      2. 文件体积较小: 生成的可执行文件不包含库代码,体积较小。
      3. 灵活性: 更新库文件不需要重新编译可执行文件,只需要保证新的库文件和旧的库文件的接口兼容。
      4. 动态链接库文件后缀名: Linux/Unix系统为 “.so” ,Windows系统为 “.dll” , macOs系统为 “.dylib”
  • 静态链接和动态链接的区别:

特点静态链接动态链接
文件独立性独立运行,不依赖外部库文件依赖外部库文件
可执行文件体积
内存使用低(共享库代码)
更新与维护更新库文件需要重新编译更新库文件不需要重新编译
运行效率一般较高,启动速度快一般较低,启动速度慢
共享性不共享库代码,每个程序独立共享库代码,多个程序可使用同一个库

5、什么是头文件保护符(Include Guards),为什么需要它们?

  头文件保护符是一种防止头文件被重复包含的方法。通过使用#ifndef、#define和#endif预处理指令,可以确保头文件的内容只被包含一次,从而避免重复定义和编译错误。

6、如何创建和使用静态库和动态库?

  • 创建静态库:
gcc -c file1.c file2.c
ar rcs libmylib.a file1.o file2.o
  • 使用静态库:
gcc main.c -o main -L. -lmylib
  • 创建动态库:
gcc -fPIC -c file1.c file2.c
gcc -shared -o libmylib.so file1.o file2.o
  • 使用动态库:
gcc main.c -o main -L. -lmylib
export LD_LIBRARY_PATH=/path/to/library:$LD_LIBRARY_PATH

http://www.ppmy.cn/news/1474085.html

相关文章

Cortex-A510——内核及汇编

Cortex-A510——内核及汇编 小狼http://blog.csdn.net/xiaolangyangyang 1、异常等级 2、异常等级切换 同步异常: 1、SVC/HVC/SMC; 2、MMU引发的异常(内核态EL1发生,发生后不会进行异常等级切换…

智能井盖采集装置 开启井下安全新篇章

在现代城市的脉络之下,错综复杂的管网系统如同城市的血管,默默支撑着日常生活的有序进行。而管网的监测设备大多都安装在井下,如何给设备供电一直是一个难题,选用市电供电需经过多方审批,选用电池供电需要更换电池包&a…

鸿蒙NEXT

鸿蒙NEXT:华为操作系统的新篇章 随着华为鸿蒙生态千帆启航仪式的圆满举行,标志着鸿蒙原生应用开发正式进入一个新的阶段。作为对技术保持敏感的程序员,我们有必要深入了解这一全新操作系统HarmonyOS NEXT的技术细节和未来发展方向。 首先引…

科普文:微服务之服务网格Service Mesh

一、ServiceMesh概念 背景 随着业务的发展,传统单体应用的问题越来越严重: 单体应用代码库庞大,不易于理解和修改持续部署困难,由于单体应用各组件间依赖性强,只要其中任何一个组件发生更改,将重新部署整…

深入理解外观模式(Facade Pattern)及其实际应用

引言 在软件开发中,复杂的系统往往由多个子系统组成,这些子系统之间的交互可能非常复杂。外观模式(Facade Pattern)通过为这些子系统提供一个统一的接口,简化了它们的交互。本篇文章将详细介绍外观模式的概念、应用场…

ArcGIS Pro SDK (七)编辑 11 撤销重做

ArcGIS Pro SDK (七)编辑 11 撤销&重做 文章目录 ArcGIS Pro SDK (七)编辑 11 撤销&重做1 撤消/重做最近的操作 环境:Visual Studio 2022 .NET6 ArcGIS Pro SDK 3.0 1 撤消/重做最近的操作 //撤销 if (MapV…

Simple_ReAct_Agent

参考自https://www.deeplearning.ai/short-courses/ai-agents-in-langgraph,以下为代码的实现。 Basic ReAct Agent(manual action) import openai import re import httpx import os from dotenv import load_dotenv, find_dotenvOPENAI_API_KEY os.getenv(OPEN…

【区块链+基础设施】蜀信链 | FISCO BCOS应用案例

蜀信链是在四川省经济和信息化厅指导下,在四川省区块链行业协会组织下,由全省区块链相关从业与应用机构 共同参与建设和运营的区域性区块链基础设施,通过多方协同,共同打造合作共赢的区块链产业生态。 蜀信链区块链服务生态秉承“…