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

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

文章目录

  • 1. 前言
  • 2. 初见gcc和g++
  • 3. 程序的翻译过程
    • 3.1 预处理
      • 3.1.1 宏替换 去注释 头文件展开
      • 3.1.2 条件编译
    • 3.2 编译
    • 3.3 汇编
    • 3.4 链接
  • 4. 链接
    • 4.1 动态链接
    • 4.2 静态链接

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;
 
  }

在这里插入图片描述

当我们进行编译的时候:
在这里插入图片描述
发现根本就编译不了。

这个是因为编译器版本的问题:
查看编译器的版本:gcc -v
在这里插入图片描述
版本不是最新的,不支持在for里面定义变量。

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

gcc test.c -std=c99

此时就编过了。
在这里插入图片描述
在这里插入图片描述
在用gcc时候有一个选项-o,后面接一个名称,就是把编译的可执行程序再起一个名字:

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

在这里插入图片描述
-o也可以放在前面,但是-o紧跟的就是修改的文件名

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

在这里插入图片描述

在这里插入图片描述
在Linux中以.cpp和.cc结尾的都是c++代码
在这里插入图片描述
写一个简单的C++代码:

#include<iostream>

using namespace std;

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

在这里插入图片描述
在这里编译这个C++代码

gcc test.cc

就直接报错了
在这里插入图片描述
所以gcc不能用来编译c++代码。
因为gcc是用来编译C语言的,所以它不认识c++的语法。
在这里插入图片描述

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

g++ test.cc

在这里插入图片描述
如果想让编译c++代码时支持更高的特性,可以加上-std=c++11

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

总之:
在编译C语言时候可以带上:std=c99
在编译C++代码时可以带上:std=c++11.

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

g++ test.c

是可以的。
在这里插入图片描述
这个也和我们认知是一样的,c++兼容c。
所以g++既能编译c++,又能编译C语言

在这里插入图片描述
如果想要编译一个指定名称的c++程序,怎么写呢?
同gcc一样,加上-o选项,-o后面紧跟着指定的名称:

g++ -o my.exe test.cc

在这里插入图片描述

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

g++ test.cc -o you.exe

在这里插入图片描述
在这里插入图片描述
同样c++代码的后缀还有.cpp。
将test.cc先改名为test.cpp:

mv test.cc test.cpp

在这里插入图片描述

然后编译test.cpp,再指向a.out
在这里插入图片描述

C++代码后缀除了.cc和.cpp之外,还有一个.cxx
在这里插入图片描述
来直接编译一下:

g++ test.cxx -o my.exe

在这里插入图片描述

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

 mv test.cxx test.txt

在这里插入图片描述
这里是不行的,Linux是不关心文件后缀的,但是编译器是关系。这里编译器就是把.txt当成文本文件了。

在之后的博客中都统一将C++后缀为.cc,因为最简单。
在这里插入图片描述

在这里插入图片描述
想知道自己对应的g++是哪个版本的,就直接用命令:

g++ --version

在这里插入图片描述
如果没有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

在这里插入图片描述
进入test.i
在这里插入图片描述
保存的就是-E后的结果

在这里插入图片描述
将test.c打开,对比发现test.i有800多行,是怎么来的?
是从test.c的头文件 #include<stdio.h>来的。

在这里插入图片描述
用来查看C语言标准的头文件库:

ls /usr/include/

在这里插入图片描述
打开stdio.h发现有很多函数声明

vim /usr/include/stdio.h

在这里插入图片描述
再打开test.i

vim test.i

对比一下代码,发现宏已经替换了,而且注释了的代码也不在。
在这里插入图片描述

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
在这里插入图片描述
然后用宏定义将V1 定为1:#define V1 1
在这里插入图片描述
然后直接编译:

gcc proj.c

发现结果只剩下功能1了。
在这里插入图片描述

就行打开proj.c,将#define V1 1 改为#define V2 1
在这里插入图片描述
编译运行后:
在这里插入图片描述
同样将v2改为v3.
在这里插入图片描述

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

在现实中,可以在软件维护一份代码,用条件编译的方式,来进行代码的裁剪,这样就能定制出各种功能的代码。
在这里插入图片描述
把宏删除。
在这里插入图片描述
用-D加上要宏定义的对象和值,再加上宏定义的文件,就可以直接对代码进行宏定义,更方便对代码进行裁剪

gcc -DV1=1 proj.c

在这里插入图片描述

也可以裁剪其他的选项。
在这里插入图片描述

3.2 编译

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

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

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

gcc -S test.c -o test.s

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

gcc -S test.i -o test.s

这里发现报错,是因为版本的原因
在这里插入图片描述
加上它提示的-std=c99就可以了:

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

在这里插入图片描述
进入test.s看看

vim test.s

发现里面是汇编语言。
在这里插入图片描述

3.3 汇编

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

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

gcc -c test.s -o test.o

