g++ 编译过程体会与命令行参数argc,argv[]详解

article/2025/10/5 7:56:03

argc, *argv[] 参数介绍

main(int argc,char *argv[ ])

  1. argc为整数, 代表参数的个数。
  1. argv为指针数组,里面的元素个数是 argc 个,(可理解为:char **argv or: char *argv[] or: char argv[][] )。
    注:main()括号内是固定的写法。

下面给出一个例子来理解这两个参数的用法:

假设程序的名称为prog,

  • 当只输入prog,则由操作系统传来的参数为:
    argc=1,表示只有一程序名称。
    argv 指针数组中只有一个元素,
    argv[0]指向输入的程序路径及名称:./prog

当输入prog para_1,有一个参数,则由操作系统传来的参数为:
argc=2,表示除了程序名外还有一个参数。
argv[0]指向输入的程序路径及名称。
argv[1]指向参数para_1字符串。

当输入prog para_1 para_2 有2个参数,则由操作系统传来的参数为:
argc=3,表示除了程序名外还有2个参数。
argv[0]指向输入的程序路径及名称。
argv[1]指向参数para_1字符串。
argv[2]指向参数para_2字符串。

4.void main( int argc, char *argv[] )
char *argv[] :
argv 是一个指针数组,他的元素个数是argc,存放的是指向每一个参数的指针


#include <stdio.h>
#include <stdlib.h>int main(int argc,char *argv[])
{printf("%s\n",argv[0]);//读取可执行程序(包括路径)/*读取参数*/int i = 1;while(i < argc){printf("%s\n",argv[i]);i++;}//说明在dos和unix环境下,用""扩起来的表示其是一个字符串,代表着一个参数return 0;
}

不同类型的指针, 占用的字节个数, 从而便于系统分配内存;


x86
sizeof(char)  1
sizeof(char*)  4
sizeof(int)  4
sizeof(int*)  4
sizeof(double)  8
sizeof(double*)  4
sizeof(float)  4
sizeof(float*)  4
sizeof(string)  28
sizeof(string*)  4x64sizeof(char)  1
sizeof(char*)  8
sizeof(int)  4
sizeof(int*)  8
sizeof(double)  8
sizeof(double*)  8
sizeof(float)  4
sizeof(float*)  8
sizeof(string)  40
sizeof(string*)  8

1. 代码文件;

g++ --version:7.5.0

  1. main.cpp 函数的执行入口处,
// main.cpp
#include <iostream>
using namespace std;int main(int argc, char *argv[])
{cout<<"this is a g++ : Hello World!!! "<<endl;return 0;
}

整体的过程 分为四部:

  1. 预编译 ( 生成预编译文件.ii )
    c 文件生成的预编译是.i 文件, C++ 生成的是.ii 文件;
g++  -E  main.cpp   -o   hello.ii
//C++预处理后生成的是.ii文件
  1. 编译 (生成 汇编代码.s 文件)
g++  -S  hello.ii    -o hello.s 
//.s  由编译器生成汇编代码
  1. 汇编 ( 将汇编代码生成 目标文件.o , 为二进制文件)
g++  -c  hello.s   -o hello.o
//.o  汇编器 生成 目标文件, 该目标文件为二进制文件, 为机器执行的指令  
  1. 链接 ( 对源文件 main.cpp 执行命令行 生成 .out 可执行文件)
g++  main.cpp  -o hello.out 
//:由链接器 ld,   将目标文件.o,  与库文件链接
// 将目标文件由链接器 链接库文件 生成  可执行文件.out  

1. 预编译

1.1 预编译的作用

主要处理源代码文件中的以“#”开头的预编译指令。处理规则见下:

  1. 删除所有的#define,展开所有的宏定义。

  2. 处理所有的条件预编译指令,如“#if”、“#endif”、“#ifdef”、“#elif”和“#else”。

  3. 处理“#include”预编译指令,将文件内容替换到它的位置,这个过程是递归进行的,文件中包含其他文件。

  4. 删除所有的注释,“//”和“/**/”。

  5. 保留所有的#pragma 编译器指令,编译器需要用到他们,如:#pragma once 是为了防止有文件被重复引用。

  6. 添加行号和文件标识,便于编译时编译器产生调试用的行号信息,和编译时产生编译错误或警告时能够显示行号;

1.2 预编译的使用

