当前位置: 首页 > news >正文

【Linux初阶】基础IO - 动静态库 | 初识、生成、链接、加载

🌟hello,各位读者大大们你们好呀🌟
🍭🍭系列专栏:【Linux初阶】
✒️✒️本篇内容:动静态库初识,库的含义,静态库的生成与链接,gcc/g++默认链接方式,动态库的生成与动态链接,查看动态链接的方法,动静态库的加载原理
🚢🚢作者简介:计算机海洋的新进船长一枚,请多多指教( •̀֊•́ ) ̖́-


文章目录

  • 一、动静态库初识
    • 1.静态库和动态库
    • 2.动态库的理解
  • 二、理解库的含义
  • 三、静态库和静态链接
    • 1.生成静态库
    • 2.查看静态库中的目录列表
    • 3.静态库的下载和安装
    • 4.静态库的链接
    • 5.gcc/g++的默认链接方式
  • 四、动态库和动态链接
    • 1.生成动态库
    • 2.动态链接
      • (1)共享路径法
      • (2)环境变量法
      • (3)更改配置文件法
      • (4)软连接法【推荐】
      • (5)查看动态库是否链接成功
  • 五、动静态库的加载
    • 1.静态库不存在加载
    • 2.动态库加载
      • (1)动态库的编址方式
      • (2)动态库加载和访问的逻辑(重点)
  • 结语


一、动静态库初识

1.静态库和动态库

  • 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。
  • 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

2.动态库的理解

  • 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码。
  • 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
  • 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。

二、理解库的含义

我们可以创建一个测试程序:

测试程序
/add.h/
#pragma once
#include <stdio.h>
extern int Add(int a, int b);/add.c/
#include "my_add.h"
int Add(int a, int b)
{printf("enter Add func, %d + %d = ?\n", a, b);return a + b;
}/sub.h/
#pragma once
#include <stdio.h>
extern int Sub(int a, int b);/add.c/
#include "add.h"
int sub(int a, int b)
{return a - b;
}///main.c
#include "my_add.h"
#include "my_sub.h"int main()
{int a = 10;int b = 20;int res = Sub(a, b);printf("result: %d\n", res);res = Add(a, b);printf("result: %d\n", res);return 0;
}

程序的编译分为四个阶段:预处理、编译、汇编、链接。输入下面三条指令,分别会形成 3个汇编之后的二进制文件,这种二进制文件无法运行,因为它缺了链接的步骤。

gcc -c main.c		-> main.o
gcc -c my_add.c		-> my_add.o
gcc -c my_sub.c		-> my_sub.o

这种 .o文件,我们称它为:可重定位目标二进制文件。通过对 .o文件的链接,可以形成一个统一的可执行文件。

在这里插入图片描述

我们在上面说过,.o文件是一个二进制文件,无法阅读。如果我们不想给对方我们的源码,可以给对方提供 .o可重定位目标二进制文件让别人用你的代码进行链接即可。

也就是说,如果要在没有源码的情况下,形成可执行文件,我们需要给对方提供 .o(方法的实现).h(都有什么方法),还要有自己调用方法的文件(main.o)

在上面的基础上,我们可以试着给所有的 .o文件打一个包,最后只给对方提供一个库文件即可。

库文件:.o文件 -> 一个文件 -> 库 -> (根据打包工具和方式不同)静态库和动态库!

总结:库文件就是 .o文件的集合


三、静态库和静态链接

1.生成静态库

为了方便理解,我们使用 Makefile工具

libmymath.a:my_add.o my_sub.o
ar - rc $@ $^		#ar是gnu归档工具,rc表示(replace and create)
my_add.o:my_add.c
gcc - c my_add.c - o my_add.o	#形成.o文件
my_sub.o : my_sub.c
gcc - c my_sub.c - o my_sub.o.PHONY : output		#发布
output :
mkdir - p mylib / include	#-p,建立多级目录
mkdir - p mylib / lib
cp - f *.a mylib / lib		#将生成的libmymath.a和头文件拷贝到特定的目录中
cp - f *.h mylib / include.PHONY:clean
clean :
rm - rf *.o libmymath.a mylib	#删除所有.o文件和对应的库

在这里插入图片描述

在这里插入图片描述

至此,我们生成了对应的目录文件 mylib,而这个mylib就是我们的静态库。

