【Linux】编译器-gcc/g++使用

这篇具有很好参考价值的文章主要介绍了【Linux】编译器-gcc/g++使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

个人主页 : zxctscl
文章封面来自:艺术家–贤海林
如有转载请先通知

1. 前言

在之前已经分享了 【Linux】vim的使用,这次来看看在云服务器上的编译器gcc。

2. 初见gcc和g++

我们先写一段简单的代码:

  #include<stdio.h>
  
  int main()
   {
    for(int i=0;i<10;i++)
     {
      printf("hello: %d\n",i);
     }
     return 0;
 
  }

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

当我们进行编译的时候:
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
发现根本就编译不了。

这个是因为编译器版本的问题:
查看编译器的版本:gcc -v
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
版本不是最新的,不支持在for里面定义变量。

如果想要支持,那么得加上这个命令:

gcc test.c -std=c99

此时就编过了。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
在用gcc时候有一个选项-o,后面接一个名称,就是把编译的可执行程序再起一个名字:

gcc test.c -o my.exe -std=c99

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
-o也可以放在前面,但是-o紧跟的就是修改的文件名

gcc -o you.exe test.c -std=c99

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
在Linux中以.cpp和.cc结尾的都是c++代码
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
写一个简单的C++代码:

#include<iostream>

using namespace std;

int main()
{
  for(int i=0;i<10;i++)
  {
    cout<<"hello linux"<<i<<endl;
  }
  return 0;
}

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
在这里编译这个C++代码

gcc test.cc

就直接报错了
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
所以gcc不能用来编译c++代码。
因为gcc是用来编译C语言的,所以它不认识c++的语法。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

所以编译c++代码得用g++:

g++ test.cc

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
如果想让编译c++代码时支持更高的特性,可以加上-std=c++11

g++ test.cc -std=c++11

总之:
在编译C语言时候可以带上:std=c99
在编译C++代码时可以带上:std=c++11.
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

那么g++能不能编译C语言的代码呢?

g++ test.c

是可以的。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
这个也和我们认知是一样的,c++兼容c。
所以g++既能编译c++,又能编译C语言

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
如果想要编译一个指定名称的c++程序,怎么写呢?
同gcc一样,加上-o选项,-o后面紧跟着指定的名称:

g++ -o my.exe test.cc

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

当然-o可以放在前面,也可以放在后面,和gcc的一样。

g++ test.cc -o you.exe

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
同样c++代码的后缀还有.cpp。
将test.cc先改名为test.cpp:

mv test.cc test.cpp

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

然后编译test.cpp,再指向a.out
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

C++代码后缀除了.cc和.cpp之外,还有一个.cxx
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
来直接编译一下:

g++ test.cxx -o my.exe

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

那么将后缀改为.txt能行吗?

 mv test.cxx test.txt

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
这里是不行的,Linux是不关心文件后缀的,但是编译器是关系。这里编译器就是把.txt当成文本文件了。

在之后的博客中都统一将C++后缀为.cc,因为最简单。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
想知道自己对应的g++是哪个版本的,就直接用命令:

g++ --version

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
如果没有g++怎么安装呢?
可以直接在网上搜索,就会出来了
安装命令就是:

sudo yum install -y gcc-c++

能直接将gcc-c++的标准库给装上了。
装好了,就能直接查看版本:

g++ --version

3. 程序的翻译过程

程序的翻译过程:预处理 编译 汇编 链接

先写一个简单的代码,想看见每个阶段的编译结果

  1 #include<stdio.h>
  2 #define M 100
  3 
  4 int main()
  5 {
  6     for(int i=0;i<10;i++)
  7      {
  8       printf("hello: %d\n,M:%d",i,M);
  9      }
 10     printf("hello gcc\n");
 11     //printf("hello gcc\n");
 12     //printf("hello gcc\n");
 13     //printf("hello gcc\n");
 14     //printf("hello gcc\n");
 15     //printf("hello gcc\n");
 16     //printf("hello gcc\n");
 17     //printf("hello gcc\n");
 18     //printf("hello gcc\n");
 19     //printf("hello gcc\n");
 20     //printf("hello gcc\n");
 21      return 0;
 22 
 23 }

3.1 预处理

预处理:要做的是宏替换,去注释,头文件展开,条件编译。

3.1.1 宏替换 去注释 头文件展开

-E 就是从现在开始进行程序的翻译,预处理完成,就停下。

gcc -E test.c -o test.i

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
进入test.i
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
保存的就是-E后的结果

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
将test.c打开,对比发现test.i有800多行,是怎么来的?
是从test.c的头文件 #include<stdio.h>来的。

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
用来查看C语言标准的头文件库:

ls /usr/include/

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
打开stdio.h发现有很多函数声明

vim /usr/include/stdio.h

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
再打开test.i

vim test.i

对比一下代码,发现宏已经替换了,而且注释了的代码也不在。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

3.1.2 条件编译

