为什么GIF文件是图像文件而不是视频文件?(GIF文件格式详解)

news2024/12/24 21:59:08

今天整理硬盘的时候想到一个问题:GIF 是放在静态图像文件里还是视频文件里?
因为放视频里吧,GIF 的分类是静态图像,而且由图像组成;放图像里吧,它又会动。

然后我就开始想:GIF 会动但为什么被归类在静态图像?

看了一下国内外的一些博客,得到的答案不能让我满足,就是感觉还差一点的感觉🤏;或者有些说到了一些点上,但是没有继续深入了。所以就自己做了点研究,写下本博客,希望能帮到和我一样有这个疑问的人。

本文按照“GIF 文件格式(技术原理)”->“GIF 的历史”->“结论”的顺序。一些关于技术的历史介绍也会放在“GIF 的历史”中。

GIF 文件格式(技术原理)

如果想深入解释这一点,需要先简单介绍一下 GIF 的文件格式,这样才能了解为什么历史上会出现 GIF 格式。如果你想深入了解 GIF 文件格式,这里有篇文章写的挺细致,也是本文的参考资料之一,如果你能阅读英文的话非常建议看看:《LZW and GIF explained----Steve Blackstock》。

GIF 文件由 5 大部分组成:GIF 签名,屏幕描述符,全局颜色映射,图像描述符,本地颜色映射,光栅数据和 GIF 终止符。
请添加图片描述

为了方便理解,这里直接举个例子来详细说明。
请添加图片描述

以上面这个 GIF 为例,使用任何十六进制查看器查看可以得到如下内容:

请添加图片描述

GIF 签名(标头)

在 UNIX 系统中,文件类型是由标头表明的,与后缀无关。GIF 文件的标头则是 GIF 签名,有 6 个字节,有两个版本:“GIF87a(47h 49h 46h 38h 37h 48h)”和“GIF89a(47h 49h 46h 38h 39h 48h)”。
屏幕描述符中说明了图像的尺寸和一些图像相关的信息,是上图中图像“尺寸”、“信息”、“背景颜色”、“表示结束”四个框框的 7 个字节:

  • 尺寸信息占 4 个字节,长宽各一半,也就是长和宽的最大值为65536(2^16)。这个 GIF 尺寸为 72x72,72 的十六进制为 48h,可以看到上图中正是“48”。这个需要注意两点:GIF 使用的是大端,也就是说,这里的长应该是0048h,后面的00要放到前面去;第二,文档写的是屏幕尺寸,这是图形系统和计算机历史的问题,所以这里不过多解释。如果感兴趣可以看看The 8-Bit Guy 的一系列关于早期计算机图形系统的介绍,相对来说没有那么枯燥。
  • 图像信息占 1 个字节,但是包含了很多信息,所以我们要将其写成二进制讲解。上图中f6写成二进制为“1111 0110”。
    • 第 1 位为全局颜色映射符号,表示后面是否有全局颜色映射,这里1表示有;
    • 第 2~4 位的值加一表示色深,这里是111,也就是 7,加一就是 8,也就是说色深为 8 位,最多 256 个颜色(也是最大值了),该值是给颜色映射使用的;
    • 第 5 位是为未来保留的位,必须为0
    • 第 6~8 位加一表示图像中每个像素的位数,这里为110,也就是 6,加一为 7,也就是说这张图单个像素大小为 7 位,最多 128 个颜色,该值与图像有关。
  • 背景颜色为00,也就是白色。
  • 最后的00表示结束。

全局颜色映射

上图中第一行最后到00000180行之前的区域就是全局颜色映射的部分了。全局颜色映射虽然可选,但是现代的 GIF 基本上都有,是用来表示每个像素的颜色的。

何为颜色映射