在这里插入图片描述
这里的后缀.o,就是.obj,打开之前用vs写的程序,发现同样有。这个文件叫可重定位目标文件,不能直接执行,形成exe想要用到它。
在这里插入图片描述
打开这个test.o文件:

vim test.o

发现里面形成乱码:
在这里插入图片描述

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

 file test.o

在这里插入图片描述

那么能不能直接运行呢?
发现是不行的。
在这里插入图片描述
那么给它加上可执行的权限:
发现还是不能运行
在这里插入图片描述

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

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

3.4 链接

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

直接:

gcc test.o

就形成可执行的目标文件了r
在这里插入图片描述
当然可以加-o带上形成的程序名:

gcc test.o -o my.exe

在这里插入图片描述
就能直接执行。
在这里插入图片描述

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

4. 链接

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

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

ldd my.exe

最重要的就是:
在这里插入图片描述
查看链接到的库

 ls /lib64/libc.so.6 -l

这里就是c标准库。
在这里插入图片描述

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

ls /lib64/libc-2.17.so -l

在这里插入图片描述
一般进行链接时是把程序和这个库链接形成一个可执行的程序。
这个库里面在不是库之前,是C语言标准库的源代码,像printf和各种方法,进行打包形成这个库。这个库的安全性是很高的。

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

在这里插入图片描述

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

在这里插入图片描述

在在Linux中库的真正的名字是把前缀lib去掉,去掉“.”后面的后缀。
所以这个就是c标准库。
在这里插入图片描述
在这里插入图片描述
因为Linux存在这两种库,就决定了,在链接时,有两种方式:动态链接静态链接

4.1 动态链接

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

在这里插入图片描述
c动态库,是默认提供的
gcc默认形成可执行程序,默认采用动态链接

查看文件类型:

file my.exe

使用的是动态库链接:
在这里插入图片描述
动态库和动态链接的优缺点:

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

在这里插入图片描述
重新创建一个文件夹,把test.c移动到里面,然后执行。
在这里插入图片描述
默认采用动态链接
在这里插入图片描述

4.2 静态链接

接上个例子:小明在买了网吧9号机器(库的方法),这样每次上网(执行程序)都能用,不需要这个网吧了,每次执行程序就拷贝到自己的电脑上,这个过程叫静态链接。这个网吧卖电脑就是静态库。
在这里插入图片描述

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

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

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

在这里插入图片描述
形成静态链接:

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

发现报错了:
在这里插入图片描述
这个是因为在默认情况下,一般静态库都是默认没有安装的。

安装命令是:

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

然后再执行:
在这里插入图片描述
再ldd看看:

ldd mytest-static

在这里插入图片描述

有问题请指出,大家一起进步!!!

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

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

相关文章

DRC:扩散模型的推荐系统应用

1 Title Diffusion Recommender Model&#xff08;Wenjie Wang、Yiyan Xu、Fuli Feng、Xinyu Lin、Xiangnan He、Tat-Seng Chua&#xff09;【SIGIR 23】 2 Conclusion . In light of the impressive advantages of Diffusion Models (DMs) over traditional generative model…

万字完整版【C语言】指针详解~

一、前言 初始指针&#xff08;0&#xff09;&#xff1a;着重于讲解指针的概念、基本用法、注意事项、以及最后如何规范使用指针深入指针&#xff08;1&#xff09;&#xff1a;讲解指针变量常见的类型&#xff0c;如何去理解这些类型、最后就是如何正确的使用深入指针&#…

【语法基础练习】1.变量、输入输出、表达式与顺序语句

&#x1f338;博主主页&#xff1a;釉色清风&#x1f338;文章专栏&#xff1a;算法练习&#x1f338;今日语录&#xff1a;You don’t know until you try. 文章简介&#xff1a;下面的题目是AcWing网站语法基础练习篇的第一小节&#xff0c;内容基础&#xff0c;难度&#xf…

如何进入Windows 11的安全模式?这里提供详细步骤

序言 如果你在启动Windows 11 PC时遇到问题,则重新启动到安全模式可能会有所帮助,该模式会暂时禁用驱动程序和功能,以使你的PC更稳定。下面是如何做到这一点。 在Windows 7和更早版本中,通常可以在打开电脑后按功能键(如F8)启动安全模式。Microsoft从Windows 8中删除了…

MybatisPlus知识点总结(基于黑马2023MybatisPlus课程)

MybatisPlus知识点总结 配套资料 黑马微服务框架笔记&#xff0c;内含mpMybatisPlus.pptxMyBatis-Plus &#xff08;mp中文官网&#xff09; 快速入门 入门案例 使用MybatisPlus的基本步骤&#xff1a;1.引入MybatisPlus依赖&#xff0c;代替Mybatis依赖2.定义Mapper接口并继…

C++_可变参数模板

目录 1、可变参数模板的用法 2、参数包展开 2.1 递归方式展开 2.2 逗号表达式形式展开 3、参数包的大小 结语 前言&#xff1a; C11引入了可变参数模板&#xff0c;他的作用是可以让创建的函数模板或者类模板的模板参数可以接收任意数量参数&#xff0c;在C11前&#x…