总结:交付库 = 库文件(.a/.so)+ 匹配的头文件

———— 我是一条知识分割线 ————

2.查看静态库中的目录列表

方法如下:

查看静态库中的目录列表
[root@localhost linux]# ar - tv libmymath.a
rw - r--r-- 0 / 0 1240 Sep 15 16:53 2017 add.o
rw - r--r-- 0 / 0 1240 Sep 15 16 : 53 2017 sub.o
t : 列出静态库中的文件
v : verbose 详细信息

———— 我是一条知识分割线 ————

3.静态库的下载和安装

  • 我们可以使用 tar命令对静态库进行压缩。
  • 然后将这个文件,放在某一个网站中,让用户下载。

在这里插入图片描述

  • 用户下载后可进行解压和安装。

在这里插入图片描述

  • 安装实际上就是将库文件和对应的头文件放到系统的特定路径下。
    在这里插入图片描述

总结:安装的本质就是拷贝。库的安装就是将库文件和头文件分别拷贝到对应的默认路径中。库的卸载就是将库文件和头文件从默认路径下删除

———— 我是一条知识分割线 ————

4.静态库的链接

  • 首先我们一起来看下 mylib的结构。

在这里插入图片描述

  • 此时如果我们直接链接,或者只添加头文件路径都会会出现报错。

在这里插入图片描述

  • 因为gcc/g++需要详细的头文件、库文件路径、还有库文件名称。

在这里插入图片描述

这里:-I(大写i)后跟头文件路径,-L (大写l)后跟库文件路径,-l(小写l)后跟库文件名
补充:上述字母后面空格可带可不带。gcc/g++只能在当前路径下搜索,因此需要具体的头文件、库文件路径、还有库文件名称。

  • 如果已经将库文件和头文件安装到默认路径下,只需要指明库文件名称即可。

在这里插入图片描述

在这里插入图片描述

总结:链接第三方库时,必须指明头文件路径、库文件路径、库文件名称

注意:我们平时编译代码不用提供路径是因为库文件和头文件在系统的默认路径下。gcc/g++默认能识别C/C++的库

———— 我是一条知识分割线 ————

5.gcc/g++的默认链接方式

  • gcc、g++是默认使用动态链接的
  • 如果软件有动态库和静态库,在链接过程中,软件会将静态库的代码拷贝过来,但是最后使用的是动态链接。
  • 如果软件只使用了静态库,没有使用任何一个动态库,最终才会以静态方式进行链接。

在这里插入图片描述

总结:gcc、g++是默认使用动态链接的


四、动态库和动态链接

1.生成动态库

在学习动态库生成之前,我们需要了解几个名词:

  • shared: 表示生成共享库格式
  • fPIC:产生位置无关码(position independent code)
  • 库名规则:libxxx.so

示例:

 #生成共享库格式的 .o文件[root@localhost linux]# gcc -fPIC -c sub.c add.c #生成对应的动态库文件[root@localhost linux]# gcc -shared -o libmymath.so *.o 

在这里插入图片描述

在这里插入图片描述

接下来,我们要生成一个目录,存放库文件和头文件

在这里插入图片描述

至此,我们创建好了我们的动态库。

———— 我是一条知识分割线 ————

2.动态链接

创建好目录之后我们尝试链接,发现会存在报错(err:找不到文件或目录),因此动态链接并没有我们想象中那么简单。
在这里插入图片描述

我们不是已经告诉 gcc/g++,头文件、库文件路径还有库文件名称了吗?为什么还是不能链接呢?答案是,gcc/g++只完成了编译的步骤,我们在运行的时候还需要操作系统通过动态链接调用我们的代码,也就是说,OS也需要知道我们库的位置,但是库不在系统路径下,无法找到。

下面介绍动态链接的四种方法

(1)共享路径法

拷贝.so文件到系统共享库路径下, 一般指/usr/lib。

(2)环境变量法

更改环境变量 LD_LIBRARY_PATH,系统除了会在默认路径下搜索库,还会在这个变量下搜索。

 [root@localhost linux]# export LD_LIBRARY_PATH=.=后跟库的具体路径)[root@localhost linux]# gcc main.c -lmymath[root@localhost linux]# ./a.out

在这里插入图片描述

(3)更改配置文件法

我们通过更改自己的配置文件,也可以让操作系统找到。

ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新
  1. 进入(cd)系统存放配置文件的路径;
  2. 创建一个配置文件;
  3. 将所需要链接的库文件的具体地址填入到自定义的配置文件中;
  4. 输入指令 ldconfig,进行配置文件更新(永久有效,除非删除);
  5. 删除:先删除配置文件,再输入指令 ldconfig;

注意,配置文件操作大多需要 root权限,普通用户可以通过 sudo提权实现配置文件的创建和更新

(4)软连接法【推荐】

操作系统可以查找当前路径下的库文件,所以我们可以在当前路径下创建一个软连接文件,链接库文件,实现OS的访问。

  • 在当前路径下创建软连接文件。

在这里插入图片描述
断开链接:
在这里插入图片描述

  • 或者我们可以将软连接文件放到系统默认路径下。

在这里插入图片描述

———— 我是一条知识分割线 ————

(5)查看动态库是否链接成功

ldd 文件名	#指令

在这里插入图片描述


五、动静态库的加载

1.静态库不存在加载

静态库不存在加载,因为程序在编译完成之后,就会将静态库的内容拷贝到我们的可执行程序中。当可程序运行起来之后再整体加载到内存。

注意:程序加载 != 静态库加载,静态库加载不存在

当其他可执行程序再次调用静态库时,就需要再次将静态库内容拷贝到可执行程序中。静态库的使用可能会导致代码的冗余。

代码在编译的过程中,就已经以虚拟地址空间的方式将我们的代码编译好了,因此,静态库拷贝的本质:将静态库的代码展开,将代码拷贝到可执行程序的代码区中

总结:代码在编译好后,会按照虚拟地址空间的排布规则对代码进行排布,静态库在编译过程中会将展开的代码拷贝到代码区中。未来这部分代码,必须通过相对确定的地址位置进行访问

———— 我是一条知识分割线 ————

2.动态库加载

(1)动态库的编址方式

动态链接并没有将代码拷贝到我们的可执行程序中,它是将动态库中指定函数的地址,写进了可执行程序中。

举个例子:假设我们有一个 my.exe可执行文件、libc.so动态库,在可执行程序中有一个 printf函数,函数在可执行文件中具有对应的地址,完成动态库加载之后,它会将 printf的地址写进可执行程序中。当程序需要的时候,可以通过地址找到对应的方法。

在动态库的生成中,我们讲解了一个名词: fPIC:产生位置无关码(position independent code)。它具体的含义是什么呢?与位置无关:用特定的参照系来定位某个人或物体所处位置的相对定位的方式

也就是说,我们是用这个方法实现动态库的连接和加载的。动态库加载会将函数的地址写入到可执行程序中,这个地址是偏移地址(记录了函数在 .so中的偏移量)。

总结:静态库拷贝,依据确定起始点进行拷贝,方法的位置确定,这种编址方式称为绝对编址;动态库加载会将函数的偏移地址写入到可执行程序中,根据不同的起始地址查找方法,这种编址方式为相对编址

(2)动态库加载和访问的逻辑(重点)

动态库加载和访问的逻辑(详解):

还是以 printf函数为例,当我们的计算机需要调用代码的 printf函数,通过页表读取之后,发现 printf的实现代码在可执行程序中并不存在,这是编译时就标识好的,同时还会发现代码区中的这个地址是一个外部地址。

此时操作系统就知道要访问这个库了,接下来操作系统不会继续执行 printf的代码,它会先将磁盘中的动态库加载到内存

再将内存中库的内容通过页表映射到虚拟地址空间的共享区中,映射完成后库天然就拥有了起始地址。不同的程序可能会加载不同的动态库,因此在动态库没有完成加载映射之前,它的起始地址是不确定的。

在虚拟地址空间的代码区中,因为我们的代码存有库方法的偏移地址,所以在库完成动态加载映射之后,当我们想调用 printf函数(跳转动态库的执行方法),我们就可以在确定了库的起始地址的前提下,根据代码中保存的偏移地址直接跳转到共享区的库方法之中

至此,我们就可以在有需要调用库函数的时候,直接在上下文中跳转。最终实现动态库加载和访问。

在这里插入图片描述