使用 g++ -E 代表在预编译过后, 停止编译的过程;

g++ -E

//预处理后的版本将超过 两万 行。
//这主要是因为头文件 iostream 被包含进来,而且它又包含了其他的头文件,
//除此之外,还有若干个处理输入和输出的类的定义。

1.3 预编译的调试作用

当我们无法判断宏定义是否 正确
或者 头文件包含是否正确时,
可以通过查看预编译后文件来确定问题;

2. 编译 (生成汇编语言)

汇编代码是在编译阶段生成的;

2.1 编译的作用

把预编译之后生成的xxx.i(c 文件而来)或xxx.ii文件(C++ 文件),进行一系列词法分析、语法分析、语义分析及优化后,生成相应的汇编代码文件

  1. 词法分析:利用类似于“有限状态机”的算法,将源代码程序输入到扫描机中,将其中的字符序列分割成一系列的记号。

  2. 语法分析:语法分析器对由扫描器产生的记号,进行语法分析,产生语法树。由语法分析器输出的语法树是一种以表达式为节点的树。

  3. 语义分析:语法分析器只是完成了对表达式语法层面的分析,语义分析器则对表达式是否有意义进行判断,其分析的语义是静态语义——在编译期能分期的语义,相对应的动态语义是在运行期才能确定的语义。

  4. 优化:源代码级别的一个优化过程。

  5. 目标代码生成:由代码生成器将中间代码转换成目标机器代码,生成一系列的代码序列——汇编语言表示。

  6. 目标代码优化:目标代码优化器对上述的目标机器代码进行优化:寻找合适的寻址方式、使用位移来替代乘法运算、删除多余的指令等。

2.2 编译的使用

  1. 把预编译之后生成的xxx.ii文件,进行一系列词法分析、语法分析、语义分析及优化后,生成相应的汇编代码文件。
 g++ -S  

请添加图片描述

注意: 汇编过程 会和CPU的架构相关,
不同的CPU架构 采用不同的汇编指令集
故生成不通过的汇编代码请添加图片描述

3. 汇编(生成目标文件 obj.o )

3.1 汇编的作用

生成目标文件 (obj.o ):
汇编代码转变成机器可以执行的指令,
每一个汇编语句 几乎都会都对应一条机器指令

汇编器的汇编过程相对于编译器来说更简单,没有复杂的语法,也没有语义,更不需要做指令优化,只是根据汇编指令和机器指令的对照表一一翻译过来,汇编过程可以由汇编器as完成。

经汇编之后,产生目标文件xxx.o(Windows下)、xxx.obj(Linux下)。

注意这里的目标文件是指 机器可以执行的指令;

3.2 汇编的使用

输出的 .o 代表的是目标文件, 该目标文件是二进制码文件;

g++ -C

4. 链接( 生成可执行文件 .out)

实践中, 会有多个源文件, 即多个 .cpp 文件, 并且多个源文件, 也会生成多个对应的 .o 目标文件;

链接: 便是将 不同源文件生成的目标文件进行 链接, 从而形成一个可执行程序.out 文件;

而链接有两种方式可以实现:
静态链接 和 动态链接;

4.1 静态链接

函数和数据被编译进一个二进制文件。在使用静态库的情况下,在编译链接可执行文件时,链接器从库中复制这些函数和数据并把它们和应用程序的其它模块组合起来创建最终的可执行文件。

  1. 空间浪费:因为每个可执行程序中对所有需要的目标文件都要有一份副本,所以如果多个程序对同一个目标文件都有依赖,会出现同一个目标文件都在内存存在多个副本;

  2. 更新困难:每当库函数的代码修改了,这个时候就需要重新进行编译链接形成可执行程序。

  3. 运行速度快:但是静态链接的优点就是,在可执行程序中已经具备了所有执行程序所需要的任何东西,在执行的时候运行速度快。

4.2 动态链接

动态链接的基本思想是把程序按照模块拆分成各个相对独立部分,在程序运行时才将它们链接在一起形成一个完整的程序,而不是像静态链接一样把所有程序模块都链接成一个单独的可执行文件。

  1. 共享库:就是即使需要每个程序都依赖同一个库,但是该库不会像静态链接那样在内存中存在多分副本,而是这多个程序在执行时共享同一份副本;

  2. 更新方便:更新时只需要替换原来的目标文件,而无需将所有的程序再重新链接一遍。当程序下一次运行时,新版本的目标文件会被自动加载到内存并且链接起来,程序就完成了升级的目标。

  3. 性能损耗:因为把链接推迟到了程序运行时,所以每次执行程序都需要进行链接,所以性能会有一定损
    失。