16. C++标准库

C标准库兼容C语言标准函数库&#xff0c;可以在C标准库中直接使用C语言标准函数库文件&#xff0c;同时C标准库增加了自己的源代码文件&#xff0c;新增文件使用C编写&#xff0c;多数代码放在std命名空间中&#xff0c;所以连接C标准库文件后还需要 using namespace std;。 【…

【OpenGL手册11】材质的模型

目录 一、说明二、材质表面和光照三、设置材质四、光的属性五、不同的光源颜色练习 一、说明 在现实世界里&#xff0c;每个物体会对光产生不同的反应。比如&#xff0c;钢制物体看起来通常会比陶土花瓶更闪闪发光&#xff0c;一个木头箱子也不会与一个钢制箱子反射同样程度的…

Seata 2.x 系列【6】微服务项目搭建

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Seata 版本 2.0.0 本系列Spring Boot 版本 3.2.0 本系列Spring Cloud 版本 2023.0.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 概述2. 数据库…

2024年3月ZZUACM 招新赛题解

2024年3月ZZUACM 招新赛 题号题目A区间次大值B上课签到C魔法森林&#xff08;一&#xff09;D魔法森林&#xff08;二&#xff09;ELOPF跳格子G猜数字H抽卡记录I安达的二维矩阵J安达的数字手术K跳楼梯L前缀和 A 区间次大值—循环/签到题 题目描述 给定一个 n n n的全排列 a i…

DeepLearning in Pytorch|共享单车预测NN详解(思路+代码剖析)

目录 概要 一、代码概览 二、详解 基本逻辑 1.数据准备 2.设计神经网络 初版 改进版 测试 总结 概要 原文链接&#xff1a;DeepLearning in Pytorch|我的第一个NN-共享单车预测 我的第一个深度学习神经网络模型---利用Pytorch设计人工神经网络对某地区租赁单车的使用…

自然语言处理: 第十三章P-tuing系列之P-tuning V1

项目地址: P-Tuning 论文地址: [2103.10385] GPT Understands, Too (arxiv.org) 理论基础 正如果上一节介绍LoRA(自然语言处理: 第十二章LoRA解读_lora自然英语处理-CSDN博客)一样,本次介绍的在21年由清华团推提出来的 P-Tuning V1系列也属于PEFT(参数高效微调系列)里的一种&…

【前端】平面转换与渐变

目录 1.字体图标 2.平面转换 2.1位移 2.2旋转 2.3多重转换 2.4缩放 3.渐变 1.字体图标 引入iconfont平台字体图标样式表 <link rel"stylesheet" href"./iconfont/iconfont.css"> <i class"iconfont xx"></i> 第一个类…

函数柯里化:JavaScript中的高级技巧

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

学习嵌入式C语言要掌握到什么程度?

学习嵌入式C语言要掌握到什么程度&#xff1f; 在开始前我分享下我的经历&#xff0c;我刚入行时遇到一个好公司和师父&#xff0c;给了我机会&#xff0c;一年时间从3k薪资涨到18k的&#xff0c; 我师父给了一些 电气工程师学习方法和资料&#xff0c;让我不断提升自己&#…

anaconda问题合集

目录 一. 万分注意 二. ImportError: DLL load failed while importing _ctypes: 找不到指定的模块。 1. 发生情况 2. 导致结果和解决方法 三. WARNING: A newer version of conda exists. 1. 在conda install 某库的时候 2. 解决方法 一. 万分注意 不要轻易使用 conda …

YOLO建筑物损伤评估数据集

YOLO建筑物损伤评估数据集&#xff0c;重度损伤&#xff0c;轻微损伤&#xff0c;中度损伤&#xff0c;未损伤4类&#xff0c;近五千张图像&#xff0c;yolo标注完整&#xff0c;应用数据增强。 适用于CV项目&#xff0c;毕设&#xff0c;科研&#xff0c;实验等 需要此数据集…

举个栗子!Alteryx 技巧(10):解决连数据库时出现中文乱码的问题

在日常工作中&#xff0c;我们经常遇到需要连接 Oracle 数据库的场景。当采用 ODBC 的方式进行连接时&#xff0c;可能会出现中文乱码。那么&#xff0c;应该如何解决中文乱码这个问题呢&#xff1f; 本期《举个栗子&#xff01;Alteryx 技巧》&#xff0c;我们就来分享方法吧…

近年来文本检测相关工作梳理

引言 场景文本检测任务&#xff0c;一直以来是OCR整个任务中最为重要的一环。虽然有一些相关工作是端对端OCR工作的&#xff0c;但是从工业界来看&#xff0c;相关落地应用较为困难。因此&#xff0c;两阶段的OCR方案一直是优先考虑的。 在两阶段中&#xff08;文本检测文本识…

猫头虎分享已解决Bug || 云服务中断:CloudOutage, CloudProviderError

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …