c/c++ 程序运行的过程分析

c/c++编译基础知识

GNU

GNU(GNU’s Not Unix!)是一个由理查德·斯托曼(Richard
Stallman)在1983年发起的自由软件项目,旨在创建一个完全自由的操作系统,包括操作系统的内核、编译器、工具、库、文本编辑器、邮件系统、新闻系统等。GNU项目是自由软件运动的核心,其目标是确保用户有使用、复制、修改和分发软件的自由。

GNU项目的一些关键组件包括:

  1. GCC(GNU Compiler Collection):一套支持多种编程语言的编译器,包括C、C++、Objective-C、Fortran、Ada、Go等。

  2. GDB(GNU Debugger):一个强大的程序调试工具,用于调试C和C++程序。

  3. Glibc(GNU C Library):GNU项目开发的C标准库实现,广泛用于Linux操作系统。

  4. Gawk:一个文本处理工具,类似于Unix的awk。

  5. Grep:一个用于搜索文本的工具,类似于Unix的grep。

  6. Gnuplot:一个绘图工具,用于绘制函数、数据等图形。

  7. Emacs:一个功能强大的文本编辑器。

  8. Bash(Bourne Again Shell):一种Unix shell和命令语言。

  9. GnuPG(GNU Privacy Guard):一个加密软件,用于数据加密和数字签名。

  10. AutoconfAutomake:用于生成配置脚本和Makefile的工具。

GNU项目还开发了Hurd,这是一个旨在替代Unix内核的操作系统内核,但由于种种原因,Hurd并没有得到广泛的应用。相反,Linux内核(由林纳斯·托瓦兹开发)与GNU工具集合成为今天广泛使用的Linux操作系统。

GNU项目强调软件的自由性,其发布的软件遵循GNU通用公共许可证(GPL),这是一种“传染性”的许可证,要求所有基于GPL软件的衍生作品也必须以GPL发布,从而确保软件的自由性得以传递。

GCC

GCC,全称为GNU编译器集合(GNU Compiler
Collection),是一个由GNU项目开发的编程语言编译器系统。它支持多种编程语言,包括但不限于C、C++、Objective-C、Fortran、Ada、Go和D等。GCC是自由软件,遵循GNU通用公共许可证(GPL)发布。

GCC的主要特点包括:

  1. 跨平台:GCC可以在多种操作系统上编译源代码,包括Linux、Windows、macOS等。

  2. 优化:GCC提供了多种优化选项,以提高生成代码的执行效率。

  3. 调试支持:GCC能够生成调试信息,与GDB(GNU Debugger)等调试工具配合使用。

  4. 多种语言支持:GCC支持多种编程语言的编译,使其成为一个多功能的编译器集合。

  5. 自动并行化:GCC的一些版本提供了自动并行化的功能,可以自动将某些循环转换为并行执行的形式。

  6. 内联汇编:GCC支持内联汇编语言,允许开发者在高级语言代码中嵌入汇编指令。

  7. 插件支持:GCC允许通过插件扩展其功能。

  8. 交叉编译:GCC支持交叉编译,即在一种平台上编译出另一种平台上运行的代码。

GCC是许多Linux发行版默认的系统编译器,并且广泛用于嵌入式系统、高性能计算和各种软件开发项目中。由于其强大的功能和灵活性,GCC是开源社区中最受欢迎的编译器之一。

gcc 和 g++

GCC(GNU Compiler Collection)是一个编译器集合,它包括多个不同的编译器,其中最常用的是针对C语言的gcc和针对C++语言的g++。以下是gccg++的简要说明:

  1. gcc

    • 这是GNU项目提供的C语言编译器。
    • 它用于编译C语言源代码文件(通常以.c为扩展名)。
    • gcc支持多种操作系统和硬件平台,可以生成针对不同目标的可执行文件或库文件。
  2. g++

    • g++是GNU编译器集合中的C++语言编译器。
    • 它用于编译C++语言源代码文件(通常以.cpp.cc为扩展名)。
    • g++同样支持跨平台编译,并提供了C++特有的特性支持,如类、模板、异常处理等。

两者的主要区别在于它们支持的语言特性和标准库。gcc专门用于C语言,而g++则用于C++语言。尽管它们在某些底层组件上共享代码,但它们的前端(解析源代码的部分)是不同的,以适应各自语言的语法和特性。