先写一个代码在proj.c中:

  1 #include<stdio.h>
  2 int main()
  3 {
  4 #ifdef V1
  5   printf("功能1\n");
  6
  7 #elif V2
  8   printf("功能1\n");
  9   printf("功能2\n");
 10   printf("功能3\n");
 11
 12 #else
 13   printf("功能1\n");
 14   printf("功能2\n");
 15   printf("功能3\n");
 16   printf("功能4\n");
 17   printf("功能5\n");
 18   printf("功能6\n");
 19 #endif
 20
 21   return 0;
 22 }
~

在编译之后打开proj.i
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
然后用宏定义将V1 定为1:#define V1 1
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
然后直接编译:

gcc proj.c

发现结果只剩下功能1了。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

就行打开proj.c,将#define V1 1 改为#define V2 1
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
编译运行后:
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
同样将v2改为v3.
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

这个就叫做条件编译,可以根据用户指明的条件,实现代码的动态裁剪。

在现实中,可以在软件维护一份代码,用条件编译的方式,来进行代码的裁剪,这样就能定制出各种功能的代码。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
把宏删除。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
用-D加上要宏定义的对象和值,再加上宏定义的文件,就可以直接对代码进行宏定义,更方便对代码进行裁剪

gcc -DV1=1 proj.c

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

也可以裁剪其他的选项。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

3.2 编译

编译:将C语言变成汇编语言。

-S:从现在开始进行程序的编译,编译完成就停下来。

如果想要重新做一遍前面的预处理再到编译,那么就用.c文件

gcc -S test.c -o test.s

如果想要从预处理阶段直接编译就用.i:

gcc -S test.i -o test.s

这里发现报错,是因为版本的原因
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
加上它提示的-std=c99就可以了:

gcc -S test.i -o test.s -std=c99

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
进入test.s看看

vim test.s

发现里面是汇编语言。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

3.3 汇编

汇编:将汇编语言翻译为二进制目标文件,这种二进制是没有办法指向的,还差一个链接。

-c:从现在开始进行程序的汇编,汇编完成就停下来。

gcc -c test.s -o test.o

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
这里的后缀.o,就是.obj,打开之前用vs写的程序,发现同样有。这个文件叫可重定位目标文件,不能直接执行,形成exe想要用到它。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
打开这个test.o文件:

vim test.o

发现里面形成乱码:
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

发现已经是二进制文件了:

 file test.o

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

那么能不能直接运行呢?
发现是不行的。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
那么给它加上可执行的权限:
发现还是不能运行
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

一个文件能不能被指向,不止取决于它的权限,还要本身就是可执行程序。

得明白二进制目标文件是一个临时文件,是不能够执行的。

3.4 链接

链接:将二进制目标文件形成可执行程序。

直接:

gcc test.o

就形成可执行的目标文件了r
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
当然可以加-o带上形成的程序名:

gcc test.o -o my.exe

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
就能直接执行。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

为了方便记忆这些选项,观察一下可以发现它们连在一起就是:-ESc,只是E和S要大写。
后缀就是-iso,就像镜像文件。

4. 链接

链接是什么呢?
链接是我吗程序和库结合的过程。
语言一定有自己的标准库,就像c中有c99标准,要保证跨平台性。

ldd后面接可执行程序就会显示它的动静态库

ldd my.exe

最重要的就是:
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
查看链接到的库

 ls /lib64/libc.so.6 -l

这里就是c标准库。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

我们可以看看这个库的大小:

ls /lib64/libc-2.17.so -l

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
一般进行链接时是把程序和这个库链接形成一个可执行的程序。
这个库里面在不是库之前,是C语言标准库的源代码,像printf和各种方法,进行打包形成这个库。这个库的安全性是很高的。

怎么知道库里面有哪些文件?
会有一批对应的头文件,这个头文件相当于一个方法说明。
所以安装开发环境是:安装C标准库和C头文件

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

库分为动态库和静态库。在Linux里面有,同样在windows里面也有。

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

在在Linux中库的真正的名字是把前缀lib去掉,去掉“.”后面的后缀。
所以这个就是c标准库。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
因为Linux存在这两种库,就决定了,在链接时,有两种方式:动态链接静态链接

4.1 动态链接

举个例子:就像在学校旁边有个网吧,一个学长(相当于编译器)告诉了小明这个网吧的地址,(就相当于有了目标库的地址)这个地址就是,这个过程就是动态链接。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
小明在这个网吧(就相当于动态库)的9号机(相当于库里面的一个方法,printf),当小明在学校里面作业(程序执行的代码)想要用到电脑,去了网吧(跳转到库)的9号机(想要的方法),用完之后回学校(返回程序),这个过程就是一次动态运行的过程。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
在网吧被派出所查封以后,这个网吧就不能进了。也就是说动态链接依赖动态库,一旦动态库缺失,所有静态链接,这个库的程序,都无法执行了。

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
c动态库,是默认提供的
gcc默认形成可执行程序,默认采用动态链接

查看文件类型:

file my.exe

使用的是动态库链接:
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
动态库和动态链接的优缺点:

  1. 不能丢失
  2. 节约资源

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
重新创建一个文件夹,把test.c移动到里面,然后执行。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
默认采用动态链接
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

4.2 静态链接

