《WebKit 技术内幕》之六(1): CSS解释器和样式布局

《WebKit 技术内幕》之六(1):CSS解释器和样式布局

        CSS解释器和规则匹配处于DOM树建立之后,RenderObject树之前,CSS解释器解释后的结果会保存起来,然后RenderObject树基于该结果来进行规范匹配和布局计算。当网页有用户交互或者动画等动作的时候,通过CSSOM等技术,JavaScript代码同样可以非常方便地修改CSS代码,WebKit此时需要重新解释样式并重复以上这个过程。

1 CSS基本功能

1.1 简介

        先谈一谈HTML网页的开发者们所遭遇的痛苦和悲惨的经历。在CSS出现之前或者更早,HTML网页设计者们因为要设计不同风格和样式的元素,所以规范不停地加入很多新的元素来表示网页布局,例如p、span等元素。然而,问题依然存在,例如,使用表格(Table)元素来排列网页中的元素,这可能存在一些问题:其一,表格经常内嵌表格,导致网页内容较大,占用带宽;其二,被搜索引擎解析后,网页内容将会变得杂乱无章。所以这时候急需一种技术来解决这些问题。庆幸的是,此时CSS出现了。

        CSS的全称是Cascading Style Sheet,中文名是级联样式表,主要是用来控制网页的显示风格。它被广泛地使用在网页中,绝大多数的现代浏览器都支持它。CSS的一个比较重要的特征就是将网页的内容和内容的展示方式分离,这对开发者提高开发效率非常有用。另一个重要的特征是它很强大,而且不是一般的强大,特别是新的CSS3标准,不仅能提供对页面任意元素的精准控制,同时还能提供丰富多彩的样式。简而言之,CSS是一种非常出色的文本展示语言。

        Web开发者有两种方法可以使用CSS,第一种就是示例代码中将CSS的代码放入元素“style”中,这称为内部样式表;第二种就是形如代码<link rel="stylesheet"type="text/css"href="css-url.css">这样的用法,引用了一个外部的CSS文档,这称为外部样式表。

示例代码  6-1 使用CSS的HTML网页

        为了便于读者对CSS有个直观的印象,示例代码6-1展示了一个使用CSS的简单例子,后面很多描述都是基于它来展开的。不过,该例子虽然简单,但却是一个展示了CSS众多特征的例子,CSS的主要部分包含在元素“Style”中,也就是例子中的第3行到第16行。同时,JavaScript代码部分也有对样式的操作,如第29行,后面的部分会对它们逐一加以解释。

        样式的来源有三种类型,其一是网页开发者编写的样式信息,它被包含在网页或者外部样式文件中,这也是最常见的方式;其二是网页的读者设置的样式信息,读者可以设置一个样式,这个样式可以应用到其浏览的网页;其三是浏览器的内在默认样式。以上三种类型的优先级自然是递减的。

        CSS语言主要定义了一系列作用在各个元素上的样式规则,如示例代码6-1中的第4到17行就是一个规则,该规则表示div所应用的部分样式设置。CSS3标准中还有很多新的功能,示例代码6-1中也描述了其中的一些功能,那就是3D变形(Transform)。这些样式给网页设计带来了非常震撼的视觉效果,读者可以尝试在浏览器中运行上面的网页。这些新功能笔者将在高级篇中的第8章来介绍。

  • 选择器: 上面介绍的属性选择器就是CSS3新加入的,除此之外,还加入了控制精确的选择器用来选择特定位置的子女、特定元素标签的子女等。
  • 样式: CSS3增加了一些比较实用的功能,例如自定义字体、圆角属性、边框颜色等。
  • 变形、变换和动画(transform、transition和animation): CSS3提供了令人惊奇的变形、变换和动画功能,令其更加赏心悦目。规范的草案中仅定义了2D的变换,而WebKit却可以提供3D的变形。变形有四种类型,包括平移、旋转、缩放和扭曲。同2D变形不同的是,3D变形增加了绕Z轴的平移、旋转和缩放。有一点颇令人遗憾,那就是各个不同的浏览器对这些属性的名字定义不一致,例如标准的变换的定义属性名是“transform”,而Webkit的则是“-webkit-transform”,如例子中第15行所示。IE支持的是“-ms-transform”,Firefox支持的是“-moz-transform”,Opera支持的是“-o-transform”,这些不免令人心烦意乱。变换描述了属性从一个值过渡到另一个值的过程,定义了过程的时间、启动过程的延迟时间等。但是,这些规范草案中的定义还不足以描述更精确的变化过程,所以规范引入了更为灵活的方式,这就是CSS动画。Web开发者使用CSS动画能够定义不同的“keyframes”来控制动画中间的变化过程而不仅仅是动画的开始和结束。读者可以这么理解——变换是一种较为简单和常见的动画。

        CSS2引入了一个概念,可以设置跟“media”相关的样式信息,例如用于屏幕显示、打印等。这样,网页可以为了达到不同的目的来设置CSS样式信息,其格式形如“@media screen{div{color:read}}”,它表明该CSS设置的属性仅仅作用于屏幕的显示。