使用示例:

  • 编译C语言程序: sh gcc -o program program.c 这将编译program.c并生成名为program的可执行文件。

  • 编译C++语言程序: sh g++ -o program program.cpp 这将编译program.cpp并生成名为program的可执行文件。

在实际使用中,您可能还会使用到其他选项和参数,例如优化标志(-O2)、调试信息生成(-g)、链接特定库(-L-l)等。此外,g++在编译混合C和C++代码时,也可以调用gcc来编译C语言部分的代码。

gcc 和 g++常见编译选项

gccg++提供了一系列的编译命令选项,用于控制编译过程的不同方面。以下是一些常用的编译命令选项:

  1. 输出可执行文件的名称sh -o <file> 指定输出的可执行文件名。

  2. 优化选项

    • -O0:没有优化。
    • -O1:启用基本优化。
    • -O2:进一步优化。
    • -O3:更多的优化,可能包括更激进的优化策略。
    • -Os:优化生成更小的代码。
  3. 调试信息sh -g 生成调试信息。

  4. 包括搜索路径sh -I <dir> 添加头文件搜索路径。

  5. 库搜索路径sh -L <dir> -l <library> 指定库文件的搜索路径,并链接指定的库。

  6. 链接时的库sh -l <library> 链接时包括特定的库。

  7. 静态链接sh -static 使用静态链接而不是动态链接。

  8. C++ 特定选项(在使用g++时): sh -std=c++11 -std=c++14 -std=c++17 -std=c++20 指定C++语言标准。

  9. 警告选项

    • -Wall:打开几乎所有的警告信息。
    • -Wextra:打开额外的警告信息。
    • -Werror:将所有警告当作错误处理。
  10. 编译特定文件

    -c
    

    只编译和生成目标文件(.o文件),不进行链接。

  11. 生成依赖文件

    -MF <depfile>
    

    生成包含依赖关系的文件。

  12. 使用多个处理器编译

    -j <n>
    

    使用n个处理器进行编译,可以加快编译速度。

  13. 指定架构

    -m32
    -m64
    

    指定生成32位或64位代码。

  14. 禁用标准库

    -nostdlib
    

    编译时不使用标准库。

  15. 内联汇编

    -S
    

    编译后只生成汇编代码。

这些只是gccg++提供的众多选项中的一部分。根据项目的具体需求,您可能还会使用到其他一些选项。在命令行中使用gcc --helpg++ --help可以查看完整的选项列表和说明。

c++ 程序运行的过程分析

  1. 编写完的 c/c++程序想要运行起来,需要四个步骤:预处理、编译、汇编、链接。
    在这里插入图片描述
  2. 编写 c++程序:main.cpp
#include <iostream>
using namespace std;

int add (int a, int b)
{
    return a+b;
}

int main()
{
    int x = 30;
    int y = 100;

    int ret = add(x, y);

    cout << "sum: " << ret << endl;

    return 0;
}

预处理