接上个例子:小明在买了网吧9号机器(库的方法),这样每次上网(执行程序)都能用,不需要这个网吧了,每次执行程序就拷贝到自己的电脑上,这个过程叫静态链接。这个网吧卖电脑就是静态库。
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

静态链接就是:在编译的时候,把库中的方法,拷贝到自己的可执行程序中。

静态库和静态链接的优缺点:

  1. 一旦形成,与库无关
  2. 浪费资源

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
形成静态链接:

gcc -o mytest-static test.c -static -

发现报错了:
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
这个是因为在默认情况下,一般静态库都是默认没有安装的。

安装命令是:

 sudo yum install -y glibc-static libstdc++-static

然后再执行:
【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言
再ldd看看:

ldd mytest-static

【Linux】编译器-gcc/g++使用,Linux,linux,运维,服务器,c++,c语言

有问题请指出,大家一起进步!!!文章来源地址https://www.toymoban.com/news/detail-838584.html

到了这里,关于【Linux】编译器-gcc/g++使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux】Linux编译器 gcc/g++的使用&&初识动静态链接库

    ​ ​📝个人主页:@Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:Linux 🎯 长路漫漫浩浩,万事皆有期待 上一篇博客:【Linux】Linux环境基础工具的基本使用及配置(yum、vim) 在上一篇 Linux 博客中,我们讲解了 vim 编辑器的使用,可以在 Linux 上写

    2024年02月11日
    浏览(43)
  • 【Linux】Linux编译器 gcc 的使用 | 动静态库的初步认识

    👑作者主页:@安 度 因 🏠学习社区:StackFrame 📖专栏链接:Linux

    2024年01月15日
    浏览(29)
  • 【Linux】编译器-gcc/g++与调试器-gdb的使用

    👀 樊梓慕: 个人主页  🎥 个人专栏: 《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》《Linux》 🌝 每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.gcc/g++语法 2.gcc的使用及编译器是如何\\\"翻译\\\"代码的? (1)预处理 (2)编译 (3)汇编

    2024年02月04日
    浏览(49)
  • 【Linux】编译器gcc和g++与调试器gdb的使用

    我们知道,一个程序被运行起来之后需要经历四个阶段然后才变成一个可执行的程序,他们分别为:预处理,编译,汇编和链接。下面我们将介绍这四个阶段的操作,测试代码如下: 1.1 预处理 预处理也叫预编译,程序在预处理阶段会完成如下操作: 展开头文件,将头文件中

    2024年02月07日
    浏览(33)
  • 【探索Linux】—— 强大的命令行工具 P.4(编译器 gcc/g++ 使用)

    前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C++的一些知识,也学习了一些Linux的基本操作,也了解并学习了有关Linux开发工具vim ,也相信大家都掌握的不错,今天博主带大家了解一下Linux编译器 gcc/g++ 使用, 下面话不多说坐稳扶好咱们要开车了!!

    2024年02月12日
    浏览(46)
  • Linux:编译器 - gcc

    GCC(英文全拼:GNU Compiler Collection)是 GNU 工具链的主要组成部分,是一套以 GPL 和 LGPL 许可证发布的程序语言编译器自由软件,由 Richard Stallman 于 1985 年开始开发。 gcc是GCC中的C语言编译器,而g++是GCC中的C++编译器。本博客只讲解gcc,g++的语法和选项和gcc都是一致的。 gcc 编译

    2024年04月14日
    浏览(70)
  • Linux GCC常用命令以及GCC编译器

    GCC 是编译工具,它的意思是 GNU C Compiler 。经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言;它现在还支持 Ada 语言、C++ 语言、Java 语言、Objective C 语言、Pascal 语言、COBOL语言,以及支持函数式编程和逻辑编程的 Mercury 语言等等。而 GCC 也不再单只是 GNU C 语言编译器的意

    2024年02月05日
    浏览(38)
  • Linux——gcc/g++编译器

    目录 I.Linux编译器 1.gcc/g++编译器 在C代码生成可执行程序的过程中,会有四个过程: 1预处理,2编译,3汇编,4链接 Linux对.c文件分辨进行预处理,编译,汇编三大步指令: 预处理指令: 编译指令: 汇编指令: 接下来说一说链接过程: II.动静态链接  一.动态链接 二.静态链接

    2024年02月04日
    浏览(40)
  • Linux编译器gcc/g++

    以gcc编译 以g++编译,但是此时会发现没有g++这个指令,所有需要安装它,安装指令 yum install gcc gcc-c++ gcc和g++都会形成可执行文件a.out gcc只能编译c语言代码,g++能编译c/c++ 以c程序为例,来看看它从一个文本类的c程序编译成计算机可以认识的二进制程序它需要经过四个阶段 预

    2024年02月10日
    浏览(35)
  • 《Linux从练气到飞升》No.05 Linux编译器gcc/g++的使用及编译过程 【云边有个小卖部】上新

    🕺作者: 主页 我的专栏 C语言从0到1 探秘C++ 数据结构从0到1 探秘Linux 菜鸟刷题集 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇 码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要,有问题可在评论区提出,感谢阅读!!! 本篇我们将讲述gcc/g++的使用以及它是如何完成一

    2024年02月14日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包