这里本来想省略对与颜色映射的解释,但是由于这个技术有点太古早了,很多人可能不了解就详细说说。
现在很多人都知道,屏幕上的颜色大多是以红绿蓝三个颜色组合而成的(印刷行业不同)在表达的时候是用红绿蓝三个颜色的值这种格式。但是为什么我们确定一个“RGB”值就可以确定一个颜色呢?你可能会说:是去色域中按照这个值提取的颜色,然后显示出来。
这样说很接近了。现在麻烦您将自己想象成一个上世纪八十年代的游戏开发者,你需要只用用 8 bits 就显示出比较细腻的颜色。你心里会想 8 bits 也就 256 个值,还要三个颜色一起用,不可能显示出比较细腻的颜色的。(现在最常见的 8 bit 屏幕单个像素为 24 bits,也就是 16777216 个颜色)
但是你注意到没有,我一直说的是多少个颜色,这个颜色不一定是均匀分布的哦。比如说上面那个 GIF 的画面中,主要颜色为黑、深蓝、红、白,组成非常简单,并不是由很复杂的颜色组成的。那么我们就可以将 8 bit 转换成 256 个值,每个值对应映射一个图中会用到的颜色,这样就可以显示出来比较细腻的画面了。红白机这些早期游戏机上的游戏很多都是通过这种技术,从而达到了超出规格的画面效果。
可以把这个颜色映射理解成调色板,系统或显示器支持的颜色空间理解成颜料盒,颜料可能有几十万个颜色,但是调色板只能放几十个颜色。 比如说在24 位的 RGB 颜色空间中创建单像素大小为 8 位的 GIF 时,就是从 16777216 个颜料中取出 256 个颜色(局部颜色映射就是给每个图像一个调色板)。

那么继续介绍全局颜色映射。颜色映射一般情况下是按照“纯黑到纯白”的顺序排列的。也可以按照出现频率排列或者其他因素排列(详情请跳转到“图像描述符”部分)。
比如说上图中的03h 03h 03h,这个颜色是小人的发绳颜色最深处的颜色:
请添加图片描述
17h 17h 17h是第二深的颜色:
请添加图片描述

如何计算全局颜色映射区域的大小

需要注意的是:GIF 文件的全局颜色映射区域不是固定大小的,不同文件可能是不一样的。大小通过下面这个式子计算:

(1 <<((图像信息那个字节的值 & 0x07) + 1)) * 3

例如上面的f6就是:

(1 <<((0xf6 & 0x07) + 1)) * 3

0xf6 & 0x07 = 1111 0110b
			& 0000 0111b
			————————————
			  0000 0110b = 6
			  
1 <<((0xf6 & 0x07) + 1)) = 1 << 7 = 1000 0000b = 128

(1 <<((0xf6 & 0x07) + 1)) * 3 = 128*3=384

所以上面的全局颜色映射的数据块大小为 384 个字节。

扩展块

在这个地方,可能还会有一个或多个扩展块,以21h开头,00h结尾。可以用来说明动画间隔和背景透明度等很多相关信息。
扩展块的大小是固定的,不过 87a 和 89a 的不一样大。如果是 87a,那么这部分是图形控制扩展块(8 字节)。
如果是 89a,那么会有图形控制扩展块(8 字节)、纯文本扩展块(15 字节)、应用程序扩展块(14 字节)、注释扩展块(5~256 字节) 这 4 个扩展块,每个扩展块都以21h开头,区分在于第二个字节:

  • 如果是f9h,那么将数据块标识为图形控制扩展块;
  • 如果是01h,那么将数据块标识为纯文本扩展块;
  • 如果是ffh,那么将数据块标识为应用程序扩展块;

还是以上面的图为例,截取扩展块的部分:
请添加图片描述
两条红线之间的字节便是扩展块的部分。