5.

6.

参考链接:
https://blog.csdn.net/Three_dog/article/details/103688043#t1


http://chatgpt.dhexx.cn/article/abROqCsL.shtml

相关文章

C语言中函数main的参数argc和argv是什么

在 Xcode 中新建一个 macOS 平台 Command Line Tool&#xff0c;使用 C 语言&#xff0c;会发现 main 带了两个参数&#xff1a;argc和argv。如下&#xff1a; argc被程序唤起的命令行参数的数量&#xff0c;用于统计参数数量。这里会导致你有一个误区&#xff0c;在下面argv[…

李宏毅线性代数笔记6:矩阵的计算

1 矩阵的几个概念 1.1 特殊矩阵 1.1.1 数量矩阵 主对角线上元素是同一个数&#xff0c;其余元素全为0的n级矩阵 1.1.2 对角矩阵&#xff08;diagonal matrix&#xff09; 主对角线元素之外全为0的方阵 记作diag{d1,d2,……dn} 1.1.3 基本矩阵 只有一个元素是1&#xff…

二、线性代数

6 特殊类型的矩阵和向量 对角矩阵 对角矩阵&#xff08;diagonal matrix&#xff09;只在主对角线上含有非零元素&#xff0c;其他位置都是零。形式上&#xff0c;矩阵 D D D 是对角矩阵&#xff0c;当且仅当对于所有的 i ≠ j , D i , j 0 i\ne j, \ D_{i,j}0 i​j, Di…

边缘计算与雾计算的区别

雾计算是对MEC的扩展&#xff0c;扩展到了终端侧&#xff0c;包括计算、存储、存储、控制功能。区别如下&#xff1a; 1.MEC使用的资源是网络边缘的设备&#xff0c;而雾计算还要使用终端设备。 2.雾计算是使得云到物的计算无缝连续衔接。 3.雾计算为垂直行业和应用除提供电信业…

雾计算、边缘计算区别和联系

01 从计算方式上边来说的话&#xff0c;雾计算的层次性稍微强一点&#xff0c;并且架构方面比较平坦&#xff0c;这样下来的话整个计算的平稳性就比较好一点。 02 对于边缘计算来说的话&#xff0c;边缘计算在进行计算的时候是不会对网络产生依赖的&#xff0c;也就是说边缘计算…

雾计算机和云计算机哪个好,怎么理解云计算和雾计算还有边缘计算

此外&#xff0c;《数据时代 2025》还预测&#xff0c;2025 年数据量产生的大主体将由消费者转移到企业&#xff0c;届时企业产生的数据量将占到数据总量的 60%。企业领导者将可以从这些海量数据信息和其价值中获得新的商业机遇&#xff0c;但同时也需要对收集、使用和存储数据…

雾计算-思科白皮书 原文+翻译 | 带你全面官方解读雾计算

前言 预感近阶段雾计算会被再次炒起&#xff0c;众所周知雾计算的概念是思科提出来的&#xff0c;于是找来思科白皮书&#xff0c;却是英文版&#xff0c;闲来无事借google翻译将PDF翻译并排版&#xff0c;方便更多的人认识原汁原味的雾计算。 雾计算和物联网&#xff1a;将云…

[Spark基础]--雾计算

wiki解释 雾计算&#xff08;英语&#xff1a;Fog Computing&#xff09;或雾联网&#xff08;fog networking&#xff0c;或fogging&#xff09;&#xff0c;是使用最终用户终端设备或连接最终用户设备的边缘设备&#xff0c;以分布式协作架构进行数据存储&#xff08;相较于将…

AI之边缘计算、雾计算云计算技术分析

边缘计算产生背景&#xff1a; 随着移动智能设备的普及以及5G等无线通信技术的发展,涌现出许多具有低延迟要求的计算密集型应用,如在线沉浸式游戏、增强现实和视频流分析等. 由于传统的云计算无法满足这些应用对低延迟的需求,研究者提出了一种新型的计算模式,称为边缘计算. 边…

第三章-云计算边缘计算雾计算