总结:调用库方法前需要对动态库进行加载映射,使动态库具有起始地址,然后代码区中的代码就可以通过偏移量在上下文中进行跳转,最终找到共享区的库方法

补充:动态库加载时,操作系统会根据一定的策略加载库方法,而不会将所有方法一次性加载

补充:操作系统会在有需要的时候对库进行加载链接,当100个进程都用了同一个库,内存中这个库的代码也就只有一份。因此我们可以通过使用动态链接的方式,实现节省内存的目的


结语

🌹🌹 基础IO - 动静态库 的知识大概就讲到这里啦,博主后续会继续更新更多C++ 和 Linux 的相关知识,干货满满,如果觉得博主写的还不错的话,希望各位小伙伴不要吝啬手中的三连哦!你们的支持是博主坚持创作的动力!💪💪

相关文章:

【Linux初阶】基础IO - 动静态库 | 初识、生成、链接、加载

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【Linux初阶】 ✒️✒️本篇内容&#xff1a;动静态库初识&#xff0c;库的含义&#xff0c;静态库的生成与链接&#xff0c;gcc/g默认链接方式&#xff0c…...

为Git仓库设置签名信息

前言 在首次使用git版本库或创建新的仓库时&#xff0c;需要为其仓库设定管理员和管理员邮箱。 在为仓库添加管理员和邮箱地址时&#xff0c;有以下两种情况&#xff1a; &#xff08;1&#xff09;全局模式&#xff1a;首次创建&#xff0c;后面做为默认使用&#xff0c;对当…...

iOS开发Swift开发UI页面链式调用库推荐

首页链接 https://github.com/zhiguangqiao/ChainableUIKit 安装方法 pod ChainableUIKit调用片段 UIButton import ChainableUIKitprivate let button UIButton().chain.setTitleColor(.init(hex: "#9583EB"), state: .normal).setTitle("全部视频",…...

ClickHouse SQL与引擎--基本使用(一)

1.查看所有的数据库 show databases; 2.创建库 CREATE DATABASE zabbix ENGINE Ordinary; ATTACH DATABASE ck_test ENGINE Ordinary;3.创建本地表 CREATE TABLE IF NOT EXISTS test01(id UInt64,name String,time UInt64,age UInt8,flag UInt8 ) ENGINE MergeTree PARTI…...

2023-08-07力扣今日七题-好题

链接&#xff1a; 剑指 Offer 11. 旋转数组的最小数字 154. 寻找旋转排序数组中的最小值 II 题意&#xff1a; 找一个数组里的最小值&#xff0c;这个数组是有非递减数组旋转而来的&#xff0c;旋转n次表示把前n个数移动到数组末尾 解&#xff1a; 很有趣的二分&#xff…...

支持多用户协同的思维导图TeamMapper

什么是 TeamMapper &#xff1f; TeamMapper 是基于 Mindmapp 开发的用于绘制思维导图的 Web 应用程序。它使得思维导图变得简单&#xff0c;你可以托管并创建您自己的思维导图。与您的团队分享您的思维导图会议并在思维导图上进行协作。 软件特点&#xff1a; 创建&#xff1…...

【Vue】Parsing error: No Babel config file detected for ... vue

报错 Parsing error: No Babel config file detected for E:\Study\Vue网站\实现防篡改的水印\demo02\src\App.vue. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files.             …...

2023-08-07力扣今日五题

链接&#xff1a; 剑指 Offer 53 - II. 0&#xff5e;n-1中缺失的数字 题意&#xff1a; 如题 解&#xff1a; 长度n的递增数组里&#xff0c;要找0到n中没出现的那个数字&#xff0c;那么出现的下标是0到n-1&#xff0c;一一对应即可&#xff0c;都出现了就是n没有 实际…...

ETHERCAT转PROFIBUS连接到300plc的配置方法

由于捷米JM-DP-ECT&#xff0c;是自主研发的一款PROFIBUS从站功能的通讯网关&#xff0c;它的主要功能是将ETHERCAT设备接入到PROFIBUS网络中生产环境比较复杂有多个设备采用不同的协议这极大的阻碍了&#xff0c;各个设备的数据互通。 JM-DP-ECT这个小小的网关可不简单&#x…...

Spring Boot配置文件与日志文件