在C++编译过程中,预处理是一个重要的步骤,它发生在实际编译之前。以下是预处理的一些主要作用:

  1. 宏替换: 预处理器会处理宏定义(由#define指令定义)和宏展开。例如,如果你在代码中使用了#define PI 3.14159,预处理器会将代码中所有的PI替换为3.14159

  2. 文件包含: 使用#include指令包含标准库头文件或用户自定义的头文件。预处理器会将这些文件的内容插入到该指令的位置。

  3. 条件编译: 预处理器根据条件编译指令(如#ifdef#ifndef#if#else#elif#endif)来决定是否包含特定的代码段。这允许开发者根据不同的编译条件编写不同的代码。

  4. 行控制#line指令可以用来控制编译器报告错误和警告时显示的文件名和行号。

  5. 错误诊断: 使用#error指令可以在编译时生成错误信息。

  6. 编译时间计算#if指令可以用来进行编译时常量的计算和比较。

  7. 版本控制和编译选项: 预处理器可以根据不同的定义来启用或禁用特定的代码段,这通常用于处理不同操作系统或编译器的特性。

  8. 依赖性分析: 预处理器可以生成依赖性信息,这对于自动构建系统来说是有用的,以确保在头文件更改时重新编译依赖的文件。

  9. 函数宏和宏函数: 预处理器处理函数宏和宏函数的调用和展开。

  10. 预定义宏
    编译器会定义一些预定义宏,如__FILE____LINE____DATE____TIME__等,它们在预处理时被替换为当前文件名、行号、日期和时间。

预处理的结果是一个或多个预处理过的源文件,这些文件随后将被编译器进行语法分析、语义分析和代码生成等后续编译步骤。预处理是C++源代码转换为可执行程序的第一步,对于编译器正确理解源代码结构至关重要。

  1. 预处理命令g++ -E main.cpp -o main.i
  2. 生成文件main.i,仍是文本文件,可以用任意文本编辑器打开。

编译

编译是将高级语言代码转换成低级代码(通常是汇编代码或中间代码)的过程,侧重于语言特性的处理和代码优化。 编译阶段的作用:

  • 语法分析:检查代码是否符合C++语言的语法规则。
  • 词法分析:将源代码分解成一系列的词素(tokens)。
  • 语义分析:确保代码符合C++的语义规则,比如类型检查和作用域解析。
  • 抽象语法树(AST)构建:将源代码转换成AST,这是一种树状结构,表示程序的逻辑。
  • 优化:对AST进行优化,以提高程序性能或减少资源消耗。
  • 代码生成:将优化后的AST转换成中间代码或汇编代码。

在一些编译器实现中,编译阶段可能直接生成机器代码,而在其他情况下,编译器可能先生成汇编代码,然后由汇编器转换成机器代码。无论哪种情况,编译和汇编都是将源代码转换成可执行程序的必要步骤。

  1. 编译命令g++ -S main.cpp -o main.s
  2. 生成文件main.s

汇编

汇编是将汇编语言代码转换成机器代码的过程,侧重于目标机器的指令集和内存管理。 汇编阶段的作用:

  • 转换为汇编语言:将编译器生成的中间代码转换成目标机器的汇编语言。
  • 符号替换:将代码中的符号(如变量名和常量)替换为内存地址或立即数。
  • 地址分配:为代码和数据分配具体的内存地址。
  • 生成汇编文件:创建包含汇编指令的文件,这些指令可以被汇编器进一步处理。
  • 错误检测:检测汇编代码中的错误,如非法指令或不正确的地址引用。
  • 准备链接:生成的目标文件通常是可重定位的,为后续的链接阶段做准备。
  1. 汇编命令g++ -c main.cpp -o main.o 或者直接用汇编文件命令as main.s -o main.o
  2. 生成文件main.o

链接

C++编译的链接阶段是将编译器生成的目标文件(通常是.o.obj文件)组合成最终可执行文件或库文件的过程。以下是链接阶段的主要作用:

  1. 符号解析: 链接器解析目标文件中的符号引用,确保每个外部符号(变量和函数)都能正确地关联到其定义。

  2. 地址和空间分配: 链接器为程序中的代码和数据分配最终的内存地址,并决定它们在可执行文件中的布局。

  3. 代码和数据合并: 链接器将所有目标文件中的代码和数据合并成一个单一的可执行文件或库文件。

  4. 库链接: 如果程序依赖于外部库,链接器会将这些库中的代码和数据与目标文件合并。这包括静态库和动态库的链接。

  5. 重定位: 链接器处理重定位项,将代码和数据中的相对地址转换为绝对地址。

  6. 生成可执行文件: 对于最终的可执行文件,链接器生成一个可在操作系统上运行的程序。

  7. 生成库文件: 对于库文件,链接器生成一个包含多个函数和变量定义的文件,这些可以在其他程序中使用。

  8. 符号表生成: 链接器生成一个符号表,列出了程序中所有的符号及其地址。

  9. 调试信息整合: 如果编译时带有调试信息,链接器会整合这些信息到最终的可执行文件或库中。

  10. 资源文件处理
    链接器处理程序中使用的资源文件,如图形、声音等,并将它们整合到最终的程序中。

  11. 优化
    某些链接器或与之集成的工具可能会进行进一步的优化,如死代码消除。

  12. 生成调试符号
    如果需要,链接器可以生成调试符号文件,如DWARF格式的符号信息,以支持后续的调试工作。

  13. 错误检测
    链接器在链接过程中会检测未解决的外部引用或其他链接错误,并报告这些问题。

链接是编译过程的最后阶段,确保了所有编译后生成的片段能够正确地组合在一起,形成一个完整的程序。链接后的程序可以直接在目标机器上运行或被其他程序作为依赖库使用。

  1. 链接命令g++ -o main main.o
  2. 生成文件main

验证

  1. 文件目录
.
├── main
├── main.cpp
├── main.i
├── main.o
└── main.s
  1. 验证可执行程序./main
  2. 输出结果sum:130
admin@bogon test % ls
main		main.cpp	main.i		main.o		main.s
admin@bogon test % ./main
sum: 130

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/777725.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度网络现代实践 - 深度前馈网络之反向传播和其他的微分算法篇

序言 反向传播&#xff08;Backpropagation&#xff0c;简称backprop&#xff09;是神经网络训练过程中最关键的技术之一&#xff0c;尤其在多层神经网络中广泛应用。它是一种与优化方法&#xff08;如梯度下降法&#xff09;结合使用的算法&#xff0c;用于计算网络中各参数的…

前端正悄悄蚕食后端开发者的工作,这真的好吗?

**前端正悄悄蚕食后端开发者的工作&#xff0c;这真的好吗&#xff1f;** 前端开发者的职责范围正在逐渐扩大。从最初的单纯页面设计&#xff0c;到现在的与后端数据交互、应用逻辑处理等&#xff0c;前端开发者在项目中的作用日益重要。与此同时&#xff0c;这也引发了一个值…

固态,机械,移动(U盘),sd卡,哪个更适合长期储存数据 保存数据用什么硬盘可靠 硬盘数据丢失怎么找回 硬盘维护注意事项

有关硬盘数据丢失的恢复技巧&#xff0c;这篇文章一定要收藏好。在硬盘使用过程中&#xff0c;很多情况都会导致数据丢失&#xff0c;例如硬盘跌落、病毒感染、系统文件损坏等。这时候&#xff0c;一定要采用正确的方法&#xff0c;抢救硬盘中存储的珍贵数据和文档。 有关长期保…

技术实现路径怎么写?(Word项目技术路径文档参考)

软件项目编写技术实现路径至关重要&#xff0c;因为它为项目团队提供了清晰的开发蓝图。这一路径明确了从项目启动到交付各阶段所需的技术方案、步骤及预期成果&#xff0c;有助于团队统一认识&#xff0c;确保开发工作有序进行。同时&#xff0c;技术实现路径有助于识别潜在的…

ELK优化之Filebeat部署

目录 1.安装配置Nginx 2.安装 Filebeat 3.设置 filebeat 的主配置文件 4.修改Logstash配置 5.启动配置 6.kibana验证 主机名ip地址主要软件es01192.168.9.114ElasticSearches02192.168.9.115ElasticSearches03192.168.9.116ElasticSearch、Kibananginx01192.168.9.113ng…

Docker(二):Docker image Docker Container

本文将介绍 Docker 映像和容器以及 docker 文件之间的差异与联系&#xff0c;本文还将解释如何以及何时使用它们。 什么是 Dockerfile&#xff1f; 它是一个简单的文本文件&#xff0c;包含命令或过程的集合。我们运行的这些命令和准则作用于配置为创建新的 Docker 镜像的基本…

G1.【C语言】EasyX初步了解

1.介绍 EasyX 是针对 C/C 的图形库&#xff0c;可以帮助使用C/C语言的程序员快速上手图形和游戏编程。 2.安装 EasyX Graphics Library for CEasyX Graphics Library 是针对 Visual C 的绘图库&#xff0c;支持 VC6.0 ~ VC2019&#xff0c;简单易用&#xff0c;学习成本极低…

轻预压:滚珠丝杆精度与刚性的平衡点!

预压是指在所需的工作负荷下&#xff0c;使滚珠丝杆预先承受一定的负荷&#xff0c;从而使滚珠丝杆的轴向向心度和侧向偏差达到较小的偏差范围&#xff0c;保证了滚珠丝杆的准确性和稳定性&#xff0c;也确保机器的高精度和长期运作的可靠性。 预压是滚珠丝杆设计中的一个重要参…

vue3项目图片压缩+rem+自动重启等plugin使用与打包配置

一、Svg配置 每次引入一张 SVG 图片都需要写一次相对路径&#xff0c;并且对 SVG 图片进行压缩优化也不够方便。 vite-svg-loader插件加载SVG文件作为Vue组件&#xff0c;使用SVGO进行优化。 插件网站https://www.npmjs.com/package/vite-svg-loader 1. 安装 pnpm i vite-svg…

智能与伦理:Kimi与学术道德的和谐共舞

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 Kimi&#xff0c;由月之暗面科技有限公司开发的智能助手&#xff0c;擅长中英文对话&#xff0c;能处理多种文档和网页内容。在论文写作中&#xff0c;Kimi可提供资料查询、信息整理、语…

JavaWeb--jquery篇

概述 jQuery是一个快速、简洁的JavaScript框架&#xff0c;是一个优秀的JavaScript代码库&#xff08;框架&#xff09;于2006年1月由John Resig发布。它封装JavaScript常用的功能代码&#xff0c;提供一种简便的JavaScript设计模式&#xff0c;优化HTML文档操作、事件处理、动…

Faster-RCNN·代码解读系列01:Selective Search 和 R-CNN、Fast-CNN 简介

Selective Search 和 R-CNN、Fast-CNN 简介 1 目标检测算法简介1.0滑窗法的思路1.1 Selective Search 和 R-CNN 简介1.2.1 Selective Search简介1.1.1 Selective Search的思路1.1.2 Selective Search图解 1.2 Selective Search 和 Fast-CNN简介1.2.1 SPP和ROI Pooling简介1.2.2…

高级计算机体系结构--期末教材复习

Chap2 性能评测和并行编程性能评测并行编程为什么需要三次 barrier改进方法 Chap3 互连网络交换和路由二维网格中 XY 路由 死锁、活锁及饿死死锁避免的方法&#xff1a;虚通道、转弯模型二维网格中最小 西向优先、北向最后和负向优先算法转弯模型&#xff1a;超立方体的部分自适…

原生JavaScript实现录屏功能

1. 前言 使用JavaScript实现浏览器中打开系统录屏功能 示例图: 2. 源码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><…

深度学习——卷积神经网络(convolutional neural network)CNN详解(一)——概述. 步骤清晰0基础可看

在CNN的学习过程中我会提供相应的手算例子帮助理解训练过程。 其他关于神经网络的学习链接如下&#xff1a; 一、了解卷积神经网络 卷积神经网络的作用 总的来说&#xff0c;卷积神经网络的第一个主要作用是对图像进行特征提取&#xff0c;所谓特征提取&#xff0c;就是明白…

7.6第三天作业

一、在数据库中创建一个表student&#xff0c;用于存储学生信息 CREATE TABLE student( id INT PRIMARY KEY, name VARCHAR(20) NOT NULL, grade FLOAT ); &#xff08;1.&#xff09;先创建一个数据库 &#xff08;2.&#xff09;创建student表 查看是否创建成功 1、向studen…

QT c++函数模板与类模板的使用

QT c类模板的使用 #pragma once#include <QtWidgets/QMainWindow> #include "ui_QtWidgetsApplication5.h"class QtWidgetsApplication5 : public QMainWindow {Q_OBJECTpublic:QtWidgetsApplication5(QWidget *parent nullptr);~QtWidgetsApplication5();te…

代码随想录算法训练营第13天|二叉树的递归遍历、二叉树的迭代遍历、二叉树的统一迭代法、102.二叉树的层序遍历

打卡Day13 1.理论基础2.二叉树的递归遍历3.二叉树的迭代遍历3.二叉树的统一迭代法4.102.二叉树的层序遍历扩展107. 二叉树的层序遍历 II199.二叉树的右视图637.二叉树的层平均值429.N叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的下一个右侧节点指针117. 填充每个…

嵌入式C语言面试相关知识——关键字(不定期更新)

嵌入式C语言面试相关知识——关键字 一、博客声明二、C语言关键字1、sizeof关键字2、static关键字3、const关键字4、volatile关键字5、extern关键字 一、博客声明 又是一年一度的秋招&#xff0c;怎么能只刷笔试题目呢&#xff0c;面试题目也得看&#xff0c;想当好厂的牛马其实…

数据可视化之智慧城市的脉动与洞察

在数字化转型的浪潮中,城市作为社会经济发展的核心单元,正经历着前所未有的变革。城市数据可视化大屏看板作为这一变革中的重要工具,不仅极大地提升了城市管理效率,还为公众提供了直观、全面的城市运行状态视图,成为智慧城市建设不可或缺的一部分。本文将深入探讨以“城市…