【前言】随着万物互联时代的到来&#xff0c;网络边缘设备产生的数据量快速增加&#xff0c;带来了更高的数据传输带宽需求。于此同时&#xff0c;新型应用也对数据处理的实时性提出了更高要求&#xff0c;传统云计算模型已经无法有效应对&#xff0c;边缘计算、雾计算应用而生…

云计算、雾计算、边缘计算、移动边缘计算和自动驾驶的关系

什么是云计算呢&#xff1f; 简单来说&#xff0c;云计算就是将很多计算机资源和服务集中起来&#xff0c;人们只要接入互联网&#xff0c;将能很轻易、方便的访问各种基于云的应用信息&#xff0c;省去了安装和维护的繁琐操作。 当然&#xff0c;个人和企业也能使用云计算中心…

【笔记】雾计算中移动应用的优先级约束任务调度

目录 前置 摘要 介绍 模型 应用模型 计算和通信模型 能耗模型 问题定义 NP难 预功率分配算法 能量约束调度 算法1&#xff1a;具有启发式H的能量约束列表调度&#xff08;ECLS-H&#xff09; 时间约束调度 算法2&#xff1a;具有启发式H的时间约束列表调度&#…

文章云计算的兄弟,雾计算要来了

转自&#xff1a; http://tech.china.com/news/company/892/20160219/21553952_all.html#page_2 现在正在流行的“云计算”&#xff0c;是把大量数据放到“云”里去计算或存储。这样&#xff0c;就解决了目前电脑或手机存储量不够&#xff0c;或者是运算速度不够快的问题&#…

话题 | 雾计算和边缘计算有什么区别?

原文&#xff1a;http://readwrite.jp/infrastructure/32649/ 随着物联网的发展&#xff0c;经常听到「雾计算」和「边缘计算」这样的单词。 雾计算这个词相对来说是最近出现的一个词。因为和云相比位置上更接近设备&#xff0c;所以表示为雾&#xff0c;它是作为实现IoT的结构…

边缘计算和雾计算什么关系_什么是雾计算?

边缘计算和雾计算什么关系 By now most people are more than familiar with the concept of Cloud Computing, but what about the new concept referred to as Fog Computing? Today’s Q&A post takes a look at this new concept and how it differs from Cloud Compu…

【知识积累】Edge vs Fog Computing 边缘计算和雾计算的基本介绍

前言 边缘计算和雾计算都可以被定义为技术平台&#xff0c;使计算过程更接近数据产生和收集的地方&#xff0c;以下详细解释了这两个概念。 顾名思义&#xff0c;边缘计算发生在应用网络的“边缘”。从拓扑结构上看&#xff0c;“边缘计算机”在网络的端点上&#xff08;如控…

大话:边缘计算、雾计算、云计算

云计算 一种利用互联网实现随时随地、按需、便捷地使用共享计算设施、存储设备、应用程序等资源的计算模式。 云计算系统由云平台、云存储、云终端、云安全四个基本部分组成&#xff0c;云平台从用户的角度可分为公有云、私有云、混合云等。 通过从提供服务的层次可分为&#x…

边缘计算与雾计算

现在人们常将云计算、边缘计算、雾计算放在一起来讨论&#xff0c;而云计算大家都很熟悉了&#xff0c;但是往往很难搞清楚什么是边缘计算&#xff0c;什么是雾计算&#xff0c;而网络上的文章多为长篇大论&#xff0c;又说不清楚&#xff0c;本文将尽量用浅显明了的方式对其进…

雾计算主要有哪些优点,主要面临哪些挑战?

雾平台由数量庞大的雾节点&#xff08;即上文中雾使用的硬件设备&#xff0c;以及设备内的管理系统&#xff09;构成。这些雾节点可以各自散布在不同地理位置&#xff0c;与资源集中的数据中心形成鲜明对比。 根据以上内容&#xff0c;可以总结出雾计算与云计算的不同&#xf…

区分云计算,边缘计算,雾计算

物联网架构 Edge Layer之下应该还有一个&#xff1a;Device Layer 设备层负责物联网设备的传感器采集、监控、数据的实时分析&#xff08;需要使用其他技术&#xff09;等信息。 物联网架构中&#xff0c;服务组织是自下向上的&#xff0c;即边缘计算的结果可以提供给雾计算用于…