1.2 样式规则

        样式规则是CSS规范中最基本的组成,通常,CSS文档包含一系列的样式规则,如上所述,示例代码6-1中的第4行到第17行就是一个完整的样式规则。

       下图描述了一个典型的CSS规则结构。一个规则包括两个部分——规则头和规则体。规则头由一个或者多个选择器组成,选择器随后会被介绍;规则体则由一个或者多个样式声明组成,每个样式声明由样式名和样式值构成,表示这个规则对哪些样式进行了规定和设置。

                         CSS的样式规则表示

        当HTML中的某个元素经过后面的匹配算法使用了这条规则,那么就将这些样式设置成该元素的样式,除非有更高优先级的规则匹配上该元素。

1.3 选择器

        CSS的选择器是一组模式,用来匹配相应的HTML元素。当选择器匹配相应元素的时候,该选择器包含的各种样式值就会作用于匹配的元素上。通过选择器,CSS能够精准地控制HTML页面中的任意一个或者多个元素的样式属性。查看示例代码6-1中的第4行,该行中的“div”就是一个选择器,这是元素选择器类型,其含义是选择该页面中的所有“div”元素。因为仅有第20行包含一个“div”元素,所以,该元素会使用该选择器的属性设置。那么,“div”元素下面所设置的样式等属性(花括号内)都会作用于该元素,从第6行到第16行。

        示例代码中的选择器仅是众多选择器类型中的一种,从CSS1到CSS3,规范陆续地加入了多达42种选择器,极大地增强了选择的能力,下面介绍其中一些主要的选择器。

  • 标签选择器: 根据标签元素的名称来匹配,例如示例代码6-1中的选择器。它可以选择一个或者多个元素。
  • 类型选择器: 根据类型信息来选择目标元素,类型选择器可以选择一个或者多个元素,示例代码中选择div元素也可以使用类型选择器,方法是“.aclass”。
  • lD选择器: 根据元素的ID来选择目标元素,一个选择器仅能选择一个元素,这是因为ID的唯一性。示例代码中选择div元素也可以使用ID选择器,方法是“#adiv”。
  • 属性选择器: 根据属性来选择目标元素,可以选择一个或者多个,示例代码中选择div元素也可以使用属性选择器,方法是“div[id]”、“div[id=’adiv’]”、“div[id~=’di’]”、“div[id|=’ad’]”。
  • 后代选择器: 选择某元素包含的后代元素,可以选择一个或者多个,示例代码中选择div元素也可以使用后代选择器,方法是“body div”。
  • 子女选择器: 选择某元素包含的子女元素,可以选择一个或者多个,示例代码中选择div元素也可以使用子女选择器,方法是“body>div”。
  • 相邻同胞选择器: 根据相邻同胞信息来确定选择的元素,可以选择一个或者多个,示例代码中选择div元素也可以使用相邻同胞选择器,方法是“p+div”。

        还有很多其他类型的选择器,例如伪类选择器、通用选择器、群组选择器、根选择器等,这里不再一一介绍,请查阅CSS规范。

        介绍完选择器之后,还有个非常重要的问题,那就是优先级。对于某个元素的一个属性,因为多个选择器可能都作用于该元素,并且它们可能对该属性设置了不同的属性值,这种情况下,应该怎么确定使用哪种选择器呢?

        一般而言,选择器描述得越具体,它的优先级越高,也就是说选择器指向的越准确,它的优先级就越高。例如,如果用1表示标签选择器的优先级,那么类选择器优先级是10,ID选择器就是100,数值越大表示优先级越高。所以,尽量使用控制精确的选择器,使用优先级合理的选择器。假如对于元素的某一样式属性,两个匹配上的选择器都设置了该属性值,那么在此情况下,优先级高的选择器所设置的属性值将会应用到该元素上。

        标准中还引入了两个新的JavaScript接口:QuerySelector和QuerySelectorAll。这两个接口让CSS定义的所有选择器都可以作为参数传给这两个接口,从而获取到相应的HTML页面中的DOM节点。Chrome、Safari和Firefox等浏览器都支持该接口。

