首页 > 编程语言 >C++编译

C++编译

时间:2022-09-19 10:35:09浏览次数:74  
标签:文件 程序 C++ 链接 编译 endif 可执行程序

为什么需要编译:编写好的代码最终翻译为机器可执行的二进制指令,编译的过程如下图所示:

 

 

编译预处理:在预编译过程中主要处理源代码中的预处理指令。

引入头文件 #include

条件编译指令:#ifdef, #ifndef, #else, #elif, #endif

条件编译指令

说 明

#if

如果条件为真,则执行相应操作

#elif

如果前面条件为假,而该条件为真,则执行相应操作

#else

如果前面条件均为假,则执行相应操作

#endif

结束相应的条件编译指令

#ifdef

如果该宏已定义,则执行相应操作

#ifndef

如果该宏没有定义,则执行相应操作

调用格式:

#if 条件表达式

    程序段1

#else

    程序段2

#endif

如果#if后的条件表达式为真,则程序段 1 被选中,否则程序段 2 被选中,必须使用 #endif 结束该条件编译指令。避免同一个头文件被多次包含、重复引用,最常用也是最简单的方法就是利用“#ifndef/#define/#endif”结构产生预处理块来防止头文件被重复引用。

如下面的示例代码所示:

#ifndef __HEADERNAME_H__

#define __HEADERNAME_H__

    #include<string>

#endif

对于重复包含的头文件会忽略编译,这样提高运行的速度和效率,条件编译就用来控制预编译可以达成的条件。

编译:针对预处理后的文件进行词法分析、语法分析、语义分析、符号汇总、汇编代码生成,并针对程序的结构或者特定的CPU平台进行优化,简而言之就是: 将.cpp源文件翻译成.s的汇编代码。

汇编:将汇编代码.s翻译成机器指令.o文件,一个.cpp文件只会生成一个.o文件。

链接:汇编程序生成的目标文件即为.o文件,单独的.o文件可能无法执行。因为一个程序可能由多个源文件组成,此时就存在多个.o文件。文件A中的函数引用了另一个文件B中定义的符号或者调用了某个库文件中的函数,这就需要链接处理。那链接的目的就是将这些文件对应的目标文件连接成一个整体,从而生成一个可被操作系统加载执行的ELF程序文件。

静态链接:代码在生成可执行文件时,将该程序所需要的全部外部调用函数全部拷贝到最终的可执行程序文件中,在该程序被执行时,该程序运行时所需要的全部代码都会被装入到该进程的虚拟地址空间中。在Linux系统下,静态链接库一般以.a文件,我们可以将多个.o文件链接成一个静态链接库。

动态链接:代码在生成可执行文件时,该程序所调用的部分程序被放到动态链接库或共享对象的某个目标文件中,链接程序只是在最终的可执行程序中记录了共享对象的名字等一些信息,最终生成的ELF文件中并不包含这些调用程序二进制指令。在程序执行时,当需要调用这部分程序时,操作系统会从将这些动态链或者共享对象进行加载,并将全部内容会被映射到该进行运行的虚拟地址的空间。在Linux系统下,动态链接库一般以.so文件,我们可以将多个.o文件链接成一个动态链接库。

优缺点:静态链接浪费空间,每个可执行程序都会有目标文件的一个副本,这样如果目标文件进行了更新操作,就需要重新进行编译链接生成可执行程序(更新困难),优点就是执行的时候运行速度快,因为可执行程序具备了程序运行的所有内容;动态链接节省内存、更新方便,但是动态链接是在程序运行时,每次执行都需要链接,相比静态链接会有一定的性能损失。静态链接是由连接器完成的,动态链接最终是由操作系统来完成链接的功能,动态链接在不同的操作系统下可能由不同的实现原理,比如在Linux系统下,动态链接库通常以.so文件存在,在windows下同下,动态链接库一般以.dll文件存在。

标签:文件,程序,C++,链接,编译,endif,可执行程序
From: https://www.cnblogs.com/acec/p/16706842.html

相关文章

  • UEC++ 数据类型
    禁止在UE中使用C++的基本数据类型,这样会影响引擎的跨平台特性1、基本数据类型bool代表布尔值(永远不要假设布尔值的大小)。BOOL将不会进行编译。TCHAR代表字符型......
  • C++定义变量与生存周期
    作用域:作用域即一个变量可以被引用的范围,常见的作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作用域。全局变量:具有全局作用域。全局变......
  • GCC编译过程
    转:https://blog.csdn.net/chen1415886044/article/details/104537547GCC编译过程:上述gcc命令其实依次执行了四步操作:1.预处理(Preprocessing)2.编译(Compilation),3.汇......
  • C/C++公交路线自动化选择系统
    C/C++公交路线自动化选择系统程序设计题1:公交路线自动化选择系统实现出题人:张勤面向专业:测控技术与仪器难度等级:31问题描述要求编写一个程序,实现公交路线的自动......
  • C++11 -- 匿名函数(lambda 表达式)
    0.一道题目引入关于sb力扣定义外部函数和变量报错这件事最初我定义了一个\(cmp\)函数用来对\(vector\)排序,和一个全局变量\(unordered\_map\)用来记录元素个数......
  • LayaBox2.4配置VsCode编译及运行环境
    前言Laya2.4取消了内置VsCode编辑器,现在代码编辑需要在单独的代码编辑器里面写,推荐使用VsCode。发现不少同学无法运行启动调试了。这篇博客就是讲述如何配置编译及调试环......
  • Qt 5.14 编译驱动库连接Firebird 3.0.x(编译驱动库,修改驱动库源代码以支持Boolean类型
    本人一直喜欢用Firebird,目前用的3.0.X版本,更新的4.0.X尚未使用(主要是用不惯那个int128字段类型),近期初学Qt,想连接firebird使用,照着网上教的方法,自己做了一些修改(网上以连......
  • 脚本编译安装httpd
    脚本编译安装httpd没有演技全是精髓#/bin/bash#列出httpd版本号echo'有以下可以选择的版本号:1.2.4.542.2.4.53'#设置执行权限if[$UID-ne0];then echo"请......
  • 03(C++二级)
    1.函数不可嵌套定义,但可以嵌套调用。2.静态数据成员必须在类外初始化,使用类名调用。 初始化格式:<数据类型><类名>::<静态数据成员名>=<值>3.C++不能重载的:     ......
  • 霍夫变换原理及实现(Opencv C++)
    已知一幅图像中的n个点,假设我们希望找到这些点中位于直线上的子集。一种可能的解决方法是,首先找到由每对点确定的所有直线,然后寻找靠近特定直线的那些点的所有子集。这种方......