g++与 gcc 的区别?g++能编译.c 文件吗?gcc 能编译.cpp 文件吗?
GCC是GNU推出的功能强大、性能优越的多平台编译器,是GNU的代表作品之一。GCC可以针对多种硬件平台编译出可执行程序,其平均执行效率比一般编译器生成的程序要高20~30%。使用GCC由C语言源代码文件生成可执行文件的过程要经历四个相互关联的步骤:预处理、编译、汇编和链接。
- 预处理: GCC调用cpp程序进行预处理,分析和处理#include、#define等预处理命令
- 编译: GCC调用ccl程序进行编译,根据C源代码生成对应的汇编语言源代码
- 汇编: GCC调用as程序将上步生成的汇编源代码,汇编生成二进制可重定位目标文件
- 链接: GCC调用ld程序对组成程序的目标文件进行链接,生成可执行程序文件
- 使用GCC的命令是gcc,最常用的方式如下:
- #gcc -o filename sample1.c sample2.c sample3.c
使用[-o filename]参数,可以在c程序编译后,输出可执行的文件名为filename;如果没有这个参数,GCC将使用缺省的可执行文件名a.out
- -x language 指定语言(C、C++和汇编为有效值)
- -c 只进行编译和汇编(不链接)
- -S 编译(不汇编或链接)
- (-s) file
- -E 只进行预处理(不编译、汇编或链接)
- -o file 用来指定输出文件名
- -l library 用来指定链接所用库
- -L directory 为库文件的搜索指定目录
- -I directory 为include文件的搜索指定目录
- -w 禁止警告消息
- -pedantic 严格要求符合ANSI标准
- -Wall 显示附加的警告信息
- -g 产生排错信息(同gdb一起使用时)
- -ggdb 产生排错信息(用于gdb)
- -p 产生proff所需的信息
- -pg 产生groff所需的信息
- -o 优化
- 主要处理C语言源文件中的#ifdef、#include以及#define等命令
- GCC会忽略掉不需要预处理的输入文件,该阶段会生成中间文件*.i
- 例:对于源程序example.c ,使用如下命令对源文件进行预处理
- gcc -E example.c -o example.i
- 说明:该例子使用了两个选项:-E和-o,其中-E表示在预处理结束后即停止编译过程;-o指定输出文件。前面的选项不同,输出的文件类型也不相同,可能为预处理后的C代码、汇编文件、目标文件或可执行文件,这里即为预处理后的C代码
- 1) gcc 现在是 GNU 提供的一些编译器工具的集合(Gnu Compiler Collection),以前是GNU 组织提供的 c 编译器(Gnu C Compiler)。 g++是 c++编译器编译器。
- 2) gcc 可以编译.c 和.cpp 的源文件,对*.c 按 c 语言语法规则处理, *.cpp 自动按 c++语法规则处理,但默认不链接相应的 c++库,需要手动指定链接的库名"-lstdc++"
- 3) g++可以编译.c 和.cpp 的源文件,但是都按 c++的语法规则来处理。
- gcc具有优化代码的功能,它的优化功能也有多种不同的选项,主要的优化选项如下所示:
- -O0 不进行优化处理
- -O或-O1 进行基本的优化,这些优化在大多数情况下都会使程序执行得更快
- -O2 除了完成-O1级别的优化外,还要一些额外的调整工作,如处理器指令调度等, 这是GNU发布软件的默认优化级别
- -O3 除了完成-O2级别的优化外,还进行循环的展开以及其它一些与处理器特性相关 的优化工作
- -Os 生成最小的可执行文件,主要用在嵌入式领域
编译优化选项的选择
- 一般来讲,优化级别越高,生成的可执行文件的运行速度也越快,但消耗在编译上的时间就越长,因此在开发的时候最好不要使用优化选项,只有到软件发行或开发结束的时候,才考虑对最终生成的代码进行优化。
- 推荐使用-O2选项,因为它在优化长度、编译时间和代码大小之间,取得了一个比较理想的平衡点,它是最安全的优化选项。
- 对于桌面应用,可以尝试-O3选项,在优化时对循环进行了展开,这会使可执行文件增大,速度是否增加取决于特定环境。其实他们之间的速度差异也并不是很明显。
- -O2选项已经启用绝大多数安全的优化选项,-O3选项是在-O2选项的基础上又增添了一些。其实用户也可以根据需要,在-O2选项的基础自行添加,这样比直接使用-O3选项更加安全。例如增添如下选项:
- -finline-functions:允许编译器将一些简单的函数在其调用处展开
- -funswitch-loops:将循环体中值不改变的变量移到循环体之外
实例:查看gcc优化选项的效果
- 具体的命令格式举例:
- gcc -O2 -finline-functions example.c -o example
- 首先不加任何优化选项,对上面的源程序进行编译:
- gcc example.c -o example
- 使用Linux系统下的time命令来大致统计程序的运行时间:
- time ./example
- time命令的输出结果由三部分组成:
- real:程序的总执行时间,包括进程的调度、切换等时间;
- user:用户进程执行的时间;
- sys:内核执行的时间。
- 接下来使用优化选项-O2对上面的源程序进行处理:
- gcc -O2 example.c -o example
- 再次统计程序的运行时间,可以看到程序的性能得到大幅度的改善
- time ./example
- 此外,还有一个比较重要的优化选项-march,它表示为特定的CPU类型编译二进制代码,进而取得最佳的优化效果。具体的命令格式为:
- gcc --march=<CPU类型> example.c -o example
- CPU类型如pentium4、pentium4m、pentium-m或athlon64等。
- 汇编:是将输入的汇编语言文件转换为目标代码,可通过使用-c选项来完成
- 对应的GCC命令如下例所示:
- gcc -c example.s -o example.o
- 注意:目标文件虽然是机器代码,但不可执行。
汇编器 as
- 使用gcc编译程序时,产生汇编代码,as会处理这些汇编代码,从而产生目标文件(二进制文件),而目标文件将生成.o 文件、库或者最终的可执行文件。
- as 通常情况下是被gcc调用的,但是要使用汇编语言编写程序时,可以手工调用。
- 将生成的目标文件与其它目标文件(或库文件)链接成可执行的二进制代码文件。这一步骤可以使用如下的GCC命令来完成:
- gcc example.o -o example
- 运行example
- 如果只需要最终的可执行文件,也可以直接对源文件进行编译链接,对应的GCC命令如下所示:
- gcc example.c -o example
- 对于一个程序的多个源文件进行编译链接时,可以使用如下格式:
- gcc -o test first.c second.c third.c
- 该命令将同时编译三个源文件,即first.c、second.c和third.c,然后将它们链接成一个可执行程序,名为test。
- 注意:生成可执行文件时,被编译和链接的多个源文件中必须有且只能有一个main函数,因为main函数是该程序的入口。
- 在编写一个较大程序时,经常把它分成许多独立的模块,这时需要链接器把所有的模块组合起来,并结合 C 函数库和初始化代码,产生最后的可执行文件。链接器在产生可执行文件之前,起到重要的作用。
- 通常情况下,ld被编译器所调用,产生可执行代码,但是如果想更好地控制链接过程,最好手工调用ld。
- GCC编译器提供的链接器也提供有多个选项:
- -Idirectory 向GCC的头文件搜索路径中添加新的目录
- -Ldirectory 向GCC的库文件搜索路径中添加新的目录
- -llibrary 提示链接程序在创建可执行文件时包含指定的库文件
- -static 强制使用静态链接库
- -shared 生成动态库文件
- 首先区分头文件和库文件这两个基本概念
- 头文件包含变量和函数的声明,但没有定义函数的实现。例如我们经常用到的头文件stdio.h,其中就包含printf和scanf等格式化输入输出函数的声明,如果在代码中要用到这些函数就需要包含该头文件。
- 函数的具体实现是在库文件中完成的。库文件可分为静态库和动态库。
- 使用GCC直接指定链接程序在创建可执行文件时包含的库文件
- gcc example5.c -o example /usr/lib/i386-linux-gnu/libm.so
- GCC编译器为链接函数库还提供了一个快捷的选项-l,命令的格式为:
- gcc example5.c -o example5 -lm
- 它与上面指定库文件的全路径/usr/lib/libm.so命令等价,避免了在命令行写长路径。之所以写为-lm,是因为在Linux下,库文件在命名时遵循一个规范,即以lib开头,因此在用-l选项指定库文件名时可以省去lib,也就是说GCC在对-lm进行处理时,会自动去链接名为libm.so的库文件。
- GCC编译器在默认情况下使用动态库,但如果使用了-static选项,链接器将忽略动态库,强制使用静态链接库,即使用如下命令:
- gcc example5.c -o example5 -static -lm
- 此时静态库文件中的代码全部包含到可执行文件中,所以生成的可执行文件比较大。
- GCC编译器提供了-shared选项来生成动态库文件。
- 与动态库链接的可执行文件只包含它需要的函数的引用表,而不是所有的函数代码,且只有在程序执行时函数代码才会被拷贝到内存之中。这样使可执行文件比较小,进而节省了磁盘空间;更重要的是,如果库文件本身被更新了,不需要重新编译与它链接的源程序。
- gdb(GNU Debugger)是由GNU计划完成的、受通用公共许可证(GPL)保护的一个功能强大的交互式程序调试工具,主要工作在字符模式下。gdb不仅可以用来调试C/C++语言编写的程序,还可以用来调试Pascal、Objective-C以及Fortran等语言编写的程序。gdb能在程序运行时观察程序的内部结构和内存的使用情况。gdb主要提供以下功能:
- 监视程序中变量的值的变化
- 设置断点,使程序在指定的位置暂停执行,便于检查程序数据和状态
- 单步执行代码
- 分析崩溃程序产生的core文件
- 命令形式:
- gdb filename
文章篇幅太长了,就分开写啦~查看该文:GDB调试
UCOSIII操作系统UCOSIII操作系统——系统初始化篇(1)系统内部任务系统初始化函数UCOSIII默认有5个系统任务:空闲任务时钟节拍任务统计任务定时任务中断服务管理任务UCOSIII其他内容导航不迷路UCOSIII操作系统-简介UCOSIII操作系统——任务篇(1)创建任务UCOSIII操作系统——任务篇(2)相关API函数正在更新整理…说在前面:这个内容不适合0基础的人......_ucos iii初始化做了哪些?
TDCS是铁路调度指挥信息管理系统,主要完成调度指挥信息的记录、分析、车次号校核、自动报点、正晚点统计、运行图自动绘制、调度命令及计划的下达、行车日志自动生成等功能,还句话说就是原来行车调度员和车站值班员需要用笔记下的东西现在都可以由TDCS自动完成。 CTC是分散自律式调度集中系统,除了完成TDCS的全部功能外,还可以完成管内车站信号设备的操控功能,也就是说原来车站值班员要动手的工作也可以由...
Unable to open Assets/xxxxx.fbx: Check external application preferences_check external application preferences.
问题现象:小地球启动报错:读取系统初始化信息失败!,如下图:引发原因:注册表相关键值丢失解决办法:恢复同版本的注册表键值或重新安装软件
尽管conda info有回应,但这个文件默认是没有的只需执行conda config相关命令后,会自动创建.condarc文件,并且会使用其中输入的信息直接覆盖掉对应的默认设置(而不是补充)。所以放心使用conda config --add pkgs_dirs xxx即可...
编写函数,输出一个正整数的素数分解式。主函数的功能为输入若干正整数(大于1),输出每一个数的素分解式。素数分解式是指将整数写成若干素数(从小到大)乘积的形式。单位 哈尔滨师范大学。_7-260 素分解式
一、前言在Linux平台上 有valgrind可以非常方便的帮助我们定位内存泄漏,因为Linux在开发领域的使用场景大多是跑服务器,再加上它的开源属性,相对而言,处理问题容 易形成“统一”的标准。而在Windows平台,服务器和客户端开发人员惯用的调试方法有很大不同。下面结合我的实际经验,整理下常见定位内存泄漏的方 法。注意:我们的分析前提是Release版本,因为在Debug环境下,通过VLD这..._c++内存泄漏怎么排查
应用场景:需要获取mysql多表跨库建表语句时import pymysqltables = [""]hosts = [""]user = ''password = ""port = db_host = ''for host in hosts: mysql = pymysql.connect(host=host, user=user, password=password, port=port) cursor = mysql.cursor() for dbtbs in_python批量读取mysql 的表的ddl语句
Android应用App启动白屏(黑屏)问题解决点击Android手机桌面的应用App icon图标后,Android启动这个应用,正常情况下会立即看到并进入到开发者自己写在MainActivity(配置启动模式为android.intent.category.LAUNCHER的主acitivity)。但是现在业界开发的App越来越复杂和沉重,往往会在App启动最初在application里面..._android启动黑屏
第一步https://www.raspberrypi.com/documentation/computers/configuration.html#setting-up-a-routed-wireless-access-point参考树莓派官方链接,将树莓派配置为使用802.11g协议的AP。第二步https://github.com/raspberrypi/linux/issues/2619#issuecomment-410703338参考Github链接将hostapd。conf中的内容原原本
<checkbox-group @change="selectUniverSity" checked> <checkbox v-for="(item,index) in universityTypes" class="m-2" :key="item.typeId" :value="item.typeId" <!--每次触发一次多选则向checkUnType追加一次,使用includes判断如果当前typeId包._uniapp checkbox取消选中
随着互联网的大量普及,越来越多的企业在不断迭代产品的同时,也在进行技术架构升级,将早期的单体式架构升级成分布式架构。升级改造的成本是非常之大的,那么为什么各大企业仍趋之若鹜的要做架构改造呢?主要原因有三点:1)单体式系统带来的成本太高了,互联网涌入网民的增多导致需要更好的计算能力、网络能力、存储能力,而只是通过扩展小型机、大型机来提高单机性能,太贵了,一般的企业承受不起。2)数据为王的时代需要更多的数据进行分析,企业们需要更经济实惠的方式来存储数据、分析数据,分布式系统多节点显然..._分布式学习系统的四个基本单元有