1.4 框模型

        框模型(Box model,或称箱子模型)是CSS标准中引入来表示HTML标签元素的布局结构。一个框模型大致包括了四个部分,它们从外到内分别是外边距(Margin)、边框(Border)、内边距(Padding)和内容(Content)。图描述的就是一个标准的框模型结构。在HTML网页中,每个可视元素(之所以强调可视是因为很多HTML元素其实不是用来显示的,例如用来表示语义的元素)的布局都是按照框模型来设计的。网页通过对元素设置这些样式属性,就可以达到特定的布局效果。

        框模型中的最边缘部分分别是四个方向上的外边距(TM、RM、BM、LM),可以为这四个外边距设置不同的大小,图中特意将这些方向上的外边距绘制得不一样,也是表明了这个含义。图中外边距往内是四个方向上的边框(左边框、右边框、上边框、下边框),再次是四个方向上的内边距(同边框类似),最后是该元素显示自己的内容所使用的区域。

                                                          CSS标准的框模型结构

        示例代码也包含了框模型的使用方法,但是不足以完全展示这一模型。所以笔者将它略作修改,变成示例代码所示的代码。笔者希望通过专门的框模型示例和显示结果来帮助读者更直观清晰地理解该模型。

示例代码     框模型的HTML网页代码片段

CSS代码:

    #adiv/*ID选择器*/
    {
      width:300px;/*宽度*/
      background-color:#efefef;/*背景色*/
      border:2px solid black;/*边框*/
    }
    .aclass/*类选择器*/
    {
      border:5px solid red;/*边框*/
      margin:150px 100px 10px 40px;/*外边距*/
      padding:15px 20px 25px 30px;/*内边距*/
      color:green;/*颜色*/
    }

HTML代码:

    <p> This is a test to demonstrate the mechanism of layout!</p>
    <div id="adiv">
      <div class="aclass">A B C D E F G H I J K L M N O P Q RS T</div>
    </div>

        图是示例代码在Chrome浏览器中的显示结果。ID为“#adiv”的div元素被设置了边框是为了让读者了解它的内容区域。图中最大的区域就是该div元素的内容区域,最外边的黑色边框就是它的边框。该元素的内部就是“.aclass”的类选择器所选择的div元素的包含块,笔者后面会介绍包含块的概念。包括块内部就是类型为“.aclass”的div元素的框模型显示结果,这也是笔者希望描述的框模型结构。为了便于读者对框模型的理解,在显示区域旁边的标注表明了框模型的各个属性值,可以同图的框模型进行对照,看看实际的效果是怎么样的。

                                        图示例代码的框模型显示结果

                框模型是布局计算的基础,渲染引擎可以根据模型来理解该如何排版元素以及元素之间的位置关系。

1.5 包含块(Containing Block)模型

        当WebKit计算元素的箱子的位置和大小时,WebKit需要计算该元素和另外一个矩形区域的相对位置,这个矩形区域称为该元素的包含块。上面介绍的框模型就是在包含块内计算和确定各个元素的,包含块的具体定义如下。

  • 根元素的包含块称为初始包含块,通常它的大小就是可视区域(Viewport)的大小。
  • 对于其他位置属性设置为“static”或者“relative”的元素,它的包含块就是最近祖先的箱子模型中的内容区域(Content)。
  • 如果元素的位置属性为“fixed”,那么该元素的包含块脱离HTML文档,固定在可视区域的某个特定位置。
  • 如果元素的位置属性为“absolute”,那么该元素的包含块由最近的含有属性“absolute”、“relative”或者“fixed”的祖先决定,具体规则如下:如果一个元素具有“inline”属性,那么元素的包含块是包含该祖先的第一个和最后一个inline框的内边距的区域;否则,包含块则是该祖先的内边距所包围的区域。

        结合实例来讲,类型为“aclass”的div元素的包含块就是其父亲的内容区域,其框模型就是在该内容区域上进行计算生成得来的。