首先21h ffh说明为应用程序扩展块。
0bh为应用程序标识符和 Authent Code 字段中的字节数(这个值是固定的,必须是0b)。AuthentCode 字段包含一个值,该值用于标识创建应用程序扩展块的软件应用程序。如果识别此标识符值成功,则读取数据块的剩余部分,并对其数据进行操作。如果无法识别标识符值,则读取数据块的剩余部分并丢弃其数据。
接下来的4e 45 54 53 43 41 50 45(十六进制)就是应用程序标识符,根据 ASCII 可以得到“NETSCAPE”。32 2e 30(十六进制)则为 Authent Code,根据 ASCII 可以得到“2.0”。这后面则是取决于应用程序和开发者。最后00h结束块。

Netscape 是第一个允许用户与图像交互的浏览器,比如说创新性地可以点击图像跳转页面。

然后21h f9h表示为图形控制扩展块。
接下来的04h是固定的值,为 Packed、DelayTime 和ColorIndex 字段的字节数总和,也就是一共 4 个字节。(如果是 GIF87a 则只有一个21h
Packed 字段有 4 个部分,上图中为04h,二进制为0000 0100

  • 第 1 位用来表示 ColorIndex 字段中颜色透明度字段是否有值,这里为0说明没有值。
  • 第 2 位是用户输入标志,如果进入下一个图像序列之前需要用户输入(按下某键或者点击鼠标),那么此处为1,否则为0。这里为0说明不需要用户操作即可进入下一图像。
  • 第 3~5 位表示图像显示后如何处理,(这里的数字为二进制)
    • 000(未指定处置方法)
    • 001(不处理图形),图中是001,所以就没有任何操作。
    • 010(用背景颜色覆盖图形)
    • 011(用以前的图形覆盖图形)
  • 第 6~8 位是保留的,不过 GIF89a 中不实用此子字段,所以始终为0

可以看到图形控制扩展块的内容可以让 GIF 变得可以像 PPT 一样。

接下来的 1 个字节便是 DelayTime 字段,内容为0ah,表示等待 0.1 秒再播放下一图像。0.1 秒也就是 1/10 秒,也就是可以理解成每秒显示 10 帧。
下面 2 个字节是颜色透明度,这里是00h,而且前面 Packed 字段中第一位是0。也就是说没有这个字段略过,也就是没有调整颜色透明度。
紧接着的ffh这个字节应该是00h,这里应该是软件自己的特色。
最后00h表示扩展块结束。

图像

然后便是 GIF 中每一张图像的内容了。GIF 中的图像数据使用 LZW(Lempel-Ziv-Welch)算法进行压缩,由2ch(ASCII 对应,)开始,并且由三部分以下组成:

  • 图像描述符;
  • 局部颜色映射(这个当然也是可选的了);
  • 光栅数据。

图像描述符(Local Image Descriptor)

图像描述符又被称为图像标题,以2ch开始,07h结束,也就是下图这部分:
请添加图片描述

这部分内容包含了图像描述符的分隔符2ch(一个字节),图像的坐标 X 和 Y(各两个字节)、图像的长和宽(各两个字节)、图像和颜色映射数据的信息(一个字节),以及终止符07h(一个字节)。
由上图可知,图像的坐标 X 和 Y 都为 00h 00h。图像尺寸和前文一样,长宽都是 72x72 像素。
图像和颜色映射数据的信息有 4 个子字段,这里的00h二进制为0000 0000,那么:

  • 第 1 位为局部颜色映射标志,如果此位为1,则图像有个局部颜色映射,使用局部颜色映射;如果为0,那么使用全局颜色映射。图中这里为0,说明使用全局颜色映射。
  • 第 2 位为隔行生成标志,如果此处为1,那么图像是隔行生成的,0反之。图中这里为0,说明不是隔行生成。
  • 第 3 位是分类标志,用于表示颜色映射是否按照出现频率排列(或者其他因素)。不过只适用于 GIF89a。如果是 GIF87a,这部分始终为0。图中这里为0,说明没有排序颜色映射。
  • 第 3~4 位是保留位,始终为0。
  • 第 5~8 位是局部颜色映射条目的数量,用来表示局部颜色映射条目的数量。这里为0,说明此图像没有局部颜色映射。

局部颜色映射

局部颜色映射和全局颜色映射是一样的。而且由上一节可知,这里没有局部颜色映射,所以没啥好说的了。

光栅数据

光栅数据(Raster data)就是图像数据(Image data)。
这部分数据由一块一块的数据构成。每一块由“块大小的计数字节”开始,值为 1~255(1h~ffh)。每一块的数据都使用 LZW(Lempel-Ziv-Welch)算法进行压缩。

还是以上面的例子说明一下,第一个图像的光栅数据是从1b3h的这个ff开始的,ff表示接下来的这块数据为 255 字节:
请添加图片描述

那么我们继续往下翻可以看到2b3h3b3h4b3h5b3h 都是ff,也就是往后挪 256 位:
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

但是6b3h这个位置上是c3
请添加图片描述

那么就往后挪 196(c3h + 1 = 195 + 1=196)位看看,也就是777h(6b0h + c3h + 1h)这个位置:
请添加图片描述

可以看到这个位置为00,这表示当前图像块的光栅数据结束了(因为这里需要理解成下面的这块数据块有 0 个,然后就没有然后了)。

然后往后继续读取,在下一行780h的位置可以看到2c,表示新的图像描述符开始了。就这样循环往复,直到结束。

但是需要注意的是,不是每个块都是 255+255+…+xxx 这样美好的格式,有的是乱的,只要每个值在

GIF文件结尾

如果你了解一些底层的知识,会知道文件和数据可以没有开始符,但是需要结尾符。例如 C(或者 Python 这种 C 延伸出来的语言)的字符串都是以\0表示字符串结尾的。因为这样作为数据流在 UNIX 系统中就知道在哪里结束。那么 GIF 文件的结尾是什么呢?
GIF 的终止符是;,十六进制为3b
请添加图片描述

可以看到终止符3bh前面有个00h,表示一个光栅数据的结尾。

GIF的静态图像长什么样

在 GIF 诞生的头几年,GIF 只有静态图像这一个用法。
下面这个图像是一个 GIF 文件(源自《Encyclopedia of Graphics File Formats, 2nd Edition》,是 2005 年的一本书),只有一个图像,分辨率为 1419 × 1001,你可以右键下载看看原图:
请添加图片描述

GIF 的历史

诞生

背景知识

GIF 诞生在互联网出现之前。在互联网出现之前,有很多计算机厂商,这些厂商不像今天的厂商,只负责组装或者生产一部分硬件,当时大部分计算机厂商是要负责开发计算机的系统,甚至包括软件,例如现在大名鼎鼎的苹果就是当时众多计算机厂商中的一员。
不同的硬件、不同的目的导致设计出来的系统和应用也不是互相兼容的,当时买电脑会送一本书,这本书会告诉你如何在这台电脑上编程。比如下面的 Apple II 的说明书:

请添加图片描述

目的

当时CompuServe 的老板 Sandy Trevor 需要程序员为他解决两个主要问题:
首先,CompuServe 为需要访问电子邮件和传输文件的用户提供订阅(按小时计算),这需要一种可以在所有计算机上无缝显示的简单图形格式。也就是说,这个文件必须要通用。
其次,可能有些用电脑比较早的人还会记得,很早之前用拨号上网的时候,由于网速很慢,浏览网页会出现图片一点点往下刷新,如果网络出问题了,等了半天的图片就没了,需要刷新页面重新下载。所以这个文件必须要小。
最后,由于当时电脑内存太小了,所以不能占用太多的内存的同时,还要保持画面质量。

为了解决这个问题 CompuServe 就开发了 GIF。GIF 可以做到将数据流按照一块块地传输到客户端,然后逐步显示图片。或者隔行生成图像,那么就可以将图像隔行传输数据给客户端,这样虽然画面有损耗,但是可以脑补一下。比如说下面这样的图片隔行显示,看到下图中左边和中间的图像都可以大致脑补出图片内容,而逐行显示如果一点点从上到下显示是没办法脑补的。

请添加图片描述

替代品

GIF 虽然是无损压缩的,但是单张图像的颜色最多只有 256 色。如果想实现颜色细腻的话可以使用拼接法,这样会导致文件过大,以及过于复杂。再者说就算费大劲解决了前面的问题(这个时候文件大小会非常恐怖),最高只能支持 24 位的 RGB 色彩空间也使得 GIF 的色彩是不会特别细腻的(现在的屏幕)。
其他方面,GIF 理论上最多可以显示约 43 亿像素的图片(这点可以看下面“GIF 文件格式”的内容),这点直到现在都不落伍。
但是 GIF 的尺寸和颜色一直是两大致命问题,所以就发明了 PNG 格式用来淘汰 GIF,甚至 PNG 的全称就是“PNG’s not GIF”,不过这是 1995 年之后的故事了,此时 GIF 已经诞生了快十年。
现在的我们可以看到,PNG 作为无损压缩图片很成功地在静态图像方面替代了 GIF,全方位优于 GIF(而且当时 GIF 由于使用 LZW 算法的原因是有专利限制的,而 PNG 是完全开源的)。但是 GIF 的动态图像却一直没有可替代者。
1999年的互联网上还有过一段全方位销毁 GIF 的活动,但是没有成功,现在也还有这样的行为,感兴趣可以看看https://burnallgifs.org/archives/。
没有成功是因为没有任何一个文件可以做到又容易实现、无声、又可以循环播放一个小动画。还有一个更重要的原因就是:GIF 是不需要任何解码器的就可以播放的。这样几乎所有的浏览器都可以播放 GIF 文件。
2001 年虽然围绕着 PNG 诞生了 MNG(Multiple-image Network Graphics)多图像文件,并且功能和画质远好于 GIF,但是还是没有战胜 GIF(个人猜测是因为过于复杂了,MNG 甚至可以加上音轨,这种程度不如直接使用 MP4 等视频格式)。

结论

GIF诞生之初是为了作为静态图片使用,就相当于今天的 PNG 和 JEPG。不过它的结构可以理解成一个简易版 PPT。pptx 文件是由 xml 和 图像文件组成的一个 tar 包,GIF 文件是由一些信息块、控制块和 LZW 压缩过后的光栅图像构成的,而且很巧合的是 Power Point 和 GIF 是同一年诞生的。但是可以通过控制显示 GIF 文件中每个光栅图像之间的间隔和动画,使得它可以呈现出动画/运动的效果(就像幻灯片可以做动画片,但是不能说幻灯片是视频一样)。

大胆的推测

由于时间太过久远,我有一个想法无法得到验证。就是那个时候是不是有一股技术热潮,内容就是如何在计算机上做出幻灯片;于此同时 GIF 的开发者既想展现图片,又想有一些特殊的功能(不过更大的可能是公司要求)。
因为 GIF 可以响应用户操作这个功能就可以达到幻灯片的效果,而至今为止最出名的幻灯片软件 Power Point 也是同年诞生的,发布在苹果的 Macintosh 上。如果只是为了解决图片显示的问题,那么没有必要给 GIF 添加一些没必要的功能。
这里要考虑到当时还没有互联网,计算机科学这个学科也才诞生 20 多年,各种技术和应用还不成熟,个人计算机才刚刚推广开来。一些现在看来自然存在的技术和应用,是在当时多方竞争下存活的,比如 GIF,再比如 Linux 内核。所以我觉得这真的挺奇妙的:GIF 可能是根据要求加了一些额外的功能,但是碰巧是这些功能,让其没有被淘汰掉。
话说是谁想到的 GIF 可以做动画呢?

希望本文能帮助到和我一样有疑惑的人哦~

参考资料

《LZW and GIF explained----Steve Blackstock》
《GIF File Format Summary》
《GIF Signature Format: Introduction & Recovery》
《THE HISTORY OF GIFS AND HOW TO USE THEM》

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分享113个图片切换JS特效,总有一款适合您

分享113个图片切换JS特效&#xff0c;总有一款适合您 113个图片切换JS特效下载链接&#xff1a;https://pan.baidu.com/s/1NNSP-DMf3n0PeNbdNd8jEg?pwdsfwr 提取码&#xff1a;sfwr Python采集代码下载链接&#xff1a;https://wwgn.lanzoul.com/iKGwb0kye3wj jQuery中间…

Java基础学习笔记(十九)—— 多线程

多线程1 多线程相关概念2 多线程的实现方式2.1 继承Thread类2.2 实现Runnable接口2.3 实现Callable接口3 线程休眠4 线程优先级5 守护线程6 线程同步6.1 案例引入6.2 同步代码块6.3 同步方法6.4 Lock锁6.5 死锁1 多线程相关概念 并行与并发&#xff1a; 并行&#xff1a;在同…

未授权和敏感文件泄露

目前存在未授权访问漏洞的服务主要 包括&#xff1a;NFS、Samba、LDAP、Rsync、FTP、GitLab、Jenkins、 MongoDB、Redis、ZooKeeper、ElasticSearch、Memcache、CouchDB、 Docker、Solr、Hadoop等。 redis未授权 通过手工进行未授权访问验证&#xff0c;在安装Redis服务的Kal…

MATLAB 线性整数规划

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

oracle官网下载指定版本的jdk

文章目录前言下载JDK环境变量前言 oracle官网下载jdk&#xff0c;如果是想下载指定版本的&#xff0c;总是提示需要你登录。如何解决呢&#xff1f; 下载JDK oracle官网 https://www.oracle.com 或者直达此页 https://www.oracle.com/java/technologies/downloads/archive…

springboot相关

2023.2.3 springboot的示例sagan涉及到很多软件技术&#xff0c;运行这个示例在Windows 7下遇到问题。将Windows 7重装为Windows 10专业版。下载了node-v18.14.0-x64.msi&#xff0c;安装node时可以选择安装相关的软件&#xff0c;例如python 3.11.0。下载python 3.11.0太慢了…

07、微服务组件Seata

1、事务简介 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在关系数据库中&#xff0c;一个事务由一组SQL语句组成。事务应该具有4个属性&#xff1a;原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。 原子性&#xff08;ato…

正则表达式记录

正则用途:分割 查找 匹配 替换 1 * ?的区别 *代表匹配任意次, 包括0,1,多次代表匹配最少一次, 1或者多次?代表匹配最多1次,0,1次 2 单次边界(\b和\B) 2.1 定义 首先说一下零宽: 只匹配位置, 不匹配字符, 然后我们再来谈单词边界: 何谓单词? 在JS中, 单词的定义就是\w也…

Python中的字典

1. 前言 字典&#xff0c;是Python中唯一实现了映射关系的内置类型。 2.映射关系 摩斯密码就是通过映射关系来实现的。 这里的字母 A 和 .- 就是其中的一对映射关系&#xff0c;字母 U 和 …- 又是另一对映射关系&#xff0c;那么有了这张表&#xff0c;破解莫斯密码就不再…

矩阵相关的性质

矩阵相关的计算性质1.矩阵的某一行*一个常数2.矩阵的一行加(减)另一行3.交换矩阵的两行两个未知数两个方程线程方程组解的结构以几何的角度查看矩阵的方式初等矩阵采用初等变换的方式在矩阵的元素中进行操作 相关的性能的变化采用点阵的乘法&#xff0c;在矩阵的维度进行处理将…

DeepLabV3+:ASPP加强特征提取网络的搭建

目录 ASPP结构介绍 ASPP在代码中的构建 参考资料 ASPP结构介绍 ASPP&#xff1a;Atrous Spatial Pyramid Pooling&#xff0c;空洞空间卷积池化金字塔。 简单理解就是个至尊版池化层&#xff0c;其目的与普通的池化层一致&#xff0c;尽可能地去提取特征。 利用主干特征提取…

低代码开发——创新赋能企业办公模式转变

近年来&#xff0c;国内云计算高速发展、SAAS 软件模式快速普及、企业数字 化的需求增长等方面促进了低代码平台开发与应用的高速发展&#xff0c;使之成为继 RPA之后企业数字化转型的明星工具。如果说RPA 将线上流程自动化&#xff0c;那么低代码解决了更基础的问题&#xff…

微信小程序 java Springboot大学生心理健康测试职位推荐系统

心理测试学生端要求在系统的安卓手机上可以运行&#xff0c;主要实现了线上考试测试等相关信息的查看&#xff0c;并且根据需求进行对管理端&#xff1b;首页、个人中心、学生管理、职业职位管理、职位申请管理、活动类型管理、活动项目管理、活动报名管理、试卷管理、试题管理…

Python算术运算符

Python算术运算符以下假设变量&#xff1a; a10&#xff0c;b20&#xff1a;运算符描述实例加 - 两个对象相加a b 输出结果 30-减 - 得到负数或是一个数减去另一个数a - b 输出结果 -10*乘 - 两个数相乘或是返回一个被重复若干次的字符串a * b 输出结果 200/除 - x除以yb / a …

C++内联函数:那时我还太年轻,并不知道使用inline带来的效率,早已在暗中标好了价格

&#x1f451;专栏内容&#xff1a;C学习笔记⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;日拱一卒&#xff0c;功不唐捐 文章目录一、前言二、内联函数1、起源2、概念三、与宏的区别1、宏的缺点2、两者区别四、内联函数的代价代价一&#xff1a;可执…

1.DjangoRestFramework【前后端分离项目搭建】

1.使用cmd创建项目 在你需要创建项目的文件夹中打开cmd,进入对应的Django的虚拟环境中输入下面语句: django-admin startproject drfproject然后使用pycharm打开项目 2.创建子apps 在tirminal中输入: python manage.py startapp user python manage.py startapp shop3.注册…

博途1200PLC/1500PLCMODBUS从站通信应用(MB_SLAVE指令)

博途PLC作为MODBUS主站通信请参看下面的文章链接: 博途PLC 1200/1500PLC MODBUS-RTU通讯优化(状态机编程)_博途plc modbus-rtu通信优化_RXXW_Dor的博客-CSDN博客博途PLC 1200/1500PLC MODBUS-RTU通讯_RXXW_Dor的博客-CSDN博客_博图modbus通讯1、1200PLC的modbus通讯,可以参看…

3.3 接口

文章目录1.接口的概念2.接口格式3.接口的特点3.1 练习-1:创建接口3.2 练习-2:创建接口实现类3.3 练习-3:创建接口测试类4.接口的用法5.接口的多继承多实现6.接口总结6.1 类与类的关系6.2 类与接口的关系6.3 接口与接口的关系6.4 抽象类与接口的区别1.接口的概念 与之前学习过的…

webpackEslint插件使用

webpackEslint插件使用 首先安装eslint-webpack-plugin npm i eslint-webpack-plugin -S 注意&#xff1a;如果未安装eslint>7,还需要先安装eslint npm i eslint -S 然后把插件添加到你的webpack配置&#xff0c;例如 const ESLintPluginreuqire(eslint-webpack-plugin) mo…

Android开发常谈—【热启动冷启动】

冷启动概述 app冷启动&#xff1a; 当应用启动时&#xff0c;后台没有该应用的进程&#xff0c;这时系统会重新创建一个新的进程分配给该应用&#xff0c; 这个启动方式就叫做冷启动&#xff08;后台不存在该应用进程&#xff09;。冷启动因为系统会重新创建一个新的进程分配给…