1. Spring Boot 配置文件 我们知道, 当我们创建一个Spring Boot项目之后, 就已经有了配置文件存在于目录结构中. 1. 配置文件作用 整个项目中所有重要的数据都是在配置文件中配置的&#xff0c;比如: 数据库的连接信息 (包含用户名和密码的设置) ;项目的启动端口;第三方系统的调…...

可解释性分析的一些类别(草稿)(视觉)

目录 1.交互性解释 2. 本身具有解释性的模型 3.如何将可解释性分析应用到生成模型 参考文献 视觉领域从2020年开始可以分为两块&#xff0c;一个是图像分类&#xff0c;一个是图像生成。 图像分类&#xff1a;输入一张图片&#xff0c;输出语义标签&#xff0c;就是这张图…...

HTTPS-RSA握手

RSA握手过程 HTTPS采用了公钥加密和对称加密结合的方式进行数据加密和解密 RSA握手是HTTPS连接建立过程中的一个关键步骤&#xff0c;用于确保通信双方的身份验证和生成对称加密所需的密钥 通过RSA握手过程&#xff0c;客户端和服务器可以协商出一个共享的对称密钥&#xff0c;…...

bigemap国土管理行业应用

由于国营企业单位&#xff0c;管理土地&#xff0c;必须要有这样的软件套图 客户之前用的谷歌&#xff0c;后来不能访问了&#xff0c;通过其他途径搜索到我们 客户使用软件一般都用于套坐标以及空间规划图&#xff0c;方便于项目选址和居民建房报建在卫星图上找到用地范围&am…...

深入探索 Splashtop Enterprise 的潜力

在当今高度技术化的环境中&#xff0c;远程访问解决方案已成为无数组织的支柱。远程访问解决方案缩短了员工与工作之间的地理差距&#xff0c;提高了工作的效率和灵活性&#xff0c;促进形成了无缝的工作体验。在众多远程访问解决方案中&#xff0c;Splashtop Enterprise 作为远…...

创建型模式-单例模式

文章目录 一、创建型模式1. 单例设计模式1.1 单例模式的结构1.2 单例模式的实现&#xff08;1&#xff09;饿汉式-方式1&#xff08;静态变量方式&#xff09;&#xff08;2&#xff09;饿汉式-方式2&#xff08;静态代码块方式&#xff09;&#xff08;3&#xff09;懒汉式-方…...

2. Linux安装Git

yum安装 查看版本 版本太低&#xff0c;所以我们采用自己上传编译的方式进行 删除已安装的git yum remove git 下载最新安装包&#xff0c;并上传到服务器文件夹下 上传&#xff0c;解压 5.安装编译需要的依赖 yum install curl-devel expat-devel gettext-devel openssl-…...

检查网站是HTTP那种协议与获取域名的ipv6地址

前言 最近在做HTTPS的应用&#xff0c;可能需要使用ipv6的地址做SLB&#xff0c;但是怎么检查配置正确&#xff0c;总不能每次都看日志吧&#xff0c;实际上客户端也很容易查看&#xff0c;总结工作经验。 检查HTTP协议版本 笔者想到了使用浏览器方式&#xff0c;或者抓包&a…...

【转】金融行业JR/T0197-2020《金融数据安全 数据安全分级指南》解读

原文链接&#xff1a;金融行业JR/T0197-2020《金融数据安全 数据安全分级指南》解读 《金融数据安全 数据安全分级指南》 解 读 随着IT技术的发展&#xff0c;银行的基础业务、核心流程等众多事务和活动都运营在信息化基础之上&#xff0c;金融机构运行过程中产生了大量的数字…...

FPGA学习——电子时钟模拟(新)

文章目录 一、数码管简介二、C4开发板数码管原理图三、代码实现四、实现效果五、总结 博主在之前曾经编写过一篇电子时钟的博客&#xff08;详情请见此篇博文&#xff09;&#xff0c;但曾经编写的电子时钟&#xff0c;未显示小数点位&#xff0c;同时当时的数码管模块是为了电…...

一文读懂快速开发平台

一、开发平台是什么&#xff1f; 开发平台是指以一或多种编程语言为基础而开发的一种软件&#xff0c;通常其不作为最终的软件产品&#xff0c;它是一类可二次开发的软件框架&#xff0c;开发者能利用其高效地开发各类软件产品。 在利用开发平台进行开发工作时&#xff0c;可摒…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...