1.6 CSS样式属性

        CSS标准中定义了各式各样的样式属性,用来描述元素的显示效果。示例代码6-1的第6行到第16行设置了选择的元素的样式属性值,笔者大致把这些属性分成以下类别。

  • 背景: 通常有两种方式来设置元素的背景,一种是设置背景颜色(例子中的background-color),另外一种是设置背景图片。
  • 文本: 设置文本缩进、对齐、单词间隔、字母间隔、字符转换、装饰和空白字符等。
  • 字体: 设置字体属性,可以是内嵌的,也可以是自定义字体的方式,另外还可以设置加粗、变形等属性。
  • 列表: 设置列表类型,可以以字母、希腊字母、数字等方式编号列表。
  • 表格: 通过设置边框来达到显示表格的视觉效果的目的。设置是否把表格边框合并为单一的边框,设置分隔单元格边框的距离,设置表格标题的位置,设置是否显示表格中的空单元格,设置显示单元、行和列的算法等。
  • 定位: CSS提供元素的相对、绝对定位和浮动定位。示例使用了绝对定位,参见示例代码中的第6到第8行。

1.7 CSSOM(CSS Object Model)

        想象一下上面两个示例代码中关于CSS部分的代码,读者会发现它们都是静态的,那么CSS有没有提供一些方法可以让开发者自定义一些脚本去操作它们的状态呢?这就是CSSOM,称为CSS对象模型。它的思想是在DOM中的一些节点接口中,加入获取和操作CSS属性或者接口的JavaScript接口,因而JavaScript可以动态操作CSS样式。DOM提供了接口让JavaScript修改HTML文档,同理,CSSOM提供了接口让JavaScript获得和修改CSS代码设置的样式信息,这听起来非常酷吧,确实是这样的。

        对于内部和外部样式表,CSSOM定义了样式表的接口,称为“CSSStyleSheet”,这是一个可以在JavaScript代码中访问的接口。借助于该接口,开发者可以在JavaScript中获取样式表的各种信息,例如CSS的“href”、样式表类型“type”、规则信息“cssRules”等,甚至可以获取样式表中的CSS规则列表。这个接口同DOM中的“Script”节点或者“Link”节点不一样,它是CSSOM定义的新接口。开发者可以通过document.stylesheets查看当前网页中包含的所有CSS样式表,这是因为CSSOM对DOM中的Document接口进行了扩展,下面是新加入的属性。

    partial interface Document{
      readonly attribute StyleSheetList styleSheets;
      attribute DOMString? selectedStyleSheetSet;
      readonly attribute DOMString? lastStyleSheetSet;
      readonly attribute DOMString? preferredStyleSheetSet;
      readonly attribute DOMString[] styleSheetSets;
      void enableStyleSheetsForSet(DOMString? name);
    };

        通过上面这些属性,开发者甚至可以动态选择使用哪些CSS样式表。获取的样式表就是前面定义的CSSStyleSheet对象,JavaScript代码可以修改这些对象的属性,非常便于使用。

        W3C还定义了另外一个规范,那就是CSSOM View,它的基本含义是增加一些新的属性到Window、Document、Element、HTMLElement和MouseEvent等接口,这些CSS的属性能够让JavaScript获取视图信息,用于表示跟视图相关的特征,例如窗口大小、网页滚动位移、元素的框位置、鼠标事件的坐标等信息。这些特征在很多浏览器中获得了支持,它们非常有用,下面以CSSOM View对Window的扩展为例,笔者省略了一些属性。

    partial interface Window{
            MediaQueryList matchMedia(DOMString media_query_list);
            readonly attribute Screen screen;
            //viewport
            readonly attribute long innerWidth;
            readonly attribute long innerHeight;
            //viewport scrolling
            readonly attribute long scrollX;
            readonly attribute long pageXOffset;
            readonly attribute long scrollY;
            readonly attribute long pageYOffset;
            …
    };

1.8 实践:理解CSSOM和选择器

        本节中,笔者希望通过例子来理解CSSOM标准定义的内容,结合选择器的匹配方法来加深对CSS技术的认识。

        图是一个代码示例图和在Chrome浏览器的控制台中的信息。下面按照步骤逐步分析这一例子。

图理解CSSOM和选择器的示例代码和控制台语句

  1. 同样是在Chrome浏览器中运行左边的网页,同时打开Chrome的开发者工具,切换到控制台这一功能。
  2. 读者会看到“Test CCSOM1”字符串的颜色是绿色的,而“Test CCSOM2”字符串的颜色是红色的。这是因为例子中第一个“div”元素只匹配到第二个样式表中的规则。而第二个“div”元素,虽然两个规则对它而言都可以匹配,但是类规则的优先级更高,因而它的结果是红色。
  3. 在控制台中输入JavaScript语句“document.styleSheets”,读者可以看到当前有两个CSSStyleSheet对象,单击查看它们的属性和属性值,跟前面的标准对比一下。
  4. 在控制台中输入JavaScript语句“document.styleSheets[0].disabled=true”,读者在浏览器中会发现“Test CCSOM2”变成绿色的了,这是因为将第一个样式表关闭了,所以它不再起作用了。
  5. 尝试在开发者工具的控制台中输入如下JavaScript代码“document. styleSheets[1].cssRules[0].style.color=‘gray’”,读者会看到所有字符都变成灰色的了,这是因为这条语句将第二个样式表中的第一个规则中的字体颜色设置成了灰色,浏览器即刻生效。

        还可以在控制台中尝试一下其他的JavaScript语句,或者在更复杂一些的网页里面理解规则,这里只是描述基本原理。

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

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

相关文章

NodeJs 第二十章 代理

在计算机网络中&#xff0c;代理是一种中间服务&#xff0c;能够代理用户与网络资源之间的通信。代理服务器可以缓存网页内容、过滤网络流量或隐藏用户的真实IP地址等功能。 在日常开发中&#xff0c;我们接触最多的是客户端发送ajax到服务端。但是服务端并不是 node &#xf…

搭建DNS 服务

安装DNS 服务 [rootlocalhost ~]# yum install bind -y Complete! [rootlocalhost ~]# DNS 配置文件 [rootlocalhost ~]# vim /etc/named.conf [rootlocalhost ~]# cat -n /etc/named.conf 1 // ... 12 options { 13 #listen-on port 53 { 127.0.0.1; }; 14 list…

【蓝桥杯冲冲冲】动态规划初步[USACO2006 OPEN] 县集市

蓝桥杯备赛 | 洛谷做题打卡day13 文章目录 蓝桥杯备赛 | 洛谷做题打卡day13题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示样例说明数据规模与约定 思路&#xff1a;方程&#xff1a; 题解代码我的一些话 [USACO2006 OPEN] 县集市 The County Fair 题目描述 每年…

说说你对归并排序的理解?如何实现?应用场景?

一、是什么 归并排序&#xff08;Merge Sort&#xff09;是建立归并操作上的一种有效&#xff0c;稳定的排序算法&#xff0c;该算法是采用分治法的一个非常典型的应用 将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff0c;即先使每个子序列有序&#xff0c;再使…

几个简单好用Python库,让你工作效率翻倍

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Python是一门强大的编程语言&#xff0c;不仅可以进行软件开发&#xff0c;还可以通过各种优秀的第三方库来提高工作效率。本文将介绍几个简单而好用的Python库&#xff0c;它们可以帮助你在各种领域提高工作效率…

02不吉利日期,noi练习题,小学生编程

02:不吉利日期 总时间限制: 1000ms 内存限制: 65536kB 描述 在国外&#xff0c;每月的13号和每周的星期5都是不吉利的。特别是当13号那天恰好是星期5时&#xff0c;更不吉利。已知某年的一月一日是星期w&#xff0c;并且这一年一定不是闰年&#xff0c;求出这一年所有13号…

设计模式—行为型模式之观察者模式

设计模式—行为型模式之观察者模式 观察者模式(Observer Pattern)&#xff1a;定义对象间的一种一对多依赖关系&#xff0c;使得每当一个对象状态发生改变时&#xff0c;其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅&#xff08;Publish/Subscribe&#…

Qt应用开发(安卓篇)——Hello Qt On Android

一、前言 这一篇从实际出发&#xff0c;讲述如何创建、编译和部署Qt On Android项目。 二、ADB调试 ADB的全称为Android Debug Bridge&#xff0c;就是起到调试桥的作用&#xff0c;主要用于连接计算机与Android 设备&#xff0c;以便进行调试和数据传输。ADB 可以实现以下主要…

如何使用CRM实现销售流程自动化?CRM如何提高销售效率?

科技在当今时代扮演着重要的角色。在商业领域&#xff0c;我们用很多不同的软件来完成业务、提高效率。销售被认为是一个企业的灵魂。没有销售&#xff0c;企业很难生存。为了使销售更加有效&#xff0c;自动化是每个企业都应该采用的一个重要战略。实现销售过程自动化最简单的…

【视频媒体】深入了解直播视频流

深入了解直播视频流&#x1f3a5; YouTube、TikTok live和Twitch上的直播视频是如何工作的&#xff1f; 直播视频流与常规流媒体不同&#xff0c;因为视频内容通过互联网近乎实时发送&#xff0c;通常只有几秒钟的延迟。 下图解释了实现这一目标背后所发生的事情。 步骤1&…

【QT+QGIS跨平台编译】之四:【libSSH2+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、libSSH2介绍二、文件下载三、文件分析四、pro文件五、编译实践 一、libSSH2介绍 libSSH2是一个开源的C函数库&#xff0c;用来实现SSH2协议。 SSH(Secure SHell)到目前为止有两个不兼容的版本——SSH1和SSH2。 SSH2避免了RSA的专利问题&#xff0c;并修补了CRC…

HR人才测评,招聘技术部经理的胜任力素质模型与任职资格

招聘技术部经理是企业招聘中的关键职位之一。为了确保招聘到胜任的人才&#xff0c;需要制定一个详细的胜任力素质模型和任职资格要求。下面将详细说明。 企业版团测 - 在线人才测评系统、人才测评工具、人才盘点、团队测评、心理测评、职业测评 - 在线工具网团测&#xff0c;…

Python爬虫--5

1、异步爬虫 异步爬虫的方式&#xff1a; &#xff08;1&#xff09;多线程&#xff0c;多进程&#xff08;不建议使用&#xff09; 好处&#xff1a;可以为相关阻塞的操作单独开启线程或者进程&#xff0c;阻塞操作就可以异步执行。 弊端&#xff1a;无法无限制的开启多线程…

3.php开发-个人博客项目输入输出类留言板访问IPUA头来源

目录 知识点 : 输入输出 配置环境时&#xff1a; 搜索框&#xff1a; 留言板&#xff1a; 留言板的显示&#xff08;html&#xff09;&#xff1a; php代码显示提交的留言&#xff1a; 写入数据库 对留言内容进行显示&#xff1a; php全局变量-$_SERVER 检测来源 墨…

1.11马原总复习PART2

社会一定发展阶段 &#xff0c;生产力&#xff0c;生产关系总和 一定经济基础之上的意识形态&#xff0c;制度、组织和设施 普遍联系的根本内容和变化发展的内在动力 唯物辩证法的实质和核心 贯穿其他规律的中心线索 提供了根本方法矛盾分析法 价值由社会必要劳动时间决定…

安装ddddocr中遇到的问题

1、需要先安装&#xff1a; pip3 install pyinstaller --no-use-pep517 pip install scikit-build pip install setuptools pip install pyinstaller pip install pillow 重要是的是保证一个python 环境&#xff0c;多个python环境会导致各种问题。并且保证python>3.8…

LTC2944库仑计(电量计)芯片应用笔记(Arduino,ESP32)

一、一些基础知识 1.蓄电池的容量单位 &#xff08;1&#xff09;毫安时mAH 蓄电池的容量一般会采用毫安时&#xff08;mAH&#xff09;为单位&#xff0c;比如2000mAH的蓄电池意思是该蓄电池理论上可以以2000mA的电流持续放电1小时&#xff0c;2000mA*1H2000mAH。当然这个是…

C++从小白到初级工程师【个人学习笔记】

目录 1.背景2.基础二维数组概念二维数组定义方式 二维数组数组名称概念例子 函数的分文件编写概念示例 指针指针的基本概念指针变量的定义和使用 空指针和野指针空指针实例野指针实例 const修饰指针概念const修饰指针 --- 常量指针 指针和数组作用示例 指针和函数作用示例 指针…

代码随想录 Leetcode150. 逆波兰表达式求值

题目&#xff1a; 代码(首刷看解析 2024年1月21日&#xff09;&#xff1a; class Solution { public:int evalRPN(vector<string>& tokens) {stack<long long> st; for (int i 0; i < tokens.size(); i) {if (tokens[i] "" || tokens[i] &qu…

雍禾医疗获“年度医疗大健康消费企业”奖项 雍禾植发品牌深入人心

不久前&#xff0c;在钛媒体2023 T-EDGE全球创新大会上&#xff0c;钛媒体重磅发布了2023 EDGE AWARDS全球创新评选榜单。希望一起透过这些推动行业变革的公司、个人和产品&#xff0c;全面展现2023的产业格局。 “植发第一股”雍禾医疗荣获“年度医疗大健康消费企业”奖项。雍…