diff --git a/404.html b/404.html new file mode 100644 index 0000000..09f284d --- /dev/null +++ b/404.html @@ -0,0 +1,20 @@ + + + + + + Personal Blog --from Outis Li + + + + + + + + +

404

How did we get here?
+ Take me home. +
+ + + diff --git "a/Chip/Chip/1. \344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222.html" "b/Chip/Chip/1. \344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222.html" new file mode 100644 index 0000000..df05855 --- /dev/null +++ "b/Chip/Chip/1. \344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222.html" @@ -0,0 +1,170 @@ + + + + + + 1. 一生一芯计划 | Personal Blog --from Outis Li + + + + + + + + +

# 1. 一生一芯计划

# 预学习阶段

+ + + diff --git a/Chip/Chip/2. 2024.02.21-Chisel.html b/Chip/Chip/2. 2024.02.21-Chisel.html new file mode 100644 index 0000000..f7a8466 --- /dev/null +++ b/Chip/Chip/2. 2024.02.21-Chisel.html @@ -0,0 +1,174 @@ + + + + + + 2. 2024.02.21-Chisel | Personal Blog --from Outis Li + + + + + + + + +

# 2. 2024.02.21-Chisel

# 2024.02.21-Chisel Bootcamp

+ + + diff --git "a/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/01.Verilog \345\237\272\347\241\200\350\257\255\346\263\225.html" "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/01.Verilog \345\237\272\347\241\200\350\257\255\346\263\225.html" new file mode 100644 index 0000000..0235d99 --- /dev/null +++ "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/01.Verilog \345\237\272\347\241\200\350\257\255\346\263\225.html" @@ -0,0 +1,183 @@ + + + + + + 1. Verilog 基础语法 | Personal Blog --from Outis Li + + + + + + + + +

# 1. Verilog 基础语法

# 格式

Verilog 是区分大小写的。

格式自由,可以在一行内编写,也可跨多行编写。

每个语句必须以分号为结束符。空白符(换行、制表、空格)都没有实际的意义,在编译阶段可忽略。例如下面两中编程方式都是等效的。

# 不换行(不推荐)

wire [1:0]  results ;assign results = (a == 1'b0) ? 2'b01(b==1'b0) ? 2'b102'b11 ;
+

# 换行(推荐)

wire [1:0]  results ;
+assign      results = (a == 1'b0) ? 2'b01(b==1'b0) ? 2'b102'b11 ;
+

# 注释

Verilog 中有 2 种注释方式:

用  //  进行单行注释:

reg [3:0] counter ;  // A definition of counter register
+

/* */进行跨行注释:

wire [11:0]  addr ;
+/*
+Next are notes with multiple lines.
+Codes here cannot be compiled.
+*/
+assign   addr = 12'b0 ;
+

# 标识符与关键字

标识符(identifier)可以是任意一组字母、数字、$  符号和  _(下划线)符号的合,但标识符的第一个字符必须是字母或者下划线,不能以数字或者美元符开始。

另外,标识符是区分大小写的。

关键字是 Verilog 中预留的用于定义语言结构的特殊标识符。

Verilog 中关键字全部为小写。

# 实例

reg [3:0] counter ; *//reg 为关键字, counter 为标识符*
+input clk; *//input 为关键字,clk 为标识符*
+input CLK; *//CLK 与 clk是 2 个不同的标识符*
+
+ + + diff --git "a/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/02.Verilog \346\225\260\345\200\274\350\241\250\347\244\272.html" "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/02.Verilog \346\225\260\345\200\274\350\241\250\347\244\272.html" new file mode 100644 index 0000000..beeabb5 --- /dev/null +++ "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/02.Verilog \346\225\260\345\200\274\350\241\250\347\244\272.html" @@ -0,0 +1,193 @@ + + + + + + 2. Verilog 数值表示 | Personal Blog --from Outis Li + + + + + + + + +

# 2. Verilog 数值表示

# 数值种类

Verilog HDL 有下列四种基本的值来表示硬件电路中的电平逻辑:

  • 0:逻辑 0 或 "假"
  • 1:逻辑 1 或 "真"
  • x 或 X:未知
  • z 或 Z:高阻

x  意味着信号数值的不确定,即在实际电路里,信号可能为 1,也可能为 0。

z  意味着信号处于高阻状态,常见于信号(input, reg)没有驱动时的逻辑结果。例如一个 pad 的 input 呈现高阻状态时,其逻辑值和上下拉的状态有关系。上拉则逻辑值为 1,下拉则为 0 。

# 整数数值表示方法

数字声明时,合法的基数格式有 4 中,包括:十进制('d 或 'D),十六进制('h 或 'H),二进制('b 或 'B),八进制('o 或 'O)。数值可指明位宽,也可不指明位宽。

# 指明位宽:

4'b1011         *// 4bit 数值*
+32'h3022_c0de   *// 32bit 的数值    一个16进制的数需要4bit来表示*
+

其中,下划线  _  是为了增强代码的可读性。

# 不指明位宽:

一般直接写数字时,默认为十进制表示,例如下面的 3 种写法是等效的:

counter = 'd100; *//一般会根据编译器自动分频位宽,常见的为32bit*
+counter = 100;
+counter = 32'h64;
+

# 负数表示

通常在表示位宽的数字前面加一个减号来表示负数。例如:

-6'd15
+-15
+
  • 15 在 5 位二进制中的形式为 5'b10001, 在 6 位二进制中的形式为 6'b11_0001。

需要注意的是,减号放在基数和数字之间是非法的,例如下面的表示方法是错误的:

4'd-2 //非法说明
+

# 实数表示方法

实数表示方法主要有两种方式:

# 十进制:

30.123
+6.0
+3.0
+0.001
+

# 科学计数法:

1.2e4         //大小为12000
+1_0001e4      //大小为100010000
+1E-3          //大小为0.001
+

# 字符串表示方法

字符串是由双引号包起来的字符队列。字符串不能多行书写,即字符串中不能包含回车符。Verilog 将字符串当做一系列的单字节 ASCII 字符队列。例如,为存储字符串 "www.runoob.com", 需要 14*8bit 的存储单元。例如:

reg [0: 14*8-1]   str ;
+initial begin   
+			str = "www.runoob.com";
+end
+
+ + + diff --git "a/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/03.Verilog \346\225\260\346\215\256\347\261\273\345\236\213.html" "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/03.Verilog \346\225\260\346\215\256\347\261\273\345\236\213.html" new file mode 100644 index 0000000..5b668a0 --- /dev/null +++ "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/03.Verilog \346\225\260\346\215\256\347\261\273\345\236\213.html" @@ -0,0 +1,252 @@ + + + + + + 3. Verilog 数据类型 | Personal Blog --from Outis Li + + + + + + + + +

# 3. Verilog 数据类型

Verilog 最常用的 2 种数据类型就是线网(wire)与寄存器(reg),其余类型可以理解为这两种数据类型的扩展或辅助。

# 线网(wire)

wire 类型表示硬件单元之间的物理连线,由其连接的器件输出端连续驱动。如果没有驱动元件连接到 wire 型变量,缺省值一般为 "Z"。举例如下:

wire   interrupt;
+wire   flag1, flag2;
+wire   gnd = 1'b0;
+

线网型还有其他数据类型,包括 wand,wor,wri,triand,trior,trireg 等。这些数据类型用的频率不是很高,这里不做介绍。

# 寄存器(reg)

寄存器(reg)用来表示存储单元,它会保持数据原有的值,直到被改写。声明举例如下:

reg    clk_temp;
+reg    flag1, flag2;
+

例如在 always 块中,寄存器可能被综合成边沿触发器,在组合逻辑中可能被综合成 wire 型变量。寄存器不需要驱动源,也不一定需要时钟信号。在仿真时,寄存器的值可在任意时刻通过赋值操作进行改写。例如:

reg rstn ;
+initial begin   
+		rstn = 1'b0;
+    #100;
+    rstn = 1'b1;
+end
+

# 向量

当位宽大于 1 时,wire 或 reg 即可声明为向量的形式。例如:

reg [3:0]      counter ;    *//声明4bit位宽的寄存器counter*
+wire [32-1:0]  gpio_data;   *//声明32bit位宽的线型变量gpio_data*
+wire [8:2]     addr ;       *//声明7bit位宽的线型变量addr,位宽范围为8:2*
+reg [0:31]     data ;       *//声明32bit位宽的寄存器变量data, 最高有效位为0*
+

对于上面的向量,我们可以指定某一位或若干相邻位,作为其他逻辑使用。例如:

wire [9:0]     data_low = data[0:9] ;addr_temp[3:2] = addr[8:7] + 1'b1 ;
+

Verilog 支持可变的向量域选择,例如:

reg [31:0]     data1 ;
+reg [7:0]      byte1 [3:0];
+integer j ;
+always@* begin
+    for (j=0; j<=3;j=j+1) begin
+        byte1[j] = data1[(j+1)*8-1 : j*8];
+        *//把data1[7:0]…data1[31:24]依次赋值给byte1[0][7:0]…byte[3][7:0]*
+    end
+end
+

Verilog 还支持指定 bit 位后固定位宽的向量域选择访问。

  • [bit+: width] : 从起始 bit 位开始递增,位宽为 width。
  • [bit-: width] : 从起始 bit 位开始递减,位宽为 width。
*//下面 2 种赋值是等效的*
+A = data1[31-: 8] ;
+A = data1[31:24] ;
+*//下面 2 种赋值是等效的*
+B = data1[0+ : 8] ;
+B = data1[0:7] ;
+

对信号重新进行组合成新的向量时,需要借助大括号。例如:

wire [31:0]    temp1, temp2 ;
+assign temp1 = {byte1[0][7:0], data1[31:8]};  *//数据拼接*
+assign temp2 = {32{1'b0}};  *//赋值32位的数值0*
+

# 整数,实数,时间寄存器变量

整数,实数,时间等数据类型实际也属于寄存器类型。

# 整数(integer)

整数类型用关键字 integer 来声明。声明时不用指明位宽,位宽和编译器有关,一般为 32 bit。reg 型变量为无符号数,而 integer 型变量为有符号数。例如:

reg [31:0]      data1 ;
+reg [3:0]       byte1 [7:0]; *//数组变量,后续介绍*
+integer j ;  *//整型变量,用来辅助生成数字电路*
+always@* begin
+    for (j=0; j<=3;j=j+1) begin
+        byte1[j] = data1[(j+1)*8-1 : j*8];
+        *//把data1[7:0]…data1[31:24]依次赋值给byte1[0][7:0]…byte[3][7:0]*
+        end
+end
+

此例中,integer 信号 j 作为辅助信号,将 data1 的数据依次赋值给数组 byte1。综合后实际电路里并没有 j 这个信号,j 只是辅助生成相应的硬件电路。

# 实数(real)

实数用关键字 real 来声明,可用十进制或科学计数法来表示。实数声明不能带有范围,默认值为 0。如果将一个实数赋值给一个整数,则只有实数的整数部分会赋值给整数。例如:

real        data1 ;
+integer     temp ;
+initial begin
+    data1 = 2e3 ;
+    data1 = 3.75 ;
+end
+
+initial begin
+    temp = data1 ; *//temp 值的大小为3*
+end
+

# 时间(time)

Verilog 使用特殊的时间寄存器 time 型变量,对仿真时间进行保存。其宽度一般为 64 bit,通过调用系统函数 $time 获取当前仿真时间。例如:

time       current_time ;
+initial begin
+       #100 ;
+       current_time = $time ; *//current_time 的大小为 100*
+end
+

# 数组

在 Verilog 中允许声明 reg, wire, integer, time, real 及其向量类型的数组。

数组维数没有限制。线网数组也可以用于连接实例模块的端口。数组中的每个元素都可以作为一个标量或者向量,以同样的方式来使用,形如:数组名[下标]。对于多维数组来讲,用户需要说明其每一维的索引。例如:

integer          flag [7:0] ; *//8个整数组成的数组*
+reg  [3:0]       counter [3:0] ; *//由4个4bit计数器组成的数组*
+wire [7:0]       addr_bus [3:0] ; *//由4个8bit wire型变量组成的数组*
+wire             data_bit[7:0][5:0] ; *//声明1bit wire型变量的二维数组*
+reg [31:0]       data_4d[11:0][3:0][3:0][255:0] ; *//声明4维的32bit数据变量数组*
+

下面显示了对数组元素的赋值操作:

flag [1]   = 32'd0 ; *//将flag数组中第二个元素赋值为32bit的0值*
+counter[3] = 4'hF ;  *//将数组counter中第4个元素的值赋值为4bit 十六进制数F,等效于counter[3][3:0] = 4'hF,即可省略宽度;*
+assign addr_bus[0]        = 8'b0 ; *//将数组addr_bus中第一个元素的值赋值为0*
+assign data_bit[0][1]     = 1'b1;  *//将数组data_bit的第1行第2列的元素赋值为1,这里不能省略第二个访问标号,即 assign data_bit[0] = 1'b1; 是非法的。*
+data_4d[0][0][0][0][15:0] = 15'd3 ;  *//将数组data_4d中标号为[0][0][0][0]的寄存器单元的15~0bit赋值为3*
+

虽然数组与向量的访问方式在一定程度上类似,但不要将向量和数组混淆。向量是一个单独的元件,位宽为 n;数组由多个元件组成,其中每个元件的位宽为 n 或 1。它们在结构的定义上就有所区别。

# 存储器

存储器变量就是一种寄存器数组,可用来描述 RAM 或 ROM 的行为。例如:

reg               membit[0:255] ;  *//256bit的1bit存储器*
+reg  [7:0]        mem[0:1023] ;    *//1Kbyte存储器,位宽8bit*
+mem[511] = 8'b0 ;                  *//令第512个8bit的存储单元值为0*
+

# 参数

参数用来表示常量,用关键字 parameter 声明,只能赋值一次。例如:

parameter      data_width = 10'd32 ;
+parameter      i=1, j=2, k=3 ;
+parameter      mem_size = data_width * 10 ;
+

但是,通过实例化的方式,可以更改参数在模块中的值。此部分以后会介绍。

局部参数用 localparam 来声明,其作用和用法与 parameter 相同,区别在于它的值不能被改变。所以当参数只在本模块中调用时,可用 localparam 来说明。

# 字符串

字符串保存在 reg 类型的变量中,每个字符占用一个字节(8bit)。因此寄存器变量的宽度应该足够大,以保证不会溢出。

字符串不能多行书写,即字符串中不能包含回车符。如果寄存器变量的宽度大于字符串的大小,则使用 0 来填充左边的空余位;如果寄存器变量的宽度小于字符串大小,则会截去字符串左边多余的数据。例如,为存储字符串 "run.runoob.com", 需要 14*8bit 的存储单元:

reg [0: 14*8-1]       str ;
+initial begin
+    str = "run.runoob.com";
+end
+

有一些特殊字符在显示字符串中有特殊意义,例如换行符,制表符等。如果需要在字符串中显示这些特殊的字符,则需要在前面加前缀转义字符  \ 。例如下表所示:

转义字符 显示字符
\n 换行
\t 制表符
%% %
\ \
" "
\ooo 1 到 3 个 8 进制数字字符

其实,在 SystemVerilog(主要用于 Verilog 仿真的编程语言)语言中,已经可以直接用关键字 string 来表示字符串变量类型,这为 Verilog 的仿真带来了极大的便利。有兴趣的学者可以简单学习下 SystemVerilog。

+ + + diff --git "a/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/04.Verilog \350\241\250\350\276\276\345\274\217.html" "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/04.Verilog \350\241\250\350\276\276\345\274\217.html" new file mode 100644 index 0000000..f89d12a --- /dev/null +++ "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/04.Verilog \350\241\250\350\276\276\345\274\217.html" @@ -0,0 +1,282 @@ + + + + + + 4. Verilog 表达式 | Personal Blog --from Outis Li + + + + + + + + +

# 4. Verilog 表达式

# 表达式

表达式由操作符和操作数构成,其目的是根据操作符的意义得到一个计算结果。表达式可以在出现数值的任何地方使用。例如:

# 实例

a^b ;          *//a与b进行异或操作*
+address[9:0] + 10'b1 ;  *//地址累加*
+flag1 && flag2 ;  *//逻辑与操作*
+

# 操作数

操作数可以是任意的数据类型,只是某些特定的语法结构要求使用特定类型的操作数。

操作数可以为常数,整数,实数,线网,寄存器,时间,位选,域选,存储器及函数调用等。

# 实例

module test;
+*//实数*
+real a, b, c;
+c = a + b ;
+*//寄存器*
+reg  [3:0]       cprmu_1, cprmu_2 ;
+always @(posedge clk) begin
+        cprmu_2 = cprmu_1 ^ cprmu_2 ;
+end
+         
+*//函数*
+reg  flag1 ;
+flag = calculate_result(A, B);
+ *//非法操作数*
+reg [3:0]         res;
+wire [3:0]        temp;
+always@*begin
+    res    = cprmu_2 – cprmu_1 ;
+    *//temp = cprmu_2 – cprmu_1 ; //不合法,always块里赋值对象不能是wire型*
+end
+endmodule
+

# 操作符

Verilog 中提供了大约 9 种操作符,分别是算术、关系、等价、逻辑、按位、归约、移位、拼接、条件操作符。

大部分操作符与 C 语言中类似。同类型操作符之间,除条件操作符从右往左关联,其余操作符都是自左向右关联。圆括号内表达式优先执行。例如下面每组的 2 种写法都是等价的。

//自右向左关联,两种写法等价
+A+B-C ;
+(A+B)-C ;
+
+//自右向左关联,两种写法等价,结果为 B、D 或 F
+A ? B : C ? D : F ;
+A ? B : (C ? D : F) ;
+
+//自右向左关联,两种写法不等价
+(A ? B : C) ? D : F ;  //结果 D 或 F
+A ? B : C ? D : F ; //结果为 B、D 或 F
+

不同操作符之间,优先级是不同的。下表列出了操作符优先级从高至低的排列顺序。当没有圆括号时,Verilog 会根据操作符优先级对表达式进行计算。为了避免由操作符优先级导致的计算混乱,在不确定优先级时,建议用圆括号将表达式区分开来。

操作符 操作符号 优先级
单目运算 + - ! ~ 最高
乘、除、取模 * / %
加减 + -
移位 <<  >>
关系 <  <=  >  >=
等价 ==  !=  ===  !===
归约 & ~&
^ ~^
~
逻辑 &&
条件 ?: 最低

# 算术操作符

算术操作符包括单目操作符和双目操作符。

双目操作符对 2 个操作数进行算术运算,包括乘(*)、除(/)、加(+)、减(-)、求幂()、取模(%)。

# 实例

reg [3:0]  a, b;reg [4:0]  c ;
+a = 4'b0010 ;
+b = 4'b1001 ;
+c = a+b;        *//结果为c=b'b1011*
+c = a/b;          *//结果为c=4,取整*
+

如果操作数某一位为 X,则计算结果也会全部出现 X。例如:

# 实例

b = 4'b100x ;
+c = a+b ;       *//结果为c=4'bxxxx*
+

对变量进行声明时,要根据变量的操作符对变量的位宽进行合理声明,不要让结果溢出。上述例子中,相加的 2 个变量位宽为 4bit,那么结果寄存器变量位宽最少为 5bit。否则,高位将被截断,导致结果高位丢失。无符号数乘法时,结果变量位宽应该为 2 个操作数位宽之和。

# 实例

reg [3:0]        mula ;reg [1:0]        mulb;reg [5:0]        res ;
+mula = 4'he   ;
+mulb = 2'h3   ;
+res  = mula * mulb ; *//结果为res=6'h2a, 数据结果没有丢失位数*
+
  • 和 - 也可以作为单目操作符来使用,表示操作数的正负性。此类操作符优先级最高。
-4  //表示负4
++3  //表示正3
+

负数表示时,可以直接在十进制数字前面增加一个减号 -,也可以指定位宽。因为负数使用二进制补码来表示,不指定位宽来表示负数,编译器在转换时,会自动分配位宽,从而导致意想不到的结果。例如:

# 实例

mula = -4'd4 ;
+mulb = 2 ;
+res = mula * mulb ;      *//计算结果为res=-6'd8, 即res=6'h38,正常*
+res = mula * (-'d4) ;    *//(4的32次幂-4) * 2, 结果异常*
+

# 关系操作符

关系操作符有大于(>),小于(<),大于等于(>=),小于等于(<=)。

关系操作符的正常结果有 2 种,真(1)或假(0)。

如果操作数中有一位为 x 或 z,则关系表达式的结果为 x。

# 实例

A = 4 ;
+B = 3 ;
+X = 3'b1xx ;
+   
+A > B     *//为真*
+A <= B    *//为假*
+A >= Z    *//为X,不确定*
+

# 等价操作符

等价操作符包括逻辑相等(==),逻辑不等(!=),全等(===),非全等(!==)。

等价操作符的正常结果有 2 种:为真(1)或假(0)。

逻辑相等/不等操作符不能比较 x 或 z,当操作数包含一个 x 或 z,则结果为不确定值。

全等比较时,如果按位比较有相同的 x 或 z,返回结果也可以为 1,即全等比较可比较 x 或 z。所以,全等比较的结果一定不包含 x。举例如下:

# 实例

A = 4 ;
+B = 8'h04 ;
+C = 4'bxxxx ;
+D = 4'hx ;
+A == B        *//为真*
+A == (B + 1)  *//为假*
+A == C        *//为X,不确定*
+A === C       *//为假,返回值为0*
+C === D       *//为真,返回值为1*
+

# 逻辑操作符

逻辑操作符主要有 3 个:&&(逻辑与), ||(逻辑或),!(逻辑非)。

逻辑操作符的计算结果是一个 1 bit 的值,0 表示假,1 表示真,x 表示不确定。

如果一个操作数不为 0,它等价于逻辑 1;如果一个操作数等于 0,它等价于逻辑 0。如果它任意一位为 x 或 z,它等价于 x。

如果任意一个操作数包含 x,逻辑操作符运算结果不一定为 x。

逻辑操作符的操作数可以为变量,也可以为表达式。例如:

# 实例

A = 3;
+B = 0;
+C = 2'b1x ;
+   
+A && B    *//     为假*
+A || B    *//     为真*! A       *//     为假*! B       *//     为真*
+A && C    *//     为X,不确定*
+A || C    *//     为真,因为A为真*(A==2) && (! B)  *//为真,此时第一个操作数为表达式*
+

# 按位操作符

按位操作符包括:取反(~),与(&),或(|),异或(^),同或(~^)。

按位操作符对 2 个操作数的每 1 bit 数据进行按位操作。

如果 2 个操作数位宽不相等,则用 0 向左扩展补充较短的操作数。

取反操作符只有一个操作数,它对操作数的每 1 bit 数据进行取反操作。

下图给出了按位操作符的逻辑规则。

&(与) 0 1 x (或) 0 1 x
0 0 0 0 0 0 1 x
1 0 1 x 1 1 1 1
x 0 x x x x 1 x
^(异或) 0 1 x ~^(同或) 0 1 x
0 0 1 x 0 1 0 x
1 1 0 x 1 0 1 x
x x x x x x x x

# 实例

A = 4'b0101 ;
+B = 4'b1001 ;
+C = 4'bx010 ;
+~A        *//4'b1010*
+A & B     *//4'b0001*
+A | B     *//4'b1101*
+A^B       *//4'b1100*
+A ~^ B    *//4'b0011*
+B | C     *//4'b1011*
+B&C       *//4'bx000*
+

# 归约操作符

归约操作符包括:归约与(&),归约与非(~&),归约或(|),归约或非(~|),归约异或(^),归约同或(~^)。

归约操作符只有一个操作数,它对这个向量操作数逐位进行操作,最终产生一个 1bit 结果。

逻辑操作符、按位操作符和归约操作符都使用相同的符号表示,因此有时候容易混淆。区分这些操作符的关键是分清操作数的数目,和计算结果的规则。

A = 4'b1010 ;
+&A ;      //结果为 1 & 0 & 1 & 0 = 1'b0,可用来判断变量A是否全1
+~|A ;     //结果为 ~(1 | 0 | 1 | 0) = 1'b0, 可用来判断变量A是否为全0
+^A ;      //结果为 1 ^ 0 ^ 1 ^ 0 = 1'b0
+

# 移位操作符

移位操作符包括左移(<<),右移(>>),算术左移(<<<),算术右移(>>>)。

移位操作符是双目操作符,两个操作数分别表示要进行移位的向量信号(操作符左侧)与移动的位数(操作符右侧)。

算术左移和逻辑左移时,右边低位会补 0。

逻辑右移时,左边高位会补 0;而算术右移时,左边高位会补充符号位,以保证数据缩小后值的正确性。

# 实例

A = 4'b1100 ;
+B = 4'b0010 ;
+A = A >> 2 ;        *//结果为 4'b0011*
+A = A << 1;         *//结果为 4'b1000*
+A = A <<< 1 ;       *//结果为 4'b1000*
+C = B + (A>>>2);    *//结果为 2 + (-4/4) = 1, 4'b0001*
+

# 拼接操作符

拼接操作符用大括号 {,} 来表示,用于将多个操作数(向量)拼接成新的操作数(向量),信号间用逗号隔开。

拼接符操作数必须指定位宽,常数的话也需要指定位宽。例如:

# 实例

A = 4'b1010 ;
+B = 1'b1 ;
+Y1 = {B, A[3:2], A[0], 4'h3 };  *//结果为Y1='b1100_0011*
+Y2 = {4{B}, 3'd4};  *//结果为 Y2=7'b111_1100*
+Y3 = {32{1'b0}};  *//结果为 Y3=32h0,常用作寄存器初始化时匹配位宽的赋初值*
+

# 条件操作符

条件表达式有 3 个操作符,结构描述如下:

condition_expression ? true_expression : false_expression
+

计算时,如果 condition_expression 为真(逻辑值为 1),则运算结果为 true_expression;如果 condition_expression 为假(逻辑值为 0),则计算结果为 false_expression。

assign hsel    = (addr[9:8] == 2'b0) ? hsel_p1 : hsel_p2 ;
+//当信号 addr 高 2bit 为 0 时,hsel 赋值为 hsel_p1; 否则,将 hsel_p2 赋值给 hsel。
+

其实,条件表达式类似于 2 路(或多路)选择器,其描述方式完全可以用 if-else 语句代替。

当然条件操作符也能进行嵌套,完成一个多次选择的逻辑。例如:

# 实例

assign   hsel = (addr[9:8] == 2'b00) ? hsel_p1 :
+                (addr[9:8] == 2'b01) ? hsel_p2 :
+                (addr[9:8] == 2'b10) ? hsel_p3 :
+                (addr[9:8] == 2'b11) ? hsel_p4 ;
+
+ + + diff --git "a/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/10.Verilog \345\244\232\350\267\257\345\210\206\346\224\257\350\257\255\345\217\245.html" "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/10.Verilog \345\244\232\350\267\257\345\210\206\346\224\257\350\257\255\345\217\245.html" new file mode 100644 index 0000000..ce62179 --- /dev/null +++ "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/10.Verilog \345\244\232\350\267\257\345\210\206\346\224\257\350\257\255\345\217\245.html" @@ -0,0 +1,229 @@ + + + + + + 10. Verilog 多路分支语句 | Personal Blog --from Outis Li + + + + + + + + +

# 10. Verilog 多路分支语句

# 关键词:case,选择器

case 语句是一种多路条件分支的形式,可以解决 if 语句中有多个条件选项时使用不方便的问题。

# case 语句

case 语句格式如下:

case(case_expr)
+    condition1     :             true_statement1 ;
+    condition2     :             true_statement2 ;
+    ……
+    default        :             default_statement ;
+endcase
+

case 语句执行时,如果 condition1 为真,则执行 true_statement1 ; 如果 condition1 为假,condition2 为真,则执行 true_statement2;依次类推。如果各个 condition 都不为真,则执行 default_statement 语句。

default 语句是可选的,且在一个 case 语句中不能有多个 default 语句。

条件选项可以有多个,不仅限于 condition1、condition2 等,而且这些条件选项不要求互斥。虽然这些条件选项是并发比较的,但执行效果是谁在前且条件为真谁被执行。

ture_statement1 等执行语句可以是一条语句,也可以是多条。如果是多条执行语句,则需要用 begin 与 end 关键字进行说明。

# case 语句支持嵌套使用。

下面用 case 语句代替 if 语句实现了一个 4 路选择器的功能。仿真结果与 testbench 可参考条件语句 (opens new window)一章,两者完全一致。

# 实例

module mux4to1(
+    input [1:0]     sel ,
+    input [1:0]     p0 ,
+    input [1:0]     p1 ,
+    input [1:0]     p2 ,
+    input [1:0]     p3 ,
+    output [1:0]    sout);
+ 
+    reg [1:0]     sout_t ;
+    always @(*)
+        case(sel)
+            2'b00:   begin      
+                    sout_t = p0 ;
+                end
+            2'b01:       sout_t = p1 ;
+            2'b10:       sout_t = p2 ;
+            default:     sout_t = p3 ;
+        endcase
+    assign sout = sout_t ;
+ endmodule
+

case 语句中的条件选项表单式不必都是常量,也可以是 x 值或 z 值。

当多个条件选项下需要执行相同的语句时,多个条件选项可以用逗号分开,放在同一个语句块的候选项中。

# 例如,对 4 路选择器的 case 语句进行扩展,举例如下:

case(sel)
+    2'b00:   sout_t = p0 ;
+    2'b01:   sout_t = p1 ;
+    2'b10:   sout_t = p2 ;
+    2'b11:     sout_t = p3 ;
+    2'bx0, 2'bx1, 2'bxz, 2'bxx, 2'b0x, 2'b1x, 2'bzx :
+        sout_t = 2'bxx ;
+    2'bz0, 2'bz1, 2'bzz, 2'b0z, 2'b1z :
+        sout_t = 2'bzz ;
+    default:  $display("Unexpected input control!!!");endcase
+

# casex/casez 语句

casex、 casez 语句是 case 语句的变形,用来表示条件选项中的无关项。

casex 用 "x" 来表示无关值,casez 用问号 "?" 来表示无关值。

两者的实现的功能是完全一致的,语法与 case 语句也完全一致。

  1. 在 case 语句中,敏感表达式中与各项值之间的比较是一种全等比较,每一位都相同才认为匹配。
  2. 在 casez 语句中,如果分支表达式某些位的值为高阻 z,那么对这些位的比较就会忽略,不予考虑,而只关注其他位的比较结果。
  3. 在 casex 语句中,则把这种处理方式进一步扩展到对 x 的处理,即如果比较双方有一方的某些位的值是 z 或 x,那么这些位的比较就不予考虑。

Untitled

# 例如用 casez 语句来实现一个 4bit 控制端的 4 路选择选择器。

module mux4to1(
+    input [3:0]     sel ,
+    input [1:0]     p0 ,
+    input [1:0]     p1 ,
+    input [1:0]     p2 ,
+    input [1:0]     p3 ,
+    output [1:0]    sout);
+ 
+    reg [1:0]     sout_t ;
+    always @(*)
+        casez(sel)
+            4'b???1:     sout_t = p0 ;
+            4'b??1?:     sout_t = p1 ;
+            4'b?1??:     sout_t = p2 ;
+            4'b1???:     sout_t = p3 ;  
+        default:         sout_t = 2'b0 ;
+    endcase
+    assign      sout = sout_t ;
+ endmodule
+
+ + + diff --git "a/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/2023.11.15-Vivado.html" "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/2023.11.15-Vivado.html" new file mode 100644 index 0000000..c91b8fc --- /dev/null +++ "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/2023.11.15-Vivado.html" @@ -0,0 +1,192 @@ + + + + + + 2023.11.15-Vivado | Personal Blog --from Outis Li + + + + + + + + +

# 2023.11.15-Vivado

# 1. RTL Schematic & Synthesis Schematic

在 Vivado 或类似的 FPGA 开发环境中,您会遇到 RTL (Register Transfer Level) 分析中的 Schematic 和 Synthesis 过程中的 Schematic。它们虽然看起来相似,但代表了不同阶段的电路设计和功能。

  1. RTL Analysis Schematic:

    • 这个 Schematic 是您用硬件描述语言(如 Verilog)编写的代码的直接可视化表示。
    • 它展示了代码中定义的模块、它们的互联以及信号流。
    • RTL Schematic 重点在于逻辑功能的实现,而不是实际硬件如何实现这些功能。它更多地表示逻辑结构而非物理结构。
    • 这是设计验证的早期阶段,您可以在这里检查逻辑错误或结构问题。

    Untitled

  2. Synthesis Schematic:

    • 经过综合后的 Schematic 是将 RTL 设计转换为实际 FPGA 内部资源(如查找表(LUTs)、寄存器和逻辑单元)的表示。
    • 这个过程涉及优化、逻辑最小化、资源分配和时序分析。
    • Synthesis Schematic 展示了设计如何映射到 FPGA 的实际硬件上,包括使用的具体资源和连接。
    • 这是设计流程的后期阶段,您可以在这里优化性能、资源使用和满足时序要求。

    Untitled

总结来说,RTL Schematic 关注于逻辑设计的表示,而 Synthesis Schematic 则关注于该设计在 FPGA 上的物理实现。理解两者的区别对于 FPGA 开发至关重要,因为这影响着您如何优化设计以及解决可能出现的问题。

# 2. Project 汇总中的 LUT,FF,IO,BUFG

在 Vivado 或类似的 FPGA 设计项目中,您会遇到几个关键的资源指标,如 LUT、FF、IO 和 BUFG。这些指标是 FPGA 设计和资源利用的重要部分。下面是每个术语的简要解释:

  1. LUT (Look-Up Table): +
    • LUT 是 FPGA 中实现逻辑功能的基本单元。
    • 它本质上是一个可编程的真值表,可以配置为执行各种逻辑操作(如 AND、OR、NOT、XOR 等)。
    • LUT 的大小和数量是 FPGA 性能和复杂性的关键决定因素。在设计中,LUT 的使用量通常是衡量设计复杂度的一个重要指标。
  2. FF (Flip-Flop): +
    • FF 是用于存储数据的基本存储元件,通常用于实现寄存器、计数器等。
    • 在 FPGA 中,FF 通常与 LUT 配对使用,以实现存储和逻辑功能的组合。
    • FF 的数量通常表明了设计中的数据存储需求和时序复杂度。
  3. IO (Input/Output Ports): +
    • 这些是 FPGA 与外界通信的端口,包括输入端口和输出端口。
    • IO 的数量和类型(如单端或差分)取决于 FPGA 的物理特性和您的设计需求。
    • 在设计中,您需要确保 FPGA 有足够的 IO 端口来满足您的外部连接需求。
  4. BUFG (Buffered Global Clock): +
    • BUFG 是一种专用的时钟缓冲器,用于分配全局时钟信号。
    • 在复杂的 FPGA 设计中,确保时钟信号的稳定和同步是非常重要的。BUFG 能够在整个芯片上稳定地分配时钟信号。
    • BUFG 的使用和配置对于实现有效的时钟管理和避免时钟偏移非常关键。

理解这些资源对于 FPGA 设计至关重要,因为它们直接影响您的设计能否在特定的 FPGA 上实现,以及该设计的性能和效率。在 Vivado 的项目汇总中,这些参数帮助您评估设计对 FPGA 资源的利用情况。

# 3. FPGA 的组成构造

FPGA (Field-Programmable Gate Array) 是一种高度灵活的可编程硬件,它由多个不同的元件构成,共同实现复杂的数字逻辑功能。以下是 FPGA 内部主要组成部分的概述:

  1. 查找表 (LUTs): +
    • 如您所述,LUTs 是 FPGA 的核心,用于实现基本的逻辑功能。它们通过存储预定义的输出值来模拟逻辑门的行为。
    • LUTs 可以通过编程来实现简单的逻辑操作(如 AND、OR、NOT)或更复杂的组合逻辑。
  2. 多路选择器 (MUXes): +
    • 虽然在传统的逻辑电路中,MUXes 是通过逻辑门实现的,但在 FPGA 中,它们通常与 LUTs 结合或独立实现。
    • MUXes 在 FPGA 设计中用于根据控制信号选择不同的输入路径,这对于创建复杂的数据路径和逻辑结构至关重要。
  3. 触发器 (Flip-Flops): +
    • Flip-Flops 用于存储信息,是实现时序逻辑的关键元件。它们通常与 LUTs 配对,以构成可存储状态的逻辑单元。
  4. 编程互联资源 (Programmable Interconnects): +
    • 这些是连接 FPGA 内部不同部件的路径。它们可以被编程以形成任何所需的逻辑网络,从而将 LUTs、Flip-Flops 和其他资源连接起来。
  5. 输入/输出块 (I/O Blocks): +
    • 这些块连接 FPGA 和外部世界,提供数据输入和输出功能。它们可以配置为不同类型的接口(如单端或差分)。
  6. 专用硬件资源: +
    • 许多 FPGA 还包含专用的硬件资源,如 DSP (数字信号处理) 块、内存控制器、时钟管理模块(如 PLLs 和 BUFGs),以及其他特定功能块。
  7. 存储资源: +
    • 包括 RAM 块 (Block RAM) 或更小的存储单元,用于数据存储和缓冲。

FPGA 的关键优势在于其高度可编程性和灵活性。设计师可以通过编程定义 LUTs、MUXes、Flip-Flops 以及互连的配置和组合方式,从而在没有物理改动硬件的情况下实现几乎任何数字逻辑设计。这种灵活性使得 FPGA 在快速原型制作、定制硬件加速和可重配置系统中非常有价值。

FPGA (Field-Programmable Gate Array) 是一种高度灵活的可编程硬件,它由多个不同的元件构成,共同实现复杂的数字逻辑功能。以下是 FPGA 内部主要组成部分的概述:

  1. 查找表 (LUTs): +
    • 如您所述,LUTs 是 FPGA 的核心,用于实现基本的逻辑功能。它们通过存储预定义的输出值来模拟逻辑门的行为。
    • LUTs 可以通过编程来实现简单的逻辑操作(如 AND、OR、NOT)或更复杂的组合逻辑。
  2. 多路选择器 (MUXes): +
    • 虽然在传统的逻辑电路中,MUXes 是通过逻辑门实现的,但在 FPGA 中,它们通常与 LUTs 结合或独立实现。
    • MUXes 在 FPGA 设计中用于根据控制信号选择不同的输入路径,这对于创建复杂的数据路径和逻辑结构至关重要。
  3. 触发器 (Flip-Flops): +
    • Flip-Flops 用于存储信息,是实现时序逻辑的关键元件。它们通常与 LUTs 配对,以构成可存储状态的逻辑单元。
  4. 编程互联资源 (Programmable Interconnects): +
    • 这些是连接 FPGA 内部不同部件的路径。它们可以被编程以形成任何所需的逻辑网络,从而将 LUTs、Flip-Flops 和其他资源连接起来。
  5. 输入/输出块 (I/O Blocks): +
    • 这些块连接 FPGA 和外部世界,提供数据输入和输出功能。它们可以配置为不同类型的接口(如单端或差分)。
  6. 专用硬件资源: +
    • 许多 FPGA 还包含专用的硬件资源,如 DSP (数字信号处理) 块、内存控制器、时钟管理模块(如 PLLs 和 BUFGs),以及其他特定功能块。
  7. 存储资源: +
    • 包括 RAM 块 (Block RAM) 或更小的存储单元,用于数据存储和缓冲。

FPGA 的关键优势在于其高度可编程性和灵活性。设计师可以通过编程定义 LUTs、MUXes、Flip-Flops 以及互连的配置和组合方式,从而在没有物理改动硬件的情况下实现几乎任何数字逻辑设计。这种灵活性使得 FPGA 在快速原型制作、定制硬件加速和可重配置系统中非常有价值。

+ + + diff --git "a/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/2023.11.16-\351\230\273\345\241\236\344\270\216\351\235\236\351\230\273\345\241\236\350\265\213\345\200\274.html" "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/2023.11.16-\351\230\273\345\241\236\344\270\216\351\235\236\351\230\273\345\241\236\350\265\213\345\200\274.html" new file mode 100644 index 0000000..d311e11 --- /dev/null +++ "b/Chip/Chip/2023.11.07-Verilog\350\257\255\346\263\225/2023.11.16-\351\230\273\345\241\236\344\270\216\351\235\236\351\230\273\345\241\236\350\265\213\345\200\274.html" @@ -0,0 +1,174 @@ + + + + + + 2023.11.16-阻塞与非阻塞赋值 | Personal Blog --from Outis Li + + + + + + + + +

# 2023.11.16-阻塞与非阻塞赋值

Untitled

Untitled

组合逻辑电路使用阻塞赋值

时序逻辑电路使用非阻塞赋值

在 Verilog 中,阻塞赋值(Blocking Assignment)和非阻塞赋值(Non-Blocking Assignment)是两种不同的信号赋值方法,它们在时序逻辑的模拟和硬件描述语言(HDL)代码的编写中有着重要的区别。

# 阻塞赋值(Blocking Assignment)

  • 使用符号 = 进行赋值。
  • 阻塞赋值在执行时会“阻塞”代码的进一步执行,直到赋值完成。
  • 在执行下一条语句之前,当前语句必须完成其操作。
  • 在组合逻辑设计中常用,但在时序逻辑中使用可能会导致问题,因为它们可能会引起模拟时序和硬件时序的不一致。

举例:

a = b;
+c = a;
+

在这个例子中,c = a; 会等待 a = b; 完成后才执行。

# 非阻塞赋值(Non-Blocking Assignment)

  • 使用符号 <= 进行赋值。
  • 非阻塞赋值允许代码的后续部分在赋值完成之前继续执行。
  • 这意味着所有非阻塞赋值都是并行发生的(或看起来如此),这更接近于硬件的实际行为。
  • 在时序逻辑,特别是在描述触发器(如寄存器)的行为时非常重要和常用。

举例:

a <= b;
+c <= a;
+

在这个例子中,c <= a; 不会等待 a <= b; 的完成。ac 的赋值看似同时发生。

在一个 always 块中,不同地方对同一个变量的赋值会被同时执行,最终结果是变量变成最后一次赋值的结果(前面的操作被覆盖)

+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot.html new file mode 100644 index 0000000..07638a4 --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot.html @@ -0,0 +1,166 @@ + + + + + + 2024.02.21-Chisel BootCamp | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.21-1 Introduction to Scala.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.21-1 Introduction to Scala.html new file mode 100644 index 0000000..b59f511 --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.21-1 Introduction to Scala.html @@ -0,0 +1,317 @@ + + + + + + 2024.02.21-1. Introduction to Scala | Personal Blog --from Outis Li + + + + + + + + +

# 2024.02.21-1. Introduction to Scala

# Variables and Constants - var and val

var numberOfKittens = 6
+val kittensPerHouse = 101
+val alphabet = "abcdefghijklmnopqrstuvwxyz"
+var done = false
+
+/*
+numberOfKittens: Int = 6
+kittensPerHouse: Int = 101
+alphabet: String = "abcdefghijklmnopqrstuvwxyz"
+done: Boolean = false
+*/
+

变量使用var声明,常量则使用val

# Conditionals

if (done) {
+    println("we are done")
+}
+else if (numberOfKittens < kittensPerHouse) {
+    println("more kittens!")
+    numberOfKittens += 1
+}
+else {
+    done = true
+}
+

类似于 C++,如果只有一行,可以省略大括号

val likelyCharactersSet = if (alphabet.length == 26)
+    "english"
+else
+    "not english"
+
+println(likelyCharactersSet)
+// likelyCharactersSet: String = "english"
+

if这一串的返回值又所选择的分支的最后一行确定

# Methods (Functions)

// Simple scaling function with an input argument, e.g., times2(3) returns 6
+// Curly braces can be omitted for short one-line functions.
+def times2(x: Int): Int = 2 * x
+
+// More complicated function
+def distance(x: Int, y: Int, returnPositive: Boolean): Int = {
+    val xy = x * y
+    if (returnPositive) xy.abs else -xy.abs
+}
+

# Overloading Functions

// Overloaded function
+def times2(x: Int): Int = 2 * x
+def times2(x: String): Int = 2 * x.toInt
+
+times2(5)   // 10
+times2("7")   // 14
+

# Recursive and Nested Functions

def asciiTriangle(rows: Int) {
+
+    // This is cute: multiplying "X" makes a string with many copies of "X"
+    // Unit means no return value
+    def printRow(columns: Int): Unit = println("X" * columns)
+
+    if(rows > 0) {
+        printRow(rows)
+        asciiTriangle(rows - 1) // Here is the recursive call
+    }
+}
+
+// printRow(1) // This would not work, since we're calling printRow outside its scope
+asciiTriangle(6)
+
+// Output:
+XXXXXX
+XXXXX
+XXXX
+XXX
+XX
+X
+

# Named Parameters and Parameter Defaults

Consider the following method definition.

def myMethod(count: Int, wrap: Boolean, wrapValue: Int= 24): Unit= { ... }
+

When calling the method, you will often see the parameter names along with the passed-in values.

myMethod(count= 10, wrap= false, wrapValue= 23)
+

Using named parameters, you can even call the function with a different ordering.

myMethod(wrapValue= 23, wrap= false, count= 10)
+

For frequently called methods, the parameter ordering may be obvious. But for less common methods and, in particular, boolean arguments, including the names with calls can make your code a lot more readable. If methods have a long list of arguments of the same type, using names also decreases the chance of error. Parameters to class definitions also use this named argument scheme (they are actually just the parameters to the constructor method for the class).

When certain parameters have default values (that don't need to be overridden), callers only have to pass (by name) specific arguments that do not use defaults. Notice that the parameter  wrapValue has a default value of 24. Therefore, this will work as if 24 had been passed in.

myMethod(wrap= false, count= 10)
+

# Lists

val x = 7
+val y = 14
+val list1 = List(1, 2, 3)
+val list2 = x :: y :: y :: Nil       // An alternate notation for assembling a list
+                                     // Nil就是一个空的List[Nothing],即一个可以封装任何类型元素但又没有元素的容器
+
+val list3 = list1 ++ list2           // Appends the second list to the first list
+val m = list2.length
+val s = list2.size
+
+val headOfList = list1.head          // Gets the first element of the list
+val restOfList = list1.tail          // Get a new list with first element removed
+
+val third = list1(2)                 // Gets the third element of a list (0-indexed)
+
+// Output:
+x: Int = 7
+y: Int = 14
+list1: List[Int] = List(1, 2, 3)
+list2: List[Int] = List(7, 14, 14)
+list3: List[Int] = List(1, 2, 3, 7, 14, 14)
+m: Int = 3
+s: Int = 3
+headOfList: Int = 1
+restOfList: List[Int] = List(2, 3)
+third: Int = 3
+

# for Statement

for (i <- 0 to 7) { print(i + " ") } // include 7
+println()
+
+i <- 0 until 7 // exclude 7
+i <- 0 to 10 by 2
+

print 用于连续输出不换行,而 println 用于输出后换行。

<- 是用在 for 循环构造中的一个操作符,表示从一个集合中逐一取出元素

# Packages and Imports

  • package 用于定义一个命名空间,它可以包含类、对象和特质(traits),以及其他包。包主要用于组织和管理代码,防止命名冲突,并提供访问控制。
  • class 是定义数据结构及其行为的蓝图。它可以包含数据成员(属性)和方法。类用于实例化对象,每个对象都可以拥有不同的属性值。

import语句可以用来引入包、类、对象,甚至是特定的方法或属性。这意味着你可以使用import来引用几乎任何你需要的代码实体。以下是一些例子:

  • 引入一个包中的所有成员:import scala.collection.mutable._,这里的_相当于 Java 中的``,表示引入mutable包下的所有成员。
  • 引入一个特定的类:import scala.collection.mutable.ListBuffer,这表示只引入ListBuffer类。
  • 引入一个包中的多个类:import scala.collection.mutable.{ArrayBuffer, LinkedList},这表示同时引入ArrayBufferLinkedList两个类。
  • 引入一个对象中的特定成员:import java.lang.System.{out => stdout},这里还演示了将System.out重命名为stdout,以便在代码中使用简化的名称。
// 从chisel3.iotesters包中引入特定的几个类:ChiselFlatSpec、Driver、和PeekPokeTester
+import chisel3.iotesters.{ChiselFlatSpec, Driver, PeekPokeTester}
+

# Class

// WrapCounter counts up to a max value based on a bit size
+class WrapCounter(counterBits: Int) {
+
+  val max: Long = (1 << counterBits) - 1
+  var counter = 0L
+
+  def inc(): Long = {
+    counter = counter + 1
+    if (counter > max) {
+        counter = 0
+    }
+    counter
+  }
+  println(s"counter created with max value $max")
+}
+
  • class WrapCounter -- This is the definition of WrapCounter.
  • (counterBits: Int) -- Creating a WrapCounter requires an integer parameter, nicely named to suggest it is the bit width of the counter.
  • Braces ({}) delimit a block of code. Most classes use a code block to define variables, constants, and methods (functions).
  • val max: Long = -- the class contains a member variable max, declared as type Long and initialized as the class is created.
  • (1 << counterBits) - 1 computes the maximum value that can be contained in counterBits bits. Since max was created with val it cannot be changed.
  • A variable counter is created and initialized to 0L. The L says that 0 is a long value; thus, counter is inferred to be Long.
  • max and counter are commonly called member variables of the class.
  • A class method inc is defined which takes no arguments and returns a Long value.
  • The body of the method inc is a code block that has: +
    • counter = counter + 1 increments counter.
    • if (counter > max) { counter = 0 } tests if the counter is greater than the max value and sets it back to zero if it is.
    • counter -- The last line of the code block is important. +
      • Any value expressed as the last line of a code block is considered to be the return value of that code block. The return value can be used or ignored by the calling statement.
      • This applies quite generally; for example, since an if then else statement defines its true and false clauses with code blocks, it can return a value i.e., val result = if (10 * 10 > 90) "greater" else "lesser" would create a val with the value "greater".
    • So in this case the function inc returns the value of counter.
  • println(s"counter created with max value $max") prints a string to standard output. Because the println is directly in the defining code block, it is part of the class initialization code and is run, i.e. prints out the string, every time an instance of this class is created.
  • The string printed in this case is an interpolated string. +
    • The leading s in front of the first double quote identifies this as an interpolated string.
    • An interpolated string is processed at run time.
    • The $max is replaced with the value of max.
    • If the $ is followed by a code block, arbitrary Scala can be in that code block. +
      • For example, println(s"doubled max is ${max + max}").
      • The return value of this code block will be inserted in place of ${...}.
      • If the return value is not a string, it will be converted to one; virtually every class or type in scala has an implicit conversion to a string defined).
    • You should generally avoid printing something every time an instance of a class is created to avoid flooding standard output, unless you're debugging.

    # Creating an Instance of a Class

    val x = new WrapCounter(2)
    +x.inc() // Increments the counter
    +
    +// Member variables of the instance x are visible to the outside, unless they are declared private
    +if(x.counter == x.max) {
    +    println("counter is about to wrap")
    +}
    +
    +x inc() // Scala allows the dots to be omitted; this can be useful for making embedded DSL's look more natural
    +
    有时候实例化类时不需要使用new关键字,这通常是因为该类定义了一个或多个apply方法。apply方法可以在类的伴生对象(companion object)中定义,允许你直接通过类名加括号的方式创建类的实例,而不需要显式地使用new关键字。这种方式提供了一种更简洁的语法来创建对象,同时也可以在apply方法内部执行初始化操作或参数处理,为对象创建提供更多的灵活性和控制。 +例如,假设有一个名为Person的类及其伴生对象,伴生对象中定义了apply方法:
    class Person(val name: String)
    +
    +object Person {
    +  def apply(name: String): Person = new Person(name)
    +}
    +
    在这个例子中,可以通过调用Person伴生对象的apply方法来创建Person类的实例,而不需要使用new关键字:
    val person = Person("Alice")  // 相当于调用 Person.apply("Alice")
    +
    这里,Person("Alice")实际上调用的是伴生对象中的apply方法,该方法内部使用new关键字创建了Person类的实例。这种方式使得代码看起来更简洁,同时保留了通过构造函数创建对象的灵活性。

# Code Blocks

Code blocks are delimited by braces. A block can contain zero or more lines of Scala code. The last line of Scala code becomes the return value (which may be ignored) of the code block. A code block with no lines would return a special null-like object called Unit. Code blocks are used throughout Scala: they are the bodies of class definitions, they form function and method definitions, they are the clauses of if statements, and they are the bodies of for and many other Scala operators.

# Parameterized Code Blocks

Code blocks can take parameters. In the case of class and method definitions, these parameters look like those in most conventional programming languages. In the example below, c and s are parameters of the code blocks.

// A one-line code block doesn't need to be enclosed in {}
+def add1(c: Int): Int = c + 1
+
+class RepeatString(s: String) {
+    val repeatedString = s + s
+}
+

IMPORTANT: There is another way in which code blocks may be parameterized. Here is an example.

val intList = List(1, 2, 3)
+val stringList = intList.map { i =>
+    i.toString
+}
+

使用map方法对intList中的每个元素应用一个函数,该函数将整数转换为其对应的字符串表示。具体来说,map方法遍历intList中的每个元素(用i表示),并对每个元素执行i.toString操作,将其转换为字符串。This type of code block is called an anonymous function, and more details on anonymous functions are provided in a later module.

+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.23-2.1 First Chisel Module.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.23-2.1 First Chisel Module.html new file mode 100644 index 0000000..d5ace71 --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.23-2.1 First Chisel Module.html @@ -0,0 +1,284 @@ + + + + + + 2024.02.23-2.1 First Chisel Module | Personal Blog --from Outis Li + + + + + + + + +

# 2024.02.23-2.1 First Chisel Module

# Setup

val path = System.getProperty("user.dir") + "/source/load-ivy.sc"
+interp.load.module(ammonite.ops.Path(java.nio.file.FileSystems.getDefault().getPath(path)))
+import chisel3._
+import chisel3.util._
+import chisel3.tester._
+import chisel3.tester.RawTester.test
+import dotvisualizer._
+

这两句代码在使用 Chisel(一种硬件描述语言)时,涉及到 Ammonite 脚本的动态加载。第一句定义了一个path变量,它通过获取系统属性"user.dir"(当前用户目录)并附加上"/source/load-ivy.sc"路径,用于指定一个 Scala 脚本文件的位置。第二句使用 Ammonite 的interp.load.module方法动态加载这个指定路径下的 Scala 脚本文件。

动态加载脚本在使用 Chisel 编写代码时可以有多个用途,如:

  1. 引入依赖:动态加载load-ivy.sc脚本可以用来引入或更新 Ammonite 会话中的 Ivy 依赖,确保代码运行时有必要的库支持。
  2. 执行初始化代码:可以在脚本中执行必要的初始化操作,为后续的 Chisel 硬件设计代码执行设置适当的环境或参数。
  3. 灵活性和模块化:通过动态加载脚本,可以根据需要灵活地加载和卸载模块,使代码结构更加模块化,便于管理和维护。
  • import chisel3._:基础的 Chisel 功能,包括定义硬件组件的基本构建块。
  • import chisel3.util._:提供了一些实用工具和额外的硬件构建块,比如计数器、移位寄存器等。
  • import chisel3.tester._:提供了测试 Chisel 硬件设计的工具和框架。
  • import chisel3.tester.RawTester.test:是chisel3.tester中的一个具体的测试功能,用于执行硬件测试。

# Example Module

class Passthrough extends Module {
+  val io = IO(new Bundle {
+    val in = Input(UInt(4.W))
+    val out = Output(UInt(4.W))
+  })
+  io.out := io.in
+}
+
+// with parameter
+class PassthroughGenerator(width: Int) extends Module {
+  val io = IO(new Bundle {
+    val in = Input(UInt(width.W))
+    val out = Output(UInt(width.W))
+  })
+  io.out := io.in
+}
+
class Passthrough extends Module {
+

我们声明一个叫做Passthrough的新模块。Module是 Chisel 内置的一个类,所有硬件模块都必须扩展它

val io = IO(...)
+

我们在一个特殊的io变量中声明所有的输入和输出端口。它必须被命名为io,并且是一个IO对象或实例,这需要形如IO(_instantiated_bundle_)的东西

在 Chisel 中,ioinout被声明为val(不可变引用)而不是var(可变引用),因为它们代表硬件模块的接口。在硬件设计中,接口的结构(例如信号的数量、类型和方向)在编译时确定且不会改变。虽然信号的值在模拟过程中会变化,但信号的定义(即接口)是固定的。使用val声明这些接口强调了它们是不变的结构,而信号值的变化则通过信号之间的连接和赋值来体现,这与软件编程中变量的概念有所不同。

new Bundle {
+    val in = Input(...)
+    val out = Output(...)
+}
+

我们声明了一个新的硬件结构类型(Bundle),它包含了一些命名的信号inout,分别具有输入和输出的方向。

在 Chisel 中,Bundle是一种用于定义一组相关信号的类,类似于 Verilog 中的module内部信号或 VHDL 中的record。它允许开发者将多个信号组合成一个单一的复合类型,这样可以更方便地管理和传递数据结构。每个Bundle内的信号可以有不同的类型和方向(如输入Input、输出Output),使其成为定义模块接口和内部数据结构的强大工具。

UInt(4.W)
+

我们声明了信号的硬件类型。在这个案例中,它是宽度为 4 的无符号整数。

io.out := io.in
+

我们将我们的输入端口连接到我们的输出端口,这样io.in驱动io.out。注意,:=操作符是一个Chisel操作符,它表示右手边的信号驱动左手边的信号。它是一个有方向的操作符。

硬件构建语言(HCLs)的一个整洁之处在于我们可以使用底层的编程语言作为脚本语言。例如,在声明我们的 Chisel 模块之后,我们接着使用 Scala 调用 Chisel 编译器将 Chisel 的Passthrough翻译成 Verilog 的Passthrough。这个过程被称为精炼

# Generate Verilog

println(getVerilog(new Passthrough))
+
module Passthrough(
+  input        clock,
+  input        reset,
+  input  [3:0] io_in,
+  output [3:0] io_out
+);
+  assign io_out = io_in; // @[cmd2.sc 6:10]
+endmodule
+

# Generate Firrtl

println(getFirrtl(new Passthrough))
+
circuit Passthrough :
+  module Passthrough :
+    input clock : Clock
+    input reset : UInt<1>
+    output io : { flip in : UInt<4>, out : UInt<4>}
+
+    io.out <= io.in @[cmd2.sc 6:10]
+

# Example Tester

// Scala Code: `test` runs the unit test.
+// test takes a user Module and has a code block that applies pokes and expects to the
+// circuit under test (c)
+test(new Passthrough()) { c =>
+    c.io.in.poke(0.U)     // Set our input to value 0
+    c.io.out.expect(0.U)  // Assert that the output correctly has 0
+    c.io.in.poke(1.U)     // Set our input to value 1
+    c.io.out.expect(1.U)  // Assert that the output correctly has 1
+    c.io.in.poke(2.U)     // Set our input to value 2
+    c.io.out.expect(2.U)  // Assert that the output correctly has 2
+}
+println("SUCCESS!!") // Scala Code: if we get here, our tests passed!
+
+// Test with width 10
+test(new PassthroughGenerator(10)) { c =>
+    c.io.in.poke(0.U(10.W))     // Set our input to value 0
+    c.io.out.expect(0.U(10.W))  // Assert that the output correctly has 0
+    c.io.in.poke(1.U(10.W))     // Set our input to value 1
+    c.io.out.expect(1.U(10.W))  // Assert that the output correctly has 1
+    c.io.in.poke(2.U(10.W))     // Set our input to value 2
+		c.io.out.expect(2.U(10.W))  // Assert that the output correctly has 2
+}
+
  • c.io.in.poke(0.U):设置模块的输入in为 0。
  • c.io.out.expect(0.U):检查模块的输出out是否为 0,确保电路按预期工作。
  • 接下来,代码以相同的方式测试输入值 1 和 2,分别使用poke方法设置输入值,并用expect方法验证输出值。

在 Scala 中,可以直接在函数调用后跟一个代码块,这是因为 Scala 支持高阶函数,即可以接受函数作为参数的函数。在这个例子中,test函数接受两个参数:一个是Passthrough模块的实例,另一个是一个匿名函数(或称为代码块),这个匿名函数以c作为参数进行操作。这种语法使得代码更加简洁易读,允许直接在调用函数时定义行为逻辑,非常适合进行单元测试等场景。当一个函数的最后一个参数是函数类型时,可以使用特殊的语法糖允许将这个函数参数写在方法调用的外部。这种语法不仅使得代码更加清晰,而且在使用匿名函数或代码块作为参数时尤其有用,因为它允许代码块在视觉上更为突出,从而提高了代码的可读性。这就是为什么test(new Passthrough())后面可以直接跟一个代码块的原因。

c =>是一个函数字面量(匿名函数)的语法,用于定义一个函数。这里,c是函数的参数,=>后面跟着的是函数体。在这个上下文中,c代表传递给测试代码块的模块实例(如Passthrough模块实例),然后在代码块内部,你可以使用c来访问和操作这个实例的输入和输出端口。在 Scala 的函数字面量中,参数类型通常是通过上下文推断出来的,不需要显式声明。在test(new Passthrough()) { c => ... }这段代码中,c是由test函数根据其参数类型推断出的Passthrough模块实例。也就是说,当你写c =>时,c的类型(在这个例子中是Passthrough模块实例)是由test函数的定义确定的,根据这个函数期望的参数类型。这就是为什么可以直接使用c来访问Passthrough实例的成员,如c.io.inc.io.out,而不需要额外的类型声明。

Note that the poke and expect use chisel hardware literal notation. Both operations expect literals of the correct type. +If pokeing a UInt() you must supply a UInt literal (example: c.io.in.poke(10.U)), likewise if the input is a Bool() the poke would expect either true.B or false.B.

# Appendix: A Note on "printf" Debugging

class PrintingModule extends Module {
+    val io = IO(new Bundle {
+        val in = Input(UInt(4.W))
+        val out = Output(UInt(4.W))
+    })
+    io.out := io.in
+
+    printf("Print during simulation: Input is %d\n", io.in)
+    // chisel printf has its own string interpolator too
+    printf(p"Print during simulation: IO is $io\n")
+
+    println(s"Print during generation: Input is ${io.in}")
+// s用于一般的Scala字符串插值,而p专门为Chisel设计,用于更方便地在仿真中打印硬件信号和对象
+}
+
+test(new PrintingModule ) { c =>
+    c.io.in.poke(3.U)
+    c.io.out.expect(3.U)
+    c.clock.step(5) // circuit will print
+
+    println(s"Print during testing: Input is ${c.io.in.peek()}")
+}
+
Elaborating design...
+Print during generation: Input is UInt<4>(IO in unelaborated PrintingModule)
+Done elaborating.
+Print during simulation: Input is   3
+Print during simulation: IO is AnonymousBundle(in ->   3, out ->   3)
+Print during simulation: Input is   3
+Print during simulation: IO is AnonymousBundle(in ->   3, out ->   3)
+Print during simulation: Input is   3
+Print during simulation: IO is AnonymousBundle(in ->   3, out ->   3)
+Print during simulation: Input is   3
+Print during simulation: IO is AnonymousBundle(in ->   3, out ->   3)
+Print during simulation: Input is   3
+Print during simulation: IO is AnonymousBundle(in ->   3, out ->   3)
+Print during testing: Input is UInt<4>(3)
+Print during simulation: Input is   0
+Print during simulation: IO is AnonymousBundle(in ->   0, out ->   0)
+test PrintingModule Success: 0 tests passed in 7 cycles in 0.003471 seconds 2016.88 Hz
+

这段代码定义了一个PrintingModule类,它扩展了 Chisel 的Module,用于演示在不同阶段打印信息:

  1. 模块定义中的printf语句:这些在仿真时每个时钟周期都会打印。printf("Print during simulation: Input is %d\n", io.in)会打印输入信号的值,而printf(p"Print during simulation: IO is $io\n")会打印io对象的信息。这些仅在仿真(运行时)生效。
  2. 模块定义中的println语句:这句话在模块的生成阶段打印,即代码编译时,打印到终端或控制台。它不会在仿真时打印,因为它是 Scala 的打印语句,不是 Chisel 的。
  3. 测试块中的println语句:这在 Scala 测试环境中执行,用于打印测试时的信息。如println(s"Print during testing: Input is ${c.io.in.peek()}")将在测试过程中打印输入信号的当前值。
  • c.io.in.poke(3.U)设置输入为 3。
  • c.io.out.expect(3.U)期望输出为 3,这个测试会通过,因为输出应该与输入相同。
  • c.clock.step(5)推进仿真时钟 5 个周期,这期间printf语句会打印信息。
  1. 最后的Print during simulation: Input is 0 是因为被重置回到默认状态
  2. 7 周期则是因为测试中执行了c.clock.step(5),推进了 5 个时钟周期,加上测试开始前后的各 1 个周期

综上,println用于代码生成阶段和测试代码中,打印到 Scala 的执行环境;printf用于仿真阶段,打印到仿真的输出中。

+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.24-2.2 Combinational Logic.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.24-2.2 Combinational Logic.html new file mode 100644 index 0000000..f4fedd7 --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.24-2.2 Combinational Logic.html @@ -0,0 +1,342 @@ + + + + + + 2024.02.24-2.2 Combinational Logic | Personal Blog --from Outis Li + + + + + + + + +

# 2024.02.24-2.2 Combinational Logic

# Common Operators

class MyModule extends Module {
+  val io = IO(new Bundle {
+    val in  = Input(UInt(4.W))
+    val out = Output(UInt(4.W))
+  })
+
+	// Scala expression
+  val two  = 1 + 1
+  println(two)
+	// Chisel expression
+  val utwo = 1.U + 1.U
+  println(utwo)
+	// incorrect
+	val twotwo = 1.U + 1
+
+  io.out := io.in
+}
+
class MyOperators extends Module {
+  val io = IO(new Bundle {
+    val in      = Input(UInt(4.W))
+    val out_add = Output(UInt(4.W))
+    val out_sub = Output(UInt(4.W))
+    val out_mul = Output(UInt(4.W))
+  })
+
+  io.out_add := 1.U + 4.U
+  io.out_sub := 2.U - 1.U
+  io.out_mul := 4.U * 2.U
+}
+
+// 没有参数时可以省略小括号
+test(new MyOperators) {c =>
+  c.io.out_add.expect(5.U)
+  c.io.out_sub.expect(1.U)
+  c.io.out_mul.expect(8.U)
+}
+

# Mux and Concatenation

class MyOperatorsTwo extends Module {
+  val io = IO(new Bundle {
+    val in      = Input(UInt(4.W))
+    val out_mux = Output(UInt(4.W))
+    val out_cat = Output(UInt(4.W))
+  })
+
+  val s = true.B
+  io.out_mux := Mux(s, 3.U, 0.U) // should return 3.U, since s is true
+  io.out_cat := Cat(2.U, 1.U)    // concatenates 2 (b10) with 1 (b1) to give 5 (101)
+}
+
+println(getVerilog(new MyOperatorsTwo))
+
+test(new MyOperatorsTwo) { c =>
+  c.io.out_mux.expect(3.U)
+  c.io.out_cat.expect(5.U)
+}
+

The Mux operates like a traditional ternary operator, with the order (select, value if true, value if false)

The Cat ordering is MSB then LSB (where B refers to bit or bits), and only takes two arguments.

# MAC: multiply accumulate function

class MAC extends Module {
+  val io = IO(new Bundle {
+    val in_a = Input(UInt(4.W))
+    val in_b = Input(UInt(4.W))
+    val in_c = Input(UInt(4.W))
+    val out  = Output(UInt(8.W))
+  })
+
+  io.out := (io.in_a * io.in_b) + io.in_c
+}
+
+test(new MAC) { c =>
+  val cycles = 100
+  import scala.util.Random
+  for (i <- 0 until cycles) {
+    val in_a = Random.nextInt(16)
+    val in_b = Random.nextInt(16)
+    val in_c = Random.nextInt(16)
+    c.io.in_a.poke(in_a.U)
+    c.io.in_b.poke(in_b.U)
+    c.io.in_c.poke(in_c.U)
+    c.io.out.expect((in_a * in_b + in_c).U)
+  }
+}
+

# Arbiter

The following circuit arbitrates data coming from a FIFO into two parallel processing units. The FIFO and processing elements (PEs) communicate with ready-valid interfaces. Construct the arbiter to send data to whichever PE is ready to receive data, prioritizing PE0 if both are ready to receive data. Remember that the arbiter should tell the FIFO that it's ready to receive data when at least one of the PEs can receive data. Also, wait for a PE to assert that it's ready before asserting that the data are valid. You will likely need binary operators to complete this exercise.

Untitled

class Arbiter extends Module {
+  val io = IO(new Bundle {
+    // FIFO
+    val fifo_valid = Input(Bool())
+    val fifo_ready = Output(Bool())
+    val fifo_data  = Input(UInt(16.W))
+
+    // PE0
+    val pe0_valid  = Output(Bool())
+    val pe0_ready  = Input(Bool())
+    val pe0_data   = Output(UInt(16.W))
+
+    // PE1
+    val pe1_valid  = Output(Bool())
+    val pe1_ready  = Input(Bool())
+    val pe1_data   = Output(UInt(16.W))
+  })
+
+  io.fifo_ready := io.pe0_ready || io.pe1_ready
+  io.pe0_valid  := io.fifo_valid && io.pe0_ready
+  io.pe1_valid  := io.fifo_valid && !io.pe0_ready && io.pe1_ready
+  io.pe0_data   := io.fifo_data
+  io.pe1_data   := io.fifo_data
+}
+
+test(new Arbiter) { c =>
+  import scala.util.Random
+  val data = Random.nextInt(65536)
+  c.io.fifo_data.poke(data.U)
+
+  for (i <- 0 until 8) {
+    c.io.fifo_valid.poke((((i >> 0) % 2) != 0).B)
+    c.io.pe0_ready.poke((((i >> 1) % 2) != 0).B)
+    c.io.pe1_ready.poke((((i >> 2) % 2) != 0).B)
+
+    c.io.fifo_ready.expect((i > 1).B)
+    c.io.pe0_valid.expect((i == 3 || i == 7).B)
+    c.io.pe1_valid.expect((i == 5).B)
+
+    if (i == 3 || i ==7) {
+      c.io.pe0_data.expect((data).U)
+    } else if (i == 5) {
+      c.io.pe1_data.expect((data).U)
+    }
+  }
+}
+println("SUCCESS!!")
+

数据线(如io.pe0_dataio.pe1_data)通常会持续地带有它们可能需要使用的数据信号(本例中为io.fifo_data)。但是,这些数据是否被“接收”或“采用”通常由valid信号来控制。

测试代码设计用来验证Arbiter模块的行为。测试通过随机生成一个数据,然后使用不同的组合的fifo_validpe0_readype1_ready信号来模拟不同的工作情况。

  • c.io.fifo_data.poke(data.U)模拟从 FIFO 发送的数据。
  • 循环for (i <- 0 until 8)遍历 8 种不同的信号组合状态。
  • c.io.fifo_valid.pokec.io.pe0_ready.pokec.io.pe1_ready.poke根据i的不同值模拟不同的信号状态,使用位操作来确定每个信号是否应该被激活。
  • c.io.fifo_ready.expectc.io.pe0_valid.expectc.io.pe1_valid.expect是对仲裁器预期行为的断言检查。
  • 如果i的值表示 PE0 或 PE1 应该接收数据(如i == 3 || i == 7是 PE0,i == 5是 PE1),则使用expect断言来检查io.pe0_dataio.pe1_data与 FIFO 的数据相同。

# Parameterized Adder

class ParameterizedAdder(saturate: Boolean) extends Module {
+  val io = IO(new Bundle {
+    val in_a = Input(UInt(4.W))
+    val in_b = Input(UInt(4.W))
+    val out  = Output(UInt(4.W))
+  })
+  val sum = io.in_a +& io.in_b
+  if(saturate){
+    io.out := Mux(sum>15.U,15.U,sum)
+  }else{
+    io.out := sum
+  }
+}
+
+for (saturate <- Seq(true, false)) {
+  test(new ParameterizedAdder(saturate)) { c =>
+    // 100 random tests
+    val cycles = 100
+    import scala.util.Random
+    import scala.math.min
+    for (i <- 0 until cycles) {
+      val in_a = Random.nextInt(16)
+      val in_b = Random.nextInt(16)
+      c.io.in_a.poke(in_a.U)
+      c.io.in_b.poke(in_b.U)
+      if (saturate) {
+        c.io.out.expect(min(in_a + in_b, 15).U)
+      } else {
+        c.io.out.expect(((in_a + in_b) % 16).U)
+      }
+    }
+
+    // ensure we test saturation vs. truncation
+    c.io.in_a.poke(15.U)
+    c.io.in_b.poke(15.U)
+    if (saturate) {
+      c.io.out.expect(15.U)
+    } else {
+      c.io.out.expect(14.U)
+    }
+  }
+}
+println("SUCCESS!!")
+

在 Chisel 中,+&是一个用于加法的运算符,它会考虑输入的进位,得到一个比最大输入位宽更宽的结果。如果输入是 4 位UInt,标准加法结果io.in_a + io.in_b会是 4 位,可能会截断超出的位。而+&加法会产生一个 5 位的结果,这可以用于在必要时实现饱和加法逻辑。连接一个 4 位的UInt线到一个 5 位的UInt线(一个 4.W 的量等于 5.W 的量),默认会截断最高位(MSB)。这样,你可以用这个方法来轻松实现非饱和加法器,只保留 5 位和的低 4 位。

+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.25-2.3 Control Flow.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.25-2.3 Control Flow.html new file mode 100644 index 0000000..c0e1c7d --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.25-2.3 Control Flow.html @@ -0,0 +1,305 @@ + + + + + + 2024.02.25-2.3 Control Flow | Personal Blog --from Outis Li + + + + + + + + +

# 2024.02.25-2.3 Control Flow

# Last Connect Semantics

class LastConnect extends Module {
+  val io = IO(new Bundle {
+    val in = Input(UInt(4.W))
+    val out = Output(UInt(4.W))
+  })
+  io.out := 1.U
+  io.out := 2.U
+  io.out := 3.U
+  io.out := 4.U
+}
+
+//  Test LastConnect
+test(new LastConnect) { c => c.io.out.expect(4.U) }
+

当有多个值被赋值给一个量时,最后的那个生效

# when, elsewhen, and otherwise

when(someBooleanCondition) {
+  // things to do when true
+}.elsewhen(someOtherBooleanCondition) {
+  // things to do on this condition
+}.otherwise {
+  // things to do if none of th boolean conditions are true
+}
+

when是一种特殊的构造,它用于硬件生成。它类似于软件编程中的if语句,但是在硬件描述中,when会生成实际的硬件逻辑,如多路复用器。而标准的if语句通常用于生成时(编译时)的控制流,并不直接生成硬件。if语句在 Scala(因此在 Chisel 的生成时)可以有返回值,可以用于赋值或者作为表达式的一部分。相比之下,when是一种专门为硬件设计提供的控制结构,用于生成条件硬件逻辑,如多路复用器或条件赋值,但它不返回值。因此,当你需要根据输入信号在运行时动态地选择硬件行为时,你会使用when。而当你在编译时根据某些条件生成不同的硬件模块时,你会使用if

在 Scala 中,==用于基本类型和对象的相等性比较,而在 Chisel 中(一个建立在 Scala 之上的硬件构建语言),===用于硬件信号之间的相等性比较。这是因为 Chisel 需要区分硬件操作和 Scala 的软件操作,===在 Chisel 中被定义为生成硬件电路中的等于比较逻辑。而在 Scala 的if语句中,==仍然用于比较两个值是否相等。这种区分确保了代码的清晰性,以及硬件设计中逻辑正确性的维护。因此,在when中使用===来生成判断相等的硬件电路

# The Wire Construct

Wire是一种基本的硬件构造类型,用于创建一个可以在模块内部读取和写入的信号。它主要用于表示组合逻辑或暂存数据,允许在硬件描述中定义中间变量或内部连接。使用Wire时,需要指定信号的数据类型,如UIntSInt等。Wire类型的变量在定义时不持有初始值,需要在逻辑中显式赋值。在使用过程中,可以根据需要多次对其赋值,但在每个时钟周期结束时,Wire仅保留最后一次赋值的结果。val myWire = Wire(UInt(32.W))

List(1, 2, 3, 4).permutations.foreach { case i0 :: i1 :: i2 :: i3 :: Nil =>
+    println(s"Sorting $i0 $i1 $i2 $i3")}
+List(1, 2, 3, 4).permutations.foreach { case i0 :: i1 :: i2 :: _ :: Nil =>
+  println(s"Sorting $i0 $i1 $i2")}
+

使用 Scala 的集合和模式匹配功能来遍历List(1, 2, 3, 4)的所有排列组合。List(1, 2, 3, 4).permutations生成一个包含所有可能排列的列表的迭代器。foreach循环遍历这些排列。

foreach的代码块中,case i0 :: i1 :: i2 :: i3 :: Nil =>是一个模式匹配表达式,用于解构每个排列列表。这个表达式匹配一个包含四个元素的列表,将这四个元素分别绑定到变量i0i1i2i3Nil在这里表示列表的末尾,确保列表只有这四个元素。这种方式允许直接访问每个排列中的元素,然后可以将它们打印出来或用于其他逻辑操作。

# Exercise: Polynomial

class Polynomial extends Module {
+  val io = IO(new Bundle {
+    val select = Input(UInt(2.W))
+    val x = Input(SInt(32.W))
+    val fOfX = Output(SInt(32.W))
+  })
+
+  val result = Wire(SInt(32.W))
+  val square = Wire(SInt(32.W))
+
+  square := io.x * io.x
+  when(io.select === 0.U){
+    result := square - 2.S * io.x + 1.S
+  }.elsewhen(io.select === 1.U) {
+    result := 2.S * square + 6.S * io.x + 3.S
+  }.otherwise {
+    result := 4.S * square - 10.S * io.x - 5.S
+  }
+
+  io.fOfX := result
+}
+
+// Test Polynomial
+test(new Polynomial) { c =>
+  for(x <- 0 to 20) {
+    for(select <- 0 to 2) {
+      c.io.select.poke(select.U)
+      c.io.x.poke(x.S)
+      c.io.fOfX.expect(poly(select, x).S)
+    }
+  }
+}
+

# Exercise: Finite State Machine

Grad students pass through four states in their career: Idle, Coding, Writing, and Graduating. These states transition based off three inputs: Coffee, Ideas they come up with, and Pressure from their advisor to make progress. Once they Graduate, they return to the Idle state. The FSM diagram below shows these states and transitions. Any unlabelled transition (i.e. when there are no inputs) returns a grad student to the Idle state instead of staying in the current state. The input precedence is coffee > idea > pressure, so when in the Idle state and receiving both coffee and pressure, a graduate student will move to the Coding state.

Untitled

检查逻辑:

// state map
+def states = Map("idle" -> 0, "coding" -> 1, "writing" -> 2, "grad" -> 3)
+
+// life is full of question marks
+def gradLife (state: Int, coffee: Boolean, idea: Boolean, pressure: Boolean): Int = {
+  var nextState = states("idle")
+  if(state == states("idle")){
+    if(coffee) nextState = states("coding")
+    else if(idea) nextState = states("idle")
+    else if(pressure) nextState = states("writing")
+    else nextState = states("idle")
+  }else if(state == states("coding")){
+    if(coffee) nextState = states("coding")
+    else if(idea) nextState = states("writing")
+    else if(pressure) nextState = states("writing")
+    else nextState = states("idle")
+  }else if(state == states("writing")){
+    if(coffee) nextState = states("writing")
+    else if(idea) nextState = states("writing")
+    else if(pressure) nextState = states("grad")
+    else nextState = states("idle")
+  }
+  nextState
+}
+
+// some sanity checks
+(0 until states.size).foreach{ state => assert(gradLife(state, false, false, false) == states("idle")) }
+assert(gradLife(states("writing"), true, false, true) == states("writing"))
+assert(gradLife(states("idle"), true, true, true) == states("coding"))
+assert(gradLife(states("idle"), false, true, true) == states("idle"))
+assert(gradLife(states("grad"), false, false, false) == states("idle"))
+

Chisel:

class GradLife extends Module {
+  val io = IO(new Bundle {
+    val state = Input(UInt(2.W))
+    val coffee = Input(Bool())
+    val idea = Input(Bool())
+    val pressure = Input(Bool())
+    val nextState = Output(UInt(2.W))
+  })
+
+  val idle :: coding :: writing :: grad :: Nil = Enum(4)
+
+  when(io.state === idle){
+    when(io.coffee) {io.nextState := coding}
+    .elsewhen(io.idea) {io.nextState := idle}
+    .elsewhen(io.pressure) {io.nextState := writing}
+    .otherwise {io.nextState := idle}
+  } .elsewhen (io.state === coding) {
+    when      (io.coffee) { io.nextState := coding }
+    .elsewhen (io.idea || io.pressure) { io.nextState := writing }
+    .otherwise {io.nextState := idle}
+  } .elsewhen (io.state === writing) {
+    when      (io.coffee || io.idea) { io.nextState := writing }
+    .elsewhen (io.pressure) { io.nextState := grad }
+    .otherwise {io.nextState := idle}
+  }.otherwise {io.nextState := idle}
+}
+
+// Test
+test(new GradLife) { c =>
+  // verify that the hardware matches the golden model
+  for (state <- 0 to 3) {
+    for (coffee <- List(true, false)) {
+      for (idea <- List(true, false)) {
+        for (pressure <- List(true, false)) {
+          c.io.state.poke(state.U)
+          c.io.coffee.poke(coffee.B)
+          c.io.idea.poke(idea.B)
+          c.io.pressure.poke(pressure.B)
+          c.io.nextState.expect(gradLife(state, coffee, idea, pressure).U)
+        }
+      }
+    }
+  }
+}
+
+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.26-2.4 Sequential Logic.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.26-2.4 Sequential Logic.html new file mode 100644 index 0000000..ee65419 --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.26-2.4 Sequential Logic.html @@ -0,0 +1,317 @@ + + + + + + 2024.02.26-2.4 Sequential Logic | Personal Blog --from Outis Li + + + + + + + + +

# 2024.02.26-2.4 Sequential Logic

# Registers

A Reg holds its output value until the rising edge of its clock, at which time it takes on the value of its input.

class RegisterModule extends Module {
+  val io = IO(new Bundle {
+    val in  = Input(UInt(12.W))
+    val out = Output(UInt(12.W))
+  })
+
+	// val register : UInt = Reg(UInt(12.W))
+  val register = Reg(UInt(12.W))
+  register := io.in + 1.U
+  io.out := register
+}
+
+test(new RegisterModule) { c =>
+  for (i <- 0 until 100) {
+    c.io.in.poke(i.U)
+    c.clock.step(1)
+    c.io.out.expect((i + 1).U)
+  }
+}
+println("SUCCESS!!")
+

Notice: One important note is that Chisel distinguishes between types (like UInt) and hardware nodes (like the literal 2.U, or the output of myReg).

// legal because a Reg needs a data type as a model
+val myReg = Reg(UInt(2.W))
+// error because `2.U` is already a hardware node and can't be used as a model
+val myReg = Reg(2.U)
+

# RegInit

The register in RegisterModule was initialized to random data for simulation. Unless otherwised specified, registers do not have a reset value (or a reset). The way to create a register that resets to a given value is with RegInit.

// The first argument is a type node that specified the datatype and its width.
+// The second argument is a hardware node that specified the reset value, in this case 0.
+val myReg = RegInit(UInt(12.W), 0.U)
+
+// It is a hardware node that specifies the reset value, but normally `0.U`.
+val myReg = RegInit(0.U(12.W))
+

RegInit 不仅初始化,也创建了这个 reg,因此不需要先创建再 init

class RegInitModule extends Module {
+  val io = IO(new Bundle {
+    val in  = Input(UInt(12.W))
+    val out = Output(UInt(12.W))
+  })
+
+  val register = RegInit(0.U(12.W))
+  register := io.in + 1.U
+  io.out := register
+}
+

# RegNext

RegNext 在 Chisel 中是一个用于创建寄存器并在下一个时钟周期将输入信号的值传递给该寄存器的便捷方法。它简化了寄存器的声明和初始化,使得您可以轻松地创建一个将当前输入信号的值保存到下一个时钟周期的寄存器。使用RegNext时,可以指定一个初始值,如果不指定,则寄存器在复位时的值是未定义的

在 Chisel 中使用 RegNext 的基本语法如下:

val myReg = RegNext(inputSignal, initValue)
+
  • inputSignal 是你希望在下一个时钟周期传递给寄存器的信号。
  • initValue 是可选参数,用于指定寄存器在复位时的初始值。如果不提供初始值,寄存器在复位时的值是未定义的。

# Shift Register

Untitled

class MyShiftRegister(val init: Int = 1) extends Module {
+  val io = IO(new Bundle {
+    val in  = Input(Bool())
+    val out = Output(UInt(4.W))
+  })
+
+  val state = RegInit(UInt(4.W), init.U)
+  val stateTemp = (state << 1.U) + io.in.asUInt
+  state := stateTemp
+  io.out := state
+}
+
+test(new MyShiftRegister()) { c =>
+  var state = c.init
+  for (i <- 0 until 10) {
+    // poke in LSB of i (i % 2)
+    c.io.in.poke(((i % 2) != 0).B)
+    // update expected state
+    state = ((state * 2) + (i % 2)) & 0xf
+    c.clock.step(1)
+    c.io.out.expect(state.U)
+  }
+}
+println("SUCCESS!!")
+

# Parameterized Shift Register

// n is the output width (number of delays - 1)
+// init state to init
+class MyOptionalShiftRegister(val n: Int, val init: BigInt = 1) extends Module {
+  val io = IO(new Bundle {
+    val en  = Input(Bool())
+    val in  = Input(Bool())
+    val out = Output(UInt(n.W))
+  })
+
+  val state = RegInit(init.U(n.W))
+
+  when(io.en){
+    state := state << 1 | io.in
+  }
+  io.out := state
+}
+
+// test different depths
+for (i <- Seq(3, 4, 8, 24, 65)) {
+  println(s"Testing n=$i")
+  test(new MyOptionalShiftRegister(n = i)) { c =>
+    val inSeq = Seq(0, 1, 1, 1, 0, 1, 1, 0, 0, 1)
+    var state = c.init
+    var i = 0
+    c.io.en.poke(true.B)
+    while (i < 10 * c.n) {
+      // poke in repeated inSeq
+      val toPoke = inSeq(i % inSeq.length)
+      c.io.in.poke((toPoke != 0).B)
+      // update expected state
+      state = ((state * 2) + toPoke) & BigInt("1"*c.n, 2)
+      c.clock.step(1)
+      c.io.out.expect(state.U)
+
+      i += 1
+    }
+  }
+}
+println("SUCCESS!!")
+

Notice: Chisel 中变量被声明为常量val,因此一个变量只能被赋值一次,因为这表示硬件电路连接,但是会根据输入等的不同而具有不同的值。因此不能多次给一个变量赋值,如果需要,可以把中间值重新命名为一个val来调用

# Appendix: Explicit clock and reset

Chisel 模块默认使用隐式的时钟和复位信号,每个内部创建的寄存器都会使用这些默认信号。在某些情况下,你可能需要覆盖这种默认行为,比如使用生成时钟或复位信号的黑盒,或者设计多时钟系统。Chisel 提供了withClock() {}withReset() {}withClockAndReset() {}等构造来处理这些情况,允许分别或同时覆盖时钟和复位。需要注意的是,至本教程编写时,复位信号总是同步的并且是Bool类型。时钟在 Chisel 中有其自身的类型(Clock),并且应该相应声明。Bool类型可以通过调用asClock()转换为Clock类型,但需要确保这样做是合理的。同时,chisel-testers目前对多时钟设计的支持并不完全。

# Example: Multi-Clock Module

// we need to import multi-clock features
+import chisel3.experimental.{withClock, withReset, withClockAndReset}
+
+class ClockExamples extends Module {
+  val io = IO(new Bundle {
+    val in = Input(UInt(10.W))
+    val alternateReset    = Input(Bool())
+    val alternateClock    = Input(Clock())
+    val outImplicit       = Output(UInt())
+    val outAlternateReset = Output(UInt())
+    val outAlternateClock = Output(UInt())
+    val outAlternateBoth  = Output(UInt())
+  })
+
+  val imp = RegInit(0.U(10.W))
+  imp := io.in
+  io.outImplicit := imp
+
+  withReset(io.alternateReset) {
+    // everything in this scope with have alternateReset as the reset
+    val altRst = RegInit(0.U(10.W))
+    altRst := io.in
+    io.outAlternateReset := altRst
+  }
+
+  withClock(io.alternateClock) {
+    val altClk = RegInit(0.U(10.W))
+    altClk := io.in
+    io.outAlternateClock := altClk
+  }
+
+  withClockAndReset(io.alternateClock, io.alternateReset) {
+    val alt = RegInit(0.U(10.W))
+    alt := io.in
+    io.outAlternateBoth := alt
+  }
+}
+
+println(getVerilog(new ClockExamples))
+

通过import chisel3.experimental.{withClock, withReset, withClockAndReset}引入了多时钟特性。ClockExamples模块定义了一个 10 位宽的输入io.in,以及替代的复位和时钟信号io.alternateResetio.alternateClock。模块输出了四种不同情况下的寄存器值:使用默认时钟和复位、只替换复位、只替换时钟、同时替换时钟和复位。

  1. withReset(io.alternateReset) {...}块定义了一个新的作用域,其中所有寄存器的复位信号被替换为io.alternateReset。在这个作用域内,altRst寄存器在被替代复位信号复位时初始化为 0,并在每个时钟周期将io.in的值赋给它。
  2. withClock(io.alternateClock) {...}块定义了另一个作用域,其中所有寄存器的时钟信号被替换为io.alternateClock。在这个作用域内,altClk寄存器在被替代时钟信号驱动时初始化为 0,并在每个时钟周期将io.in的值赋给它。
  3. withClockAndReset(io.alternateClock, io.alternateReset) {...}块同时替换了寄存器的时钟和复位信号为io.alternateClockio.alternateReset。在这个作用域内,alt寄存器同时被替代的时钟和复位信号控制,初始化为 0,并在每个时钟周期将io.in的值赋给它。
+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.28-2.5 FIR Filter.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.28-2.5 FIR Filter.html new file mode 100644 index 0000000..fff80be --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.28-2.5 FIR Filter.html @@ -0,0 +1,211 @@ + + + + + + 2024.02.28-2.5 FIR Filter | Personal Blog --from Outis Li + + + + + + + + +

# 2024.02.28-2.5 FIR Filter

Untitled

class My4ElementFir(b0: Int, b1: Int, b2: Int, b3: Int) extends Module {
+  val io = IO(new Bundle {
+    val in = Input(UInt(8.W))
+    val out = Output(UInt(8.W))
+  })
+
+  val reg_1 = RegInit(0.U(8.W))
+  val reg_2 = RegInit(0.U(8.W))
+  val reg_3 = RegInit(0.U(8.W))
+
+  reg_1 := io.in
+  reg_2 := reg_1
+  reg_3 := reg_2
+
+	// 或者使用RegNext来一并定义初始化及赋值
+	val reg_1 = RegNext(io.in, 0.U)
+	val reg_2 = RegNext(reg_1, 0.U)
+	val reg_3 = RegNext(reg_2, 0.U)
+
+  io.out := b0.U(8.W) * io.in + b1.U(8.W) * reg_1 + b2.U(8.W) * reg_2 + b3.U(8.W) * reg_3
+}
+

# FIR Filter Generator

一个有限脉冲响应(FIR)滤波器生成器。生成器的length参数决定了滤波器的抽头数目,即滤波器的长度。这个生成器有三个输入:in(滤波器的输入信号)、valid(一个布尔值,表示输入是否有效)和consts(一个向量,包含所有抽头的系数)。还有一个输出out,即滤波器的输出。

  • taps是一个序列,包含输入和一系列寄存器,用于实现滤波器的延迟线。
  • valid信号为真时,序列中的每个元素(除了第一个)被更新为前一个元素的值。
  • 输出out是抽头值和对应系数乘积之和。

这个结构允许滤波器动态处理不同长度的输入,通过改变consts向量的内容来改变滤波器的特性。

class MyManyDynamicElementVecFir(length: Int) extends Module {
+  val io = IO(new Bundle {
+    val in = Input(UInt(8.W))
+    val valid = Input(Bool())
+    val out = Output(UInt(8.W))
+    val consts = Input(Vec(length, UInt(8.W)))
+  })
+
+  // Such concision! You'll learn what all this means later.
+  val taps = Seq(io.in) ++ Seq.fill(io.consts.length - 1)(RegInit(0.U(8.W)))
+  taps.zip(taps.tail).foreach { case (a, b) => when (io.valid) { b := a } }
+
+  io.out := taps.zip(io.consts).map { case (a, b) => a * b }.reduce(_ + _)
+}
+
+visualize(() => new MyManyDynamicElementVecFir(4))
+
  1. val io = IO(new Bundle {...})定义了模块的接口,包括 8 位宽的输入in,一个有效信号valid,8 位宽输出out,和长度为length的系数向量consts

  2. val taps = Seq(io.in) ++ Seq.fill(io.consts.length - 1)(RegInit(0.U(8.W)))这行代码在 FIR 滤波器实现中创建了一个名为taps的序列,用于存储当前和之前的输入值,从而实现数据的时间序列延迟。首先,它将输入信号io.in作为序列的第一个元素。随后,使用++操作符将io.in与一个新的序列连接起来,后者通过Seq.fill(io.consts.length - 1)(RegInit(0.U(8.W)))创建,其中包含length - 1个初始化为 0 的 8 位寄存器。这样,taps序列就包含了一个输入信号和length - 1个延迟寄存器,总共length个元素,每个元素对应滤波器的一个抽头。在 Chisel 中,虽然io.in不是寄存器,但taps序列可以包含不同类型的元素,因为在 Chisel 里,所有这些都被视为Data类型的子类,可以被综合为硬件。在这个上下文中,io.in是直接的输入信号,而后续元素是寄存器类型,但它们共同构成了一个序列,用于表示滤波器的不同时间点上的信号值。这种混合类型的序列是可行的,并可以在 Chisel 生成的硬件中正确表达相应的逻辑。

  3. taps.zip(taps.tail).foreach { case (a, b) => when (io.valid) { b := a } }在输入valid为真时,将taps序列中每个元素的值传递到下一个元素,实现数据在寄存器间的移动。

    zip是一个方法,它将两个集合中对应位置的元素组成一对,生成一个新的集合。在这里,taps.zip(taps.tail)的作用是将taps列表中的每个元素与其后面的元素配对。tail是一个方法,返回除第一个元素外的列表所有元素。例如,如果taps[in, reg1, reg2, reg3],那么taps.tail就是[reg1, reg2, reg3]taps.zip(taps.tail)的结果将是[(in, reg1), (reg1, reg2), (reg2, reg3)]。这样,foreach就可以遍历这些配对,根据valid信号更新寄存器的值,实现数据的逐级传递。

    case (a, b) =>是模式匹配的语法,用于解构元组,将zip操作生成的元素对分别赋值给a(当前元素)和b(下一个元素)。

  4. io.out := taps.zip(io.consts).map { case (a, b) => a * b }.reduce(_ + _)计算输出out,即将每个延迟元素与其对应的系数相乘,并将所有乘积求和得到最终结果。

    在这段代码中,mapreduce是 Scala 中的集合操作方法:

    • map:对集合中的每个元素应用一个函数。这里map { case (a, b) => a * b }对每对(a, b)应用乘法操作,a来自tapsb来自io.consts,分别代表寄存器中的数据和滤波器的系数。
    • reduce:对集合中的元素应用一个二元操作,逐步将集合减少为单一结果。这里的reduce(_ + _)将所有乘法结果相加,得到最终的滤波输出。

    不使用foreach是因为foreach仅用于执行操作而不返回结果,而这里的目的是计算经过滤波器后的输出值,需要通过mapreduce聚合计算结果。

+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.29-2.6 More on ChiselTest.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.29-2.6 More on ChiselTest.html new file mode 100644 index 0000000..03909a4 --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.29-2.6 More on ChiselTest.html @@ -0,0 +1,208 @@ + + + + + + 2024.02.29-2.6 More on ChiselTest | Personal Blog --from Outis Li + + + + + + + + +

# 2024.02.29-2.6 More on ChiselTest

iotesters ChiselTest
poke poke(c.io.in1, 6) c.io.in1.poke(6.U)
peek peek(c.io.out1) c.io.out1.peek()
expect expect(c.io.out1, 6) c.io.out1.expect(6.U)
step step(1) c.clock.step(1)
initiate Driver.execute(...) { c => test(...) { c =>

# Modules with Decoupled Interfaces

class QueueModule[T <: Data](ioType: T, entries: Int) extends MultiIOModule {
+  val in = IO(Flipped(Decoupled(ioType)))
+  val out = IO(Decoupled(ioType))
+  out <> Queue(in, entries)
+}
+
  1. class QueueModule[T <: Data](ioType: T, entries: Int) extends MultiIOModule 定义了一个泛型队列模块,其中T <: Data表示TData类型或其子类型。ioType是队列中数据的类型,entries是队列的大小。
  2. Decoupled(ioType)是一个 Chisel 提供的高级接口,自动包含了validbitsready信号。validbits组合用于传输有效数据,而ready信号用于流量控制。当你声明一个Decoupled接口时,这些信号都会被自动创建。
  3. IO(Flipped(Decoupled(ioType))) 创建了一个输入端口,Flipped意味着通常的输入输出方向被反转(即原本是输出的validbits成为输入,原本是输入的ready成为输出),Decoupled表示它是一个可以被反压的接口。
  4. out <> Queue(in, entries) 将输出端口out连接到一个新建的Queue实例,Queue(in, entries)创建了一个队列,其中in是输入端口,entries是队列大小。<>是连接操作符,表示双向连接。确保了数据可以从in流向队列,经过处理后,再从队列流向out

# EnqueueNow and expectDequeueNow

EnqueueNowexpectDequeueNow是用于测试队列行为的方法。EnqueueNow用于立即将数据入队,而不需要等待队列准备好。expectDequeueNow用于立即从队列中出队数据,并验证其值是否符合预期。这两个方法都是在基于队列的测试中非常有用,使得测试代码可以直接控制和验证队列中数据的流动。这样,测试者可以确保队列正确地处理了入队和出队操作,并且数据的传输符合设计的预期。

test(new QueueModule(UInt(9.W), entries = 200)) { c =>
+    // Example testsequence showing the use and behavior of Queue
+    c.in.initSource()
+    c.in.setSourceClock(c.clock)
+    c.out.initSink()
+    c.out.setSinkClock(c.clock)
+
+    val testVector = Seq.tabulate(200){ i => i.U }
+
+    testVector.zip(testVector).foreach { case (in, out) =>
+      c.in.enqueueNow(in)
+      c.out.expectDequeueNow(out)
+    }
+}
+

There is some required boiler plate initSource, setSourceClock, etc that is necessary to ensure that the ready and valid fields are all initialized correctly at the beginning of the test.

# EnqueueSeq and DequeueSeq

EnqueueSeq 允许你一次性将一个序列的元素批量入队,这对于测试需要连续多个数据处理的场景特别有用。DequeueSeq, 相应地,用于一次性从队列中出队多个元素,并验证这些元素是否符合预期的序列。enqueueSeq must finish before the expectDequeueSeq can begin. This example would fail if the testVector's size is made larger than the queue depth, because the queue would fill up and not be able to complete the enqueueSeq.

# Fork and Join

forkjoin用于创建并发测试,允许同时执行多个操作或测试场景。使用fork可以启动一个并发的测试过程,这个过程可以与主测试流程同时运行。可以在fork后使用多个测试命令定义并发执行的操作。随后,join用于等待所有并发启动的测试过程完成。这样,你可以在一个测试中执行多个并行操作,例如同时对多个模块输入不同的信号,或者同时观察多个输出。这在需要模拟复杂交互或并行处理时特别有用。

test(new QueueModule(UInt(9.W), entries = 200)) { c =>
+    // Example testsequence showing the use and behavior of Queue
+    c.in.initSource()
+    c.in.setSourceClock(c.clock)
+    c.out.initSink()
+    c.out.setSinkClock(c.clock)
+
+    val testVector = Seq.tabulate(300){ i => i.U }
+
+    fork {
+        c.in.enqueueSeq(testVector)
+    }.fork {
+        c.out.expectDequeueSeq(testVector)
+    }.join()
+}
+

虽然fork启动了两个并发过程,似乎表明c.in.enqueueSeq(testVector)c.out.expectDequeueSeq(testVector)应该同时执行,但实际上,它们在逻辑上是有先后顺序的。enqueueSeq首先向队列中填充数据,而expectDequeueSeq则等待这些数据从队列中出现并验证它们。在 ChiselTest 中,fork创建的并发线程会同时开始执行,但是expectDequeueSeq自然会在等待有数据可以出队之后才开始验证,确保了数据的正确流向和测试的逻辑顺序。

+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.01-3.1 Generators Parameters.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.01-3.1 Generators Parameters.html new file mode 100644 index 0000000..2f571b0 --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.01-3.1 Generators Parameters.html @@ -0,0 +1,429 @@ + + + + + + 2024.03.01-3.1 Generators: Parameters | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.01-3.1 Generators: Parameters

# Parameter Passing

# Example: Parameterized Scala Object

class ParameterizedScalaObject(param1: Int, param2: String) {
+  println(s"I have parameters: param1 = $param1 and param2 = $param2")
+}
+val obj1 = new ParameterizedScalaObject(4,     "Hello")
+val obj2 = new ParameterizedScalaObject(4 + 2, "World")
+

# Example: Parameterized Chisel Object

class ParameterizedWidthAdder(in0Width: Int, in1Width: Int, sumWidth: Int) extends Module {
+  require(in0Width >= 0)
+  require(in1Width >= 0)
+  require(sumWidth >= 0)
+  val io = IO(new Bundle {
+    val in0 = Input(UInt(in0Width.W))
+    val in1 = Input(UInt(in1Width.W))
+    val sum = Output(UInt(sumWidth.W))
+  })
+  // a +& b includes the carry, a + b does not
+  io.sum := io.in0 +& io.in1
+}
+
+println(getVerilog(new ParameterizedWidthAdder(1, 4, 6)))
+

The above code block has some require(...) statements. These are pre-elaboration assertions, which are useful when your generator only works with certain parameterizations or when some parameterizations are mutually exclusive or nonsensical. The above code block checks that widths are non-negative.

# Example: Parameterized 4-input Sort

Untitled

/ Sort4 sorts its 4 inputs to its 4 outputs */
+class Sort4(ascending: Boolean) extends Module {
+  val io = IO(new Bundle {
+    val in0 = Input(UInt(16.W))
+    val in1 = Input(UInt(16.W))
+    val in2 = Input(UInt(16.W))
+    val in3 = Input(UInt(16.W))
+    val out0 = Output(UInt(16.W))
+    val out1 = Output(UInt(16.W))
+    val out2 = Output(UInt(16.W))
+    val out3 = Output(UInt(16.W))
+  })
+
+  // this comparison funtion decides < or > based on the module's parameterization
+  def comp(l: UInt, r: UInt): Bool = {
+      if (ascending) {
+        l < r
+      } else {
+        l > r
+    }
+  }
+
+  val row10 = Wire(UInt(16.W))
+  val row11 = Wire(UInt(16.W))
+  val row12 = Wire(UInt(16.W))
+  val row13 = Wire(UInt(16.W))
+
+  when(comp(io.in0, io.in1)) {
+    row10 := io.in0            // preserve first two elements
+    row11 := io.in1
+  }.otherwise {
+    row10 := io.in1            // swap first two elements
+    row11 := io.in0
+  }
+
+  when(comp(io.in2, io.in3)) {
+    row12 := io.in2            // preserve last two elements
+    row13 := io.in3
+  }.otherwise {
+    row12 := io.in3            // swap last two elements
+    row13 := io.in2
+  }
+
+  val row21 = Wire(UInt(16.W))
+  val row22 = Wire(UInt(16.W))
+
+  when(comp(row11, row12)) {
+    row21 := row11            // preserve middle 2 elements
+    row22 := row12
+  }.otherwise {
+    row21 := row12            // swap middle two elements
+    row22 := row11
+  }
+
+  val row20 = Wire(UInt(16.W))
+  val row23 = Wire(UInt(16.W))
+  when(comp(row10, row13)) {
+    row20 := row10            // preserve the first and the forth elements
+    row23 := row13
+  }.otherwise {
+    row20 := row13            // swap the first and the forth elements
+    row23 := row10
+  }
+
+  when(comp(row20, row21)) {
+    io.out0 := row20            // preserve first two elements
+    io.out1 := row21
+  }.otherwise {
+    io.out0 := row21            // swap first two elements
+    io.out1 := row20
+  }
+
+  when(comp(row22, row23)) {
+    io.out2 := row22            // preserve first two elements
+    io.out3 := row23
+  }.otherwise {
+    io.out2 := row23            // swap first two elements
+    io.out3 := row22
+  }
+}
+

# Option and Defualt Arguments

val map = Map("a" -> 1)
+val a = map.get("a")
+println(a)
+val b = map.get("b")
+println(b)
+

在 Scala 中,Map.get(key)方法返回一个Option类型:如果键存在,则返回Some(value);如果键不存在,则返回None。在您的例子中,map.get("a")返回Some(1),因为"a"是映射中的一个键,值为 1。然而,map.get("b")返回None,因为"b"不是映射中的键。SomeNone用于 Scala 中以安全且表达性的方式处理值的存在或缺失,避免空指针异常。

val some = Some(1)
+val none = None
+println(some.get)          // Returns 1
+// println(none.get)       // Errors!
+println(some.getOrElse(2)) // Returns 1
+println(none.getOrElse(2)) // Returns 2
+

getOrElse是一个常用于Option类型的方法,它允许你为Option可能不包含值(即为None)的情况提供一个默认值。getOrElse接受一个参数,这个参数是当OptionNone时将返回的值。如果OptionSome,则getOrElse会返回包裹在Some中的值。

# Options for Parameters with Defaults

class DelayBy1(resetValue: Option[UInt] = None) extends Module {
+    val io = IO(new Bundle {
+        val in  = Input( UInt(16.W))
+        val out = Output(UInt(16.W))
+    })
+    val reg = if (resetValue.isDefined) { // resetValue = Some(number)
+        RegInit(resetValue.get)
+    } else { //resetValue = None
+        Reg(UInt())
+    }
+    reg := io.in
+    io.out := reg
+}
+
+println(getVerilog(new DelayBy1))
+println(getVerilog(new DelayBy1(Some(3.U))))
+

resetValue 默认初始化为 Option[UInt] = NoneReg(UInt()) 可以从上下文中自动推断,不过最好还是指定位宽

// 还可以用match来实现ifelse
+class DelayBy1(resetValue: Option[UInt] = None) extends Module {
+  val io = IO(new Bundle {
+    val in  = Input( UInt(16.W))
+    val out = Output(UInt(16.W))
+  })
+  val reg = resetValue match {
+    case Some(r) => RegInit(r)
+    case None    => Reg(UInt())
+  }
+  reg := io.in
+  io.out := reg
+}
+

# Match/Case Statements

Scala 中的匹配概念在 Chisel 中被广泛使用,是每个 Chisel 程序员必须理解的基础知识。Scala 提供的 match 操作符支持以下功能:

  • 用于检测多种情况的简单测试,类似于 C 语言中的 switch 语句。
  • 对值的复杂组合进行测试。
  • 根据变量的类型采取行动,当变量类型未知或未完全指定时,例如: +
    • 从异构列表中取变量,如val mixedList = List(1, "string", false)
    • 变量已知属于一个超类,但不确定是哪个具体的子类。
  • 使用正则表达式提取字符串的子串。

# Example: Value Matching

// y is an integer variable defined somewhere else in the code
+val y = 7
+/// ...
+val x = y match {
+  case 0 => "zero" // One common syntax, preferred if fits in one line
+  case 1 =>        // Another common syntax, preferred if does not fit in one line.
+      "one"        // Note the code block continues until the next case
+  case 2 => {      // Another syntax, but curly braces are not required
+      "two"
+  }
+  case _ => "many" // _ is a wildcard that matches all values
+}
+println("y is " + x) // out: y is many
+

y 为 7,不匹配,因此采用默认值

  • 每个跟在=>操作符后面的代码块都会继续执行,直到它到达match的结束大括号或下一个case语句。
  • match会按照case语句的顺序进行搜索,一旦匹配到一个case语句,就不会再对其他case语句进行检查。
  • 使用下划线_作为通配符,来处理任何未找到匹配的值。

# Example: Multiple Value Matching

def animalType(biggerThanBreadBox: Boolean, meanAsCanBe: Boolean): String = {
+  (biggerThanBreadBox, meanAsCanBe) match {
+    case (true, true) => "wolverine"
+    case (true, false) => "elephant"
+    case (false, true) => "shrew"
+    case (false, false) => "puppy"
+  }
+}
+println(animalType(true, true)) // wolverine
+

# Example: Type Matching

val sequence = Seq("a", 1, 0.0)
+sequence.foreach { x =>
+  x match {
+    case s: String => println(s"$x is a String")
+    case s: Int    => println(s"$x is an Int")
+    case s: Double => println(s"$x is a Double")
+    case _ => println(s"$x is an unknown type!")
+  }
+}
+

Seq是 Scala 集合中的一个接口,它代表序列,而ListSeq的一个具体实现。在这个例子中,可以直接用List("a", 1, 0.0)来代替Seq("a", 1, 0.0),而不会影响foreachmatch语句的行为。

# Example: Multiple Type Matching

If you want to match on whether a value has one of many types, use the following syntax. Note that you must use an _ when matching.

val sequence = Seq("a", 1, 0.0)
+sequence.foreach { x =>
+  x match {
+    case _: Int | _: Double => println(s"$x is a number!")
+    case _ => println(s"$x is an unknown type!")
+  }
+}
+

# Example: Type Matching and Erasure

类型匹配在 Scala 中有一些限制。由于 Scala 运行在 JVM 上,而 JVM 不保持多态类型信息,因此你不能在运行时基于它们进行匹配(因为这些类型信息已被擦除)。注意下面的例子始终匹配第一个 case 语句,因为[String][Int][Double]这些多态类型在运行时被擦除了,case 语句实际上只是在匹配Seq

val sequence = Seq(Seq("a"), Seq(1), Seq(0.0))
+sequence.foreach { x =>
+  x match {
+    case s: Seq[String] => println(s"$x is a String")
+    case s: Seq[Int]    => println(s"$x is an Int")
+    case s: Seq[Double] => println(s"$x is a Double")
+  }
+}
+

在 Scala 中,类型擦除指的是 JVM 在运行时不保留泛型的具体类型信息。因此,当你对Seq[String]Seq[Int]Seq[Double]进行模式匹配时,JVM 实际上无法区分这些Seq的元素类型,因为泛型信息[String][Int][Double]已经被擦除,只留下了基础的Seq类型。所以,这些 case 语句在运行时都被视为对Seq类型的匹配,而无法区分具体是哪种Seq。因此,匹配总是成功于第一个 case,无论其实际参数是什么类型的Seq。这就是为什么在运行时你看到的行为似乎是它总是匹配Seq的原因。

# IOs with Optional Fields

有时我们希望 IO 端口能够根据需要选择性地包含或排除。例如,在调试时可能需要查看一些内部状态,但在生成器用于系统时希望将其隐藏。或者,你的生成器可能有一些输入在某些情况下不需要连接,因为存在合理的默认值。

# Example: Optional IO with Option

示例中展示了一个可选地接收进位信号的一位加法器。如果包含进位,io.carryIn将是Some[UInt]类型并包含在 IO 束中;如果不包含进位,io.carryIn将是None类型并从 IO 束中排除。

class HalfFullAdder(val hasCarry: Boolean) extends Module {
+  val io = IO(new Bundle {
+    val a = Input(UInt(1.W))
+    val b = Input(UInt(1.W))
+    val carryIn = if (hasCarry) Some(Input(UInt(1.W))) else None
+    val s = Output(UInt(1.W))
+    val carryOut = Output(UInt(1.W))
+  })
+  val sum = io.a +& io.b +& io.carryIn.getOrElse(0.U)
+  io.s := sum(0)
+  io.carryOut := sum(1)
+}
+

# Example: Optional IO with Zero-Width Wires

class HalfFullAdder(val hasCarry: Boolean) extends Module {
+  val io = IO(new Bundle {
+    val a = Input(UInt(1.W))
+    val b = Input(UInt(1.W))
+    val carryIn = Input(if (hasCarry) UInt(1.W) else UInt(0.W))
+    val s = Output(UInt(1.W))
+    val carryOut = Output(UInt(1.W))
+  })
+  val sum = io.a +& io.b +& io.carryIn
+  io.s := sum(0)
+  io.carryOut := sum(1)
+}
+

也可以用一个 0 宽度的 wire 来代替 None。An IO with width zero is pruned from the emitted Verilog, and anything that tries to use the value of a zero-width wire gets a constant zero.

# Implicits

为了减少大量重复的模板代码,Scala 引入了*隐式(implicits)*的概念,允许编译器为你自动进行一些语法简化。由于很多操作是在背后进行,隐式使用可能显得很神奇。

# Implicit Arguments

隐式参数的一个常见用途是当你的代码在深层的函数调用中需要访问某个顶层变量时,可以使用隐式参数自动传递这个变量,而不是手动在每个函数调用中传递它。

# Example: Implicit Cats

object CatDog {
+  implicit val numberOfCats: Int = 3
+  //implicit val numberOfDogs: Int = 5
+
+  def tooManyCats(nDogs: Int)(implicit nCats: Int): Boolean = nCats > nDogs
+
+  val imp = tooManyCats(2)    // Argument passed implicitly!
+  val exp = tooManyCats(2)(1) // Argument passed explicitly!
+}
+CatDog.imp
+CatDog.exp
+

首先,我们定义了一个隐式值numberOfCats。在给定的作用域中,同一类型的隐式值只能有一个。然后,我们定义了一个函数,它接受两个参数列表;第一个是任何显式参数,第二个是任何隐式参数。当我们调用tooManyCats时,我们可以省略第二个隐式参数列表(让编译器为我们找到它),或者显式提供一个参数(这个参数可以与隐式值不同)。

隐式参数可能失败的情况包括:

  • 在一个作用域中定义了给定类型的两个或多个隐式值
  • 如果编译器找不到调用函数所需的隐式值

object定义了一个单例对象,它是一个类的单一实例。与class不同,当你定义一个object时,Scala 会自动为你创建这个类的一个实例。你不需要使用new关键字来创建它的实例。在这个例子中,CatDog是一个单例对象,可以直接访问其成员,无需创建实例。这在定义工具方法或当你需要一个全局唯一的实体时非常有用,比如这里的numberOfCats隐式值和tooManyCats方法。

# Example: Implicit Logging

sealed trait Verbosity
+implicit case object Silent extends Verbosity
+case object Verbose extends Verbosity
+
+class ParameterizedWidthAdder(in0Width: Int, in1Width: Int, sumWidth: Int)(implicit verbosity: Verbosity)
+extends Module {
+  def log(msg: => String): Unit = verbosity match {
+    case Silent =>
+    case Verbose => println(msg)
+  }
+  require(in0Width >= 0)
+  log(s"in0Width of $in0Width OK")
+  require(in1Width >= 0)
+  log(s"in1Width of $in1Width OK")
+  require(sumWidth >= 0)
+  log(s"sumWidth of $sumWidth OK")
+  val io = IO(new Bundle {
+    val in0 = Input(UInt(in0Width.W))
+    val in1 = Input(UInt(in1Width.W))
+    val sum = Output(UInt(sumWidth.W))
+  })
+  log("Made IO")
+	// 对于结果位宽自然容纳进位的情况,直接使用+也是可行的。
+  io.sum := io.in0 + io.in1
+  log("Assigned output")
+}
+
+println(getVerilog(new ParameterizedWidthAdder(1, 4, 5)))
+println(getVerilog(new ParameterizedWidthAdder(1, 4, 5)(Verbose)))
+
  1. 定义了一个名为Verbosity的密封特质(sealed trait)和两个实现这个特质的对象。sealed trait Verbosity表示Verbosity是一个可以被继承的类型,但所有继承它的类必须定义在同一个文件中,这有助于实现模式匹配的完整性检查。implicit case object Silent extends Verbosity定义了一个隐式的单例对象Silent,它是Verbosity的一个实现,可以在需要Verbosity类型的隐式参数时自动使用。case object Verbose extends Verbosity定义了另一个名为Verbose的单例对象,也是Verbosity的实现。case object通常用于代表不可变、无状态的值或单例定义.
  2. msg: => String这样的参数定义使用了名为“call-by-name”的参数传递机制。这种机制意味着,只有在函数内部实际使用到msg时,传入的字符串表达式才会被计算。这对于条件日志记录来说非常有用,因为它允许延迟计算日志消息直到确实需要打印消息时。例如,如果verbositySilent,则msg根本不会被计算,这样就避免了不必要的性能开销。

# Implicit Conversions

隐式函数(也称为隐式转换)用于减少模板代码。更具体地说,它们用于自动将一个 Scala 对象转换为另一个对象。

# Example: Implicit Conversion

在下面的例子中,我们有两个类,AnimalHumanAnimal有一个species字段,但Human没有。然而,通过实现一个隐式转换,我们可以在Human上调用species方法。这意味着即使Human类原本不包含species字段,通过隐式转换,我们也可以像访问自己的属性一样访问species,就好像这个属性是Human类的一部分一样。

class Animal(val name: String, val species: String)
+class Human(val name: String)
+implicit def human2animal(h: Human): Animal = new Animal(h.name, "Homo sapiens")
+val me = new Human("Adam")
+println(me.species)
+
+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.03-3.2 Generators Collections.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.03-3.2 Generators Collections.html new file mode 100644 index 0000000..6ab2ff2 --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.03-3.2 Generators Collections.html @@ -0,0 +1,313 @@ + + + + + + 2024.03.03-3.2 Generators: Collections | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.03-3.2 Generators: Collections

# Generators and Collections

# FIR Golden Model

/
+  * A naive implementation of an FIR filter with an arbitrary number of taps.
+  */
+class ScalaFirFilter(taps: Seq[Int]) {
+  var pseudoRegisters = List.fill(taps.length)(0)
+
+  def poke(value: Int): Int = {
+    pseudoRegisters = value :: pseudoRegisters.take(taps.length - 1)
+    var accumulator = 0
+    for(i <- taps.indices) {
+      accumulator += taps(i) * pseudoRegisters(i)
+    }
+    accumulator
+  }
+}
+

# Seq

taps变为Seq[Int]时,意味着类的用户可以在构造类时传递任意长度的Int序列。

# 寄存器

使用var pseudoRegisters = List.fill(taps.length)(0)创建了一个List,用于存储前几个周期的值。选择List是因为其添加元素到头部和移除最后一个元素的语法非常简单。理论上可以使用 Scala 集合家族中的任何成员。这个列表被初始化为全零。

# Poke

我们的类添加了一个 poke 函数/方法,模拟将新输入放入过滤器并循环时钟。

# 更新寄存器

pseudoRegisters = value :: pseudoRegisters.take(taps.length - 1)首先使用列表的take方法保留除最后一个元素外的所有元素,然后使用::列表连接操作符将value添加到缩减版列表的头部。

# 计算输出

一个简单的 for 循环和累加器用于求和列表中每个元素与其对应抽头系数的乘积。仅含accumulator的行将该值作为函数结果返回。

# Test circuit using the golden model

为了避免使用繁杂的手动验证,这里使用 Golden Model 来生成期望的值,并与 Chisel 的结果对比

val goldenModel = new ScalaFirFilter(Seq(1, 1, 1, 1))
+
+test(new My4ElementFir(1, 1, 1, 1)) { c =>
+    for(i <- 0 until 100) {
+        val input = scala.util.Random.nextInt(8)
+
+        val goldenModelResult = goldenModel.poke(input)
+
+        c.io.in.poke(input.U)
+
+        c.io.out.expect(goldenModelResult.U, s"i $i, input $input, gm $goldenModelResult, ${c.io.out.peek().litValue}")
+
+        c.clock.step(1)
+    }
+
+}
+

注意:这里软件上的 Golden Model 没有考虑位宽,而硬件则与位宽有很大关系。这里只考虑了 8 以内,即 3bit 的数,因此不存在这个问题

# Example: Parameterized FIR Generator

class MyManyElementFir(consts: Seq[Int], bitWidth: Int) extends Module {
+  val io = IO(new Bundle {
+    val in = Input(UInt(bitWidth.W))
+    val out = Output(UInt(bitWidth.W))
+  })
+
+  val regs = mutable.ArrayBuffer[UInt]()
+  for(i <- 0 until consts.length) {
+      if(i == 0) regs += io.in
+      else       regs += RegNext(regs(i - 1), 0.U)
+  }
+
+  val muls = mutable.ArrayBuffer[UInt]()
+  for(i <- 0 until consts.length) {
+      muls += regs(i) * consts(i).U
+  }
+
+  val scan = mutable.ArrayBuffer[UInt]()
+  for(i <- 0 until consts.length) {
+      if(i == 0) scan += muls(i)
+      else scan += muls(i) + scan(i - 1)
+  }
+
+  io.out := scan.last
+}
+
  1. val regs = mutable.ArrayBuffer[UInt]()声明了一个名为regs的不可变变量,它被初始化为一个可变的ArrayBuffer,其中包含UInt类型的元素。ArrayBuffer是一个可变的序列,允许在序列两端高效地添加或删除元素,适用于需要动态修改元素的场景。在这里,regs可以被用来存储和更新UInt类型的数据,但由于使用了valregs本身的引用是不可变的,尽管它指向的ArrayBuffer内容是可变的。
  2. regs += io.in这行代码的意思是将io.in这个UInt信号添加到regs这个ArrayBuffer中。这里没有直接的数值相加操作,而是将io.in这个元素添加(追加)到regs这个列表的末尾。regs是一个容器,可以逐个添加元素,即使一开始regs是空的。这行代码的作用是初始化regs列表的第一个元素,后续元素则在循环中通过RegNext添加。
  3. regs作为一个ArrayBuffer,可以包含不同类型的UInt元素。在这种情况下,io.in是一个Input(UInt)类型,而RegNext(regs(i - 1), 0.U)生成的是一个Reg(UInt)类型。尽管io.in和通过RegNext创建的寄存器在硬件层面扮演不同的角色(一个是输入信号,另一个是寄存器),但它们都是UInt类型,可以存储在同一个ArrayBuffer中。在 Chisel 生成的硬件逻辑中,这将创建一个信号和寄存器链,其中信号和寄存器可以互相连接。
  4. 使用scan数组缓存逐步累加的结果而不是直接对muls求和,是为了展示在每一步如何逐渐累积计算的中间值。这种方法在某些复杂的 FIR 滤波器设计中可以提供更多的灵活性,比如在需要逐个访问累加过程中的中间结果时。尽管在这个特定例子中,只需要最终的累加结果,直接对muls求和看似更直接,但展开累加过程可以帮助理解和调试滤波器的行为,尤其是在更复杂或参数化的设计中。然而,如果目标只是获取最终的累加和,直接使用muls.reduce(_ + _)确实会更简洁高效。

# Test a bunch of different sized FIR filters

def r(): Int = {
+  scala.util.Random.nextInt(1024)
+}
+
+/
+  * run a test comparing software and hardware filters
+  * run for at least twice as many samples as taps
+  */
+def runOneTest(taps: Seq[Int]) {
+    val goldenModel = new ScalaFirFilter(taps)
+
+    test(new MyManyElementFir(taps, 32)) { c =>
+        for(i <- 0 until 2 * taps.length) {
+            val input = r()
+
+            val goldenModelResult = goldenModel.poke(input)
+
+            c.io.in.poke(input.U)
+
+            c.io.out.expect(goldenModelResult.U, s"i $i, input $input, gm $goldenModelResult, ${c.io.out.peek().litValue}")
+
+            c.clock.step(1)
+        }
+    }
+}
+
+for(tapSize <- 2 until 100 by 10) {
+    val taps = Seq.fill(tapSize)(r())  // create a sequence of random coefficients
+
+    runOneTest(taps)
+}
+
  1. 在 Chisel 测试中,c.clock.step(1)通常放在对输出进行期望检查(expect)之后,因为我们希望在提供输入后推进仿真一个时钟周期,然后在下一个时钟边沿检查输出。这样可以确保寄存器已经更新到了因输入变化而触发的新状态。
  2. 字符串s"i $i, input $input, gm $goldenModelResult, ${c.io.out.peek().litValue}"是 Scala 的字符串插值,用于构造包含变量值的字符串。这里它构建了一个描述当前测试状态的字符串,包括迭代次数i,当前输入input,金标准模型goldenModel的结果goldenModelResult,以及从待测试模块的输出c.io.out中提取的值。这对于调试和理解测试失败的上下文非常有用。

# Hardware Collections

# Example: Add run-time configurable taps to our FIR

在 FIR 生成器的 IO 中添加了一个额外的consts向量,允许在电路生成后从外部改变系数。这是通过 Chisel 集合类型Vec实现的。Vec支持许多 Scala 集合方法,但只能包含 Chisel 硬件元素。仅在普通 Scala 集合无法满足需求的情况下使用Vec,主要是以下两种情况:1. 在 Bundle 中需要元素集合,通常是作为 IO 使用的 Bundle。2. 需要通过硬件部分的索引访问集合(如寄存器文件)。

原因在于Vec能够创建一组硬件元素的集合,而这些硬件元素可以在生成的硬件电路中被索引和操作。相反,普通的 Scala 集合,如ListSeq,仅仅在 Scala 软件环境中存在,它们不能直接映射到硬件电路中。因此,当定义硬件模块的 IO 接口或需要在硬件级别按索引访问元素时,应该使用Vec

class MyManyDynamicElementVecFir(length: Int) extends Module {
+  val io = IO(new Bundle {
+    val in = Input(UInt(8.W))
+    val out = Output(UInt(8.W))
+    val consts = Input(Vec(length, UInt(8.W)))
+  })
+
+  // Reference solution
+  val regs = RegInit(VecInit(Seq.fill(length)(0.U(8.W))))
+  for(i <- 0 until length) {
+      if(i == 0) regs(i) := io.in
+      else       regs(i) := regs(i - 1)
+  }
+
+  val muls = Wire(Vec(length, UInt(8.W)))
+  for(i <- 0 until length) {
+      if(i == 0) muls(i) := io.in * io.consts(i)
+      else       muls(i) := regs(i - 1) * io.consts(i)
+  }
+
+  val scan = Wire(Vec(length, UInt(8.W)))
+  for(i <- 0 until length) {
+      if(i == 0) scan(i) := muls(i)
+      else scan(i) := muls(i) + scan(i - 1)
+  }
+
+  io.out := scan(length - 1)
+}
+
  1. VecInit用于创建一个Vec,这是 Chisel 中的一种集合类型,专门用于存储硬件元素。Seq.fill(length - 1)(0.U(8.W))生成一个长度为length - 1,每个元素初始化为 8 位宽的 0 的序列。VecInit将这个序列转换成一个Vec,以便在硬件设计中使用。RegInit则将这个Vec初始化为寄存器,使得其值在复位时为指定的初始值。这种方式常用于定义具有多个初始相同值的寄存器数组。

  2. Wire(Vec(length, UInt(8.W))) 用于创建一个具有 length 元素的向量,每个元素是 8 位无符号整数。这是在硬件描述语言中创建信号数组的标准方法,允许这些信号在生成的硬件电路中被实例化。

    相比之下,mutable.ArrayBuffer[UInt]() 是 Scala 的一个集合类型,主要用于软件程序中的数据存储和处理。在 Chisel 的上下文中,你不能直接将 ArrayBuffer 用作硬件信号的容器,因为 ArrayBuffer 是一个可变的、仅在 Scala 软件执行环境中存在的数据结构,它不会被合成到硬件中。

    简单来说:

    • Wire(Vec(length, UInt(8.W))) 在 Chisel 中创建一个硬件向量,这个向量可以在生成的硬件电路中存在并携带信号。
    • mutable.ArrayBuffer[UInt]() 创建一个仅在 Scala 软件执行时存在的内存数组,它不能直接用于硬件设计。

    所以,在你的代码中使用 Wire(Vec(length, UInt(8.W))) 是为了定义一个可以在硬件层面操作和传递信号的向量,这对于硬件设计至关重要。

    # Example: 32-bit RISC-V Processor

    Register file: An array of registers that can be read from or written to via a number of read or write ports. Each port consists of an address and data field.

    class RegisterFile(readPorts: Int) extends Module {
    +    require(readPorts >= 0)
    +    val io = IO(new Bundle {
    +        val wen   = Input(Bool())
    +        val waddr = Input(UInt(5.W))
    +        val wdata = Input(UInt(32.W))
    +        val raddr = Input(Vec(readPorts, UInt(5.W)))
    +        val rdata = Output(Vec(readPorts, UInt(32.W)))
    +    })
    +
    +    // A Register of a vector of UInts
    +    val reg = RegInit(VecInit(Seq.fill(32)(0.U(32.W))))
    +
    +    when(io.wen){
    +        reg(io.waddr) := io.wdata
    +    }
    +    for(i <- 0 until readPorts){
    +        when(io.raddr(i) === 0.U){
    +            io.rdata(i) := 0.U
    +        }.otherwise{
    +            io.rdata(i) := reg(io.raddr(i))
    +        }
    +    }
    +}
    +

    readPorts 表示寄存器文件的读端口数量。这个数量决定了在任何给定的时钟周期内,可以同时读取多少个独立寄存器的数据。每个读端口由其自己的读取地址(raddr)和读取数据(rdata)组成。在这种设置中,你可以在一个时钟周期内并行读取多个寄存器的值,而不是一次只能读取一个,这对于增加处理器的数据吞吐量非常有用。

    具体到代码:

    • readPorts:定义了有多少个并行的读端口可用于同时读取寄存器文件中的数据。
    • io.raddr:一个向量,包含了每个读端口对应的读取地址。每个读端口都可以独立地从寄存器文件中选择一个寄存器进行读取。
    • io.rdata:一个向量,用于输出每个读端口读取到的寄存器值。每个端口根据对应的raddr读取寄存器文件中的数据,并将其放置在rdata的相应位置。
+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.04-3.3 Interlude Chisel Standard Library.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.04-3.3 Interlude Chisel Standard Library.html new file mode 100644 index 0000000..d2dbe8f --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.04-3.3 Interlude Chisel Standard Library.html @@ -0,0 +1,518 @@ + + + + + + 2024.03.04-3.3 Interlude: Chisel Standard Library | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.04-3.3 Interlude: Chisel Standard Library

# Decoupled: A Standard Ready-Valid Interface

在 Chisel 中,DecoupledIO 是一种标准的准备就绪(ready-valid)接口,广泛用于不同模块间的数据传输,提供了一种带有流控制的通信机制。使用 DecoupledIO 可以有效地处理数据传输的同步问题,特别是在生产者(source)和消费者(sink)速率不匹配时,确保数据的正确传输与接收。

# 组件

DecoupledIO 接口由以下三个主要部分组成:

  1. valid(有效) - 这是一个输出信号(从数据源角度看),用于表明当前的数据是有效的,可以被读取。当数据源有数据准备好发送时,它会将 valid 信号置为高电平。
  2. ready(准备就绪) - 这是一个输入信号(从数据源角度看),用于表明目标模块(接收端)准备好接收数据。当接收端可以接收新的数据时,它会将 ready 信号置为高电平。
  3. bits(数据位) - 这个信号承载了要传输的实际数据。数据的宽度和类型可以是任意的,从简单的 UIntBool 到复杂的用户定义 Bundle

# 数据传输

DecoupledIO 接口中,数据传输在以下条件下发生:

  • 数据源设置 valid 为高电平,表示其有数据要发送。
  • 接收端设置 ready 为高电平,表示其准备好接收数据。

当且仅当同一时钟周期内 validready 同时为高电平时,数据才会被传输。这允许在接收端或发送端任一端控制数据流,实现背压(backpressure)机制:

  • 如果接收端未准备好接收(ready 为低),即使发送端有数据发送(valid 为高),数据也不会被传输。
  • 如果发送端没有数据要发送(valid 为低),即使接收端准备好了(ready 为高),也不会有数据传输。

# 使用场景

DecoupledIO 非常适用于生产者和消费者速率不一致的情况,如:

  • 在 FIFO 队列的实现中,确保数据不会在缓冲区满时被写入,或在缓冲区空时被读出。
  • 在处理器设计中,用于不同执行单元间的数据传输,确保在数据未准备好或处理单元未准备好时不发生数据传输。

# 代码示例

以下是如何在 Chisel 中创建一个 DecoupledIO 接口的简单示例:

val data = UInt(8.W) // 定义数据宽度
+val decoupledData = Decoupled(data) // 创建 DecoupledIO 接口
+

这里,decoupledData 将是一个拥有 validreadybits 字段的 DecoupledIO Bundle,可用于模块间的数据传输。

# Queue

test(new Module {
+    // Example circuit using a Queue
+    val io = IO(new Bundle {
+      val in = Flipped(Decoupled(UInt(8.W)))
+      val out = Decoupled(UInt(8.W))
+    })
+    val queue = Queue(io.in, 2)  // 2-element queue
+    io.out <> queue
+  }) { c =>
+    c.io.out.ready.poke(false.B)
+    c.io.in.valid.poke(true.B)  // Enqueue an element
+    c.io.in.bits.poke(42.U)
+    println(s"Starting:")
+    println(s"\tio.in: ready=${c.io.in.ready.peek().litValue}")
+    println(s"\tio.out: valid=${c.io.out.valid.peek().litValue}, bits=${c.io.out.bits.peek().litValue}")
+    c.clock.step(1)
+
+    c.io.in.valid.poke(true.B)  // Enqueue another element
+    c.io.in.bits.poke(43.U)
+    // What do you think io.out.valid and io.out.bits will be?
+    println(s"After first enqueue:")
+    println(s"\tio.in: ready=${c.io.in.ready.peek().litValue}")
+    println(s"\tio.out: valid=${c.io.out.valid.peek().litValue}, bits=${c.io.out.bits.peek().litValue}")
+    c.clock.step(1)
+
+    c.io.in.valid.poke(true.B)  // Read a element, attempt to enqueue
+    c.io.in.bits.poke(44.U)
+    c.io.out.ready.poke(true.B)
+    // What do you think io.in.ready will be, and will this enqueue succeed, and what will be read?
+    println(s"On first read:")
+    println(s"\tio.in: ready=${c.io.in.ready.peek().litValue}")
+    println(s"\tio.out: valid=${c.io.out.valid.peek().litValue}, bits=${c.io.out.bits.peek().litValue}")
+    c.clock.step(1)
+
+    c.io.in.valid.poke(false.B)  // Read elements out
+    c.io.out.ready.poke(true.B)
+    // What do you think will be read here?
+    println(s"On second read:")
+    println(s"\tio.in: ready=${c.io.in.ready.peek().litValue}")
+    println(s"\tio.out: valid=${c.io.out.valid.peek().litValue}, bits=${c.io.out.bits.peek().litValue}")
+    c.clock.step(1)
+
+    // Will a third read produce anything?
+    println(s"On third read:")
+    println(s"\tio.in: ready=${c.io.in.ready.peek().litValue}")
+    println(s"\tio.out: valid=${c.io.out.valid.peek().litValue}, bits=${c.io.out.bits.peek().litValue}")
+    c.clock.step(1)
+}
+
Starting:
+	io.in: ready=1
+	io.out: valid=0, bits=0
+After first enqueue:
+	io.in: ready=1
+	io.out: valid=1, bits=42
+On first read:
+	io.in: ready=0
+	io.out: valid=1, bits=42
+On second read:
+	io.in: ready=1
+	io.out: valid=1, bits=43
+On third read:
+	io.in: ready=1
+	io.out: valid=0, bits=42
+
  1. val in = Flipped(Decoupled(UInt(8.W))) 这里的Flipped表示是Input,因为Decoupled默认是Output

  2. val queue = Queue(io.in, 2) 连接 io.in 到队列的输入端: 这意味着 io.in 上发生的任何事情(比如信号变化)都会直接影响到队列。具体来说,当您在测试代码中设置 io.in.validio.in.bits,您实际上是在向队列的入队端提供数据。

  3. io.out <> queue 时,你实际上是在将模块的输出接口 io.out 和队列 queue 的出队接口双向连接。

    具体来说,对于 DecoupledIO 接口:

    • io.out.valid 会连接到 queue.io.deq.valid
    • io.out.bits 会连接到 queue.io.deq.bits
    • queue.io.deq.ready 会连接到 io.out.ready

    这种连接方式确保了数据可以从 queue 的出队端传输到模块的输出 io.out,同时允许 io.out 控制背压(通过 ready 信号)以及 queue 报告其状态(通过 valid 信号)。

  • 开始时: +
    • 首先,输出端 io.out.ready 被设为 false,表示消费者还没准备好接收数据。
    • 输入端 io.in.valid 被设为 true,并通过 io.in.bits 提供了值 42,尝试将其入队。
    • 打印的输出显示,初始时,io.in.ready 应该为 true(队列未满,可以接收数据),而 io.out.valid 应该为 false(数据尚未出队到输出端)。
  • 首次入队后: +
    • 程序尝试将另一个值 43 入队,并再次检查状态。
    • 由于队列不满,第二个值应该成功入队。io.in.ready 仍然为 true,表明还可以接收更多数据。
    • io.out.valid 被设置为 true 并且 io.out.bits 被更新为 42,因为队列内部确实有一个元素(42)准备好了并且尝试发送。即使 io.out.readyfalseio.out.validio.out.bits 仍然会反映队列出口处的数据状态。
    • 尽管 io.out.validtrue 并且 io.out.bits 显示了数据(42),但由于 io.out.readyfalse,这次数据传输并不会真正完成。换句话说,42 在逻辑上是"准备发送"的,但由于缺乏接收准备就绪的确认(即 io.out.readyfalse),它实际上并没有"被接收"。
  • 首次读取尝试: +
    • 程序尝试同时进行读取(将 io.out.ready 设为 true)和入队(值 44)。
    • 由于此时输出准备好接收数据,第一个入队的值(42)应该会被传递到 io.outio.out.valid 应变为 trueio.out.bits 应显示 42。
    • io.in.ready0。这是因为队列(queue)此时已经满了。
  • 第二次读取: +
    • 这时不再有新数据入队,但 io.out 准备好读取数据。
    • 应该能读取到之前入队的第二个值 43,io.out.valid 应为 trueio.out.bits 应显示 43。
  • 第三次读取尝试: +
    • 在这一步,尽管 io.out 依然准备好接收数据,但队列应该已经空了。
    • 因此,io.out.valid 应该变回 false,表示没有更多数据可读。
    • 不过为什么是 42? +注:
    1. peek() 函数用于查看信号的当前值,而 .litValue 用于获取这个值作为一个 Scala 的字面量(literal)。因此,c.io.in.ready.peek().litValue 表示查看 c.io.in.ready 信号的当前值,并获取其字面量值。
    2. 必须要c.clock.step(1)以后才会有输出

# Arbiter

一个 Arbiter 是用于解决多个请求源争用单一资源的组件。它的基本功能是在多个输入信号中选择一个进行输出,基于某种特定的优先级或策略。在处理多个并发请求访问同一资源(例如,总线或共享内存)时,仲裁器确保每个时刻只有一个选定的请求被服务,同时遵循公平性或优先级规则,避免资源冲突或死锁。

  1. Arbiter:这是一个静态优先级仲裁器,它总是优先选择索引较低的生产者。如果有多个请求同时到达,Arbiter 会根据请求信号的索引顺序来决定优先权,索引较小的请求者会获得优先服务。这意味着如果较低索引的请求者持续有请求,它将持续获得资源,而更高索引的请求者则需要等待。

    示例代码如下:

    test(new Module {
    +    // Example circuit using a priority arbiter
    +    val io = IO(new Bundle {
    +      val in = Flipped(Vec(2, Decoupled(UInt(8.W))))
    +      val out = Decoupled(UInt(8.W))
    +    })
    +    // Arbiter doesn't have a convenience constructor, so it's built like any Module
    +    val arbiter = Module(new Arbiter(UInt(8.W), 2))  // 2 to 1 Priority Arbiter
    +    arbiter.io.in <> io.in
    +    io.out <> arbiter.io.out
    +  }) { c =>
    +    c.io.in(0).valid.poke(false.B)
    +    c.io.in(1).valid.poke(false.B)
    +    c.io.out.ready.poke(false.B)
    +    println(s"Start:")
    +    println(s"\tin(0).ready=${c.io.in(0).ready.peek().litValue}, in(1).ready=${c.io.in(1).ready.peek().litValue}")
    +    println(s"\tout.valid=${c.io.out.valid.peek().litValue}, out.bits=${c.io.out.bits.peek().litValue}")
    +    c.io.in(1).valid.poke(true.B)  // Valid input 1
    +    c.io.in(1).bits.poke(42.U)
    +    c.io.out.ready.poke(true.B)
    +    // What do you think the output will be?
    +    println(s"valid input 1:")
    +    println(s"\tin(0).ready=${c.io.in(0).ready.peek().litValue}, in(1).ready=${c.io.in(1).ready.peek().litValue}")
    +    println(s"\tout.valid=${c.io.out.valid.peek().litValue}, out.bits=${c.io.out.bits.peek().litValue}")
    +    c.io.in(0).valid.poke(true.B)  // Valid inputs 0 and 1
    +    c.io.in(0).bits.poke(43.U)
    +    // What do you think the output will be? Which inputs will be ready?
    +    println(s"valid inputs 0 and 1:")
    +    println(s"\tin(0).ready=${c.io.in(0).ready.peek().litValue}, in(1).ready=${c.io.in(1).ready.peek().litValue}")
    +    println(s"\tout.valid=${c.io.out.valid.peek().litValue}, out.bits=${c.io.out.bits.peek().litValue}")
    +    c.io.in(1).valid.poke(false.B)  // Valid input 0
    +    // What do you think the output will be?
    +    println(s"valid input 0:")
    +    println(s"\tin(0).ready=${c.io.in(0).ready.peek().litValue}, in(1).ready=${c.io.in(1).ready.peek().litValue}")
    +    println(s"\tout.valid=${c.io.out.valid.peek().litValue}, out.bits=${c.io.out.bits.peek().litValue}")
    +}
    +
    Start:
    +  in(0).ready=0, in(1).ready=0
    +  out.valid=0, out.bits=0
    +valid input 1:
    +  in(0).ready=1, in(1).ready=1
    +  out.valid=1, out.bits=42
    +valid inputs 0 and 1:
    +  in(0).ready=1, in(1).ready=0
    +  out.valid=1, out.bits=43
    +valid input 0:
    +  in(0).ready=1, in(1).ready=0
    +  out.valid=1, out.bits=43
    +
    1. 初始状态检查:

      • 首先,测试确认在没有任何有效输入 (io.in(0).validio.in(1).valid 都为 false) 时,输出 (io.out.valid) 也应为 false,表示没有数据通过仲裁器。
    2. 激活第二个输入:

      • 然后,测试激活 io.in(1)(即索引为 1 的输入),同时保持 io.out.readytrue,这模拟了接收端准备好接收数据的情况。预期 io.in(1) 的数据应该通过到 io.out
      • 两个输入的 ready 信号都是 1。这是因为 Arbiter 的行为是基于它可以传递数据的能力。让我们分解这个情况: +当只有 io.in(1) 有效时: +
        • in(0).ready=1:这意味着 Arbiter 仲裁器准备好从 io.in(0) 接收数据,尽管此时 io.in(0) 没有数据(不是有效的)。ready 信号为 1 表示如果 io.in(0) 有数据,Arbiter 准备好接收它。
        • in(1).ready=1:同时,Arbiter 也表示准备好接收 io.in(1) 的数据,因为它是有效的。在这种情况下,由于 io.out.ready 被设置为 trueArbiter 知道输出端已经准备好接收数据,所以它将 io.in(1)ready 也置为 1

      这里的关键是 ready 信号表示的是接收能力而非当前的数据有效性。即使 io.in(0) 当前没有标记为有效,Arbiter 也表明它准备好从该输入接收数据,这就是为什么在 io.in(1) 有效时,io.in(0).ready 也会是 1

    3. 同时激活两个输入:

      • 接下来,测试同时激活两个输入,即 io.in(0)io.in(1) 都设置为有效。由于 Arbiter 的静态优先级策略,预期 io.in(0) 的数据(即优先级更高的输入)会被传递到 io.out
      • 当两个输入 io.in(0)io.in(1) 都被设置为有效时,Arbiter 会根据其内部逻辑来选择一个输入。对于普通的 Arbiter,它将优先选择索引较低的输入,即 io.in(0)
      • 由于 io.in(0) 被选中,io.in(1)ready 信号将会被置为 false,而 io.in(0).ready 会是 true,表示 Arbiter 准备接受 io.in(0) 的数据。
      • 在此情况下,即使您设置了 io.in(1).bits,这个数据也不会被 Arbiter 选择,因为 io.in(0) 有更高的优先级。
    4. 只激活第一个输入:

      • 最后,测试只激活 io.in(0)。即使之前 io.in(1) 被激活过,在这一步中只有 io.in(0) 有效,所以只有它的数据应该被传递到 io.out
  2. RRArbiter:这是一个循环(round-robin)仲裁器,它按照循环的顺序为请求者提供服务,确保了长期的公平性。当一个请求被服务后,RRArbiter 会记住最后被服务的请求,并在下一个服务周期中优先考虑下一个请求者。这样可以确保即使在高负载下,所有请求者也能获得均等的服务机会。

    示例代码如下:

    val rrArbiter = Module(new RRArbiter(UInt(8.W), 2))
    +rrArbiter.io.in(0) <> producer0
    +rrArbiter.io.in(1) <> producer1
    +consumer <> rrArbiter.io.out
    +

注:Ariter 是组合电路,不需要 step(1)

# Misc Function Blocks

# Bitwise Utilities

# PopCount

PopCount returns the number of high (1) bits in the input as a UInt.

test(new Module {
+    // Example circuit using PopCount
+    val io = IO(new Bundle {
+      val in = Input(UInt(8.W))
+      val out = Output(UInt(8.W))
+    })
+    io.out := PopCount(io.in)
+  }) { c =>
+    // Integer.parseInt is used create an Integer from a binary specification
+    c.io.in.poke(Integer.parseInt("00000000", 2).U)
+    println(s"in=0b${c.io.in.peek().litValue.toInt.toBinaryString}, out=${c.io.out.peek().litValue}")
+
+    c.io.in.poke(Integer.parseInt("00001111", 2).U)
+    println(s"in=0b${c.io.in.peek().litValue.toInt.toBinaryString}, out=${c.io.out.peek().litValue}")
+
+    c.io.in.poke(Integer.parseInt("11001010", 2).U)
+    println(s"in=0b${c.io.in.peek().litValue.toInt.toBinaryString}, out=${c.io.out.peek().litValue}")
+
+    c.io.in.poke(Integer.parseInt("11111111", 2).U)
+    println(s"in=0b${c.io.in.peek().litValue.toInt.toBinaryString}, out=${c.io.out.peek().litValue}")
+
+}
+
in=0b0, out=0
+in=0b1111, out=4
+in=0b11001010, out=4
+in=0b11111111, out=8
+

# Reverse

Reverse returns the bit-reversed input

test(new Module {
+    // Example circuit using Reverse
+    val io = IO(new Bundle {
+      val in = Input(UInt(8.W))
+      val out = Output(UInt(8.W))
+    })
+    io.out := Reverse(io.in)
+  }) { c =>
+    // Integer.parseInt is used create an Integer from a binary specification
+    c.io.in.poke(Integer.parseInt("01010101", 2).U)
+    println(s"in=0b${c.io.in.peek().litValue.toInt.toBinaryString}, out=0b${c.io.out.peek().litValue.toInt.toBinaryString}")
+
+    c.io.in.poke(Integer.parseInt("00001111", 2).U)
+    println(s"in=0b${c.io.in.peek().litValue.toInt.toBinaryString}, out=0b${c.io.out.peek().litValue.toInt.toBinaryString}")
+
+    c.io.in.poke(Integer.parseInt("11110000", 2).U)
+    println(s"in=0b${c.io.in.peek().litValue.toInt.toBinaryString}, out=0b${c.io.out.peek().litValue.toInt.toBinaryString}")
+
+    c.io.in.poke(Integer.parseInt("11001010", 2).U)
+    println(s"in=0b${c.io.in.peek().litValue.toInt.toBinaryString}, out=0b${c.io.out.peek().litValue.toInt.toBinaryString}")
+}
+
in=0b1010101, out=0b10101010
+in=0b1111, out=0b11110000
+in=0b11110000, out=0b1111
+in=0b11001010, out=0b1010011
+

# OneHot encoding utilities

# UIntToOH

UInt to OneHot

test(new Module {
+    // Example circuit using UIntToOH
+    val io = IO(new Bundle {
+      val in = Input(UInt(4.W))
+      val out = Output(UInt(16.W))
+    })
+    io.out := UIntToOH(io.in)
+  }) { c =>
+    c.io.in.poke(0.U)
+    println(s"in=${c.io.in.peek().litValue}, out=0b${c.io.out.peek().litValue.toInt.toBinaryString}")
+
+    c.io.in.poke(1.U)
+    println(s"in=${c.io.in.peek().litValue}, out=0b${c.io.out.peek().litValue.toInt.toBinaryString}")
+
+    c.io.in.poke(8.U)
+    println(s"in=${c.io.in.peek().litValue}, out=0b${c.io.out.peek().litValue.toInt.toBinaryString}")
+
+    c.io.in.poke(15.U)
+    println(s"in=${c.io.in.peek().litValue}, out=0b${c.io.out.peek().litValue.toInt.toBinaryString}")
+}
+
+in=0, out=0b1
+in=1, out=0b10
+in=8, out=0b100000000
+in=15, out=0b1000000000000000
+

# OHToUInt

OneHot to UInt

test(new Module {
+    // Example circuit using OHToUInt
+    val io = IO(new Bundle {
+      val in = Input(UInt(16.W))
+      val out = Output(UInt(4.W))
+    })
+    io.out := OHToUInt(io.in)
+}) { c =>
+    c.io.in.poke(Integer.parseInt("0000 0000 0000 0001".replace(" ", ""), 2).U)
+    println(s"in=0b${c.io.in.peek().litValue.toInt.toBinaryString}, out=${c.io.out.peek().litValue}")
+
+    c.io.in.poke(Integer.parseInt("0000 0000 1000 0000".replace(" ", ""), 2).U)
+    println(s"in=0b${c.io.in.peek().litValue.toInt.toBinaryString}, out=${c.io.out.peek().litValue}")
+
+    c.io.in.poke(Integer.parseInt("1000 0000 0000 0001".replace(" ", ""), 2).U)
+    println(s"in=0b${c.io.in.peek().litValue.toInt.toBinaryString}, out=${c.io.out.peek().litValue}")
+
+    // Some invalid inputs:
+    // None high
+    c.io.in.poke(Integer.parseInt("0000 0000 0000 0000".replace(" ", ""), 2).U)
+    println(s"in=0b${c.io.in.peek().litValue.toInt.toBinaryString}, out=${c.io.out.peek().litValue}")
+
+    // Multiple high
+    c.io.in.poke(Integer.parseInt("0001 0100 0010 0000".replace(" ", ""), 2).U)
+    println(s"in=0b${c.io.in.peek().litValue.toInt.toBinaryString}, out=${c.io.out.peek().litValue}")
+}
+
+in=0b1, out=0
+in=0b10000000, out=7
+in=0b1000000000000001, out=15
+in=0b0, out=0
+in=0b1010000100000, out=15
+

# MUX

# PriorityMux

Outputs the value associated with the lowest-index asserted select signal.

test(new Module {
+    // Example circuit using PriorityMux
+    val io = IO(new Bundle {
+      val in_sels = Input(Vec(2, Bool()))
+      val in_bits = Input(Vec(2, UInt(8.W)))
+      val out = Output(UInt(8.W))
+    })
+    io.out := PriorityMux(io.in_sels, io.in_bits)
+  }) { c =>
+    c.io.in_bits(0).poke(10.U)
+    c.io.in_bits(1).poke(20.U)
+
+    // Select higher index only
+    c.io.in_sels(0).poke(false.B)
+    c.io.in_sels(1).poke(true.B)
+    println(s"in_sels=${c.io.in_sels(0).peek().litValue}, out=${c.io.out.peek().litValue}")
+
+    // Select both - arbitration needed
+    c.io.in_sels(0).poke(true.B)
+    c.io.in_sels(1).poke(true.B)
+    println(s"in_sels=${c.io.in_sels(0).peek().litValue}, out=${c.io.out.peek().litValue}")
+
+    // Select lower index only
+    c.io.in_sels(0).poke(true.B)
+    c.io.in_sels(1).poke(false.B)
+    println(s"in_sels=${c.io.in_sels(0).peek().litValue}, out=${c.io.out.peek().litValue}")
+}
+
+in_sels=0, out=20
+in_sels=1, out=10
+in_sels=1, out=10
+

PriorityMux 会根据 in_sels 中的布尔值,从左到右(即从索引 0 开始)检查哪个输入是选中的,并输出第一个选中输入对应的 in_bits 值。因此,同时使 in_sels(0)in_sels(1)true 时,由于 in_sels(0) 的优先级更高,io.out 应该输出 in_bits(0) 的值,即 10.U

# OneHot Mux: Mux1H

An Mux1H provides an efficient implementation when it is guaranteed that exactly one of the select signals will be high. Behavior is undefined if the assumption is not true.

test(new Module {
+    // Example circuit using Mux1H
+    val io = IO(new Bundle {
+      val in_sels = Input(Vec(2, Bool()))
+      val in_bits = Input(Vec(2, UInt(8.W)))
+      val out = Output(UInt(8.W))
+    })
+    io.out := Mux1H(io.in_sels, io.in_bits)
+  }) { c =>
+    c.io.in_bits(0).poke(10.U)
+    c.io.in_bits(1).poke(20.U)
+
+    // Select index 1
+    c.io.in_sels(0).poke(false.B)
+    c.io.in_sels(1).poke(true.B)
+    println(s"in_sels=${c.io.in_sels(0).peek().litValue}, out=${c.io.out.peek().litValue}")
+
+    // Select index 0
+    c.io.in_sels(0).poke(true.B)
+    c.io.in_sels(1).poke(false.B)
+    println(s"in_sels=${c.io.in_sels(0).peek().litValue}, out=${c.io.out.peek().litValue}")
+
+    // Select none (invalid)
+    c.io.in_sels(0).poke(false.B)
+    c.io.in_sels(1).poke(false.B)
+    println(s"in_sels=${c.io.in_sels(0).peek().litValue}, out=${c.io.out.peek().litValue}")
+
+    // Select both (invalid)
+    c.io.in_sels(0).poke(true.B)
+    c.io.in_sels(1).poke(true.B)
+    println(s"in_sels=${c.io.in_sels(0).peek().litValue}, out=${c.io.out.peek().litValue}")
+}
+
+in_sels=0, out=20
+in_sels=1, out=10
+in_sels=0, out=0
+in_sels=1, out=30
+

# Counter

A counter that can be incremented once every cycle, up to some specified limit, at which point it overflows. Note that it is not a Module, and its value is accessible.

test(new Module {
+  // Example circuit with two counters
+  val io = IO(new Bundle {
+    val count = Input(Bool())
+    val out = Output(UInt(2.W))
+    val totalCycles = Output(UInt(32.W))  // Assuming 32-bit is enough for cycle count
+  })
+
+  // Counter for controlled increments
+  val controlledCounter = Counter(3)  // 3-count Counter (outputs range [0...2])
+  when(io.count) {
+    controlledCounter.inc()
+  }
+  io.out := controlledCounter.value
+
+  // Counter for total cycles, counting up to (2^32)-1
+  val totalCycleCounter = Counter(math.pow(2, 32).toInt)
+  totalCycleCounter.inc()  // Increment every cycle
+  io.totalCycles := totalCycleCounter.value
+}) { c =>
+  c.io.count.poke(true.B)
+  println(s"start: controlled counter value=${c.io.out.peek().litValue}, total cycles=${c.io.totalCycles.peek().litValue}")
+
+  c.clock.step(1)
+  println(s"step 1: controlled counter value=${c.io.out.peek().litValue}, total cycles=${c.io.totalCycles.peek().litValue}")
+
+  c.clock.step(1)
+  println(s"step 2: controlled counter value=${c.io.out.peek().litValue}, total cycles=${c.io.totalCycles.peek().litValue}")
+
+  c.io.count.poke(false.B)
+  c.clock.step(1)
+  println(s"step without increment: controlled counter value=${c.io.out.peek().litValue}, total cycles=${c.io.totalCycles.peek().litValue}")
+
+  c.io.count.poke(true.B)
+  c.clock.step(1)
+  println(s"step again: controlled counter value=${c.io.out.peek().litValue}, total cycles=${c.io.totalCycles.peek().litValue}")
+}
+
+start: controlled counter value=0, total cycles=0
+step 1: controlled counter value=1, total cycles=1
+step 2: controlled counter value=2, total cycles=2
+step without increment: controlled counter value=2, total cycles=3
+step again: controlled counter value=0, total cycles=4
+

在 Chisel 中创建一个计数器时,如果您传递的参数是 n,那么计数器能够表示的计数范围是从 0 到 n-1。所以,当您使用 Counter(n) 时,计数器的实际最大计数值是 n-1。

+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.05-3.4 Higher-Order Functions.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.05-3.4 Higher-Order Functions.html new file mode 100644 index 0000000..3f5e759 --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.05-3.4 Higher-Order Functions.html @@ -0,0 +1,245 @@ + + + + + + 2024.03.05-3.4 Higher-Order Functions | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.05-3.4 Higher-Order Functions

# A Tale of Two FIRs

From the last module, we had the convolution part of the FIR filter written like this:

val muls = Wire(Vec(length, UInt(8.W)))
+for(i <- 0 until length) {
+  if(i == 0) muls(i) := io.in * io.consts(i)
+  else       muls(i) := regs(i - 1) * io.consts(i)
+}
+
+val scan = Wire(Vec(length, UInt(8.W)))
+for(i <- 0 until length) {
+  if(i == 0) scan(i) := muls(i)
+  else scan(i) := muls(i) + scan(i - 1)
+}
+
+io.out := scan(length - 1)
+

As a recap, the idea is to multiply each element of io.in with the corresponding element of io.consts, and store it in muls. Then, the elements in muls are accumulated into scan, with scan(0) = muls(0), scan(1) = scan(0) + muls(1) = muls(0) + muls(1), and in general scan(n) = scan(n-1) + muls(n) = muls(0) + ... + muls(n-1) + muls(n). The last element in scan (equal to the sum of all muls) is assigned to io.out.

However, it's very verbose for what might be considered quite a simple operation. In fact, all that could be written in one line:

io.out := (taps zip io.consts).map { case (a, b) => a * b }.reduce(_ + _)
+
  • 假设 taps 是所有样本的列表,其中 taps(0) = io.intaps(1) = regs(0) 等等。
  • (taps zip io.consts) 将两个列表 tapsio.consts 合并成一个列表,其中每个元素是一个元组,这个元组包含了在相应位置的输入元素。具体来说,它的值将是 [(taps(0), io.consts(0)), (taps(1), io.consts(1)), ..., (taps(n), io.consts(n))]。记住,在 Scala 中点号是可选的,所以这等同于 (taps.zip(io.consts))
  • .map { case (a, b) => a * b } 对列表中的元素应用一个匿名函数(接收两个元素的元组并返回它们的乘积),并返回结果。在这个情况下,结果等价于在冗长示例中的 muls,其值为 [taps(0) * io.consts(0), taps(1) * io.consts(1), ..., taps(n) * io.consts(n)]
  • 最后,.reduce(_ + _) 同样应用一个函数(元素的加法)到列表的元素上。然而,它接收两个参数:第一个是当前的累加值,第二个是列表元素(在第一次迭代中,它只是将前两个元素相加)。这些由括号中的两个下划线表示。那么结果,假设是从左到右的遍历,将会是 (((muls(0) + muls(1)) + muls(2)) + ...) + muls(n),更深层次括号内的结果先被计算。这就是卷积的输出结果。

# Functions as Arguments

Formally, functions like map and reduce are called higher-order functions : they are functions that take functions as arguments. As it turns out (and hopefully, as you can see from the above example), these are very powerful constructs that encapsulate a general computational pattern, allowing you to concentrate on the application logic instead of flow control, and resulting in very concise code.

  • 对于每个参数只引用一次的函数,您可以使用下划线(_)来引用每个参数。在上面的例子中,reduce 函数接受两个参数,可以被指定为 _ + _。虽然这很方便,但它受制于一组额外的复杂规则,所以如果不起作用,您可以尝试:
  • 明确指定输入参数列表。reduce 可以被明确写成 (a, b) => a + b,通用形式是把参数列表放在括号里,后面跟着 =>,然后是引用这些参数的函数体。
  • 当需要解包元组时,使用 case 语句,如 case (a, b) => a * b。这接收一个参数,一个两个元素的元组,并将其解包到变量 ab 中,然后可以在函数体中使用它们。

# Practice in Scala

Scala 集合 API 中的主要类,如List。这些高阶函数是这些 API 的一部分。实际上,上面的示例使用了List上的mapreduce API。在这一节中,我们将通过示例和练习熟悉这些方法。在这些示例中,我们将对 Scala 数字(Int)操作,以简化和明确表示,但因为 Chisel 运算符的行为类似,所以这些概念应该是通用的。

# Example: map

List[A].map 有类型签名 map[B](f: (A) ⇒ B): List[B]。现在,将类型 A 和 B 视为 IntUInt,意味着它们可以是软件或硬件类型。它接受一个类型为 (f: (A) ⇒ B) 的参数,或者一个接受类型为 A(与输入列表的元素类型相同)的一个参数并返回类型为 B 的值的函数。map 然后返回一个新的类型为 B(参数函数的返回类型)的列表。

println(List(1, 2, 3, 4).map(x => x + 1))  // explicit argument list in function
+println(List(1, 2, 3, 4).map(_ + 1))  // equivalent to the above, but implicit arguments
+println(List(1, 2, 3, 4).map(_.toString + "a"))  // the output element type can be different from the input element type
+
+println(List((1, 5), (2, 6), (3, 7), (4, 8)).map { case (x, y) => x*y })  // this unpacks a tuple, note use of curly braces
+
+// Related: Scala has a syntax for constructing lists of sequential numbers
+println(0 to 10)  // to is inclusive , the end point is part of the result
+println(0 until 10)  // until is exclusive at the end, the end point is not part of the result
+
+// Those largely behave like lists, and can be useful for generating indices:
+val myList = List("a", "b", "c", "d")
+println((0 until 4).map(myList(_)))
+
+// output:
+List(2, 3, 4, 5)
+List(2, 3, 4, 5)
+List(1a, 2a, 3a, 4a)
+List(5, 12, 21, 32)
+Range 0 to 10
+Range 0 until 10
+Vector(a, b, c, d)
+
  1. 使用小括号而不显式使用 case 关键字: +当您直接提供一个匿名函数时,您通常只需要小括号即可。例如:

    list.map((a, b) => a + b)
    +

    这里,您直接给出了一个处理元素的函数 (a, b) => a + b,没有使用 case

  2. 使用大括号并显式使用 case 关键字: +如果您想要在处理集合元素时使用模式匹配,您可以使用大括号并在里面使用 case 关键字。这种方式通常用于元组的解构或更复杂的模式匹配。例如:

    list.map { case (a, b) => a + b }
    +

    在这个例子中,您使用 { case (a, b) => a + b } 对元组进行解构,并对解构后的元素应用函数。

# Example: zipWithIndex

List.zipWithIndex has type signature zipWithIndex: List[(A, Int)]. It takes no arguments, but returns a list where each element is a tuple of the original elements, and the index (with the first one being zero). So List("a", "b", "c", "d").zipWithIndex would return List(("a", 0), ("b", 1), ("c", 2), ("d", 3))

println(List(1, 2, 3, 4).zipWithIndex)  // note indices start at zero
+println(List("a", "b", "c", "d").zipWithIndex)
+println(List(("a", "b"), ("c", "d"), ("e", "f"), ("g", "h")).zipWithIndex)  // tuples nest
+
+// output:
+List((1,0), (2,1), (3,2), (4,3))
+List((a,0), (b,1), (c,2), (d,3))
+List(((a,b),0), ((c,d),1), ((e,f),2), ((g,h),3))
+

# Example: **reduce**

List[A].map has type signature similar to reduce(op: (A, A) ⇒ A): A. (it's actually more lenient, A only has to be a supertype of the List type, but we're not going to deal with that syntax here)

println(List(1, 2, 3, 4).reduce((a, b) => a + b))  // returns the sum of all the elements
+println(List(1, 2, 3, 4).reduce(_ * _))  // returns the product of all the elements
+println(List(1, 2, 3, 4).map(_ + 1).reduce(_ + _))  // you can chain reduce onto the result of a map
+println(List(1, 2, 3, 4).map(_*2).reduce(_*_))  // returns the product of the double of the elements of the input list.
+
+// output:
+10
+24
+14
+384
+
+// Important note: reduce will fail with an empty list
+println(List[Int]().reduce(_ * _))
+

# Example: **fold**

List[A].fold is very similar to reduce, except that you can specify the initial accumulation value. It has type signature similar to fold(z: A)(op: (A, A) ⇒ A): A. (like reduce, the type of A is also more lenient). Notably, it takes two argument lists, the first (z) is the initial value, and the second is the accumulation function. Unlike reduce, it will not fail with an empty list, instead returning the initial value directly.

println(List(1, 2, 3, 4).fold(0)(_ + _))  // equivalent to the sum using reduce
+println(List(1, 2, 3, 4).fold(1)(_ + _))  // like above, but accumulation starts at 1
+println(List().fold(1)(_ + _))  // unlike reduce, does not fail on an empty input
+println(List(1, 2, 3, 4).fold(2)(_*_))  // returns the double the product of the elements of the input list
+
+// output:
+10
+11
+1
+48
+
+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.07-3.5 Functional Programming.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.07-3.5 Functional Programming.html new file mode 100644 index 0000000..21d9a9e --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.07-3.5 Functional Programming.html @@ -0,0 +1,420 @@ + + + + + + 2024.03.07-3.5 Functional Programming | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.07-3.5 Functional Programming

# Functional Programming in Scala

# Example: Custom Functions

// No inputs or outputs (two versions).
+// To produce no output, return the Unit type
+def hello1(): Unit = print("Hello!")
+def hello2 = print("Hello again!")
+
+// Math operation: one input and one output.
+def times2(x: Int): Int = 2 * x
+
+// Inputs can have default values, and explicitly specifying the return type is optional.
+// Note that we recommend specifying the return types to avoid surprises/bugs.
+def timesN(x: Int, n: Int = 2) = n * x
+
+// Call the functions listed above.
+hello1()
+hello2
+times2(4)
+timesN(4)         // no need to specify n to use the default value
+timesN(4, 3)      // argument order is the same as the order where the function was defined
+timesN(n=7, x=2)  // arguments may be reordered and assigned to explicitly
+

# Functions as Objects

# Example: Function Objects

// These are normal functions.
+def plus1funct(x: Int): Int = x + 1
+def times2funct(x: Int): Int = x * 2
+
+// These are functions as vals.
+// The first one explicitly specifies the return type.
+val plus1val: Int => Int = x => x + 1
+val times2val = (x: Int) => x * 2
+
+// Calling both looks the same.
+plus1funct(4)
+plus1val(4)
+plus1funct(x=4)
+//plus1val(x=4) // this doesn't work
+

# Hint:

  1. 函数对象定义时使用 val ,并且不指明参数
  2. 指明返回类型时使用 type ⇒ type = x ⇒ x + 1
  3. 没有指明返回类型时使用 funcName = value ⇒ value

# Example: Higher-Order Functions

Functions that take or produce functions are called higher-order functions.

// create our function
+val plus1 = (x: Int) => x + 1
+val times2 = (x: Int) => x * 2
+
+// pass it to map, a list function
+val myList = List(1, 2, 5, 9)
+val myListPlus = myList.map(plus1)
+val myListTimes = myList.map(times2)
+
+// create a custom function, which performs an operation on X N times using recursion
+def opN(x: Int, n: Int, op: Int => Int): Int = {
+  if (n <= 0) { x }
+  else { opN(op(x), n-1, op) }
+}
+
+opN(7, 3, plus1)
+opN(7, 3, times2)
+

# Example: Functions vs. Objects

A possibly confusing situation arises when using functions without arguments. Functions are evaluated every time they are called, while vals are evaluated at instantiation.

import scala.util.Random
+
+// both x and y call the nextInt function, but x is evaluated immediately and y is a function
+val x = Random.nextInt
+def y = Random.nextInt  // def y : Int = Random.nextInt
+
+// x was previously evaluated, so it is a constant
+println(s"x = $x")
+println(s"x = $x")
+
+// y is a function and gets reevaluated at each call, thus these produce different results
+println(s"y = $y")
+println(s"y = $y")
+
+// output:
+x = -2133939285
+x = -2133939285
+y = 1035018406
+y = -968348688
+
  1. 使用 val 的函数对象在定义时就初始化了,后面调用不会改变值
  2. 而普通的函数每一次调用都会再运行一次

# Anonymous Functions

# Example: Anonymous Functions

val myList = List(5, 6, 7, 8)
+
+// add one to every item in the list using an anonymous function
+// arguments get passed to the underscore variable
+// these all do the same thing
+myList.map( (x:Int) => x + 1 )
+myList.map(_ + 1)
+
+// a common situation is to use case statements within an anonymous function
+val myAnyList = List(1, 2, "3", 4L, myList)
+myAnyList.map {
+  case (_:Int|_:Long) => "Number"
+  case _:String => "String"
+  case _ => "error"
+}
+

如果只使用一次的函数对象,就没有必要建立一个 val

# Exercise: Sequence Manipulation

在 Scala 集合中,scanLeft/scanRightreduceLeft/reduceRightfoldLeft/foldRight 是重要的函数,用于对集合进行累积运算。理解每个函数的工作方式及其适用场景是很重要的。默认情况下,scanreducefold 的方向是从左到右。

  1. scanLeft/scanRight: +
    • scanLeftscanRight 是累积函数,它们对集合中的元素逐个应用累积函数,并返回一个包含所有中间结果的新集合。
    • scanLeft 从集合的头部开始向尾部递进,而 scanRight 则从尾部开始向头部递进。
    • 例如,List(1, 2, 3).scanLeft(0)(_ + _) 会计算 (0, 1, 3, 6),其中 0 是初始值,累加过程是 0 + 1 = 11 + 2 = 33 + 3 = 6
  2. reduceLeft/reduceRight: +
    • reduceLeftreduceRight 是累积函数,它们对集合中的元素逐个应用累积函数,但只返回最终的累积结果。
    • reduceLeft 从集合的头部开始应用累积函数,直到尾部;reduceRight 则从尾部开始应用,直到头部。
    • 注意:reduceLeftreduceRight 不能为空集合使用,因为它们没有初始值。
    • 例如,List(1, 2, 3).reduceLeft(_ + _) 会计算 1 + 2 + 3 = 6
  3. foldLeft/foldRight: +
    • foldLeftfoldRightreduceLeft/reduceRight 类似,但它们接受一个初始值作为累积的起点。
    • foldLeft 从集合的头部开始应用累积函数,而 foldRight 则从尾部开始。
    • foldLeftfoldRight 可以在空集合上使用,因为它们有初始值。
    • 例如,List(1, 2, 3).foldLeft(0)(_ + _) 会计算 0 + 1 + 2 + 3 = 6
val exList = List(1, 5, 7, 100)
+
+// write a custom function to add two numbers, then use reduce to find the sum of all values in exList
+def add(a: Int, b: Int): Int = a + b
+val sum = exList.reduce(add)
+
+// find the sum of exList using an anonymous function (hint: you've seen this before!)
+val anon_sum = exList.reduce((a,b) => a + b)
+
+// find the moving average of exList from right to left using scan; make the result (ma2) a list of doubles
+def avg(a: Int, b: Double): Double = (a + b) / 2.0
+val ma2 = exList.scanRight(0.0)(avg)
+

这个 scanRight 调用将执行以下操作:

  1. 开始于最右侧元素 100 和初始值 0.0: +
    • 应用 avg(100, 0.0) 得到 (100 + 0.0) / 2 = 50.0。这是第一个累积值,它将作为下一个右侧元素的累积输入。
  2. 向左移动到元素 7: +
    • 使用刚刚计算得到的累积值 50.0 和当前元素 7 应用 avg,得到 avg(7, 50.0) = (7 + 50.0) / 2 = 28.5。这成为下一步的累积输入。
  3. 接着移动到元素 5: +
    • 应用 avg(5, 28.5) 得到 (5 + 28.5) / 2 = 16.75
  4. 最后移动到元素 1: +
    • 应用 avg(1, 16.75) 得到 (1 + 16.75) / 2 = 8.875
  5. 收集和返回结果: +
    • scanRight 不仅返回最终的累积结果,它还返回经过每个步骤的中间结果。所以对于这个特定的列表和 avg 函数,scanRight 会返回一个新的列表:List(8.875, 16.75, 28.5, 50.0, 0.0)

# Functional Programming in Chisel

# Exercise: FIR Filter

使用函数生成 FIR 的系数:

// get some math functions
+import scala.math.{abs, round, cos, Pi, pow}
+
+// simple triangular window
+val TriangularWindow: (Int, Int) => Seq[Int] = (length, bitwidth) => {
+  val raw_coeffs = (0 until length).map( (x:Int) => 1-abs((x.toDouble-(length-1)/2.0)/((length-1)/2.0)) )
+  val scaled_coeffs = raw_coeffs.map( (x: Double) => round(x * pow(2, bitwidth)).toInt)
+  scaled_coeffs
+}
+
+// Hamming window
+val HammingWindow: (Int, Int) => Seq[Int] = (length, bitwidth) => {
+  val raw_coeffs = (0 until length).map( (x: Int) => 0.54 - 0.46*cos(2*Pi*x/(length-1)))
+  val scaled_coeffs = raw_coeffs.map( (x: Double) => round(x * pow(2, bitwidth)).toInt)
+  scaled_coeffs
+}
+
+// check it out! first argument is the window length, and second argument is the bitwidth
+TriangularWindow(10, 16)
+HammingWindow(10, 16)
+

创建一个接受函数为参数的 Chisel FIR 模块:

// our FIR has parameterized window length, IO bitwidth, and windowing function
+class MyFir(length: Int, bitwidth: Int, window: (Int, Int) => Seq[Int]) extends Module {
+  val io = IO(new Bundle {
+    val in = Input(UInt(bitwidth.W))
+    val out = Output(UInt((bitwidth*2+length-1).W)) // expect bit growth, conservative but lazy
+  })
+
+  // calculate the coefficients using the provided window function, mapping to UInts
+  val coeffs = window(length, bitwidth).map(_.U)
+
+  // create an array holding the output of the delays
+  // note: we avoid using a Vec here since we don't need dynamic indexing
+  val delays = Seq.fill(length)(Wire(UInt(bitwidth.W))).scan(io.in)( (prev: UInt, next: UInt) => {
+    next := RegNext(prev)
+    next
+  })
+
+  // multiply, putting result in "mults"
+  val mults = delays.zip(coeffs).map{ case(delay: UInt, coeff: UInt) => delay * coeff }
+
+  // add up multiplier outputs with bit growth
+  val result = mults.reduce(_+&_)
+
+  // connect output
+  io.out := result
+}
+
+visualize(() => new MyFir(7, 12, TriangularWindow))
+

delays.zip(coeffs) 也可以写成 (delays zip coeffs)

# Example: FIR Filter Tester

// math imports
+import scala.math.{pow, sin, Pi}
+import breeze.signal.{filter, OptOverhang}
+import breeze.signal.support.{CanFilter, FIRKernel1D}
+import breeze.linalg.DenseVector
+
+// test parameters
+val length = 7
+val bitwidth = 12 // must be less than 15, otherwise Int can't represent the data, need BigInt
+val window = TriangularWindow
+
+// test our FIR
+test(new MyFir(length, bitwidth, window)) { c =>
+
+    // test data
+    val n = 100 // input length
+    val sine_freq = 10
+    val samp_freq = 100
+
+    // sample data, scale to between 0 and 2^bitwidth
+    val max_value = pow(2, bitwidth)-1
+    val sine = (0 until n).map(i => (max_value/2 + max_value/2*sin(2*Pi*sine_freq/samp_freq*i)).toInt)
+    //println(s"input = ${sine.toArray.deep.mkString(", ")}")
+
+    // coefficients
+    val coeffs = window(length, bitwidth)
+    //println(s"coeffs = ${coeffs.toArray.deep.mkString(", ")}")
+
+    // use breeze filter as golden model; need to reverse coefficients
+    val expected = filter(
+        DenseVector(sine.toArray),
+        FIRKernel1D(DenseVector(coeffs.reverse.toArray), 1.0, ""),
+        OptOverhang.None
+    )
+    expected.toArray // seems to be necessary
+    //println(s"exp_out = ${expected.toArray.deep.mkString(", ")}") // this seems to be necessary
+
+    // push data through our FIR and check the result
+    c.reset.poke(true.B)
+    c.clock.step(5)
+    c.reset.poke(false.B)
+    for (i <- 0 until n) {
+        c.io.in.poke(sine(i).U)
+        if (i >= length-1) { // wait for all registers to be initialized since we didn't zero-pad the data
+            val expectValue = expected(i-length+1)
+            //println(s"expected value is $expectValue")
+            c.io.out.expect(expected(i-length+1).U)
+            //println(s"cycle $i, got ${c.io.out.peek()}, expect ${expected(i-length+1)}")
+        }
+        c.clock.step(1)
+    }
+}
+

# Chisel Exercise

# Exercise: Neural Network Neuron

# Basic Multiply

Neuron

class Neuron(inputs: Int, act: FixedPoint => FixedPoint) extends Module {
+  val io = IO(new Bundle {
+    val in      = Input(Vec(inputs, FixedPoint(16.W, 8.BP)))
+    val weights = Input(Vec(inputs, FixedPoint(16.W, 8.BP)))
+    val out     = Output(FixedPoint(16.W, 8.BP))
+  })
+
+  io.out := act((io.in zip io.weights).map{case (a,b) => a*b}.reduce(_+_))
+}
+

在 Chisel 中,FixedPoint 类型用于表示定点数,这是一种在硬件设计中常用的数值表示方法,特别适用于数字信号处理(DSP)等领域。FixedPoint 类型提供了一种方式来指定数值的位宽和小数点位置,这在设计需要精确控制数值精度和范围的硬件时非常有用。

FixedPoint(16.W, 8.BP) 创建了一个定点数,其中:

  • 16.W 指定了该定点数的总位宽为 16 位。这包括了整数部分和小数部分的所有位。
  • 8.BP 指定了该定点数的二进制小数点位置(Binary Point)。这里,8.BP 意味着小数部分有 8 位。

当您在 Chisel 中使用不同格式的 FixedPoint 数进行运算时,首先需要调整它们,以确保具有相同的位宽和小数点位置。以下是如何进行这种转换和随后的加法运算的示例。

假设您有两个 FixedPoint 数,分别定义如下:

  • num1 有 16 位宽,其中 8 位是小数位:FixedPoint(16.W, 8.BP)
  • num2 有 18 位宽,其中 10 位是小数位:FixedPoint(18.W, 10.BP)

要进行加法运算,您首先需要决定一个目标格式,通常是选择两者中更“大”的格式,也就是位宽更宽、小数位更多的那个。在这个例子中,目标格式将是 FixedPoint(18.W, 10.BP)

  1. 扩展 num1 到更大的格式:

    val num1Extended = num1.setBinaryPoint(10).asFixedPoint(18.W)
    +

    这行代码将 num1 的小数点位置扩展到 10 位,并将整个数扩展到 18 位宽。

  2. 确保 num2 也符合目标格式:

    虽然 num2 已经是 FixedPoint(18.W, 10.BP),我们通常在实际代码中不需要对其进行任何操作,但是为了代码的清晰性和一致性,您可以明确指出这一点(尽管在实践中这不是必需的):

    val num2Adjusted = num2.asFixedPoint(18.W)
    +
  3. 进行加法运算:

    一旦两个数都调整到了相同的格式,就可以直接进行加法运算了:

    val sum = num1Extended + num2Adjusted
    +

    这样,sum 将会是两个数的和,也具有相同的格式 FixedPoint(18.W, 10.BP)

这个示例说明了如何在 Chisel 中将两个不同格式的 FixedPoint 数调整为相同格式,然后进行加法运算。通过这种方式,您可以确保运算的正确性,并避免由于格式不匹配导致的精度损失。

# Activation Functions

现在让我们创建一些激活函数!我们将使用零作为阈值。典型的激活函数包括 Sigmoid 函数和修正线性单元(ReLU)。

我们将使用的 Sigmoid 被称为 逻辑函数 (opens new window),其公式为:

其中 是斜率因子。然而,在硬件中计算指数函数是相当具有挑战性和开销的。我们将近似这个为阶跃函数。

第二个函数,ReLU,由类似的公式给出。

\text{relu}(x) = +\begin{cases} +0 & \text{如果 } x \leq 0 \\ +x & \text{如果 } x > 0 +\end{cases}

在下面实现这两个函数。您可以像这样指定一个固定点数值 -3.14.F(8.BP)

val Step: FixedPoint => FixedPoint = (x: FixedPoint) => Mux(x > 0.F(8.BP), 1.F(8.BP), 0.F(8.BP))
+val ReLU: FixedPoint => FixedPoint = (x: FixedPoint) => Mux(x > 0.F(8.BP), x, 0.F(8.BP))
+

Mux 的第一个参数是比较表达式 x > 0.F(0.BP),如果这个表达式为真(即 x>0),Mux 返回第二个参数 1.F(0.BP);如果为假(即 x<=0),Mux 返回第三个参数 0.F(0.BP)

# Tester

// test our Neuron
+test(new Neuron(2, Step)) { c =>
+    val inputs = Seq(Seq(-1, -1), Seq(-1, 1), Seq(1, -1), Seq(1, 1))
+
+    // make this a sequence of two values
+    val weights = Seq(1, 1)
+
+    // push data through our Neuron and check the result (AND gate)
+    c.reset.poke(true.B)
+    c.clock.step(5)
+    c.reset.poke(false.B)
+    for (i <- inputs) {
+        c.io.in(0).poke(i(0).F(8.BP))
+        c.io.in(1).poke(i(1).F(8.BP))
+        c.io.weights(0).poke(weights(0).F(16.W, 8.BP))
+        c.io.weights(1).poke(weights(1).F(16.W, 8.BP))
+        c.io.out.expect((if (i(0) + i(1) > 0) 1 else 0).F(16.W, 8.BP))
+        c.clock.step(1)
+    }
+
+}
+

在您的 Neuron 测试代码中,改变 weights 中值的类型从整数 1 到浮点数 1.0 是可行的,但这样做后需要确保 weights 的值赋予 FixedPoint 类型时小数点位置(binary point)被正确指定。在这个特定的情况下,由于您定义的权重值是 1.0,其实并没有小数部分,转换成定点数时小数部分是 0,所以您可以将其直接视为没有小数点的值。

如果您将 weights 定义为:

val weights = Seq(1.0, 1.0)
+

然后在 poke 操作时,您需要将它们转换为适当的 FixedPoint 形式。您的权重值 1.0 实际上在没有小数时与 1 是等价的,但从概念上讲,使用 1.0 表示这是一个可以有小数部分的数值。当您将这些权重值赋给 FixedPoint 信号时,您可以这样操作:

c.io.weights(0).poke(weights(0).F(16.W, 8.BP))
+c.io.weights(1).poke(weights(1).F(16.W, 8.BP))
+

在这个 poke 调用中,虽然 weights 的值是 1.0,但是由于我们这里用的是 .F(16.W, 8.BP) 转换,它会被认为是没有小数部分的数。在这里,小数点的位置被设置为 8,但由于权重是整数 1 的等价形式 1.0,其实没有影响。

在决定是否使用小数点时,主要考虑的是您期望的数值范围和精度。如果您的权重值确实需要小数部分,那么您应该使用 1.0 这样的浮点数表示,并在将其赋给 FixedPoint 类型时注意指定正确的小数点位置。在您的案例中,由于 1.0 等价于整数 1,所以实际上并不涉及小数点处理,而是直接转换为了等效的定点数表示。

+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.09-3.6 Object Oriented Programming.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.09-3.6 Object Oriented Programming.html new file mode 100644 index 0000000..25d82f5 --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.09-3.6 Object Oriented Programming.html @@ -0,0 +1,361 @@ + + + + + + 2024.03.09-3.6 Object Oriented Programming | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.09-3.6 Object Oriented Programming

# Object Oriented Programming

# Abstract Classes

# Example: Abstract Classes

abstract class MyAbstractClass {
+  def myFunction(i: Int): Int
+  val myValue: String
+}
+class ConcreteClass extends MyAbstractClass {
+  def myFunction(i: Int): Int = i + 1
+  val myValue = "Hello World!"
+}
+// Uncomment below to test!
+// val abstractClass = new MyAbstractClass() // Illegal! Cannot instantiate an abstract class
+val concreteClass = new ConcreteClass()      // Legal!
+

不能实例化抽象类

# Trait

Traits are very similar to abstract classes in that they can define unimplemented values. However, they differ in two ways:

  • a class can inherit from multiple traits
  • a trait cannot have constructor parameters

# Example: Trait and Multiple Inheritance

Traits are how Scala implements multiple inheritance, as shown in the example below. MyClass extends from both traits HasFunction and HasValue

trait HasFunction {
+  def myFunction(i: Int): Int
+}
+trait HasValue {
+  val myValue: String
+  val myOtherValue = 100
+}
+class MyClass extends HasFunction with HasValue {
+  override def myFunction(i: Int): Int = i + 1
+  val myValue = "Hello World!"
+}
+// Uncomment below to test!
+// val myTraitFunction = new HasFunction() // Illegal! Cannot instantiate a trait
+// val myTraitValue = new HasValue()       // Illegal! Cannot instantiate a trait
+val myClass = new MyClass()                // Legal!
+

extends HasFunction with HasValue: 使用 with 来继承多个类

注:通常都推荐使用 trait 除非特别想强调只能继承一个父类

# Object

一类特殊的 Class,不能实例化,可以直接调用

# Example: Object

object MyObject {
+  def hi: String = "Hello World!"
+  def apply(msg: String) = msg
+}
+println(MyObject.hi)
+println(MyObject("This message is important!")) // equivalent to MyObject.apply(msg)
+
## Companion Objects<a name="compobj"></a>
+
+When a class and an object share the same name and defined in the same file, the object is called a companion object. When you use `new` before the class/object name, it will instantiate the class. If you don't use `new`, it will reference the object:
+
+<span style="color:blue">Example: Companion Object</span><br>
+

# Companion Objects

When a class and an object share the same name and defined in the same file, the object is called a companion object. When you use new before the class/object name, it will instantiate the class. If you don't use new, it will reference the object.

# Example: Companion Object

object Lion {
+    def roar(): Unit = println("I'M AN OBJECT!")
+}
+class Lion {
+    def roar(): Unit = println("I'M A CLASS!")
+}
+new Lion().roar()
+Lion.roar()
+

在 Scala 中,伴生对象是与特定类共享同一名称的单例对象。每个类只能有一个伴生对象,反之亦然。使用伴生对象主要有几个目的,如下所述:

  1. 包含与类相关的常量: +通常,与特定类紧密相关的常量可以放在其伴生对象中。这样做的好处是可以直接通过类名访问这些常量,而不需要实例化该类。这类似于其他编程语言中的静态常量。例如,如果您有一个 Circle 类,可能会在其伴生对象中定义一个 Pi 常量。
  2. 在类构造器执行前后执行代码: +有时您可能需要在类实例化之前或之后执行某些代码。由于伴生对象可以访问类的私有成员和构造器,您可以在伴生对象中定义工厂方法或初始化代码,以确保在创建类实例之前或之后完成特定的逻辑。
  3. 为类创建多个构造器: +Scala 中的类只能有一个主构造器,但有时需要多种方式来构造类的实例。通过在伴生对象中定义 apply 方法,可以提供多个构造器。客户端代码可以通过调用这些 apply 方法,而不是直接使用 new 关键字来创建实例,使得代码更加简洁。这种模式在 Scala 集合库中非常常见。

以下是一个简单的示例来说明这些用途:

class Circle(radius: Double) {
+  def area: Double = Circle.Pi * radius * radius
+}
+
+object Circle {
+  private val Pi = 3.141592653589793
+
+  // 2. Code execution before/after class constructor
+  def init(): Unit = {
+    println("Circle companion object initialized.")
+  }
+
+  // 3. Multiple constructors
+  def apply(radius: Double): Circle = {
+    init()
+    new Circle(radius)
+  }
+}
+
+

在上面的例子中:

  • Pi 是作为与 Circle 类相关的常量定义在伴生对象中。
  • init 方法可以在创建类实例之前被调用。
  • 伴生对象提供了一个 apply 方法作为创建 Circle 实例的替代构造器,它允许客户端代码通过 Circle(radius) 而不是 new Circle(radius) 来创建 Circle 的实例,同时确保每次实例化前都调用 init 方法。

这样,伴生对象增强了 Scala 类的功能性,同时保持代码的组织性和简洁性。

# 构造器和工厂函数

在 Scala 中,类的构造器和工厂函数是用来创建类实例的,但它们的使用方式和上下文有所不同。

  1. 类的构造器:

    类的构造器是类定义的一部分,用于初始化新创建的对象。Scala 中的构造器分为两种:主构造器和辅助构造器。

    • 主构造器是类定义的一部分,紧跟在类名之后。主构造器的参数直接放在类名后面,而且这些参数可以被类中的方法直接访问。主构造器中的代码是类定义的一部分,当创建类的实例时,这些代码会被执行。
      class Person(val name: String, val age: Int) {
      +  // 主构造器的代码
      +  println("A new person instance is created.")
      +}
      +
      +
    • 辅助构造器在类体中使用 def this(...) 定义。每个辅助构造器必须以另一个已经定义好的构造器(主构造器或另一个辅助构造器)的调用开始。
      class Person(val name: String, val age: Int) {
      +  // 辅助构造器
      +  def this(name: String) = {
      +    this(name, 0)  // 调用主构造器
      +  }
      +}
      +
      +
  2. 工厂函数:

    工厂函数通常定义在类的伴生对象中,提供了一种灵活的创建类实例的方式,而不必直接使用 new 关键字。工厂函数可以有不同的名字,但习惯上经常使用 apply 方法。使用工厂函数的好处包括更简洁的语法和更丰富的逻辑处理能力。

    • 工厂函数通常在伴生对象中实现,可以包含创建实例的特定逻辑,比如参数验证或者返回现有的实例(实现单例模式或缓存实例)。
      object Person {
      +  // 工厂方法
      +  def apply(name: String, age: Int): Person = {
      +    // 可以添加逻辑,例如参数校验或预处理
      +    new Person(name, age)
      +  }
      +}
      +
      +

使用工厂函数创建实例时,可以省略 new 关键字,直接通过类名加上参数调用:

val p = Person("Alice", 25)  // 使用工厂函数而非 new 关键字
+
+

总的来说,类的构造器直接定义了如何构建类的实例,而工厂函数提供了更灵活、更丰富的逻辑来创建和管理类实例。

# Case Classes

case class(样例类)是一种特殊类型的类,它们提供了一些附加功能,使得在函数式编程和模式匹配中非常有用。样例类在 Scala 编程中非常常见,以下是它们的一些有用特性:

  1. 允许外部访问类参数:样例类的构造器参数默认是公共的(public),因此可以直接访问。
  2. 无需使用 new 关键字实例化:通常在创建普通类的实例时需要使用 new 关键字。但对于样例类,Scala 允许您省略 new 关键字直接创建实例。
  3. 自动创建 unapply 方法:这使得样例类非常适合用于模式匹配。unapply 方法可以从实例中提取构造器参数作为元组返回,这在模式匹配中特别有用。
  4. 不能被子类化:为了保证模式匹配的完整性和一致性,样例类不能被继承。这意味着每个样例类都是最终的(final)。

这里是一个声明三个不同样例类 NailScrewStaple 的例子:

class Nail(length: Int) // Regular class
+val nail = new Nail(10) // Requires the `new` keyword
+// println(nail.length) // Illegal! Class constructor parameters are not by default externally visible
+
+class Screw(val threadSpace: Int) // By using the `val` keyword, threadSpace is now externally visible
+val screw = new Screw(2)          // Requires the `new` keyword
+println(screw.threadSpace)
+
+case class Staple(isClosed: Boolean) // Case class constructor parameters are, by default, externally visible
+val staple = Staple(false)           // No `new` keyword required
+println(staple.isClosed)
+
+// 使用模式匹配来检查 Staple 实例的 isClosed 属性
+staple match {
+  case Staple(true) => println("The staple is closed.")
+  case Staple(false) => println("The staple is open.")
+}
+
+// output:
+2
+false
+The staple is open.
+

# Inheritance with Chisel

# Module

# Example: Gray Encoder and Decoder

import scala.math.pow
+
+// create a module
+class GrayCoder(bitwidth: Int) extends Module {
+  val io = IO(new Bundle{
+    val in = Input(UInt(bitwidth.W))
+    val out = Output(UInt(bitwidth.W))
+    val encode = Input(Bool()) // decode on false
+  })
+
+  when (io.encode) { //encode
+    io.out := io.in ^ (io.in >> 1.U)
+  } .otherwise { // decode, much more complicated
+    io.out := Seq.fill(log2Ceil(bitwidth))(Wire(UInt(bitwidth.W))).zipWithIndex.fold((io.in, 0)){
+      case ((w1: UInt, i1: Int), (w2: UInt, i2: Int)) => {
+        w2 := w1 ^ (w1 >> pow(2, log2Ceil(bitwidth)-i2-1).toInt.U)
+        (w2, i1)
+      }
+    }._1
+  }
+}
+

定义了一个名为 GrayCoder 的模块,用于执行格雷码的编码和解码。格雷码是一种二进制数码系统,其中两个连续的数值只有一个位数不同。这在某些硬件设计中非常有用,尤其是在减少位切换和错误率方面。

模块 GrayCoder 接受三个输入:

  1. io.in: 这是要编码或解码的输入值,其位宽由构造器参数 bitwidth 指定。
  2. io.out: 这是编码或解码后的输出值,位宽与输入相同。
  3. io.encode: 这是一个布尔输入,用于指示模块是应执行编码操作(当 encodetrue)还是解码操作(当 encodefalse)。

编码部分 (io.encode 为真时) 相对简单:

io.out := io.in ^ (io.in >> 1.U)
+
+

在这里,进行格雷码编码的方式是将输入 io.in 与其自身右移一位的结果进行异或操作。右移操作 io.in >> 1.U 生成了 io.in 每一位右移一位的结果,然后通过异或操作 ^ 与原始输入进行比较,以生成格雷码。

解码部分 (io.encode 为假时) 相对复杂:

io.out := Seq.fill(log2Ceil(bitwidth))(Wire(UInt(bitwidth.W))).zipWithIndex.fold((io.in, 0)){
+  case ((w1: UInt, i1: Int), (w2: UInt, i2: Int)) => {
+    w2 := w1 ^ (w1 >> pow(2, log2Ceil(bitwidth)-i2-1).toInt.U)
+    (w2, i1)
+  }
+}._1
+
+

这部分是格雷码的解码逻辑。解码格雷码比编码更复杂,因为需要迭代地将已解码的部分与右移的值进行异或运算来恢复原始的二进制数:

  1. Seq.fill(log2Ceil(bitwidth))(Wire(UInt(bitwidth.W))): 这创建了一个足够长度的 Wire 序列,每个元素的宽度都是 bitwidth。序列的长度由 log2Ceil(bitwidth) 确定,这是对数的上取整结果,确保能够覆盖所有位。
  2. zipWithIndex: 这将序列中的每个元素与其索引进行配对。
  3. fold: 这在序列上执行折叠操作,用于迭代地计算解码结果。在每一步,都将当前的部分解码结果 w1 与其右移特定位数后的值进行异或运算。移位的位数 pow(2, log2Ceil(bitwidth)-i2-1).toInt 是递减的,这确保了在解码过程中正确地将各个位逐个恢复。
  4. 最终,._1 用于从 (w2, i1) 这个元组中取出 w2,即最终的解码值,将其赋给 io.out

通过这种方式,GrayCoder 模块能够根据 encode 信号的值选择执行格雷码的编码或解码,并输出相应的结果。

# Test

// test our gray coder
+val bitwidth = 4
+test(new GrayCoder(bitwidth)) { c =>
+    def toBinary(i: Int, digits: Int = 8) = {
+        String.format("%" + digits + "s", i.toBinaryString).replace(' ', '0')
+    }
+    println("Encoding:")
+    for (i <- 0 until pow(2, bitwidth).toInt) {
+        c.io.in.poke(i.U)
+        c.io.encode.poke(true.B)
+        c.clock.step(1)
+        println(s"In = ${toBinary(i, bitwidth)}, Out = ${toBinary(c.io.out.peek().litValue.toInt, bitwidth)}")
+    }
+
+    println("Decoding:")
+    for (i <- 0 until pow(2, bitwidth).toInt) {
+        c.io.in.poke(i.U)
+        c.io.encode.poke(false.B)
+        c.clock.step(1)
+        println(s"In = ${toBinary(i, bitwidth)}, Out = ${toBinary(c.io.out.peek().litValue.toInt, bitwidth)}")
+    }
+}
+

这段代码是使用 Chisel 测试框架来测试 GrayCoder 模块的一个实例。GrayCoder 模块是一个旨在执行格雷码编码和解码的模块。测试主要分为两个部分:编码和解码。以下是代码的详细解释:

  1. 设置测试位宽:

    val bitwidth = 4
    +
    +

    这里设定了 bitwidth 为 4,这意味着测试将处理 4 位宽的输入和输出。在格雷码转换中,输入和输出都将具有相同的位宽。

  2. 测试实例的创建:

    test(new GrayCoder(bitwidth)) { c =>
    +
    +

    这行代码启动了对 GrayCoder 模块的测试,其中 bitwidth 为 4,传递给 GrayCoder 以设置其处理宽度。

  3. 定义二进制格式化函数:

    def toBinary(i: Int, digits: Int = 8) = {
    +    String.format("%" + digits + "s", i.toBinaryString).replace(' ', '0')
    +}
    +
    +

    toBinary 函数用于将整数格式化为二进制字符串。digits 参数指定了字符串的长度,未使用位用 '0' 填充。

  4. 编码测试:

    println("Encoding:")
    +for (i <- 0 until pow(2, bitwidth).toInt) {
    +    c.io.in.poke(i.U)
    +    c.io.encode.poke(true.B)
    +    c.clock.step(1)
    +    println(s"In = ${toBinary(i, bitwidth)}, Out = ${toBinary(c.io.out.peek().litValue.toInt, bitwidth)}")
    +}
    +
    +

    在编码测试部分,循环变量 i 从 0 遍历到 2^bitwidth - 1。对于每个 i 值:

    • 使用 poke 方法将 i 作为输入写入到 GrayCoder 模块的 in 端口。
    • 设置 encode 信号为 true,指示模块执行编码操作。
    • 执行时钟脉冲,触发模块操作。
    • 打印输入值和经过编码后的输出值。
  5. 解码测试:

    println("Decoding:")
    +for (i <- 0 until pow(2, bitwidth).toInt) {
    +    c.io.in.poke(i.U)
    +    c.io.encode.poke(false.B)
    +    c.clock.step(1)
    +    println(s"In = ${toBinary(i, bitwidth)}, Out = ${toBinary(c.io.out.peek().litValue.toInt, bitwidth)}")
    +}
    +
    +

    解码测试遵循与编码测试相似的逻辑,不同之处在于:

    • 设置 encode 信号为 false,指示模块执行解码操作。
    • 输入 i 被认为是经过格雷码编码的值,测试检查模块是否能正确地将其解码回原始数值。

通过这个测试脚本,可以验证 GrayCoder 模块在给定位宽下对所有可能的输入值进行正确的编码和解码。输出结果提供了一个直观的方式来确认格雷码转换是否按预期执行。

+ + + diff --git a/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.12-3.7 Generators Types.html b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.12-3.7 Generators Types.html new file mode 100644 index 0000000..dd4225c --- /dev/null +++ b/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.12-3.7 Generators Types.html @@ -0,0 +1,435 @@ + + + + + + 2024.03.12-3.7 Generators: Types | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.12-3.7 Generators: Types

# Static Types

# Types in Scala

println(10.getClass)
+println(10.0.getClass)
+println("ten".getClass)
+class MyClass {
+    def myMethod = ???
+}
+println(new MyClass().getClass)
+
+// output:
+int
+double
+class java.lang.String
+class ammonite.$sess.cmd4$Helper$MyClass
+

没有返回值的函数,就设置返回值类型为 Unit

var counter = 0
+def increment(): Unit = {
+    counter += 1
+}
+increment()
+

# Scala vs. Chisel Types

模块 2.2 讨论了 Chisel 类型和 Scala 类型之间的区别。例如,下面的代码是合法的,因为 0.UUInt 类型(一个 Chisel 类型):

val a = Wire(UInt(4.W))
+a := 0.U
+

而下面的代码是非法的,因为 0 是 Int 类型(一个 Scala 类型):

val a = Wire(UInt(4.W))
+a := 0
+

这同样适用于 Bool,这是一个 Chisel 类型,它与 Scala 的 Boolean 类型不同:

val bool = Wire(Bool())
+val boolean: Boolean = false
+// 合法
+when (bool) { ... }
+if (boolean) { ... }
+// 非法
+if (bool) { ... }
+when (boolean) { ... }
+

如果你错误地混合使用了 UIntIntBoolBoolean,Scala 编译器通常会为你捕捉到这些错误。这归功于 Scala 的静态类型系统。在编译时,编译器能够区分 Chisel 类型和 Scala 类型,并且能够理解 if () 期望一个 Booleanwhen () 期望一个 Bool。这种类型检查机制有助于避免类型相关的逻辑错误,确保您的硬件描述代码的正确性和稳定性。

# Scala Tye Coercion

# asInstanceOf

x.asInstanceOf[T] casts the object x to the type T. It throws an exception if the given object cannot be cast to type T.

val x: UInt = 3.U
+try {
+  println(x.asInstanceOf[Int])
+} catch {
+  case e: java.lang.ClassCastException => println("As expected, we can't cast UInt to Int")
+}
+
+// But we can cast UInt to Data since UInt inherits from Data.
+println(x.asInstanceOf[Data])
+

# Type Casting in Chisel

Chisel 提供了一套类型转换函数,可以帮助开发者在不同的 Chisel 类型之间转换数据。其中,asTypeOf() 是最通用的类型转换函数,允许将一个 Chisel 数据类型转换成另一个指定的 Chisel 数据类型,只要这样的转换在逻辑上是有意义的。

除了 asTypeOf(),还有一些特定的转换函数,如 asUInt()asSInt(),这些函数分别用于将数据转换为无符号整数(UInt)和有符号整数(SInt)。使用这些函数可以确保类型转换的意图更加明确,同时也使代码更容易理解。

class TypeConvertDemo extends Module {
+    val io = IO(new Bundle {
+        val in  = Input(UInt(4.W))
+        val out = Output(SInt(4.W))
+    })
+    io.out := io.in.asTypeOf(io.out)
+}
+

# Type Matching

# Match Operator

class ConstantSum(in1: chisel3.Data, in2: chisel3.Data) extends Module {
+    val io = IO(new Bundle {
+        val out = Output(chiselTypeOf(in1)) // in case in1 is literal then just get its type
+    })
+    (in1, in2) match {
+        case (x: UInt, y: UInt) => io.out := x + y
+        case (x: SInt, y: SInt) => io.out := x + y
+        case _ => throw new Exception("I give up!")
+    }
+}
+

下面代码会报错:

class InputIsZero extends Module {
+    val io = IO(new Bundle {
+        val in  = Input(UInt(16.W))
+        val out = Output(Bool())
+    })
+    io.out := {io.in match {
+        // note that case 0.U is an error
+        case (0.U) => true.B
+        case _   => false.B
+    }}
+}
+println(getVerilog(new InputIsZero))
+

这是因为在硬件描述语言中的 match 语句并不像软件编程语言那样工作。在 Chisel(基于 Scala),match 语句通常用于软件逻辑的模式匹配,而不是硬件逻辑。硬件描述中的条件判断应该使用 when.elsewhen.otherwise 等语句来实现。

在您的代码中,您尝试使用 match 语句来为 io.out 赋值,这是不允许的。您应该改用 when 语句来判断 io.in 是否为 0,并据此为 io.out 赋值。以下是修改后的代码:

class InputIsZero extends Module {
+  val io = IO(new Bundle {
+    val in  = Input(UInt(16.W))
+    val out = Output(Bool())
+  })
+
+  // 使用when语句代替match进行硬件条件判断
+  io.out := io.in === 0.U
+}
+
+

在这段修正后的代码中,io.out 直接被赋值为 io.in === 0.U 的结果,这是 Chisel 中比较 UInt 值的标准方法。这样的表达式直接评估 io.in 是否等于 0,并将布尔结果赋给 io.out,无需使用 when-otherwise 语句,因为这里是个直接的等式判断。

# Unapply

unapply 方法在 Scala 中是模式匹配的一种强大特性,它通常与 apply 方法相对应。apply 方法允许你以一种简洁的方式构造对象(即不需要显式地使用 new 关键字),而 unapply 方法则用于在模式匹配中分解对象,提取出关键的信息或属性。对于每个 case 类,Scala 编译器会自动创建一个伴生对象(companion object),其中包含 applyunapply 方法。apply 方法使你能够不用 new 关键字来创建对象,而 unapply 方法则用于模式匹配和提取值。当你在模式匹配中使用 case 类时,unapply 方法会自动被调用。该方法从主构造器接收的对象中提取出数据,并将其包装为一个选项(Option),通常是一个元组。模式匹配会检查这个选项,如果是 Some,则匹配成功,并允许进一步操作提取的值;如果是 None,则匹配失败,继续尝试下一个模式。

考虑下面的 Something case 类:

case class Something(a: String, b: Int)
+

对于这个 case 类,Scala 编译器自动生成 unapply 方法,当你执行类似下面的模式匹配时:

val a = Something("A", 3)
+
+a match {
+    case Something("A", value) => println(s"Matched with value: $value")
+    case Something(str, 3)     => println(s"Matched with string: $str")
+}
+

这里发生的事情是:

  1. case Something("A", value) 中,unapply 方法从对象 a 中提取 StringInt,并检查字符串是否等于 "A"。如果是,value 被赋予 Int 值,然后执行相应的代码块。
  2. case Something(str, 3) 中,同样利用 unapply 方法提取,这次是检查 Int 是否等于 3。如果是,str 被赋予相应的 String 值。

unapply 方法的存在让模式匹配变得非常强大和灵活,不仅可以检查类型,还可以提取并操作数据。这使得 Scala 的模式匹配在处理复杂数据结构时非常有用。

case class SomeGeneratorParameters(
+    someWidth: Int,
+    someOtherWidth: Int = 10,
+    pipelineMe: Boolean = false
+) {
+    require(someWidth >= 0)
+    require(someOtherWidth >= 0)
+    val totalWidth = someWidth + someOtherWidth
+}
+
+def delay(p: SomeGeneratorParameters): Int = p match {
+    case SomeGeneratorParameters(_, sw, false) => sw * 2
+    case sg @SomeGeneratorParameters(_, _, true) => sg.totalWidth * 3
+}
+

这个示例演示了如何在 Scala 中使用模式匹配结合 unapply 方法,以及如何在 case 类和普通类中实现和使用这些方法。

# SomeGeneratorParameters case 类

SomeGeneratorParameters 是一个 case 类,它接受三个参数,其中两个有默认值。由于这是一个 case 类,Scala 编译器会自动生成 applyunapply 方法:

  • apply 方法允许你直接使用 SomeGeneratorParameters(10, 10) 来构造实例,而不需要 new 关键字。
  • unapply 方法使你能够在模式匹配中解构 SomeGeneratorParameters 对象。

# delay 函数

delay 函数接受一个 SomeGeneratorParameters 实例 p 并根据其属性计算一个延迟值:

  1. 第一个 case 分支匹配任何 pipelineMefalseSomeGeneratorParameters 实例,计算延迟为 someOtherWidth * 2
  2. 第二个 case 分支使用 @ 符号 (sg @ SomeGeneratorParameters(...)) 来同时绑定整个参数实例到 sg 变量和匹配其属性。如果 pipelineMetrue,则使用该实例的 totalWidth 属性计算延迟为 totalWidth * 3

# 模式匹配的不同语法

  1. 直接匹配类型并引用参数值:

    case p: SomeGeneratorParameters => p.someOtherWidth * 2
    +

    这表示匹配 SomeGeneratorParameters 类型的任何实例 p,并使用其 someOtherWidth 属性。

  2. 解构匹配并直接引用内部值:

    case SomeGeneratorParameters(_, sw, _) => sw * 2
    +

    这表示解构 SomeGeneratorParameters 实例,匹配任何值,但只关心 someOtherWidthsw)。

  3. 使用 @ 保留整个实例的引用同时匹配内部值:

    case sg @ SomeGeneratorParameters(_, sw, true) => sw
    +

    这使得 sg 绑定到整个 SomeGeneratorParameters 实例,同时解构匹配来引用 someOtherWidth

  4. 嵌入条件检查:

    case s: SomeGeneratorParameters if s.pipelineMe => s.someOtherWidth * 2
    +

    这表示匹配 SomeGeneratorParameters 类型的实例,且只在 pipelineMetrue 时匹配。

所有这些语法形式都依赖于 unapply 方法,它在 case 类的伴生对象中自动生成。如果您想为非 case 类实现类似的模式匹配功能,可以手动实现 applyunapply 方法,如最后部分提及,但示例未给出具体实现。

# 手动定义 unapply 方法

class Boat(val name: String, val length: Int)
+object Boat {
+    def unapply(b: Boat): Option[(String, Int)] = Some((b.name, b.length))
+    def apply(name: String, length: Int): Boat = new Boat(name, length)
+}
+
+def getSmallBoats(seq: Seq[Boat]): Seq[Boat] = seq.filter { b =>
+    b match {
+        case Boat(_, length) if length < 60 => true
+        case Boat(_, _) => false
+    }
+}
+
+val boats = Seq(Boat("Santa Maria", 62), Boat("Pinta", 56), Boat("Nina", 50))
+println(getSmallBoats(boats).map(_.name).mkString(" and ") + " are small boats!")
+

在这个例子中,我们定义了一个名为 Boat 的类,它有两个属性:namelength。为了使 Boat 类能够在模式匹配中使用,我们还定义了一个伴生对象 Boat,其中实现了 applyunapply 方法。这样,即使 Boat 不是一个 case 类,我们也可以使用模式匹配的功能,就像使用 case 类那样。

  1. Boat 类定义:

    class Boat(val name: String, val length: Int)
    +

    这个定义创建了一个拥有 name(船名)和 length(船长)两个属性的 Boat 类。这两个属性是公开的,因此可以在类的外部访问。

  2. Boat 伴生对象定义:

    object Boat {
    +    def unapply(b: Boat): Option[(String, Int)] = Some((b.name, b.length))
    +    def apply(name: String, length: Int): Boat = new Boat(name, length)
    +}
    +
    • apply 方法允许我们以 Boat("Santa Maria", 62) 的形式创建 Boat 实例,而不需要使用 new 关键字。
    • unapply 方法用于模式匹配。它接收一个 Boat 实例,并返回一个包含船名和船长的元组的 Option。如果 Boat 实例不符合期望的格式(虽然在这里总是返回 Some),也可以返回 None
  3. getSmallBoats 函数定义:

    def getSmallBoats(seq: Seq[Boat]): Seq[Boat] = seq.filter { b =>
    +    b match {
    +        case Boat(_, length) if length < 60 => true
    +        case _ => false
    +    }
    +}
    +

    这个函数接收一个 Boat 序列,使用 filter 方法和模式匹配来筛选出长度小于 60 的船。case Boat(_, length) if length < 60 => true 这行代码使用 unapply 方法从 Boat 实例中提取长度,如果长度小于 60,就选择这艘船。

  4. 测试和输出:

    val boats = Seq(Boat("Santa Maria", 62), Boat("Pinta", 56), Boat("Nina", 50))
    +println(getSmallBoats(boats).map(_.name).mkString(" and ") + " are small boats!")
    +

    这部分代码创建了一个包含三艘船的序列,然后调用 getSmallBoats 函数来筛选出其中的小船,并打印出这些小船的名字。

通过这个示例,你可以看到如何通过实现 unapply 方法在普通类上使用模式匹配,以及如何将这些技术应用于实际问题。这展示了 Scala 在处理数据和模式匹配方面的强大功能。

# Partial Functions

偏函数(Partial Function)是一种特殊的函数,它只对输入值的一个子集进行定义,并不对所有可能的输入值都给出定义。偏函数在 Scala 中通常用于模式匹配,特别是处理那些只对特定输入感兴趣的情况。

偏函数的类型是 PartialFunction[A, B],其中 A 是输入类型,B 是输出类型。你可以使用 { case ... => ... } 语法来定义一个偏函数。在这个语法中,每个 case 语句定义了函数的行为对于特定的输入值或输入模式。

偏函数非常适合用在模式匹配中,特别是当你只需要处理输入数据的一部分,而不关心其他数据时。这样做可以使代码更清晰和简洁。

让我们回顾 getSmallBoats 函数的例子来看偏函数是如何工作的:

def getSmallBoats(seq: Seq[Boat]): Seq[Boat] = seq.filter { b =>
+    b match {
+        case Boat(_, length) if length < 60 => true
+        case _ => false
+    }
+}
+

在这个例子中,filter 方法接受一个函数作为参数,这个函数将每个元素 b 从序列 seq 中传递到一个 match 表达式。match 表达式实际上定义了一个偏函数,它只对长度小于 60 的船只感兴趣。

我们可以将这段代码重构为使用显式的偏函数定义:

val smallBoat: PartialFunction[Boat, Boolean] = {
+    case Boat(_, length) if length < 60 => true
+}
+
+def getSmallBoats(seq: Seq[Boat]): Seq[Boat] = seq.filter(smallBoat.lift)
+

在这个重构后的版本中,smallBoat 是一个偏函数,它仅在船的长度小于 60 时返回 truelift 方法将 PartialFunction 转换为一个返回 Option 的普通函数,使得其可以与 filter 一起使用。这里的 lifttrue 转换为 Some(true),并将不匹配的情况转换为 None,然后 filter 通过这些 Some(true)None 值来决定哪些元素应该被保留。

通过这个例子,你可以看到偏函数如何提供一种强大且表达性很好的方式来处理特定的数据和模式,同时忽略其他不相关的情况。

# Type Safe Connections

class Bundle1 extends Bundle {
+  val a = UInt(8.W)
+}
+
+class Bundle2 extends Bundle1 {
+  val b = UInt(16.W)
+}
+
+class BadTypeModule extends Module {
+  val io = IO(new Bundle {
+    val c  = Input(Clock())
+    val in = Input(UInt(2.W))
+    val out = Output(Bool())
+
+    val bundleIn = Input(new Bundle2)
+    val bundleOut = Output(new Bundle1)
+  })
+
+  //io.out := io.c // won't work due to different types
+
+  // Okay, but Chisel will truncate the input width to 1 to match the output.
+//   io.out := io.in
+
+//   // Compiles; Chisel will connect the common subelements of the two Bundles (in this case, 'a').
+//   io.bundleOut := io.bundleIn
+}
+
+println(getVerilog(new BadTypeModule))
+

在这个 Chisel 示例中,我们定义了两个 Bundle 类(Bundle1Bundle2),然后创建了一个名为 BadTypeModule 的模块,用以展示不同类型赋值时的行为。这里同时展示了可以正常工作的代码和会引发问题的代码,让我们逐一进行解释:

  1. Bundle 定义:

    Bundle1Bundle2 是 Chisel 中的两个数据包结构(或称为复合类型)。Bundle2 继承了 Bundle1,所以它包含了 Bundle1 的所有字段,并额外增加了一个字段 b

    class Bundle1 extends Bundle {
    +  val a = UInt(8.W)
    +}
    +
    +class Bundle2 extends Bundle1 {
    +  val b = UInt(16.W)
    +}
    +
  2. BadTypeModule 模块定义:

    BadTypeModule 模块中,定义了一些输入输出接口,包括标准的 UInt 和特定的 Bundle 类型。

    class BadTypeModule extends Module {
    +  val io = IO(new Bundle {
    +    val c  = Input(Clock())
    +    val in = Input(UInt(2.W))
    +    val out = Output(Bool())
    +
    +    val bundleIn = Input(new Bundle2)
    +    val bundleOut = Output(new Bundle1)
    +  })
    +}
    +

    接下来是对 io.out 赋值的不同尝试:

    • io.out := io.c 这行代码是错误的尝试,因为 io.cClock() 类型,而 io.outBool() 类型。在 Chisel 中,不能直接将时钟信号赋给布尔型输出。
    • io.out := io.in 这行是可以正常工作的,尽管 io.inUInt(2.W) 类型,而 io.outBool() 类型。Chisel 在赋值时会进行类型转换,这里会将 io.in 截断为 1 位以匹配 Bool() 的宽度。
    • io.bundleOut := io.bundleIn 也是可以正常工作的代码。尽管 io.bundleInBundle2 类型,而 io.bundleOutBundle1 类型,Chisel 在赋值时会进行宽松匹配(loose coupling),只连接两个 Bundle 中相同的字段。因为 Bundle2 继承自 Bundle1,所以 Bundle1 中的字段 a 在两者间会被正确连接。

    # Type Generics

    val seq1 = Seq("1", "2", "3") // Type is Seq[String]
    +val seq2 = Seq(1, 2, 3)       // Type is Seq[Int]
    +val seq3 = Seq(1, "2", true)  // Type is Seq[Any]
    +

    有时需要用户指明多态类型

    //val default = Seq() // Error!
    +val default = Seq[String]() // User must tell compiler that default is of type Seq[String]
    +Seq(1, "2", true).foldLeft(default){ (strings, next) =>
    +    next match {
    +        case s: String => strings ++ Seq(s)
    +        case _ => strings
    +    }
    +}
    +

    这段 Scala 代码演示了如何使用 foldLeft 方法和模式匹配来从混合类型的序列中筛选出字符串类型的元素。我将逐步解释每一部分的功能和目的。

    1. 定义默认值:

      初始的尝试定义 default 时出现错误,因为仅写 Seq() 没有足够的信息让编译器推断出序列的具体类型。这在类型推断的上下文中很重要。Scala 编译器需要明确的类型信息来保证类型安全和后续操作的正确性。

      // val default = Seq() // Error!
      +val default = Seq[String]() // 明确指定 default 为 Seq[String] 类型
      +
      +

      正确的做法是使用 Seq[String]() 明确指定序列中包含的元素类型是 String。这样,default 被明确为一个空的 String 类型序列。

    2. 创建混合类型序列并应用 foldLeft

      Seq(1, "2", true).foldLeft(default){ (strings, next) =>
      +    next match {
      +        case s: String => strings ++ Seq(s)
      +        case _ => strings
      +    }
      +}
      +
      +// output:
      +default: Seq[String] = List()
      +res17_1: Seq[String] = List("2")
      +

      这里,我们有一个包含整数、字符串和布尔值的序列 Seq(1, "2", true)。目标是从中筛选出所有的字符串。

      • foldLeft 方法从 default(空的字符串序列)开始,逐个处理原始序列中的元素。
      • (strings, next) => ... 是一个函数,其中 strings 是累积结果(开始时是 default),next 是当前遍历到的序列元素。
      • 在函数体内,使用模式匹配来检查 next 的类型: +
        • 如果 next 是一个字符串(case s: String),那么将这个字符串添加到累积结果 strings 中,并返回更新后的序列。
        • 如果 next 不是字符串(case _),仅返回当前的累积结果 strings,不做任何改动。

    通过上述步骤,foldLeft 方法最终返回一个只包含原始序列中所有字符串的新序列。在这个例子中,它将构建并返回一个只包含 "2"Seq[String]。这段代码演示了如何结合使用 foldLeft 和模式匹配来处理和筛选混合类型的数据集合。

    def time[T](block: => T): T = {
    +    val t0 = System.nanoTime()
    +    val result = block
    +    val t1 = System.nanoTime()
    +    val timeMillis = (t1 - t0) / 1000000.0
    +    println(s"Block took $timeMillis milliseconds!")
    +    result
    +}
    +
    +// Adds 1 through a million
    +val int = time { (1 to 1000000).reduce(_ + _) }
    +println(s"Add 1 through a million is $int")
    +
    +// Finds the largest number under a million that, in hex, contains "beef"
    +val string = time {
    +    (1 to 1000000).map(_.toHexString).filter(_.contains("beef")).last
    +}
    +println(s"The largest number under a million that has beef: $string")
    +

    这段代码定义了一个名为 time 的函数,用于测量任何 Scala 代码块的执行时间。然后,它演示了如何使用 time 函数来测量两个不同操作的执行时间:一个是将一百万个整数相加,另一个是在一百万个整数中查找以十六进制表示时包含字符串 "beef" 的最大数。下面是对每个部分的详细解释:

    1. 时间测量函数 time:

      def time[T](block: => T): T = {
      +    val t0 = System.nanoTime()
      +    val result = block
      +    val t1 = System.nanoTime()
      +    val timeMillis = (t1 - t0) / 1000000.0
      +    println(s"Block took $timeMillis milliseconds!")
      +    result
      +}
      +
      +
      • time 函数接受一个代码块 block 并返回该代码块的执行结果。[T] 表示这是一个泛型函数,可以接受和返回任意类型的结果。 +这个 time 函数的定义利用了 Scala 中的两个高级特性:泛型和按名参数。我将分解这个函数定义,帮助你理解每个部分的含义。 +
        1. 泛型 [T]:

          在这里,[T] 表示 time 函数是泛型的,即它可以接受并返回任意类型 T 的结果。这种定义方式使 time 函数非常灵活,因为它不限制代码块 block 的返回类型。例如,block 可以返回一个整数、字符串或任何其他类型的值,time 函数将相应地处理并返回相同的类型。

        2. 按名参数 (block: => T):

          (block: => T) 定义了一个按名参数 block。按名参数与普通(按值)参数不同,因为它不会在传递到函数时立即求值。相反,每次在函数体内访问 block 时,都会执行代码块并计算其结果。

          这里的 block: => T 意味着 block 是一个将被延迟执行的代码块,而不是一个已经计算好的值。这允许 time 函数首先记录执行前的时间,然后执行 block,最后记录执行后的时间,从而测量出 block 的执行时间。 +总结一下,def time[T](block: => T): T = { ... } 的含义是:定义一个名为 time 的泛型函数,它接受一个将被延迟执行的代码块 block 作为输入,并返回 block 执行的结果。block 可以是任意复杂的表达式或操作,time 函数将测量并打印出其执行时间,最终返回 block 的结果。这种函数在性能分析或需要测量某段代码执行时间的场景中非常有用。

      • System.nanoTime() 用于获取纳秒级的当前时间,从而计算代码块执行前后的时间差。
      • result 变量存储代码块 block 的执行结果。
      • 最后,函数打印出代码块的执行时间(以毫秒为单位),并返回执行结果 result
    2. 整数累加操作:

      val int = time { (1 to 1000000).reduce(_ + _) }
      +
      +
      • 这一行使用 time 函数测量 (1 to 1000000).reduce(_ + _) 的执行时间,该表达式计算从 1 到 1000000 的整数和。
      • reduce(_ + _) 使用简化操作,将序列中的所有数字累加。
    3. 查找特定十六进制字符串的操作:

      val string = time {
      +    (1 to 1000000).map(_.toHexString).filter(_.contains("beef")).last
      +}
      +
      +
      • 这一行使用 time 函数测量查找操作的执行时间。它将从 1 到 1000000 的整数转换为十六进制字符串,过滤出包含 "beef" 的字符串,然后获取满足条件的最大数。
      • map(_.toHexString) 将每个整数转换为其十六进制表示形式。
      • filter(_.contains("beef")) 过滤出包含 "beef" 的字符串。
      • .last 获取满足条件的最后一个元素,即最大的一个。

    这两个 time 函数调用展示了如何在实际应用中测量不同代码块的执行时间,为性能分析提供了便捷的工具。最后,程序打印出每个操作的结果以及执行时间。

    # Chisel Type Hierarchy

    chisel3.Data 是 Chisel 硬件类型的基类。UIntSIntVecBundle 等都是 Data 的实例。Data 可以用在 IO 中,并支持 :=、wires、regs 等操作。寄存器是 Chisel 中多态代码的一个很好的例子。可以查看 RegEnable(带有 Bool 使能信号的寄存器)的实现这里 (opens new window)。apply 函数为 [T <: Data] 模板化,这意味着 RegEnable 将适用于所有 Chisel 硬件类型。一些操作只在 Bits 的子类型上定义,例如 + 操作。这就是为什么你可以对 UIntSInt 进行加法操作,但不能对 BundleVec 进行加法操作的原因。

    # Example: Type Generic ShiftRegister

    在本例中,我们希望能够在一个捆绑(Bundle)中放置各种对象,能够使用 := 连接它们,并且能够用它们创建寄存器(RegNext 等)。这些操作不能对任意对象执行;例如,wire := 3 是非法的,因为 3 是一个 Scala 的 Int 类型,而不是 Chisel 的 UInt 类型。如果我们使用一个类型约束来指明类型 TData 的一个子类,那么我们就可以对任何类型为 T 的对象使用 :=,因为所有的 Data 类型都定义了 := 操作。

    class ShiftRegisterIO[T <: Data](gen: T, n: Int) extends Bundle {
    +    require (n >= 0, "Shift register must have non-negative shift")
    +
    +    val in = Input(gen)
    +    val out = Output(Vec(n + 1, gen)) // + 1 because in is included in out
    +    override def cloneType: this.type = (new ShiftRegisterIO(gen, n)).asInstanceOf[this.type]
    +}
    +
    +class ShiftRegister[T <: Data](gen: T, n: Int) extends Module {
    +    val io = IO(new ShiftRegisterIO(gen, n))
    +
    +    io.out.foldLeft(io.in) { case (in, out) =>
    +        out := in
    +        RegNext(in)
    +    }
    +}
    +

    这段代码定义了两个类:ShiftRegisterIOShiftRegister。这两个类联合实现了一个泛型的移位寄存器,在 Chisel 中移位寄存器是一种常见的硬件结构,用于数据的时序延迟。这里使用了泛型编程来允许这个移位寄存器处理任何类型的 Data。让我们逐步分析这两个类的定义和功能:

    1. ShiftRegisterIO 类:

      ShiftRegisterIO 是一个基于 Bundle 的 IO 接口定义,它被参数化以接受任何继承自 Data 的类型 T 以及整数 n 代表移位级数。

      • require (n >= 0, "Shift register must have non-negative shift"): 这行代码确保传入的移位级数 n 是非负的,否则会在运行时抛出异常。
      • val in = Input(gen): 定义了一个名为 in 的输入端口,其类型为 T
      • val out = Output(Vec(n + 1, gen)): 定义了一个名为 out 的输出端口,其类型为 Vec,长度为 n + 1,向量中的每个元素类型为 T。长度为 n + 1 是因为输出向量包括输入和所有中间移位寄存器的状态。
      • override def cloneType: 这个方法确保了 Chisel 在需要复制或实例化 ShiftRegisterIO 对象时能正确处理类型信息。这是 Chisel 的类型系统要求的。
    2. ShiftRegister 类:

      ShiftRegister 实现了泛型移位寄存器的功能。

      • val io = IO(new ShiftRegisterIO(gen, n)): 这行代码实例化了上面定义的 ShiftRegisterIO,作为模块的 IO 接口。
      • io.out.foldLeft(io.in) { case (in, out) => ... }: 这是移位寄存器的核心实现。这里使用了 foldLeft 方法来遍历输出向量 io.out 并依次连接寄存器。对于输出向量中的每一项: +
        • out := in: 当前输出连接到当前输入。
        • RegNext(in): 使用 RegNext 创建一个新的寄存器,其输入是 in,输出成为下一次迭代的输入。在 foldLeft 中,每次迭代的结果通常用于更新累积值。但在这个特定的情况下,RegNext(in) 的结果(即下一时钟周期的 in 值)并没有直接赋给一个命名的变量;相反,它隐式地成为下一次迭代中 in 参数的值。

      最终结果是,输入 io.in 通过一系列寄存器传递,每个寄存器的输出连接到下一个寄存器的输入,形成了一个链式结构。io.out 向量包含了这个链上的所有节点,因此它能够提供输入信号的每一步移位结果。

    通过这种方式,ShiftRegister 类可以用来创建任何数据类型 T 的移位寄存器,其中 T 必须是 Data 的子类。这样的设计使得 ShiftRegister 非常灵活,能够被用在多种不同的数据路径和时序电路设计中。

    # Type Generics with Typeclasses

+ + + diff --git "a/Chip/Chip/3. 2023.11.07-Verilog\350\257\255\346\263\225.html" "b/Chip/Chip/3. 2023.11.07-Verilog\350\257\255\346\263\225.html" new file mode 100644 index 0000000..4aae6cf --- /dev/null +++ "b/Chip/Chip/3. 2023.11.07-Verilog\350\257\255\346\263\225.html" @@ -0,0 +1,170 @@ + + + + + + 3. 2023.11.07-Verilog语法 | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265.html" new file mode 100644 index 0000000..567fafe --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265.html" @@ -0,0 +1,166 @@ + + + + + + 预学习阶段 | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way.html" new file mode 100644 index 0000000..546b800 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way.html" @@ -0,0 +1,170 @@ + + + + + + Learn C the hard way | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.02-\347\273\203\344\271\2401\357\274\232\345\220\257\347\224\250\347\274\226\350\257\221\345\231\250.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.02-\347\273\203\344\271\2401\357\274\232\345\220\257\347\224\250\347\274\226\350\257\221\345\231\250.html" new file mode 100644 index 0000000..c264871 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.02-\347\273\203\344\271\2401\357\274\232\345\220\257\347\224\250\347\274\226\350\257\221\345\231\250.html" @@ -0,0 +1,185 @@ + + + + + + 2024.04.02-练习 1:启用编译器 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.02-练习 1:启用编译器

# 1. make

int main(int argc, char *argv[])
+{
+    puts("Hello world.");
+
+    return 0;
+}
+

代码段没有显式包含#include <stdio.h>,但是仍然能够运行,并成功调用puts函数输出"Hello world."。这是因为,在某些编译器和开发环境中,即使没有显式地包含标准输入输出头文件stdio.h,编译器也可能会隐式地包含或者提前编译了这些基本的库函数。

具体来说,puts函数是 C 语言标准库中负责输出字符串到标准输出的函数,它定义在stdio.h中。按照 C 语言标准,使用puts或者其他标准库函数时,应该包含相应的头文件。不这样做是不符合标准的,可能导致编译器警告或错误。

然而,一些编译器为了方便开发者,可能会有以下行为:

  • 隐式包含:编译器可能会默认包含一些常用的头文件。这意味着即使开发者没有显式包含stdio.h,编译器也会处理像puts这样的标准库函数调用。
  • 预编译头文件:在某些开发环境中,常用的头文件可能被预编译并隐式地包含在每个编译单元中,以提高编译效率。
  • 特定编译器扩展:一些编译器可能会提供非标准的扩展,允许在没有包含对应头文件的情况下使用某些库函数。

不过,依赖这种非标准的行为是不推荐的。为了确保代码的可移植性和避免潜在的问题,最佳实践是始终显式包含你在代码中用到的所有标准库头文件。这样做可以保证代码在不同的编译器和环境中都能正常工作。

# 2. 如何使它崩溃?

对于这个程序,打开所有编译警告重新构建它:

$ rm ex1
+$ CFLAGS="-Wall" make ex1
+cc -Wall    ex1.c   -o ex1
+ex1.c: Infunction 'main':
+ex1.c:3: warning: implicit declaration offunction 'puts'
+$ ./ex1
+Hello world.
+

CFLAGS="-Wall":这部分设置了一个环境变量CFLAGS,它是用于 C 编译器的标志(flags)集合。在这个特定的例子中,-Wall选项被设置给CFLAGS-Wall是一个编译器标志,告诉编译器生成所有警告信息,帮助开发者发现代码中的潜在问题。这个标志对于提高代码质量和发现潜在的错误非常有用。

现在你会得到一个警告,说puts函数是隐式声明的。C 语言的编译器很智能,它能够理解你想要什么。但是如果可以的话,你应该去除所有编译器警告。把下面一行添加到ex1.c文件的最上面,之后重新编译来去除它:

#include <stdio.h>
+

# 3. 附加题 1

在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后运行它看看发生了什么。

Untitled

Untitled

# 4. 附加题 2

再多打印 5 行文本或者其它比"Hello world."更复杂的东西。

在 C 语言中,char *argv[]main函数的一个参数,它表示传递给程序的命令行参数的数组。让我们分解一下这个声明,以便更好地理解它:

  • char:表示数组中的元素是字符类型。
  • *:这是一个指针符号,表明这个变量是一个指针。
  • argv[]:这是一个数组符号,表明这个变量是一个数组。结合前面的指针符号,这意味着argv是一个指向指针的数组,或者更准确地说,是一个指向字符指针的数组。

所以,char *argv[]是一个指向字符指针数组的指针,每个字符指针指向一个字符串。这些字符串是命令行参数,即在命令行中执行程序时输入的参数。

main函数的上下文中,argc(argument count)是一个整型(int)变量,它表示命令行参数的数量,包括程序名本身。argv(argument vector)是一个指向字符串数组的指针,存储了所有的命令行参数。argv[0]通常是程序的名称,argv[1]是传递给程序的第一个参数,依此类推。argv[argc]NULL,标记数组的结束。

举例来说,如果你在命令行中运行程序如下:

./myprogram arg1 arg2
+

这里,argc将是3(因为有三个命令行参数:./myprogram, arg1, 和 arg2),而argv数组将包含以下内容:

  • argv[0] 将是字符串 "./myprogram",指向程序的名称。
  • argv[1] 将是字符串 "arg1",指向第一个命令行参数。
  • argv[2] 将是字符串 "arg2",指向第二个命令行参数。
  • argv[3] 将是NULL,标记数组的结束。

通过使用argcargv,C 程序可以接收和处理用户在命令行中输入的参数。

Untitled

# 5. 附加题 3

执行man 3 puts来阅读这个函数和其它函数的文档。

在 UNIX 或类 UNIX 系统中,man命令用于查看手册页(manual pages),它是系统文档的一个重要组成部分。手册页按照不同的部分组织,每个部分涵盖了特定类型的命令或信息。当你在命令行中输入man 3 puts时,3指的是你想要查看第三部分中puts函数的手册页。

手册页的部分主要包括:

  1. 用户命令:可执行程序或 shell 命令。
  2. 系统调用:由内核提供的函数。
  3. 库调用:标准库函数,如 C 库(libc)中的函数。
  4. 特殊文件:通常指/dev 目录下的文件。
  5. 文件格式和约定:例如/etc/passwd。
  6. 游戏和屏保:已经很少使用。
  7. 杂项:包括宏包和约定,如 man 文档自身的格式。
  8. 系统管理命令:通常只能由 root 用户执行的命令。
  9. 内核例程:内核的接口。

所以,man 3 puts命令表示你请求查看第三部分(库调用)中关于puts函数的文档。puts是标准 C 库的一部分,用于向标准输出写入一个字符串,这就是为什么它位于第三部分。这种组织方法让用户可以快速找到关于不同类型命令和函数的文档,即使它们的名字相同(例如,一个是用户命令,另一个是系统调用)。

Untitled

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.02-\347\273\203\344\271\2402\357\274\232\347\224\250Make\346\235\245\344\273\243\346\233\277Python.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.02-\347\273\203\344\271\2402\357\274\232\347\224\250Make\346\235\245\344\273\243\346\233\277Python.html" new file mode 100644 index 0000000..c768110 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.02-\347\273\203\344\271\2402\357\274\232\347\224\250Make\346\235\245\344\273\243\346\233\277Python.html" @@ -0,0 +1,278 @@ + + + + + + 2024.04.02-练习 2:用 Make 来代替 Python | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.02-练习 2:用 Make 来代替 Python

# 1. 使用 Make

make ex1
+CFLAGS="-Wall" make ex1
+

第一个命令中你告诉 make,“我想创建名为 ex1 的文件”。于是 Make 执行下面的动作:

  • 文件ex1存在吗?
  • 没有。好的,有没有其他文件以ex1开头?
  • 有,叫做ex1.c。我知道如何构建.c文件吗?
  • 是的,我会运行命令cc ex1.c -o ex1来构建它。
  • 我将使用ccex1.c文件来为你构建ex1

上面列出的第二条命令是一种向 make 命令传递“修改器”的途径。如果你不熟悉 Unix shell 如何工作,你可以创建这些“环境变量”,它们会在程序运行时生效。有时你会用一条类似于export CFLAGS="-Wall"的命令来执行相同的事情,取决于你所用的 shell。然而你可以仅仅把它们放到你想执行的命令前面,于是环境变量只会在程序运行时有效。

在这个例子中我执行了CFLAGS="-Wall" make ex1,所以它会给 make 通常使用的cc命令添加-Wall选项。这行命令告诉cc编译器要报告所有的警告(然而实际上不可能报告所有警告)。

实际上你可以深入探索使用 make 的上述方法,但是先让我们来看看Makefile,以便让你对 make 了解得更多一点。首先,创建文件并写入以下内容:

CFLAGS=-Wall -g
+
+clean:
+    rm -f ex1
+

将文件在你的当前文件夹上保存为Makefile。Make 会自动假设当前文件夹中有一个叫做Makefile的文件,并且会执行它。此外,一定要注意:确保你只输入了 TAB 字符,而不是空格和 TAB 的混合。

Makefile向你展示了 make 的一些新功能。首先我们在文件中设置CFLAGS,所以之后就不用再设置了。并且,我们添加了-g标识来获取调试信息。接着我们写了一个叫做clean的部分,它告诉 make 如何清理我们的小项目。

确保它和你的ex1.c文件在相同的目录中,之后运行以下命令:

make clean
+make ex1
+

# 2. Makefile

# 2.1 语法规则

目标 ... : 依赖 ...
+	命令1
+	命令2
+	. . .
+

Makefile 的核心规则,类似于一位厨神做菜,目标就是做好一道菜,那么所谓的依赖就是各种食材,各种厨具等等,然后需要厨师好的技术方法类似于命令,才能作出一道好菜。同时这些依赖也有可能此时并不存在,需要现场制作,或者是由其他厨师做好,那么这个依赖就成为了其他规则的目标,该目标也会有他自己的依赖和命令。这样就形成了一层一层递归依赖组成了 Makefile 文件。Makefile 并不会关心命令是如何执行的,仅仅只是会去执行所有定义的命令,和我们平时直接输入命令行是一样的效果。

1、目标即要生成的文件。如果目标文件的更新时间晚于依赖文件更新时间,则说明依赖文件没有改动,目标文件不需要重新编译。否则会进行重新编译并更新目标文件。

2、默认情况下 Makefile 的第一个目标为终极目标。

3、依赖:即目标文件由哪些文件生成。

4、命令:即通过执行命令由依赖文件生成目标文件。注意每条命令之前必须有一个 tab 保持缩进,这是语法要求(会有一些编辑工具默认 tab 为 4 个空格,会造成 Makefile 语法错误)。

5、all:Makefile 文件默认只生成第一个目标文件即完成编译,但是我们可以通过 all 指定所需要生成的目标文件。

# 2.2 变量

$符号表示取变量的值,当变量名多于一个字符时,使用"( )"

$符的其他用法

$^ 表示所有的依赖文件

$@ 表示生成的目标文件

$< 代表第一个依赖文件

SRC = $(wildcard *.c)
+OBJ = $(patsubst %.c, %.o, $(SRC))
+
+ALL: hello.out
+
+hello.out: $(OBJ)
+        gcc $^ -o $@
+
+$(OBJ): $(SRC)
+        gcc -c $^ -o $@
+

# 2.3 变量赋值

1、"="是最普通的等号,在 Makefile 中容易搞错赋值等号,使用 “=”进行赋值,变量的值是整个 Makefile 中最后被指定的值。

VIR_A = A
+VIR_B = $(VIR_A) B
+VIR_A = AA
+

经过上面的赋值后,最后 VIR_B 的值是 AA B,而不是 A B,在 make 时,会把整个 Makefile 展开,来决定变量的值

2、":=" 表示直接赋值,赋予当前位置的值。

VIR_A := A
+VIR_B := $(VIR_A) B
+VIR_A := AA
+

最后 BIR_B 的值是 A B,即根据当前位置进行赋值。因此相当于“=”,“:=”才是真正意义上的直接赋值

3、"?=" 表示如果该变量没有被赋值,赋值予等号后面的值。

VIR ?= new_value
+

如果 VIR 在之前没有被赋值,那么 VIR 的值就为 new_value。

VIR := old_value
+VIR ?= new_value
+

这种情况下,VIR 的值就是 old_value

4、"+="和平时写代码的理解是一样的,表示将符号后面的值添加到前面的变量上

# 2.4 预定义变量

CC:c 编译器的名称,默认值为 cc。cpp c 预编译器的名称默认值为$(CC) -E

CC = gcc
+

回显问题,Makefile 中的命令都会被打印出来。如果不想打印命令部分 可以使用@去除回显

@echo "clean done!"
+

@符号:在Makefile中,当你在命令行前加上@符号,它告诉make在执行这个命令时不要将命令本身输出到标准输出(即不在控制台显示命令)。通常,make会打印每个命令到标准输出,然后执行它。通过在命令前加上@符号,你可以避免显示命令,只显示命令的输出或者执行结果。这可以让你的构建输出看起来更简洁。

# 2.5 函数

通配符 SRC = $(wildcard ./*.c) 匹配目录下所有.c 文件,并将其赋值给 SRC 变量。

OBJ = $(patsubst %.c, %.o, $(SRC)) 这个函数有三个参数,意思是取出 SRC 中的所有值,然后将.c 替换为.o 最后赋值给 OBJ 变量。

示例:如果目录下有很多个.c 源文件,就不需要写很多条规则语句了,而是可以像下面这样写

SRC = $(wildcard *.c)
+OBJ = $(patsubst %.c, %.o, $(SRC))
+
+ALL: hello.out
+
+hello.out: $(OBJ)
+        gcc $(OBJ) -o hello.out
+
+$(OBJ): $(SRC)
+        gcc -c $(SRC) -o $(OBJ)
+

这里先将所有.c 文件编译为 .o 文件,这样后面更改某个 .c 文件时,其他的 .c 文件将不在编译,而只是编译有更改的 .c 文件,可以大大提高大项目中的编译速度。

# 2.6 伪目标 .PHONY

伪目标只是一个标签,clean 是个伪目标没有依赖文件,只有用 make 来调用时才会执行

当目录下有与 make 命令 同名的文件时 执行 make 命令就会出现错误。

解决办法就是使用伪目标

SRC = $(wildcard *.c)
+OBJ = $(patsubst %.c, %.o, $(SRC))
+
+ALL: hello.out
+
+hello.out: $(OBJ)
+        gcc $< -o $@
+
+$(OBJ): $(SRC)
+        gcc -c $< -o $@
+
+clean:
+        rm -rf $(OBJ) hello.out
+
+.PHONY: clean ALL
+

通常也会把 ALL 设置成伪目标

# 2.7 其他常用功能

代码清理 clean

我们可以编译一条属于自己的 clean 语句,来清理 make 命令所产生的所有文件,列如

SRC = $(wildcard *.c)
+OBJ = $(patsubst %.c, %.o, $(SRC))
+
+ALL: hello.out
+
+hello.out: $(OBJ)
+        gcc $< -o $@
+
+$(OBJ): $(SRC)
+        gcc -c $< -o $@
+
+clean:
+        rm -rf $(OBJ) hello.out
+

# 2.8 嵌套执行 Makefile

在一些大工程中,会把不同模块或不同功能的源文件放在不同的目录中,我们可以在每个目录中都写一个该目录的 Makefile 这有利于让我们的 Makefile 变的更加简洁,不至于把所有东西全部写在一个 Makefile 中。

列如在子目录 subdir 目录下有个 Makefile 文件,来指明这个目录下文件的编译规则。外部总 Makefile 可以这样写

subsystem:
+            cd subdir && $(MAKE)
+其等价于:
+subsystem:
+            $(MAKE) -C subdir
+

定义$(MAKE)宏变量的意思是,也许我们的 make 需要一些参数,所以定义成一个变量比较有利于维护。两个例子意思都是先进入"subdir"目录,然后执行 make 命令

我们把这个 Makefile 叫做总控 Makefile,总控 Makefile 的变量可以传递到下级的 Makefile 中,但是不会覆盖下层 Makefile 中所定义的变量,除非指定了 "-e"参数。

如果传递变量到下级 Makefile 中,那么可以使用这样的声明 export 如果不想让某些变量传递到下级 Makefile,可以使用 unexport

export variable = value
+等价于
+variable = value
+export variable
+等价于
+export variable := value
+等价于
+variable := value
+export variable
+如果需要传递所有变量,那么只要一个export就行了。后面什么也不用跟,表示传递所有变量
+

# 2.9 指定头文件路径

一般都是通过"-I"(大写 i)来指定,假设头文件在: /home/develop/include

则可以通过-I 指定: -I/home/develop/include 将该目录添加到头文件搜索路径中

在 Makefile 中则可以这样写:

CFLAGS=-I/home/develop/include
+

然后在编译的时候,引用 CFLAGS 即可,如下

yourapp:*.c
+    gcc $(CFLAGS) -o yourapp
+

# 3. 附加题

# 3.1 创建目标all:ex1,可以以单个命令make构建ex1

Untitled

CC=gcc
+
+CFLAGS=-Wall -g
+
+all:ex1
+
+ex1:ex1.o
+	$(CC) $(CFLAGS) ex1.o -o ex1
+
+ex1.o:ex1.c
+	$(CC) $(CFLAGS) -c ex1.c -o ex1.o
+
+clean:
+	rm -f ex1 ex1.o
+.PHONY: all clean
+

# 3.2 阅读man cc来了解关于-Wall-g行为的更多信息

-Wall

  • Wall是一个编译器选项,代表“warn all”,告诉编译器产生尽可能多的警告信息。尽管名称暗示它会启用所有警告,实际上它只启用了最常见的一组警告。这些警告可以帮助开发者发现代码中的潜在问题,比如变量未使用、可能的数据类型不匹配、未初始化的变量等。
  • 使用Wall是一种很好的做法,因为它可以帮助你提前识别潜在的错误或不一致,从而提高代码质量。在开发过程中,尽量解决所有Wall引发的警告,可以避免未来发生更复杂的问题。

-g

  • g选项用于在编译时生成调试信息。这些调试信息包括了程序中的变量、函数、类等符号的名称和类型信息,以及它们在源代码中的位置。这使得调试器(如 GDB)能够理解程序的结构,允许开发者进行断点调试、单步执行、查看变量值等调试操作。
  • 在不使用g选项的情况下编译的程序仍然可以运行,但如果需要调试,缺少调试信息会让这一过程变得非常困难。因此,开发阶段建议总是加上g选项来编译程序,以便在遇到问题时能够更容易地调试。
  • 需要注意的是,添加g选项编译的程序会因为包含了额外的调试信息而变得更大。在发布产品时,通常会移除调试信息(不使用g选项或使用像s这样的选项来剔除调试信息),以减小程序的大小和提高运行时性能。
+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.02-\347\273\203\344\271\2403\357\274\232\346\240\274\345\274\217\345\214\226\350\276\223\345\207\272.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.02-\347\273\203\344\271\2403\357\274\232\346\240\274\345\274\217\345\214\226\350\276\223\345\207\272.html" new file mode 100644 index 0000000..61368e2 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.02-\347\273\203\344\271\2403\357\274\232\346\240\274\345\274\217\345\214\226\350\276\223\345\207\272.html" @@ -0,0 +1,203 @@ + + + + + + 2024.04.02-练习3:格式化输出 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.02-练习3:格式化输出

# 1. printf

#include <stdio.h>
+
+int main()
+{
+    int age = 10;
+    int height = 72;
+
+    printf("I am %d years old.\n", age);
+    printf("I am %d inches tall.\n", height);
+
+    return 0;
+}
+

这个练习的代码量很小,但是信息量很大,所以让我们逐行分析一下:

  • 首先你包含了另一个头文件叫做stdio.h。这告诉了编译器你要使用“标准的输入/输出函数”。它们之一就是printf
  • 然后你使用了一个叫age的变量并且将它设置为10。
  • 接着你使用了一个叫height的变量并且设置为72。
  • 再然后你使用printf函数来打印这个星球上最高的十岁的人的年龄和高度。
  • printf中你会注意到你传入了一个字符串,这就是格式字符串,和其它语言中一样。
  • 在格式字符串之后,你传入了一些变量,它们应该被printf“替换”进格式字符串中。

这些语句的结果就是你用printf处理了一些变量,并且它会构造出一个新的字符串,之后将它打印在终端上。

# 2. 附加题

# 2.1 %占位符和转移字符

常用的%占位符

  • %d%i:用于输出int类型的整数。
  • %u:用于输出无符号整型unsigned int
  • %f:用于输出单精度浮点数或双精度浮点数(floatdouble),默认情况下显示六位小数。
  • %lf:用于输出双精度浮点数(double),虽然%f也可以用于double,但在某些情况下使用%lf更加明确。
  • %e%E:用科学记数法输出浮点数。
  • %g%G:自动选择%f%e%E)中较短的一种输出浮点数。
  • %c:输出单个字符。
  • %s:输出字符串。
  • %p:输出指针的地址。
  • %x%X:以十六进制形式输出无符号整数,%x产生小写字母,而%X产生大写字母。
  • %%:输出%字符本身。

转义字符

转义字符用于表示那些不能直接在源代码中表示的字符,或者具有特殊意义的字符。以下是一些常用的转义字符:

  • \n:换行符,移动到下一行的开头。
  • \t:水平制表符,常用于输出中的对齐。
  • \\:表示一个反斜杠字符\
  • \":表示双引号字符",允许在字符串常量中使用双引号。
  • \':表示单引号字符'(在字符常量中使用)。
  • \r:回车符,将光标移动到当前行的开头。
  • \b:退格符,将光标向左移动一个位置。
  • \0:空字符,字符串的结束标志。

对于浮点数:

  • %.*f:对于floatdouble类型,.*允许你通过参数指定小数点后的位数。例如,printf("%.*f", 3, 3.14159)会输出3.142
  • %.*e%.*E:以科学记数法格式输出浮点数,其中.*指定小数点后的位数。
  • %.*g%.*G:自动选择%f%e%E)中较短的一种输出浮点数,.*指定有效数字的最大位数。

对于整数:

  • %.*d%.*i:虽然通常用于指定最小宽度,但通过指定精度,可以使得输出的整数在前面用零填充到指定的长度。例如,printf("%.*d", 5, 123)会输出00123

对于字符串:

  • %.*s:指定字符串的最大输出长度。这对于输出字符串的一个子串非常有用。例如,printf("%.*s", 3, "abcdef")会输出abc

# 2.2 Makefile

CC=gcc
+CFLAGS=-Wall -g
+
+TARGET=ex3
+
+all: $(TARGET)
+
+$(TARGET): $(TARGET).o
+	$(CC) $(CFLAGS) $^ -o $@
+
+$(TARGET).o: $(TARGET).c
+	$(CC) $(CFLAGS) -c $^ -o $@
+
+clean:
+	rm -f $(TARGET) $(TARGET).o
+
+.PHONY: all clean
+
+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2404\357\274\232Valgrind \344\273\213\347\273\215.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2404\357\274\232Valgrind \344\273\213\347\273\215.html" new file mode 100644 index 0000000..a959bab --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2404\357\274\232Valgrind \344\273\213\347\273\215.html" @@ -0,0 +1,243 @@ + + + + + + 2024.04.03-练习4:Valgrind 介绍 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.03-练习4:Valgrind 介绍

# 1. Intro

Valgrind是一个编程工具,用于内存调试、内存泄漏检测,以及性能分析。它主要用于帮助开发者找出程序中的内存管理和线程使用错误,是Linux和macOS下常用的工具之一。Valgrind通过一个核心,提供了多种不同的工具,其中最著名的是Memcheck。Memcheck可以检测以下问题:

  • 访问未初始化的内存
  • 访问已经释放的内存
  • 访问申请后未释放的内存(内存泄漏)
  • 不当的堆栈使用
  • mallocfree等堆管理函数的误用

使用方法

使用Valgrind的基本语法很简单。首先,确保你的程序是用调试信息编译的(通常是使用gcc-g选项)。然后,使用下面的命令行格式运行Valgrind:

valgrind [options] your_program [program_options]
+

其中,[options]是传递给Valgrind的选项(例如,选择不同的工具),your_program是你的程序的路径,[program_options]是传递给你的程序的任何选项。

示例:使用Memcheck检测内存泄漏

假设你的可执行文件名为my_program,要使用Memcheck工具(Valgrind的默认工具),可以这样做:

valgrind --leak-check=full ./my_program
+
  • -leak-check=full选项告诉Memcheck提供每个内存泄漏的详细信息。

Valgrind运行后,会在终端输出报告,其中包含了内存泄漏的信息、未初始化变量的使用等问题。

# 2. Example

#include <stdio.h>
+
+/* Warning: This program is wrong on purpose. */
+
+int main()
+{
+    int age = 10;
+    int height;
+
+    printf("I am %d years old.\n");
+    printf("I am %d inches tall.\n", height);
+
+    return 0;
+}
+

使用 valgrind 运行,结果如下

==431815== Memcheck, a memory error detector
+==431815== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
+==431815== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
+==431815== Command: ./ex4
+==431815== 
+==431815== Conditional jump or move depends on uninitialised value(s)
+==431815==    at 0x48EAAD6: __vfprintf_internal (vfprintf-internal.c:1516)
+==431815==    by 0x48D479E: printf (printf.c:33)
+==431815==    by 0x109188: main (ex4.c:8)
+==431815==  Uninitialised value was created by a stack allocation
+==431815==    at 0x109149: main (ex4.c:3)
+==431815== 
+==431815== Use of uninitialised value of size 8
+==431815==    at 0x48CE2EB: _itoa_word (_itoa.c:177)
+==431815==    by 0x48E9ABD: __vfprintf_internal (vfprintf-internal.c:1516)
+==431815==    by 0x48D479E: printf (printf.c:33)
+==431815==    by 0x109188: main (ex4.c:8)
+==431815==  Uninitialised value was created by a stack allocation
+==431815==    at 0x109149: main (ex4.c:3)
+==431815== 
+==431815== Conditional jump or move depends on uninitialised value(s)
+==431815==    at 0x48CE2FC: _itoa_word (_itoa.c:177)
+==431815==    by 0x48E9ABD: __vfprintf_internal (vfprintf-internal.c:1516)
+==431815==    by 0x48D479E: printf (printf.c:33)
+==431815==    by 0x109188: main (ex4.c:8)
+==431815==  Uninitialised value was created by a stack allocation
+==431815==    at 0x109149: main (ex4.c:3)
+==431815== 
+==431815== Conditional jump or move depends on uninitialised value(s)
+==431815==    at 0x48EA5C3: __vfprintf_internal (vfprintf-internal.c:1516)
+==431815==    by 0x48D479E: printf (printf.c:33)
+==431815==    by 0x109188: main (ex4.c:8)
+==431815==  Uninitialised value was created by a stack allocation
+==431815==    at 0x109149: main (ex4.c:3)
+==431815== 
+==431815== Conditional jump or move depends on uninitialised value(s)
+==431815==    at 0x48E9C05: __vfprintf_internal (vfprintf-internal.c:1516)
+==431815==    by 0x48D479E: printf (printf.c:33)
+==431815==    by 0x109188: main (ex4.c:8)
+==431815==  Uninitialised value was created by a stack allocation
+==431815==    at 0x109149: main (ex4.c:3)
+==431815== 
+I am -16778360 years old.
+I am 0 inches tall.
+==431815== 
+==431815== HEAP SUMMARY:
+==431815==     in use at exit: 0 bytes in 0 blocks
+==431815==   total heap usage: 1 allocs, 1 frees, 4,096 bytes allocated
+==431815== 
+==431815== All heap blocks were freed -- no leaks are possible
+==431815== 
+==431815== For lists of detected and suppressed errors, rerun with: -s
+==431815== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
+

by 0x109188: main (ex4.c:8):第八行 printf("I am %d inches tall.\n", height); 中有未初始化的量

# 3. 附加题

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2405\357\274\232\344\270\200\344\270\252C\347\250\213\345\272\217\347\232\204\347\273\223\346\236\204.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2405\357\274\232\344\270\200\344\270\252C\347\250\213\345\272\217\347\232\204\347\273\223\346\236\204.html" new file mode 100644 index 0000000..20e1aa0 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2405\357\274\232\344\270\200\344\270\252C\347\250\213\345\272\217\347\232\204\347\273\223\346\236\204.html" @@ -0,0 +1,186 @@ + + + + + + 2024.04.03-练习5:一个C程序的结构 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.03-练习5:一个C程序的结构

# 1. printf

#include <stdio.h>
+
+/* This is a comment. */
+int main(int argc, char *argv[])
+{
+    int distance = 100;
+
+    // this is also a comment
+    printf("You are %d miles away.\n", distance);
+
+    return 0;
+}
+
+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2406\357\274\232\345\217\230\351\207\217\347\261\273\345\236\213.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2406\357\274\232\345\217\230\351\207\217\347\261\273\345\236\213.html" new file mode 100644 index 0000000..345f42e --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2406\357\274\232\345\217\230\351\207\217\347\261\273\345\236\213.html" @@ -0,0 +1,237 @@ + + + + + + 2024.04.03-练习6:变量类型 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.03-练习6:变量类型

# 1. 变量

include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+    int distance = 100;
+    float power = 2.345f;
+    double super_power = 56789.4532;
+    char initial = 'A';
+    char first_name[] = "Zed";
+    char last_name[] = "Shaw";
+
+    printf("You are %d miles away.\n", distance);
+    printf("You have %f levels of power.\n", power);
+    printf("You have %f awesome super powers.\n", super_power);
+    printf("I have an initial %c.\n", initial);
+    printf("I have a first name %s.\n", first_name);
+    printf("I have a last name %s.\n", last_name);
+    printf("My whole name is %s %c. %s.\n",
+            first_name, initial, last_name);
+
+    return 0;
+}
+

整数:使用int声明,使用%d来打印。

浮点:使用floatdouble声明,使用%f来打印。

字符:使用char来声明,以周围带有'(单引号)的单个字符来表示,使用%c来打印。

字符串(字符数组):使用char name[]来声明,以周围带有"的一些字符来表示,使用%s来打印。 你会注意到C语言中区分单引号的char和双引号的char[]或字符串。

# 2. 如何使它崩溃

你可以通过向printf传递错误的参数来轻易使这个程序崩溃。例如,如果你找到打印我的名字的那行,把initial放到first_name前面,你就制造了一个bug。执行上述修改编译器就会向你报错,之后运行的时候你可能会得到一个“段错误”,就像这样:

==453551== Memcheck, a memory error detector
+==453551== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
+==453551== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
+==453551== Command: ./ex6
+==453551== 
+==453551== Invalid read of size 1
+==453551==    at 0x484ED16: strlen (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
+==453551==    by 0x48EAD30: __vfprintf_internal (vfprintf-internal.c:1517)
+==453551==    by 0x48D479E: printf (printf.c:33)
+==453551==    by 0x109290: main (ex6.c:18)
+==453551==  Address 0x41 is not stack'd, malloc'd or (recently) free'd
+==453551== 
+==453551== 
+==453551== Process terminating with default action of signal 11 (SIGSEGV)
+==453551==  Access not within mapped region at address 0x41
+==453551==    at 0x484ED16: strlen (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
+==453551==    by 0x48EAD30: __vfprintf_internal (vfprintf-internal.c:1517)
+==453551==    by 0x48D479E: printf (printf.c:33)
+==453551==    by 0x109290: main (ex6.c:18)
+==453551==  If you believe this happened as a result of a stack
+==453551==  overflow in your program's main thread (unlikely but
+==453551==  possible), you can try to increase the size of the
+==453551==  main thread stack using the --main-stacksize= flag.
+==453551==  The main thread stack size used in this run was 8388608.
+==453551== 
+==453551== HEAP SUMMARY:
+==453551==     in use at exit: 4,096 bytes in 1 blocks
+==453551==   total heap usage: 1 allocs, 0 frees, 4,096 bytes allocated
+==453551== 
+==453551== LEAK SUMMARY:
+==453551==    definitely lost: 0 bytes in 0 blocks
+==453551==    indirectly lost: 0 bytes in 0 blocks
+==453551==      possibly lost: 0 bytes in 0 blocks
+==453551==    still reachable: 4,096 bytes in 1 blocks
+==453551==         suppressed: 0 bytes in 0 blocks
+==453551== Rerun with --leak-check=full to see details of leaked memory
+==453551== 
+==453551== For lists of detected and suppressed errors, rerun with: -s
+==453551== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
+

by 0x109290: main (ex6.c:18) 显示 printf("My whole name is %s %c. %s.\n", 这一行有问题

# 3. 附加题

# 试着打印空字符串,即""

char *null = "";
+printf("null is \"%s\"\n", null);
+
+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2407\357\274\232\346\233\264\345\244\232\345\217\230\351\207\217\345\222\214\344\270\200\344\272\233\347\256\227\346\234\257.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2407\357\274\232\346\233\264\345\244\232\345\217\230\351\207\217\345\222\214\344\270\200\344\272\233\347\256\227\346\234\257.html" new file mode 100644 index 0000000..786a06b --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2407\357\274\232\346\233\264\345\244\232\345\217\230\351\207\217\345\222\214\344\270\200\344\272\233\347\256\227\346\234\257.html" @@ -0,0 +1,202 @@ + + + + + + 2024.04.03-练习7:更多变量和一些算术 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.03-练习7:更多变量和一些算术

# 1. 基本算术操作

int main(int argc, char *argv[])
+{
+    int bugs = 100;
+    double bug_rate = 1.2;
+
+    printf("You have %d bugs at the imaginary rate of %f.\n",
+            bugs, bug_rate);
+
+    long universe_of_defects = 1L * 1024L * 1024L * 1024L;
+    printf("The entire universe has %ld bugs.\n",
+            universe_of_defects);
+
+    double expected_bugs = bugs * bug_rate;
+    printf("You are expected to have %f bugs.\n",
+            expected_bugs);
+
+    double part_of_universe = expected_bugs / universe_of_defects;
+    printf("That is only a %e portion of the universe.\n",
+            part_of_universe);
+
+    // this makes no sense, just a demo of something weird
+    char nul_byte = '\0';
+    int care_percentage = bugs * nul_byte;
+    printf("Which means you should care %d%%.\n",
+            care_percentage);
+
+    return 0;
+}
+

以特殊的语法'\0'声明了一个字符。这样创建了一个“空字节”字符,实际上是数字0。

# 2. 用%s打印\0

Untitled

# 3. 附加题

# 3.1 LONG_MAX

Untitled

会发生溢出,到负的那边循环

# 3.2 ULONG_MAX

Untitled

unsigned的范围是signed的最大值的两倍加一

# 3.3 char & int

Untitled

因为char字符都有ASCII编码,所以可以被认为是int

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2408\357\274\232\345\244\247\345\260\217\345\222\214\346\225\260\347\273\204.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2408\357\274\232\345\244\247\345\260\217\345\222\214\346\225\260\347\273\204.html" new file mode 100644 index 0000000..0d69b7e --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2408\357\274\232\345\244\247\345\260\217\345\222\214\346\225\260\347\273\204.html" @@ -0,0 +1,212 @@ + + + + + + 2024.04.03-练习8:大小和数组 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.03-练习8:大小和数组

# 1. sizeof和数组

#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+    int areas[] = {10, 12, 13, 14, 20};
+    char name[] = "Zed";
+    char full_name[] = {
+        'Z', 'e', 'd',
+         ' ', 'A', '.', ' ',
+         'S', 'h', 'a', 'w', '\0'
+    };
+
+    // WARNING: On some systems you may have to change the
+    // %ld in this code to a %u since it will use unsigned ints
+    printf("The size of an int: %ld\n", sizeof(int));
+    printf("The size of areas (int[]): %ld\n",
+            sizeof(areas));
+    printf("The number of ints in areas: %ld\n",
+            sizeof(areas) / sizeof(int));
+    printf("The first area is %d, the 2nd %d.\n",
+            areas[0], areas[1]);
+
+    printf("The size of a char: %ld\n", sizeof(char));
+    printf("The size of name (char[]): %ld\n",
+            sizeof(name));
+    printf("The number of chars: %ld\n",
+            sizeof(name) / sizeof(char));
+
+    printf("The size of full_name (char[]): %ld\n",
+            sizeof(full_name));
+    printf("The number of chars: %ld\n",
+            sizeof(full_name) / sizeof(char));
+
+    printf("name=\"%s\" and full_name=\"%s\"\n",
+            name, full_name);
+
+    return 0;
+}
+

# 2. 如何使它崩溃

# 2.1 将full_name最后的'\0'去掉

Untitled

Untitled

  1. \0终止符的后果:标准的字符串处理函数(如printf%s格式化输出、strcpystrlen等)期望字符串以\0终止。如果省略了\0,这些函数会继续读取内存,直到偶然遇到一个\0字节。这可能导致读取数组后面的内存,结果是不可预测的,可能会导致错误的输出、内存访问违规、甚至是程序崩溃。
  2. 为什么没有立即出错:在实际使用中,如果紧接在字符数组后面的内存恰好是零(可能由于内存的初始状态或者其他变量的影响),那么使用字符串相关函数时可能看起来"运行正常"。但这是纯粹偶然的,并不可靠。随着程序的运行,内存布局的变化可能会改变这一状况,从而引发难以预测的错误。

# 2.2 将areas[0]改为areas[10]

Untitled

会打印出一个随机数

# 3. 附加题

# 3.1 对areas的元素赋值

Untitled

# 3.2 对name的元素赋值

Untitled

# 3.3 将areas的一个元素赋值为name中的字符

Untitled

# 3.4 C语言中不同的CPU上整数所占的不同大小

1. 32位系统(如x86)

在32位系统上,通常遵循ILP32数据模型,其中:

  • int 通常是32位(4字节)。
  • short 通常是16位(2字节)。
  • long 也通常是32位(4字节)。
  • long long 保证至少是64位(8字节)。
  • 指针大小是32位(4字节)。

2. 64位系统(如x86_64或AMD64)

在64位系统上,最常见的数据模型是LP64,其中:

  • int 保持32位(4字节)。
  • short 仍然是16位(2字节)。
  • long 和指针的大小增加到64位(8字节)。
  • long long 保证至少是64位(8字节)。

另一个在某些64位系统(如Windows的64位版本)上使用的数据模型是LLP64,它保持long为32位,而只有指针和long long是64位。

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2409\357\274\232\346\225\260\347\273\204\345\222\214\345\255\227\347\254\246\344\270\262.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2409\357\274\232\346\225\260\347\273\204\345\222\214\345\255\227\347\254\246\344\270\262.html" new file mode 100644 index 0000000..7c59360 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.03-\347\273\203\344\271\2409\357\274\232\346\225\260\347\273\204\345\222\214\345\255\227\347\254\246\344\270\262.html" @@ -0,0 +1,227 @@ + + + + + + 2024.04.03-练习9:数组和字符串 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.03-练习9:数组和字符串

# 1. 字符数组

#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+    int numbers[4] = {0};
+    char name[4] = {'a'};
+
+    // first, print them out raw
+    printf("numbers: %d %d %d %d\n",
+            numbers[0], numbers[1],
+            numbers[2], numbers[3]);
+
+    printf("name each: %c %c %c %c\n",
+            name[0], name[1],
+            name[2], name[3]);
+
+    printf("name: %s\n", name);
+
+    // setup the numbers
+    numbers[0] = 1;
+    numbers[1] = 2;
+    numbers[2] = 3;
+    numbers[3] = 4;
+
+    // setup the name
+    name[0] = 'Z';
+    name[1] = 'e';
+    name[2] = 'd';
+    name[3] = '\0';
+
+    // then print them out initialized
+    printf("numbers: %d %d %d %d\n",
+            numbers[0], numbers[1],
+            numbers[2], numbers[3]);
+
+    printf("name each: %c %c %c %c\n",
+            name[0], name[1],
+            name[2], name[3]);
+
+    // print the name like a string
+    printf("name: %s\n", name);
+
+    // another way to use name
+    char *another = "Zed";
+
+    printf("another: %s\n", another);
+
+    printf("another each: %c %c %c %c\n",
+            another[0], another[1],
+            another[2], another[3]);
+
+    return 0;
+}
+

# 2. 使其崩溃

# 2.1 删掉name的初始化表达式

error

# 2.2 设置name[3] = 'A'

Untitled

# 2.3 初始化表达式设置为{'a','a','a','a'}

Untitled

Untitled

# 3. 附加题

# 3.1 字符赋给numbers的元素

当用%c格式化字符串来打印一个int值时,编译器通常不会发出警告,因为%c期望一个int类型的参数(在大多数情况下,字符在传递给函数时会被提升为int)。然而,如果数组中的整数值不对应于有效的ASCII字符编码,则打印的结果可能是乱码或不可预测的字符。

# 3.2 把names当成int数组

使用%d格式化字符串来打印时,如果直接传递char类型的值给printf,由于charint的隐式类型提升,这种类型不匹配通常不会导致编译器警告。但是,如果尝试直接以int数组的方式访问char数组(如通过类型转换或指针操作),并尝试打印,这将导致未定义的行为,特别是当char数组的大小小于int时。

# 3.3

如果一个字符数组占四个字节,一个整数也占4个字节,你可以像整数一样使用整个name吗?你如何用黑魔法实现它?

Untitled

Zed\0 的ASCII码对应的十六进制分别是5a,65,64,0.然后考虑到计算机是小端序,所以name存储时最低位存的是Z,所以综合起来存储的就是0064655a,十进制就是6579546

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.04-\347\273\203\344\271\24010\357\274\232\345\255\227\347\254\246\344\270\262\346\225\260\347\273\204\345\222\214\345\276\252\347\216\257.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.04-\347\273\203\344\271\24010\357\274\232\345\255\227\347\254\246\344\270\262\346\225\260\347\273\204\345\222\214\345\276\252\347\216\257.html" new file mode 100644 index 0000000..c467651 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.04-\347\273\203\344\271\24010\357\274\232\345\255\227\347\254\246\344\270\262\346\225\260\347\273\204\345\222\214\345\276\252\347\216\257.html" @@ -0,0 +1,200 @@ + + + + + + 2024.04.04-练习10:字符串数组和循环 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.04-练习10:字符串数组和循环

# 1. 字符串数组

#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+    int i = 0;
+
+    // go through each string in argv
+    // why am I skipping argv[0]?
+    for(i = 1; i < argc; i++) {
+        printf("arg %d: %s\n", i, argv[i]);
+    }
+
+    // let's make our own array of strings
+    char *states[] = {
+        "California", "Oregon",
+        "Washington", "Texas"
+    };
+    int num_states = 4;
+
+    for(i = 0; i < num_states; i++) {
+        printf("state %d: %s\n", i, states[i]);
+    }
+
+    return 0;
+}
+

argv[0] 是程序的名称

如果 num_states 大于4,会报段错误,因为这些索引超出了数组 states ****的初始化范围,它们没有被初始化指向任何有效的字符串。

# 2. 附加题

# 2.1 在for循环的每一部分可以放置什么代码

  1. 初始化表达式
  • 这部分在循环开始前执行一次。
  • 常用于初始化循环控制变量。
  • 可以定义一个或多个变量(C99标准之后),也可以是空操作,如果没有需要初始化的变量。
  • 可以执行任何有效的赋值操作或函数调用。
  1. 条件表达式
  • 这部分在每次循环迭代之前评估。
  • 决定是否执行循环体。
  • 必须是能够评估为布尔值的表达式。如果表达式结果为true(非零),循环继续;如果为false(零),循环结束。
  • 可以是复杂的表达式,包含逻辑和关系运算符。
  1. 循环后表达式
  • 这部分在每次循环迭代的末尾执行,即循环体执行完毕后。
  • 通常用于更新循环控制变量。
  • 可以执行多个更新操作,使用逗号运算符分隔。

# 2.2 for 循环中的逗号

for (int i = 0, j = 10; i < j; i++, j--) {}
+

# 2.3 NULL

在C语言中,NULL是一个宏,通常用来表示指针不指向任何有效的对象或位置。它在多个头文件中被定义,如<stddef.h><stdio.h><stdlib.h>等,通常被定义为((void *)0),即一个类型为void*的空指针。

NULL用作字符指针数组states的一个元素,相当于在数组中插入一个不指向任何有效字符串的指针。在打印时,尝试访问这个NULL指针所指向的字符串将触发未定义行为(Undefined Behavior, UB),因为试图访问一个不存在的内存位置。在大多数情况下,这可能会导致程序崩溃,因为printf%s格式化选项期望一个指向有效C字符串的指针。

# 2.4

Untitled

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24011\357\274\232While\345\276\252\347\216\257\345\222\214\345\270\203\345\260\224\350\241\250\350\276\276\345\274\217.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24011\357\274\232While\345\276\252\347\216\257\345\222\214\345\270\203\345\260\224\350\241\250\350\276\276\345\274\217.html" new file mode 100644 index 0000000..8030618 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24011\357\274\232While\345\276\252\347\216\257\345\222\214\345\270\203\345\260\224\350\241\250\350\276\276\345\274\217.html" @@ -0,0 +1,218 @@ + + + + + + 2024.04.05-练习11:While循环和布尔表达式 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.05-练习11:While循环和布尔表达式

# 1. while

#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+    // go through each string in argv
+
+    int i = 0;
+    while(i < argc) {
+        printf("arg %d: %s\n", i, argv[i]);
+        i++;
+    }
+
+    // let's make our own array of strings
+    char *states[] = {
+        "California", "Oregon",
+        "Washington", "Texas"
+    };
+
+    int num_states = 4;
+    i = 0;  // watch for this
+    while(i < num_states) {
+        printf("state %d: %s\n", i, states[i]);
+        i++;
+    }
+
+    return 0;
+}
+

# 2. 附加题

# 2.1 循环倒序执行

    int i = argc;
+    while(i > 0) {
+        printf("arg %d: %s\n", i-1, argv[i-1]);
+        i--;
+    }
+

# 2.2 使用while循环将argv中的值复制到states

    char *states[] = {
+        "California", "Oregon",
+        "Washington", "Texas"
+    };
+
+    int num_states = 4;
+    i = 0;  // watch for this
+    // 让这个复制循环不会执行失败,即使argv之中有很多元素也不会全部放进states。
+    while(i < num_states && i < argc - 1) {
+        states[i] = argv[i+1];
+        i++;
+    }
+

# 2.3 是否真正复制了这些字符串?

当在C语言中将一个字符串数组(例如argvstates)的元素赋值给另一个数组的元素时,你实际上并没有复制字符串的内容。相反,你只是复制了字符串的指针,这意味着两个数组中的对应元素现在共享同一个字符串实例(即指向同一个内存地址)。这是因为在C中,字符串是通过字符指针表示的,赋值操作只涉及指针的复制,而非指针所指向的数据(字符串内容)的复制。

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24012\357\274\232If\357\274\214Else If\357\274\214Else.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24012\357\274\232If\357\274\214Else If\357\274\214Else.html" new file mode 100644 index 0000000..d3f7f82 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24012\357\274\232If\357\274\214Else If\357\274\214Else.html" @@ -0,0 +1,195 @@ + + + + + + 2024.04.05-练习12:If,Else If,Else | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.05-练习12:If,Else If,Else

# 1. if,else if,else

#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+    int i = 0;
+
+    if(argc == 1) {
+        printf("You only have one argument. You suck.\n");
+    } else if(argc > 1 && argc < 4) {
+        printf("Here's your arguments:\n");
+
+        for(i = 0; i < argc; i++) {
+            printf("%s ", argv[i]);
+        }
+        printf("\n");
+    } else {
+        printf("You have too many arguments. You suck.\n");
+    }
+
+    return 0;
+}
+

# 2. 附加题

# 2.1 布尔运算符

在C语言中,常用的布尔运算符包括"与"(&&)、"或"(||)和"非"(!)。这些运算符用于构建逻辑表达式,从而控制程序流程如条件语句和循环。&&运算符用于判断两个条件是否同时满足,||检查至少一个条件是否满足,而!用于反转一个条件的布尔值。由于C语言中没有内置的布尔类型,在使用这些运算符时,非零值被视为真(true),而零值被视为假(false)。

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24013\357\274\232Switch\350\257\255\345\217\245.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24013\357\274\232Switch\350\257\255\345\217\245.html" new file mode 100644 index 0000000..fed3676 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24013\357\274\232Switch\350\257\255\345\217\245.html" @@ -0,0 +1,232 @@ + + + + + + 2024.04.05-练习13:Switch语句 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.05-练习13:Switch语句

# 1. switch

#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+    if(argc != 2) {
+        printf("ERROR: You need one argument.\n");
+        // this is how you abort a program
+        return 1;
+    }
+
+    int i = 0;
+    for(i = 0; argv[1][i] != '\0'; i++) {
+        char letter = argv[1][i];
+
+        switch(letter) {
+            case 'a':
+            case 'A':
+                printf("%d: 'A'\n", i);
+                break;
+
+            case 'e':
+            case 'E':
+                printf("%d: 'E'\n", i);
+                break;
+
+            case 'i':
+            case 'I':
+                printf("%d: 'I'\n", i);
+                break;
+
+            case 'o':
+            case 'O':
+                printf("%d: 'O'\n", i);
+                break;
+
+            case 'u':
+            case 'U':
+                printf("%d: 'U'\n", i);
+                break;
+
+            case 'y':
+            case 'Y':
+                if(i > 2) {
+                    // it's only sometimes Y
+                    printf("%d: 'Y'\n", i);
+                }
+                break;
+
+            default:
+                printf("%d: %c is not a vowel\n", i, letter);
+        }
+    }
+
+    return 0;
+}
+

在这个程序中我们接受了单一的命令行参数,并且用一种极其复杂的方式打印出所有原因,来向你演示switch语句。下面是swicth语句的工作原理:

  • 编译器会标记swicth语句的顶端,我们先把它记为地址Y。
  • 接着对switch中的表达式求值,产生一个数字。在上面的例子中,数字为argv[1]中字母的原始的ASCLL码。
  • 编译器也会把每个类似case 'A'case代码块翻译成这个程序中距离语句顶端的地址,所以case 'A'就在Y + 'A'处。
  • 接着计算是否Y+letter位于switch语句中,如果距离太远则会将其调整为Y+Default
  • 一旦计算出了地址,程序就会“跳”到代码的那个位置并继续执行。这就是一些case代码块中有break而另外一些没有的原因。
  • 如果输出了'a',那它就会跳到case 'a',它里面没有break语句,所以它会贯穿执行底下带有代码和breakcase 'A'
  • 最后它执行这段代码,执行break完全跳出switch语句块。

更常见的情况是,gcc会在空白处单独构建一张跳转表,各个偏移处存放对应的case语句的地址。Y不是switch语句的起始地址,而是这张表的起始地址。程序会跳转到*(Y + 'A')而不是Y + 'A'处。

# 2. 如何崩溃

# 2.1 忘记写default

在C语言中,如果switch语句中没有写default子句,那么当没有任何case标签与switch表达式的值匹配时,程序将跳过整个switch块,继续执行switch语句之后的代码。简而言之,没有匹配的case且缺少default时,switch语句不执行任何操作。

# 2.2 无意中将一些带有预料之外的值的变量放入switch

这个值如果没有在任何case标签中明确匹配到,且没有default分支处理这种情况,switch语句将不会执行任何操作,程序将跳过整个switch块,继续执行下面的代码。

# 3. 附加题

# 3.1 编写另一个程序,在字母上做算术运算将它们转换为小写,并且在switch中移除所有额外的大写字母

if(letter >= 'A' && letter <= 'Z') {
+    letter += 32; // Convert to lowercase
+}
+
+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24014\357\274\232\347\274\226\345\206\231\345\271\266\344\275\277\347\224\250\345\207\275\346\225\260.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24014\357\274\232\347\274\226\345\206\231\345\271\266\344\275\277\347\224\250\345\207\275\346\225\260.html" new file mode 100644 index 0000000..5e899f1 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24014\357\274\232\347\274\226\345\206\231\345\271\266\344\275\277\347\224\250\345\207\275\346\225\260.html" @@ -0,0 +1,216 @@ + + + + + + 2024.04.05-练习14:编写并使用函数 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.05-练习14:编写并使用函数

# 1. 函数

#include <stdio.h>
+#include <ctype.h>
+
+// forward declarations
+int can_print_it(char ch);
+void print_letters(char arg[]);
+
+void print_arguments(int argc, char *argv[])
+{
+    int i = 0;
+
+    for(i = 0; i < argc; i++) {
+        print_letters(argv[i]);
+    }
+}
+
+void print_letters(char arg[])
+{
+    int i = 0;
+
+    for(i = 0; arg[i] != '\0'; i++) {
+        char ch = arg[i];
+
+        if(can_print_it(ch)) {
+            printf("'%c' == %d ", ch, ch);
+        }
+    }
+
+    printf("\n");
+}
+
+// 属于“字母”和“空白”的字符
+int can_print_it(char ch)
+{
+    return isalpha(ch) || isblank(ch);
+}
+
+int main(int argc, char *argv[])
+{
+    print_arguments(argc, argv);
+    return 0;
+}
+

# 2. 附加题

# 2.1 使用strlen函数

# 2.2 <ctype.h>

isdigit()用于检查字符是否为数字(0-9),isspace()用于检查空白字符(如空格、制表符、换行符),islower()isupper()分别用于检查字符是否为小写或大写字母,isalnum()用于检查字符是否为字母或数字。

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24015\357\274\232\346\214\207\351\222\210\357\274\214\345\217\257\346\200\225\347\232\204\346\214\207\351\222\210.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24015\357\274\232\346\214\207\351\222\210\357\274\214\345\217\257\346\200\225\347\232\204\346\214\207\351\222\210.html" new file mode 100644 index 0000000..31b6f82 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24015\357\274\232\346\214\207\351\222\210\357\274\214\345\217\257\346\200\225\347\232\204\346\214\207\351\222\210.html" @@ -0,0 +1,228 @@ + + + + + + 2024.04.05-练习15:指针,可怕的指针 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.05-练习15:指针,可怕的指针

# 1. 指针

#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+    // create two arrays we care about
+    int ages[] = {23, 43, 12, 89, 2};
+    char *names[] = {
+        "Alan", "Frank",
+        "Mary", "John", "Lisa"
+    };
+
+    // safely get the size of ages
+    int count = sizeof(ages) / sizeof(int);
+    int i = 0;
+
+    // first way using indexing
+    for(i = 0; i < count; i++) {
+        printf("%s has %d years alive.\n",
+                names[i], ages[i]);
+    }
+
+    printf("---\n");
+
+    // setup the pointers to the start of the arrays
+    int *cur_age = ages;
+    char **cur_name = names;
+
+    // second way using pointers
+    for(i = 0; i < count; i++) {
+        printf("%s is %d years old.\n",
+                *(cur_name+i), *(cur_age+i));
+    }
+
+    printf("---\n");
+
+    // third way, pointers are just arrays
+    for(i = 0; i < count; i++) {
+        printf("%s is %d years old again.\n",
+                cur_name[i], cur_age[i]);
+    }
+
+    printf("---\n");
+
+    // fourth way with pointers in a stupid complex way
+    for(cur_name = names, cur_age = ages;
+            (cur_age - ages) < count;
+            cur_name++, cur_age++)
+    {
+        printf("%s lived %d years so far.\n",
+                *cur_name, *cur_age);
+    }
+
+    return 0;
+}
+

char ** list; 那么list是指向第一个字符串指针的指针。访问第一个字符串的第二个字符,可以使用表达式 *(*(list) + 1)

# 2. 实用的指针用法

你可以用指针做下面四个最基本的操作:

  • 向OS申请一块内存,并且用指针处理它。这包括字符串,和一些你从来没见过的东西,比如结构体。
  • 通过指针向函数传递大块的内存(比如很大的结构体),这样不必把全部数据都传递进去。
  • 获取函数的地址用于动态调用。
  • 对一块内存做复杂的搜索,比如,转换网络套接字中的字节,或者解析文件。

对于你看到的其它所有情况,实际上应当使用数组。在早期,由于编译器不擅长优化数组,人们使用指针来加速它们的程序。然而,现在访问数组和指针的语法都会翻译成相同的机器码,并且表现一致。由此,你应该每次尽可能使用数组,并且按需将指针用作提升性能的手段。

# 3. 指针词库

现在我打算向你提供一个词库,用于读写指针。当你遇到复杂的指针语句时,试着参考它并且逐字拆分语句(或者不要使用这个语句,因为有可能并不好):

type *ptr : type类型的指针,名为ptr

  • *ptr : ptr所指向位置的值。
  • *(ptr + i) : (ptr所指向位置加上i)的值。

译者注:以字节为单位的话,应该是ptr所指向的位置再加上sizeof(type) * i

&thing : thing的地址。

type *ptr = &thing : 名为ptrtype类型的指针,值设置为thing的地址。 ptr++ 自增ptr指向的位置。

# 4. 指针并不是数组

无论怎么样,你都不应该把指针和数组混为一谈。它们并不是相同的东西,即使C让你以一些相同的方法来使用它们。例如,如果你访问上面代码中的sizeof(cur_age),你会得到指针的大小,而不是它指向数组的大小。如果你想得到整个数组的大小,你应该使用数组的名称age,就像第12行那样。

译者注,除了sizeof&操作和声明之外,数组名称都会被编译器推导为指向其首个元素的指针。对于这些情况,不要用“是”这个词,而是要用“推导”。

# 5. 附加题

# 5.1 获取地址

Untitled

# 5.2 倒序遍历

Untitled

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24016\357\274\232\347\273\223\346\236\204\344\275\223\345\222\214\346\214\207\345\220\221\345\256\203\344\273\254\347\232\204\346\214\207\351\222\210.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24016\357\274\232\347\273\223\346\236\204\344\275\223\345\222\214\346\214\207\345\220\221\345\256\203\344\273\254\347\232\204\346\214\207\351\222\210.html" new file mode 100644 index 0000000..f79a0d1 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.05-\347\273\203\344\271\24016\357\274\232\347\273\223\346\236\204\344\275\223\345\222\214\346\214\207\345\220\221\345\256\203\344\273\254\347\232\204\346\214\207\351\222\210.html" @@ -0,0 +1,247 @@ + + + + + + 2024.04.05-练习16:结构体和指向它们的指针 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.05-练习16:结构体和指向它们的指针

# 1. struct

#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct Person {
+    char *name;
+    int age;
+    int height;
+    int weight;
+};
+
+struct Person *Person_create(char *name, int age, int height, int weight)
+{
+    struct Person *who = malloc(sizeof(struct Person));
+    assert(who != NULL);
+
+    who->name = strdup(name);
+    who->age = age;
+    who->height = height;
+    who->weight = weight;
+
+    return who;
+}
+
+void Person_destroy(struct Person *who)
+{
+    assert(who != NULL);
+
+    free(who->name);
+    free(who);
+}
+
+void Person_print(struct Person *who)
+{
+    printf("Name: %s\n", who->name);
+    printf("\tAge: %d\n", who->age);
+    printf("\tHeight: %d\n", who->height);
+    printf("\tWeight: %d\n", who->weight);
+}
+
+int main(int argc, char *argv[])
+{
+    // make two people structures
+    struct Person *joe = Person_create(
+            "Joe Alex", 32, 64, 140);
+
+    struct Person *frank = Person_create(
+            "Frank Blank", 20, 72, 180);
+
+    // print them out and where they are in memory
+    printf("Joe is at memory location %p:\n", joe);
+    Person_print(joe);
+
+    printf("Frank is at memory location %p:\n", frank);
+    Person_print(frank);
+
+    // make everyone age 20 years and print them again
+    joe->age += 20;
+    joe->height -= 2;
+    joe->weight += 40;
+    Person_print(joe);
+
+    frank->age += 20;
+    frank->weight += 20;
+    Person_print(frank);
+
+    // destroy them both so we clean up
+    Person_destroy(joe);
+    Person_destroy(frank);
+
+    return 0;
+}
+

使用strdup来复制字符串name,是为了确保结构体真正拥有它。strdup的行为实际上类似malloc但是它同时会将原来的字符串复制到新创建的内存。

!!!如果结构体有指针类型成员,同时结构体在堆中创建的,那么释放堆中结构体之前需要提前释放结构体中的指针成员指向的内存,然后再释放结构体自身的。

# 2. 使它崩溃

# 2.1 assert(who != NULL);

试着传递NULLPerson_destroy来看看会发生什么。如果它没有崩溃,你必须移除Makefile的CFLAGS中的g选项。

Untitled

# 2.2 内存泄漏

在结尾处忘记调用Person_destroy,在Valgrind下运行程序,你会看到它报告出你忘记释放内存。弄清楚你应该向valgrind传递什么参数来让它向你报告内存如何泄露。

Untitled

# 2.3 单独释放结构体中的指针

忘记在Person_destroy中释放who->name,并且对比两次的输出。同时,使用正确的选项来让Valgrind告诉你哪里错了。

Untitled

# 2.4 获取NULL

这一次,向Person_print传递NULL,并且观察Valgrind会输出什么。

Untitled

# 3. 附加题

# 3.1 在栈上创建结构体

Untitled

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.08-\347\273\203\344\271\24017\357\274\232\345\240\206\345\222\214\346\240\210\347\232\204\345\206\205\345\255\230\345\210\206\351\205\215.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.08-\347\273\203\344\271\24017\357\274\232\345\240\206\345\222\214\346\240\210\347\232\204\345\206\205\345\255\230\345\210\206\351\205\215.html" new file mode 100644 index 0000000..3150809 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.08-\347\273\203\344\271\24017\357\274\232\345\240\206\345\222\214\346\240\210\347\232\204\345\206\205\345\255\230\345\210\206\351\205\215.html" @@ -0,0 +1,925 @@ + + + + + + 2024.04.08-练习17:堆和栈的内存分配 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.08-练习17:堆和栈的内存分配

# 1. Program

#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#define MAX_DATA 512
+#define MAX_ROWS 100
+
+struct Address {
+    int id;
+    int set;
+    char name[MAX_DATA];
+    char email[MAX_DATA];
+};
+
+struct Database {
+    struct Address rows[MAX_ROWS];
+};
+
+struct Connection {
+    FILE *file;
+    struct Database *db;
+};
+
+void die(const char *message)
+{
+    if(errno) {
+        perror(message);
+    } else {
+        printf("ERROR: %s\n", message);
+    }
+
+    exit(1);
+}
+
+void Address_print(struct Address *addr)
+{
+    printf("%d %s %s\n",
+            addr->id, addr->name, addr->email);
+}
+
+void Database_load(struct Connection *conn)
+{
+    int rc = fread(conn->db, sizeof(struct Database), 1, conn->file);
+    if(rc != 1) die("Failed to load database.");
+}
+
+struct Connection *Database_open(const char *filename, char mode)
+{
+    struct Connection *conn = malloc(sizeof(struct Connection));
+    if(!conn) die("Memory error");
+
+    conn->db = malloc(sizeof(struct Database));
+    if(!conn->db) die("Memory error");
+
+    if(mode == 'c') {
+        conn->file = fopen(filename, "w");
+    } else {
+        conn->file = fopen(filename, "r+");
+
+        if(conn->file) {
+            Database_load(conn);
+        }
+    }
+
+    if(!conn->file) die("Failed to open the file");
+
+    return conn;
+}
+
+void Database_close(struct Connection *conn)
+{
+    if(conn) {
+        if(conn->file) fclose(conn->file);
+        if(conn->db) free(conn->db);
+        free(conn);
+    }
+}
+
+void Database_write(struct Connection *conn)
+{
+    rewind(conn->file);
+
+    int rc = fwrite(conn->db, sizeof(struct Database), 1, conn->file);
+    if(rc != 1) die("Failed to write database.");
+
+    rc = fflush(conn->file);
+    if(rc == -1) die("Cannot flush database.");
+}
+
+void Database_create(struct Connection *conn)
+{
+    int i = 0;
+
+    for(i = 0; i < MAX_ROWS; i++) {
+        // make a prototype to initialize it
+        struct Address addr = {.id = i, .set = 0};
+        // then just assign it
+        conn->db->rows[i] = addr;
+    }
+}
+
+void Database_set(struct Connection *conn, int id, const char *name, const char *email)
+{
+    struct Address *addr = &conn->db->rows[id];
+    if(addr->set) die("Already set, delete it first");
+
+    addr->set = 1;
+    // WARNING: bug, read the "How To Break It" and fix this
+    char *res = strncpy(addr->name, name, MAX_DATA);
+    // demonstrate the strncpy bug
+    if(!res) die("Name copy failed");
+
+    res = strncpy(addr->email, email, MAX_DATA);
+    if(!res) die("Email copy failed");
+}
+
+void Database_get(struct Connection *conn, int id)
+{
+    struct Address *addr = &conn->db->rows[id];
+
+    if(addr->set) {
+        Address_print(addr);
+    } else {
+        die("ID is not set");
+    }
+}
+
+void Database_delete(struct Connection *conn, int id)
+{
+    struct Address addr = {.id = id, .set = 0};
+    conn->db->rows[id] = addr;
+}
+
+void Database_list(struct Connection *conn)
+{
+    int i = 0;
+    struct Database *db = conn->db;
+
+    for(i = 0; i < MAX_ROWS; i++) {
+        struct Address *cur = &db->rows[i];
+
+        if(cur->set) {
+            Address_print(cur);
+        }
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    if(argc < 3) die("USAGE: ex17 <dbfile> <action> [action params]");
+
+    char *filename = argv[1];
+    char action = argv[2][0];
+    struct Connection *conn = Database_open(filename, action);
+    int id = 0;
+
+    if(argc > 3) id = atoi(argv[3]);
+    if(id >= MAX_ROWS) die("There's not that many records.");
+
+    switch(action) {
+        case 'c':
+            Database_create(conn);
+            Database_write(conn);
+            break;
+
+        case 'g':
+            if(argc != 4) die("Need an id to get");
+
+            Database_get(conn, id);
+            break;
+
+        case 's':
+            if(argc != 6) die("Need id, name, email to set");
+
+            Database_set(conn, id, argv[4], argv[5]);
+            Database_write(conn);
+            break;
+
+        case 'd':
+            if(argc != 4) die("Need id to delete");
+
+            Database_delete(conn, id);
+            Database_write(conn);
+            break;
+
+        case 'l':
+            Database_list(conn);
+            break;
+        default:
+            die("Invalid action, only: c=create, g=get, s=set, d=del, l=list");
+    }
+
+    Database_close(conn);
+
+    return 0;
+}
+

#define 常量

我使用了“C预处理器”的另外一部分,来创建MAX_DATAMAX_ROWS的设置常量。我之后会更多地讲解预处理器的功能,不过这是一个创建可靠的常量的简易方法。除此之外还有另一种方法,但是在特定场景下并不适用。

定长结构体

Address结构体接着使用这些常量来创建数据,这些数据是定长的,它们并不高效,但是便于存储和读取。Database结构体也是定长的,因为它有一个定长的Address结构体数组。这样你就可以稍后把整个数据一步写到磁盘。

出现错误时终止的die函数

在像这样的小型程序中,你可以编写一个单个函数在出现错误时杀掉程序。我把它叫做die。而且在任何失败的函数调用,或错误输出之后,它会调用exit带着错误退出程序。

用于错误报告的 errnoperror

当函数返回了一个错误时,它通常设置一个叫做errno的“外部”变量,来描述发生了什么错误。它们只是数字,所以你可以使用perror来“打印出错误信息”。

文件函数

我使用了一些新的函数,比如fopenfreadfclose,和rewind来处理文件。这些函数中每个都作用于FILE结构体上,就像你的结构体似的,但是它由C标准库定义。

嵌套结构体指针

你应该学习这里的嵌套结构器和获取数组元素地址的用法,它读作“读取db中的conn中的rows的第i个元素,并返回地址(&)”。

译者注:这里有个更简便的写法是db->conn->row + i。

结构体原型的复制

它在Database_delete中体现得最清楚,你可以看到我是用了临时的局部Address变量,初始化了它的idset字段,接着通过把它赋值给rows数组中的元素,简单地复制到数组中。这个小技巧确保了所有除了setid的字段都初始化为0,而且很容易编写。顺便说一句,你不应该在这种数组复制操作中使用memcpy。现代C语言中你可以只是将一个赋值给另一个,它会自动帮你处理复制。

处理复杂参数

我执行了一些更复杂的参数解析,但是这不是处理它们的最好方法。在这本书的后面我们将会了解一些用于解析的更好方法。

将字符串转换为整数

我使用了atoi函数在命令行中接受作为id的字符串并把它转换为int id变量。去查询这个函数以及相似的函数。

在堆上分配大块数据

这个程序的要点就是在我创建Database的时候,我使用了malloc来向OS请求一块大容量的内存。稍后我会讲得更细致一些。

NULL就是0,所以可转成布尔值

在许多检查中,我简单地通过if(!ptr) die("fail!")检测了一个指针是不是NULL。这是有效的,因为NULL会被计算成假。在一些少见的系统中,NULL会储存在计算机中,并且表示为一些不是0的东西。但在C标准中,你可以把它当成0来编写代码。到目前为止,当我说“NULL就是0”的时候,我都是对一些迂腐的人说的。

# 2. 堆和栈的内存分配

C使用了CPU真实的机制来完成工作,这涉及到RAM中的一块叫做栈的区域,以及另外一块叫做堆的区域。它们的差异取决于取得储存空间的位置。

堆更容易解释,因为它就是你电脑中的剩余内存,你可以通过malloc访问它来获取更多内存,OS会使用内部函数为你注册一块内存区域,并且返回指向它的指针。当你使用完这片区域时,你应该使用free把它交还给OS,使之能被其它程序复用。如果你不这样做就会导致程序“泄露”内存,但是Valgrind会帮你监测这些内存泄露。

栈是一个特殊的内存区域,它储存了每个函数的创建的临时变量,它们对于该函数为局部变量。它的工作机制是,函数的每个c参数都会“压入”栈中,并且可在函数内部使用。它是一个真正的栈数据结构,所以是后进先出的。这对于main中所有类似char sectionint id的局部变量也是相同的。使用栈的优点是,当函数退出时C编译器会从栈中“弹出”所有变量来清理。这非常简单,也防止了栈上变量的内存泄露。

理清内存的最简单的方式是遵守这条原则:如果你的变量并不是从malloc中获取的,也不是从一个从malloc获取的函数中获取的,那么它在栈上。

下面是三个值得关注的关于栈和堆的主要问题:

  • 如果你从malloc获取了一块内存,并且把指针放在了栈上,那么当函数退出时,指针会被弹出而丢失。
  • 如果你在栈上存放了大量数据(比如大结构体和数组),那么会产生“栈溢出”并且程序会中止。这种情况下应该通过malloc放在堆上。
  • 如果你获取了指向栈上变量的指针,并且将它用于传参或从函数返回,接收它的函数会产生“段错误”。因为实际的数据被弹出而消失,指针也会指向被释放的内存。

这就是我在程序中使用Database_open来分配内存或退出的原因,相应的Database_close用于释放内存。如果你创建了一个“创建”函数,它创建了一些东西,那么一个“销毁”函数可以安全地清理这些东西。这样会更容易理清内存。

最后,当一个程序退出时,OS会为你清理所有的资源,但是有时不会立即执行。一个惯用法(也是本次练习中用到的)是立即终止并且让OS清理错误。

# 3. 如何使它崩溃

# 3.1 strncpy

strncpy可能不会在字符串的末尾自动添加空字符(\0),如果源字符串的长度等于或超过目标缓冲区的大小。这可能会导致字符串没有正确终止,从而引发安全漏洞或程序错误。为了修复这个问题,确保在strncpy后手动将目标字符串的最后一个字符设置为\\0,以确保字符串总是被正确终止。例如,修改代码为:

strncpy(addr->name, name, MAX_DATA - 1);
+addr->name[MAX_DATA - 1] = '\\0';
+
+strncpy(addr->email, email, MAX_DATA - 1);
+addr->email[MAX_DATA - 1] = '\\0';
+

这样可以保证即使源字符串长度达到或超过MAX_DATAaddr->nameaddr->email也会被正确终止。

# 4. 附加题

# 4.1 报错时清理内存

void die(const char *message, struct Connection *conn)
+{
+    if(errno) {
+        perror(message);
+    } else {
+        printf("ERROR: %s\n", message);
+    }
+
+    if(conn) {
+        Database_close(conn); // 清理内存
+    }
+
+    exit(1);
+}
+

# 4.2 创建任意大小的数据库

#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+// #define MAX_DATA 512
+// #define MAX_ROWS 100
+
+struct Address
+{
+    int id;
+    int set;
+    char *name;
+    char *email;
+};
+
+struct Database
+{
+    int MAX_DATA;
+    int MAX_ROWS;
+    struct Address *rows;
+};
+
+struct Connection
+{
+    FILE *file;
+    struct Database *db;
+};
+
+void Database_close(struct Connection *conn);
+
+void die(const char *message, struct Connection *conn)
+{
+    if (errno)
+    {
+        perror(message);
+    }
+    else
+    {
+        printf("ERROR: %s\n", message);
+    }
+
+    if (conn)
+    {
+        Database_close(conn); // 清理内存
+    }
+
+    exit(1);
+}
+
+void Address_print(struct Address *addr)
+{
+    printf("%d %s %s\n",
+           addr->id, addr->name, addr->email);
+}
+
+void Database_load(struct Connection *conn)
+{
+    // 确保文件指针在首个Address记录的开始位置
+    fseek(conn->file, sizeof(int) * 2, SEEK_SET);
+
+    for (int i = 0; i < conn->db->MAX_ROWS; i++)
+    {
+        struct Address *addr = &conn->db->rows[i];
+        if (addr->set)
+            Address_print(addr);
+
+        fread(&addr->id, sizeof(addr->id), 1, conn->file);
+        fread(&addr->set, sizeof(addr->set), 1, conn->file);
+        if (addr->set)
+        {
+            fread(addr->name, sizeof(char), conn->db->MAX_DATA, conn->file);
+            fread(addr->email, sizeof(char), conn->db->MAX_DATA, conn->file);
+        }
+    }
+    // printf("Database loaded.\n");
+}
+
+struct Connection *Database_open(const char *filename, char mode, int MAX_DATA, int MAX_ROWS)
+{
+    struct Connection *conn = malloc(sizeof(struct Connection));
+    if (!conn)
+        die("Memory error", conn);
+
+    if (mode == 'c')
+    {
+        conn->db = malloc(sizeof(struct Database));
+        if (!conn->db)
+            die("Memory error", conn);
+
+        conn->file = fopen(filename, "w");
+        if (!conn->file)
+            die("Failed to open the file", conn);
+
+        // 将MAX_DATA和MAX_ROWS写入文件
+        fwrite(&MAX_DATA, sizeof(int), 1, conn->file);
+        fwrite(&MAX_ROWS, sizeof(int), 1, conn->file);
+
+        // 初始化Database结构体
+        conn->db->MAX_DATA = MAX_DATA;
+        conn->db->MAX_ROWS = MAX_ROWS;
+        conn->db->rows = malloc(sizeof(struct Address) * MAX_ROWS);
+        for (int i = 0; i < MAX_ROWS; i++)
+        {
+            conn->db->rows[i].name = malloc(MAX_DATA);
+            conn->db->rows[i].email = malloc(MAX_DATA);
+        }
+    }
+    else
+    {
+        conn->file = fopen(filename, "r+");
+        if (!conn->file)
+            die("Failed to open the file", conn);
+
+        // 从文件读取MAX_DATA和MAX_ROWS
+        fread(&MAX_DATA, sizeof(int), 1, conn->file);
+        fread(&MAX_ROWS, sizeof(int), 1, conn->file);
+
+        conn->db = malloc(sizeof(struct Database));
+        if (!conn->db)
+            die("Memory error", conn);
+
+        conn->db->MAX_DATA = MAX_DATA;
+        conn->db->MAX_ROWS = MAX_ROWS;
+        conn->db->rows = malloc(sizeof(struct Address) * MAX_ROWS);
+        for (int i = 0; i < MAX_ROWS; i++)
+        {
+            conn->db->rows[i].name = malloc(MAX_DATA);
+            conn->db->rows[i].email = malloc(MAX_DATA);
+        }
+        // printf("conn->db->MAX_DATA: %d, conn->db->MAX_ROWS: %d\n", conn->db->MAX_DATA, conn->db->MAX_ROWS);
+
+        Database_load(conn);
+    }
+
+    return conn;
+}
+
+void Database_close(struct Connection *conn)
+{
+    if (conn)
+    {
+        if (conn->file)
+            fclose(conn->file);
+        if (conn->db)
+            free(conn->db);
+        free(conn);
+    }
+}
+
+void Database_write(struct Connection *conn)
+{
+    rewind(conn->file);
+
+    // 首先写入MAX_DATA和MAX_ROWS
+    if (fwrite(&conn->db->MAX_DATA, sizeof(int), 1, conn->file) != 1)
+        die("Failed to write MAX_DATA.", conn);
+    if (fwrite(&conn->db->MAX_ROWS, sizeof(int), 1, conn->file) != 1)
+        die("Failed to write MAX_ROWS.", conn);
+
+    // 然后逐个写入Address项
+    for (int i = 0; i < conn->db->MAX_ROWS; i++)
+    {
+        struct Address *addr = &conn->db->rows[i];
+
+        // 写入Address的id和set
+        if (fwrite(&addr->id, sizeof(addr->id), 1, conn->file) != 1)
+            die("Failed to write id.", conn);
+        if (fwrite(&addr->set, sizeof(addr->set), 1, conn->file) != 1)
+            die("Failed to write set.", conn);
+
+        // printf("addr->id: %d\n", addr->id);
+        // printf("addr->set: %d\n", addr->set);
+
+        // 只有当set为真时才写入name和email
+        if (addr->set)
+        {
+            // 确保字符串不超过MAX_DATA长度,最后一个字符保留为'\0'
+            addr->name[conn->db->MAX_DATA - 1] = '\0';
+            addr->email[conn->db->MAX_DATA - 1] = '\0';
+
+            // 使用memset填充剩余的空间
+            memset(addr->name + strlen(addr->name), '\0', conn->db->MAX_DATA - strlen(addr->name) - 1);
+            memset(addr->email + strlen(addr->email), '\0', conn->db->MAX_DATA - strlen(addr->email) - 1);
+
+            // 写入name和email到文件
+            size_t written = fwrite(addr->name, sizeof(char), conn->db->MAX_DATA, conn->file);
+            if (written < conn->db->MAX_DATA)
+            {
+                die("Failed to write name.", conn);
+            }
+            written = fwrite(addr->email, sizeof(char), conn->db->MAX_DATA, conn->file);
+            if (written < conn->db->MAX_DATA)
+            {
+                die("Failed to write email.", conn);
+            }
+        }
+    }
+
+    // 刷新文件以确保写入完成
+    if (fflush(conn->file) == -1)
+        die("Cannot flush database.", conn);
+}
+
+void Database_create(struct Connection *conn)
+{
+    for (int i = 0; i < conn->db->MAX_ROWS; i++)
+    {
+        // make a prototype to initialize it
+        struct Address addr = {.id = i, .set = 0};
+        // then just assign it
+        conn->db->rows[i] = addr;
+    }
+}
+
+void Database_set(struct Connection *conn, int id, const char *name, const char *email)
+{
+    struct Address *addr = &(conn->db->rows[id]);
+    // printf("id: %d\n", id);
+    // printf("addr->set: %d\n", addr->set);
+    if (addr->set)
+        die("Already set, delete it first", conn);
+
+    addr->set = 1;
+    addr->id = id;
+    char *res = strncpy(addr->name, name, conn->db->MAX_DATA - 1);
+    addr->name[conn->db->MAX_DATA - 1] = '\0';
+    // printf("addr->name: %s\n", addr->name);
+    if (!res)
+        die("Name copy failed", conn);
+
+    res = strncpy(addr->email, email, conn->db->MAX_DATA - 1);
+    addr->email[conn->db->MAX_DATA - 1] = '\0';
+    if (!res)
+        die("Email copy failed", conn);
+    // Address_print(addr);
+}
+
+void Database_get(struct Connection *conn, int id)
+{
+    struct Address *addr = &conn->db->rows[id];
+
+    if (addr->set)
+    {
+        Address_print(addr);
+    }
+    else
+    {
+        die("ID is not set", conn);
+    }
+}
+
+void Database_delete(struct Connection *conn, int id)
+{
+    // struct Address addr = {.id = id, .set = 0};
+    conn->db->rows[id].set = 0;
+    // printf("id: %d\n", id);
+    // printf("addr->set: %d\n", conn->db->rows[id].set);
+}
+
+void Database_list(struct Connection *conn)
+{
+    int i = 0;
+    // printf("conn->db->rows[3].set: %d\n", conn->db->rows[3].set);
+
+    for (i = 0; i < conn->db->MAX_ROWS; i++)
+    {
+        struct Address *cur = &conn->db->rows[i];
+        // printf("cur->id: %d\n", cur->id);
+        // printf("cur->set: %d\n", cur->set);
+
+        if (cur->set)
+        {
+            // printf("i: %d\n", i);
+            Address_print(cur);
+        }
+    }
+}
+
+void Database_find(struct Connection *conn, const char *search_term)
+{
+    for (int i = 0; i < conn->db->MAX_ROWS; i++)
+    {
+        struct Address *cur = &conn->db->rows[i];
+        if ((cur->set) && (strcmp(cur->name, search_term) == 0 || strcmp(cur->email, search_term) == 0))
+        {
+            Address_print(cur);
+            return;
+        }
+    }
+    printf("Search term not found.\n");
+}
+
+int main(int argc, char *argv[])
+{
+    // 至少需要文件名和操作类型
+    if (argc < 3)
+        die("USAGE: ex17 <dbfile> <action> [action params]", NULL);
+
+    char *filename = argv[1];
+    char action = argv[2][0];
+    struct Connection *conn = NULL;
+    int id = 0;
+
+    // 如果是创建操作,确保有足够的参数
+    if (action == 'c')
+    {
+        if (argc != 5)
+            die("USAGE: ex17 <dbfile> c <MAX_DATA> <MAX_ROWS>", NULL);
+
+        int _MAX_DATA = atoi(argv[3]);
+        int _MAX_ROWS = atoi(argv[4]);
+        conn = Database_open(filename, action, _MAX_DATA, _MAX_ROWS);
+        Database_create(conn);
+        Database_write(conn);
+    }
+    else
+    {
+        // 对于其他操作,不需要MAX_DATA和MAX_ROWS,但需要检查数据库文件是否存在
+        // printf("filename: %s\n", filename);
+        conn = Database_open(filename, action, 0, 0); // 0s表示这些值将被忽略
+        if (!conn)
+            die("Database not found. Use 'c' option to create one.", NULL);
+    }
+
+    if (argc > 3 && action != 'c')
+    {
+        id = atoi(argv[3]);
+        if (id >= conn->db->MAX_ROWS)
+            die("There's not that many records.", conn);
+    }
+
+    if (action != 'c')
+    {
+        switch (action)
+        {
+        case 'f':
+            if (argc != 4)
+                die("Need a search term to find", conn);
+            Database_find(conn, argv[3]);
+            break;
+
+        case 'g':
+            if (argc != 4)
+                die("Need an id to get", conn);
+
+            Database_get(conn, id);
+            break;
+
+        case 's':
+            if (argc != 6)
+                die("Need id, name, email to set", conn);
+
+            Database_set(conn, id, argv[4], argv[5]);
+            Database_write(conn);
+            break;
+
+        case 'd':
+            if (argc != 4)
+                die("Need id to delete", conn);
+
+            Database_delete(conn, id);
+            Database_write(conn);
+            break;
+
+        case 'l':
+            Database_list(conn);
+            break;
+        default:
+            die("Invalid action, only: c=create, g=get, s=set, d=del, l=list", conn);
+        }
+
+        Database_close(conn);
+
+        return 0;
+    }
+}
+
+

Untitled

# 4.3 添加find操作

Untitled

# 4.4 C结构体存储方式

在结构体中,为了提高访问速度,编译器可能会按照特定的对齐规则(alignment rules)来安排成员的存储。这通常依赖于目标平台(如处理器架构)和编译器的具体实现。

  • 自然对齐:大多数编译器采用所谓的“自然对齐”原则,要求结构体的每个成员相对于结构体开始的偏移量是该成员类型大小的整数倍。例如,如果一个结构体中有一个int(假设为4字节)紧跟着一个char(1字节),那么为了使下一个int成员对齐,编译器可能会在char后面插入3字节的填充。
  • 结构体整体对齐:结构体本身也会被对齐到它的最大成员的对齐要求。这意味着整个结构体在内存中的起始地址将是其最大成员大小的整数倍,并且可能在结构体末尾添加填充,以确保整个结构体的大小是其最大成员大小的整数倍。

注:成员的排列顺序可能导致更多或更少的填充字节被插入。例如,将较小的数据类型(如char)放在较大的数据类型(如int)之间可能会导致额外的填充,以保持较大类型的对齐。

# 4.5 栈数据结构

#include <stdio.h>
+#include <stdlib.h>
+#define MAX_SIZE 10
+
+typedef struct
+{
+    int items[MAX_SIZE];
+    int top;
+} Stack;
+
+// 栈的初始化
+void initializeStack(Stack *s)
+{
+    s->top = -1;
+}
+
+// 检查栈是否为空
+int isEmpty(Stack *s)
+{
+    return s->top == -1;
+}
+
+// 检查栈是否已满
+int isFull(Stack *s)
+{
+    return s->top == MAX_SIZE - 1;
+}
+
+// 入栈
+void push(Stack *s, int item)
+{
+    if (isFull(s))
+    {
+        printf("Stack is full!\n");
+    }
+    else
+    {
+        s->items[++s->top] = item;
+    }
+}
+
+// 出栈
+int pop(Stack *s)
+{
+    if (isEmpty(s))
+    {
+        printf("Stack is empty!\n");
+        return -1; // 返回一个标识值,表示栈空
+    }
+    else
+    {
+        return s->items[s->top--];
+    }
+}
+
+// 查看栈顶元素
+int peek(Stack *s)
+{
+    if (isEmpty(s))
+    {
+        printf("Stack is empty!\n");
+        return -1; // 返回一个标识值,表示栈空
+    }
+    else
+    {
+        return s->items[s->top];
+    }
+}
+
+// 主函数,演示栈操作
+int main()
+{
+    Stack s;
+    initializeStack(&s);
+
+    // 入栈操作
+    push(&s, 10);
+    push(&s, 20);
+    push(&s, 30);
+
+    // 查看栈顶元素
+    printf("Top element is %d\n", peek(&s));
+
+    // 出栈操作,并打印出栈元素
+    printf("Popped %d from the stack\n", pop(&s));
+    printf("Popped %d from the stack\n", pop(&s));
+
+    // 再次查看栈顶元素
+    if (!isEmpty(&s))
+    {
+        printf("Top element is %d\n", peek(&s));
+    }
+
+    // 清空栈
+    while (!isEmpty(&s))
+    {
+        pop(&s);
+    }
+
+    if (isEmpty(&s))
+    {
+        printf("Stack is empty now.\n");
+    }
+
+    return 0;
+}
+

# 5. 文件操作

# 5.1 C

在C中,文件操作主要通过以下几个函数实现:

  • fopen(const char *filename, const char *mode):打开文件,filename是文件名,mode是打开模式,如"r"(只读)、"w"(只写)、"a"(追加)等。
  • fclose(FILE *stream):关闭一个已打开的文件。
  • fread(void *ptr, size_t size, size_t nmemb, FILE *stream)fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream):分别用于从文件读取数据和向文件写入数据,ptr是数据存储的内存地址,size是每个数据项的大小,nmemb是数据项的数量。
  • fprintf(FILE *stream, const char *format, ...)fscanf(FILE *stream, const char *format, ...):分别用于向文件写入格式化文本和从文件读取格式化文本。
  • fseek(FILE *stream, long int offset, int whence):移动文件指针到指定位置,offset是相对于whence指定的位置偏移量,whence可以是SEEK_SET(文件开头)、SEEK_CUR(当前位置)、SEEK_END(文件末尾)。

这些函数提供了基础的文件打开、读写、关闭等操作,是进行文件处理的基石。

# 5.2 C++

在C++中,文件操作是通过标准库中的fstream库进行的,它提供了读取、写入文件的能力。fstream库中包含了三个主要的类:ifstream、ofstream和fstream,分别用于文件输入(读取)、文件输出(写入)和同时支持文件输入输出。

# ifstream(输入文件流)

  • 用途:用于从文件读取数据。
  • 常用函数open(), close(), read(), getline(), eof()等。
  • 示例代码
#include <fstream>
+#include <iostream>
+#include <string>
+using namespace std;
+
+int main() {
+    ifstream file("example.txt");
+    if (file.is_open()) {
+        string line;
+        while (getline(file, line)) {
+            cout << line << '\\n';
+        }
+        file.close();
+    } else cout << "Unable to open file";
+    return 0;
+}
+

# ofstream(输出文件流)

  • 用途:用于向文件写入数据。
  • 常用函数open(), close(), write(), << 操作符等。
  • 示例代码
#include <fstream>
+#include <iostream>
+using namespace std;
+
+int main() {
+    ofstream file("example.txt");
+    if (file.is_open()) {
+        file << "Hello, World!\\n";
+        file.close();
+    } else cout << "Unable to open file";
+    return 0;
+}
+

# fstream(文件流)

  • 用途:同时支持读取和写入操作。
  • 常用函数:继承了ifstream和ofstream的所有函数。
  • 示例代码
#include <fstream>
+#include <iostream>
+using namespace std;
+
+int main() {
+    // 打开文件,同时用于读写
+    fstream file("example.txt", ios::in | ios::out | ios::app);
+    if (file.is_open()) {
+        // 写入文件
+        file << "Hello, file!\\n";
+        // 设置读取位置到文件开头
+        file.seekg(0, ios::beg);
+        // 读取文件
+        string line;
+        while (getline(file, line)) {
+            cout << line << '\\n';
+        }
+        file.close();
+    } else cout << "Unable to open file";
+    return 0;
+}
+

# 文件打开模式

在使用fstream、ifstream或ofstream打开文件时,可以指定文件的打开模式。这是通过在构造函数或open()方法中使用特定的标志完成的,如下所示:

  • ios::in:打开文件进行读取。
  • ios::out:打开文件进行写入。
  • ios::binary:以二进制方式打开文件。
  • ios::app:写入数据时追加到文件末尾。
  • ios::ate:打开文件后立即移动到文件末尾。
  • ios::trunc:如果文件已存在,先删除文件再创建。
  • ios::nocreate:打开文件时,如果文件不存在,则打开失败。(在某些编译器中不可用)
  • ios::noreplace:打开文件时,如果文件已存在,则打开失败。(在某些编译器中不可用)

可以组合使用这些模式,例如,ios::in | ios::out 会打开文件以进行读写操作。

通过这种方式,C++提供了强大且灵活的文件操作能力,支持多种文件处理场景。

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.10-\347\273\203\344\271\24018\357\274\232\345\207\275\346\225\260\346\214\207\351\222\210.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.10-\347\273\203\344\271\24018\357\274\232\345\207\275\346\225\260\346\214\207\351\222\210.html" new file mode 100644 index 0000000..b0d16ae --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.10-\347\273\203\344\271\24018\357\274\232\345\207\275\346\225\260\346\214\207\351\222\210.html" @@ -0,0 +1,335 @@ + + + + + + 2024.04.10-练习18:函数指针 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.10-练习18:函数指针

# 1. 函数指针

函数在C中实际上只是指向程序中某一个代码存在位置的指针。就像你创建过的结构体指针、字符串和数组那样,你也可以创建指向函数的指针。函数指针的主要用途是向其他函数传递“回调”,或者模拟类和对象。在这个练习中我们会创建一些回调,并且下一节我们会制作一个简单的对象系统。

函数指针的格式类似这样:

int (*POINTER_NAME)(int a,int b)
+

记住如何编写它的一个方法是:

  • 编写一个普通的函数声明:int callme(int a, int b)
  • 将函数用指针语法包装:int (*callme)(int a, int b)
  • 将名称改成指针名称:int (*compare_cb)(int a, int b)

这个方法的关键是,当你完成这些之后,指针的变量名称为compare_cb,而你可以将它用作函数。这类似于指向数组的指针可以表示所指向的数组。指向函数的指针也可以用作表示所指向的函数,只不过是不同的名字。

int (*tester)(int a,int b) = sorted_order;
+printf("TEST: %d is same as %d\n", tester(2, 3), sorted_order(2, 3));
+

即使是对于返回指针的函数指针,上述方法依然有效:

  • 编写:char *make_coolness(int awesome_levels)
  • 包装:char *(*make_coolness)(int awesome_levels)
  • 重命名:char *(*coolness_cb)(int awesome_levels)

需要解决的下一个问题是使用函数指针向其它函数提供参数比较困难,比如当你打算向其它函数传递回调函数的时候。解决方法是使用typedef,它是C的一个关键字,可以给其它更复杂的类型起个新的名字。你需要记住的事情是,将typedef添加到相同的指针语法之前,然后你就可以将那个名字用作类型了。

# 2. program

#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+/** Our old friend die from ex17. */
+void die(const char *message)
+{
+    if(errno) {
+        perror(message);
+    } else {
+        printf("ERROR: %s\n", message);
+    }
+
+    exit(1);
+}
+
+// a typedef creates a fake type, in this
+// case for a function pointer
+typedef int (*compare_cb)(int a, int b);
+
+/**
+ * A classic bubble sort function that uses the
+ * compare_cb to do the sorting.
+ */
+int *bubble_sort(int *numbers, int count, compare_cb cmp)
+{
+    int temp = 0;
+    int i = 0;
+    int j = 0;
+    int *target = malloc(count * sizeof(int));
+
+    if(!target) die("Memory error.");
+
+    memcpy(target, numbers, count * sizeof(int));
+
+    for(i = 0; i < count; i++) {
+        for(j = 0; j < count - 1; j++) {
+            if(cmp(target[j], target[j+1]) > 0) {
+                temp = target[j+1];
+                target[j+1] = target[j];
+                target[j] = temp;
+            }
+        }
+    }
+
+    return target;
+}
+
+int sorted_order(int a, int b)
+{
+    return a - b;
+}
+
+int reverse_order(int a, int b)
+{
+    return b - a;
+}
+
+int strange_order(int a, int b)
+{
+    if(a == 0 || b == 0) {
+        return 0;
+    } else {
+        return a % b;
+    }
+}
+
+/**
+ * Used to test that we are sorting things correctly
+ * by doing the sort and printing it out.
+ */
+void test_sorting(int *numbers, int count, compare_cb cmp)
+{
+    int i = 0;
+    int *sorted = bubble_sort(numbers, count, cmp);
+
+    if(!sorted) die("Failed to sort as requested.");
+
+    for(i = 0; i < count; i++) {
+        printf("%d ", sorted[i]);
+    }
+    printf("\n");
+
+    free(sorted);
+}
+
+int main(int argc, char *argv[])
+{
+    if(argc < 2) die("USAGE: ex18 4 3 1 5 6");
+
+    int count = argc - 1;
+    int i = 0;
+    char **inputs = argv + 1;
+
+    int *numbers = malloc(count * sizeof(int));
+    if(!numbers) die("Memory error.");
+
+    for(i = 0; i < count; i++) {
+        numbers[i] = atoi(inputs[i]);
+    }
+
+    test_sorting(numbers, count, sorted_order);
+    test_sorting(numbers, count, reverse_order);
+    test_sorting(numbers, count, strange_order);
+
+    free(numbers);
+
+    return 0;
+}
+

# 3. 函数指针汇编字节码

typedef int (*compare_cb)(int a, int b);
+compare_cb cmp;
+unsigned char *data = (unsigned char *)cmp;
+
+for(i = 0; i < 25; i++) {
+    printf("%02x:", data[i]);
+}
+
+// output:
+55:48:89:e5:89:7d:fc:89:75:f8:8b:55:fc:8b:45:f8:29:d0:c9:c3:55:48:89:e5:89:
+

这段代码试图以十六进制的形式打印出一个函数指针(cmp)所指向的函数的前25个字节。compare_cb是一个函数指针的类型定义,指向一个接受两个int类型参数并返回int类型结果的函数。unsigned char *data = (unsigned char *)cmp;这行代码将函数指针cmp转换为一个unsigned char类型的指针,这样就可以逐字节地访问函数指针所指向的函数的机器代码。

在循环中,程序逐个字节地访问并打印出这个函数的机器代码,直到打印了25个字节。每个字节以两位十六进制数的形式打印,后面跟着一个冒号。

输出的具体内容取决于cmp所指向的函数的机器代码,这又依赖于具体的函数实现、编译器以及目标平台的架构。不同的编译器优化设置可能产生不同的机器代码。此外,不同的处理器架构(如x86、ARM等)有其独特的指令集,导致即使是相同的高级语言函数,其编译成的机器代码也会不同。

由于这段代码直接访问和解释函数的机器码,它涉及到底层的、平台特定的行为。在大多数现代操作系统和处理器架构中,试图访问函数的机器码是不推荐的,因为:

  1. 可移植性差:这段代码的行为在不同的系统和编译器下可能会有很大差异。
  2. 安全性:现代操作系统通常实施某种形式的代码和数据分离(如DEP/NX),这可能阻止程序以这种方式访问函数的代码。
  3. 实用性:除了特定的底层编程或逆向工程场景外,直接处理函数的机器码通常是不必要的。

总之,这段代码的目的是展示如何以字节为单位访问和打印出一个函数的机器码,但实际应用场景有限,且在不同环境中的行为可能会有很大差异。

# 4. 附加题

# 4.1 十六进制编辑器

用十六进制编辑器打开ex18,接着找到函数起始处的十六进制代码序列,看看是否能在原始程序中找到函数。

Untitled

# 4.2 修改十六进制文件

Untitled

修改了上述函数的汇编机器码,结果就提示不合法的硬件指令

# 4.3 传递错误函数

Untitled

# 4.4 传递NULL到原函数指针位置

Untitled

# 4.5 快速排序

void swap(int *a, int *b) {
+    int temp = *a;
+    *a = *b;
+    *b = temp;
+}
+
+int partition(int *array, int low, int high, compare_cb cmp) {
+    int pivot = array[high];
+    int i = (low - 1);
+
+    for (int j = low; j <= high - 1; j++) {
+        if (cmp(array[j], pivot) < 0) {
+            i++;
+            swap(&array[i], &array[j]);
+        }
+    }
+    swap(&array[i + 1], &array[high]);
+    return (i + 1);
+}
+
+void quick_sort(int *array, int low, int high, compare_cb cmp) {
+    if (low < high) {
+        int pi = partition(array, low, high, cmp);
+
+        quick_sort(array, low, pi - 1, cmp);
+        quick_sort(array, pi + 1, high, cmp);
+    }
+}
+
+int *quick_sort_wrapper(int *numbers, int count, compare_cb cmp) {
+    int *target = malloc(count * sizeof(int));
+    if (!target) die("Memory error.");
+
+    memcpy(target, numbers, count * sizeof(int));
+    quick_sort(target, 0, count - 1, cmp);
+
+    return target;
+}
+

Untitled

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.10-\347\273\203\344\271\24032\357\274\232\345\217\214\345\220\221\351\223\276\350\241\250.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.10-\347\273\203\344\271\24032\357\274\232\345\217\214\345\220\221\351\223\276\350\241\250.html" new file mode 100644 index 0000000..7bffa2b --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.10-\347\273\203\344\271\24032\357\274\232\345\217\214\345\220\221\351\223\276\350\241\250.html" @@ -0,0 +1,519 @@ + + + + + + 2024.04.10-练习32:双向链表 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.10-练习32:双向链表

# 1. program

# 1.1 定义

#ifndef lcthw_List_h
+#define lcthw_List_h
+
+#include <stdlib.h>
+
+struct ListNode;
+
+typedef struct ListNode {
+    struct ListNode *next;
+    struct ListNode *prev;
+    void *value;
+} ListNode;
+
+typedef struct List {
+    int count;
+    ListNode *first;
+    ListNode *last;
+} List;
+
+List *List_create();
+void List_destroy(List *list);
+void List_clear(List *list);
+void List_clear_destroy(List *list);
+
+#define List_count(A) ((A)->count)
+#define List_first(A) ((A)->first != NULL ? (A)->first->value : NULL)
+#define List_last(A) ((A)->last != NULL ? (A)->last->value : NULL)
+
+void List_push(List *list, void *value);
+void *List_pop(List *list);
+
+void List_unshift(List *list, void *value);
+void *List_shift(List *list);
+
+void *List_remove(List *list, ListNode *node);
+
+#define LIST_FOREACH(L, S, M, V) ListNode *_node = NULL;\
+    ListNode *V = NULL;\
+    for(V = _node = L->S; _node != NULL; V = _node = _node->M)
+
+#endif
+

# 1.2 实现

#include <lcthw/list.h>
+#include <lcthw/dbg.h>
+
+List *List_create()
+{
+    return calloc(1, sizeof(List));
+}
+
+void List_destroy(List *list)
+{
+    LIST_FOREACH(list, first, next, cur) {
+        if(cur->prev) {
+            free(cur->prev);
+        }
+    }
+
+    free(list->last);
+    free(list);
+}
+
+void List_clear(List *list)
+{
+    LIST_FOREACH(list, first, next, cur) {
+        free(cur->value);
+    }
+}
+
+void List_clear_destroy(List *list)
+{
+    List_clear(list);
+    List_destroy(list);
+}
+
+void List_push(List *list, void *value)
+{
+    ListNode *node = calloc(1, sizeof(ListNode));
+    check_mem(node);
+
+    node->value = value;
+
+    if(list->last == NULL) {
+        list->first = node;
+        list->last = node;
+    } else {
+        list->last->next = node;
+        node->prev = list->last;
+        list->last = node;
+    }
+
+    list->count++;
+
+error:
+    return;
+}
+
+void *List_pop(List *list)
+{
+    ListNode *node = list->last;
+    return node != NULL ? List_remove(list, node) : NULL;
+}
+
+void List_unshift(List *list, void *value)
+{
+    ListNode *node = calloc(1, sizeof(ListNode));
+    check_mem(node);
+
+    node->value = value;
+
+    if(list->first == NULL) {
+        list->first = node;
+        list->last = node;
+    } else {
+        node->next = list->first;
+        list->first->prev = node;
+        list->first = node;
+    }
+
+    list->count++;
+
+error:
+    return;
+}
+
+void *List_shift(List *list)
+{
+    ListNode *node = list->first;
+    return node != NULL ? List_remove(list, node) : NULL;
+}
+
+void *List_remove(List *list, ListNode *node)
+{
+    void *result = NULL;
+
+    check(list->first && list->last, "List is empty.");
+    check(node, "node can't be NULL");
+
+    if(node == list->first && node == list->last) {
+        list->first = NULL;
+        list->last = NULL;
+    } else if(node == list->first) {
+        list->first = node->next;
+        check(list->first != NULL, "Invalid list, somehow got a first that is NULL.");
+        list->first->prev = NULL;
+    } else if (node == list->last) {
+        list->last = node->prev;
+        check(list->last != NULL, "Invalid list, somehow got a next that is NULL.");
+        list->last->next = NULL;
+    } else {
+        ListNode *after = node->next;
+        ListNode *before = node->prev;
+        after->prev = before;
+        before->next = after;
+    }
+
+    list->count--;
+    result = node->value;
+    free(node);
+
+error:
+    return result;
+}
+

# 1.3 calloc

calloc(Contiguous Allocation,连续分配)和malloc(Memory Allocation,内存分配)都是C语言标准库中用于动态内存分配的函数,但它们之间有一些关键的区别:

  1. 初始化
  • malloc 分配的内存块内容是未初始化的。这意味着分配后的内存块中的数据是不确定的,可能包含垃圾值。使用malloc分配内存后,通常需要手动初始化内存块,以避免潜在的安全问题或逻辑错误。
  • calloc 分配的内存块会自动初始化为零。这意味着分配后的内存块中的每个字节都被设置为0,这可以直接用于程序中而无需额外的初始化步骤。
  1. 参数
  • malloc 只需要一个参数,即所需分配的字节数。
  • calloc 需要两个参数:需要分配的元素数量和每个元素的大小。calloc会计算总共需要的字节数(两个参数的乘积),并分配相应的内存。
  1. 用途
  • 选择malloccalloc通常取决于是否需要自动将内存初始化为零。如果程序逻辑要求新分配的内存必须全部为零,那么calloc是一个更好的选择,因为它可以保证这一点并简化代码。如果不需要初始化,或者分配后会立即被其他值覆盖,那么使用malloc可能更有效率,因为它避免了额外的初始化开销。
  1. 性能
  • 由于calloc会初始化内存,所以相比malloc可能有额外的性能开销。如果不需要内存内容初始化为零,直接使用malloc可能更加高效。

示例

使用malloc分配内存:

int *array = (int*)malloc(10 * sizeof(int));
+// 需要手动初始化
+for(int i = 0; i < 10; i++) {
+    array[i] = 0;
+}
+

使用calloc分配内存:

int *array = (int*)calloc(10, sizeof(int));
+// 已经自动初始化为零,无需手动初始化
+

总之,选择malloc还是calloc主要取决于是否需要自动初始化内存和对性能的考虑。在某些情况下,显式地使用malloc和手动初始化可能更能清晰地表达程序员的意图,尤其是在初始化为非零值时。然而,calloc提供了一个方便的方式来确保新分配的内存区域安全地初始化为零。

# 1.4 LIST_FOREACH

#define LIST_FOREACH(L, S, M, V) \
+		ListNode *_node = NULL;\
+    ListNode *V = NULL;\
+    for(V = _node = L->S; _node != NULL; V = _node = _node->M)
+

这个宏LIST_FOREACH是一个用于遍历链表的宏,设计得非常巧妙。它利用了C语言宏的能力,提供了一个通用的、易于阅读的方式来遍历任何类型的链表。这个宏的参数有四个:

  • L:指向链表的指针。
  • S:链表中的起始节点。
  • M:节点中指向下一个节点的成员的名称。
  • V:在遍历过程中用于引用当前节点的变量。

这个宏定义了两个局部变量(_nodeV),并初始化一个for循环,用于遍历链表。以下是该宏各部分的详细解释:

  • ListNode *_node = NULL; 定义了一个名为_node的局部变量,类型为ListNode*,并将其初始化为NULL。这个变量用于在循环中跟踪当前节点。
  • ListNode *V = NULL; 定义了一个名为V的局部变量(V是宏的参数之一),类型为ListNode*,并将其初始化为NULL。这个变量用于在循环体中引用当前节点,让使用者能够访问或操作当前的链表节点。
  • for(V = _node = L->S; _node != NULL; V = _node = _node->M) 初始化一个for循环,开始于链表的起始节点(L->S),并持续到链表的末尾(_node != NULL)。循环的每一步都将_node移动到下一个节点(_node->M),同时也将V设置为当前节点,以便于使用。

这个宏的设计允许在不知道链表具体实现细节的情况下,通过一个简洁的方式遍历链表。举个例子,如果你有一个链表list,它的起始节点为head,每个节点都有一个名为next的指针指向下一个节点,你可以使用LIST_FOREACH宏来遍历这个链表,如下所示:

LIST_FOREACH(list, head, next, cur) {
+    // 在这里可以访问 cur 来操作当前节点
+}
+

这里,cur就是循环中用来引用当前节点的变量,你可以通过它访问或修改当前节点的数据。

需要注意的是,这种宏的使用方式可能在某些编译器或代码分析工具中导致警告,因为它在宏内部定义了局部变量。此外,由于它使用了宏,调试可能会比较困难,错误信息可能不会直接指向问题的根源。不过,这种方式在提高代码可读性和减少重复代码方面是非常有效的。

# 1.5 void类型指针

void类型的指针在C语言中扮演着非常重要的角色。void指针可以指向任何类型的数据,这使得它成为一种非常灵活的工具,特别是在需要处理多种数据类型但又不想在编码时指定具体类型的情况下。以下是void指针的一些主要用途:

  1. 泛型编程

void指针的一个主要用途是实现泛型编程。由于void指针可以指向任何类型的数据,它可以用来编写可以处理多种数据类型的函数和数据结构。例如,标准库函数qsort就使用void指针来排序各种不同类型的数组。

  1. 内存操作函数

C语言的标准库中有几个用于内存操作的函数,如malloccallocreallocfree,这些函数都使用void指针。这使得它们可以用于分配和释放任何类型的数据的内存空间。

  1. 回调函数

在使用回调函数时,void指针常被用来传递用户自定义的数据给回调函数。这些数据可以是任何类型,使用者在回调函数中可以根据需要将void指针转换回原始类型的指针来使用。

  1. 接口和抽象层

在设计需要抽象化处理的接口时,void指针提供了一种方便的方式来隐藏具体的实现细节。这种方式常见于各种库的设计中,特别是那些需要处理多种数据类型或提供高度抽象化的库。

注意事项

虽然void指针非常灵活和有用,但使用它们时也需要格外小心:

  • 在解引用void指针之前,必须将它转换为合适的类型的指针。void指针本身不能直接被解引用,因为编译器不知道它指向的对象的类型和大小。
  • 转换void指针时需要确保转换的目标类型正确,错误的类型转换可能导致未定义行为。
  • 在某些情况下,过度依赖void指针可能会降低代码的可读性和安全性。尽可能使用具体的类型可以帮助编译器更好地进行类型检查。

综上所述,void类型的指针是C语言中一个非常强大的特性,它为编程提供了极大的灵活性,但也需要谨慎使用。

# 2. 附加题

# 2.0 改进List_clear_destroy

void List_clear_destroy(List *list)
+{
+    check(list, "List is NULL.");
+    LIST_FOREACH(list, first, next, cur)
+    {
+        // printf("freeing: %s\n", (char *)cur->value);
+        free(cur->value);
+        if (cur->prev)
+        {
+            free(cur->prev);
+        }
+    }
+    free(list->last);
+    free(list);
+error:
+    return;
+}
+

# 2.1 单向与双向链表

双向链表和单向链表是两种基本的数据结构,它们在数据组织和操作上各有特点。理解它们的优势和劣势可以帮助在特定场景下做出更合适的选择。

# 单向链表

单向链表是由一系列节点组成的链表,每个节点都包含数据部分和一个指向下一个节点的指针。它的特点和优势包括:

  • 简单:数据结构相对简单,易于实现和理解。
  • 动态大小:链表可以根据需要动态增长和收缩。
  • 高效的插入和删除:在链表头部或已知节点后插入和删除操作效率高,时间复杂度为O(1)。
  • 内存利用率:只要有足够的内存碎片,就可以分配新节点,无需连续的内存空间。

单向链表的主要劣势是:

  • 单向遍历:只能从头到尾遍历,找到特定节点或者在尾部插入新节点的效率较低,特别是在链表较长时。
  • 无法直接访问前一个节点:这限制了某些操作的效率,比如删除当前节点(需要访问前一个节点的指针)。

# 双向链表

双向链表中的每个节点除了包含数据部分和指向下一个节点的指针外,还包含一个指向前一个节点的指针。它的优势包括:

  • 双向遍历:可以从头到尾,也可以从尾到头遍历链表,提供了更大的灵活性。
  • 高效的节点操作:在已知节点的情况下,插入和删除操作效率高,无需遍历链表就可以直接删除节点或在任意位置插入新节点,因为可以直接访问前一个节点。

双向链表的主要劣势是:

  • 更高的内存消耗:每个节点需要额外存储一个指向前一个节点的指针。
  • 复杂性:在进行插入和删除操作时,需要更新更多的指针,增加了实现的复杂度。

# 选择依据

  • 空间还是时间:如果内存空间非常宝贵,且不需要频繁地进行插入、删除或反向遍历等操作,单向链表可能更合适。双向链表虽然在某些操作上更高效,但代价是更高的内存消耗。
  • 操作的类型:如果需要频繁地在链表中间插入或删除节点,或者需要从两个方向遍历链表,双向链表提供了更好的性能和灵活性。
  • 实现的复杂度:如果希望保持数据结构的简单性,以简化代码的维护和调试,单向链表可能是更好的选择。

总的来说,没有绝对的“最佳”选择,只有最适合特定需求和场景的选择。理解双向链表和单向链表的优缺点可以帮助你根据实际情况做出明智的决策。

# 2.2 双向链表的限制

双向链表确实提供了在节点的插入和删除操作上的高效性,特别是在你已经定位到目标节点的情况下。这种数据结构允许每个节点直接链接到其前后节点,从而使得添加或移除节点成为相对简单的操作。然而,双向链表并非没有限制,以下是它们的一些主要限制和缺点:

# 1. 遍历速度

  • 尽管双向链表允许从两个方向进行遍历,但遍历本身相比于数组和其他连续存储的数据结构通常较慢。这是因为链表中的元素在内存中可能分布不连续,这使得CPU缓存的利用效率较低,导致缓存利用率低下。

# 2. 访问特定元素

  • 访问链表中的特定元素(特别是随机访问)比数组慢得多。在数组中,随机访问的时间复杂度为O(1),而在双向链表中,即使是使用最优的路径,时间复杂度也为O(n),因为可能需要从头或尾开始遍历链表来找到目标元素。

# 3. 内存开销

  • 双向链表的每个节点都需要额外的内存空间来存储前驱和后继节点的指针,这意味着与单向链表相比,它们消耗更多的内存。对于内存敏感的应用,这可能成为一个问题。

# 4. 实现复杂性

  • 相比于单向链表,双向链表的插入和删除操作需要更新更多的指针(前驱和后继),这增加了实现的复杂性和出错的可能性。

# 2.3 实现复制、连接、分割

使用strdup初始化字符串而不是直接赋值(这样可以free,而不是const)

test1 = strdup("test1 data");
+test2 = strdup("test2 data");
+test3 = strdup("test3 data");
+

实现新功能源代码:

List *List_copy(List *list)
+{
+    check(list, "List is NULL.");
+
+    List *new_list = List_create();
+    check_mem(new_list);
+
+    LIST_FOREACH(list, first, next, cur)
+    {
+        if (cur->value)
+        {
+            // 复制字符串。注意:strdup在内存分配失败时返回NULL
+            char *copy_of_value = strdup((char *)cur->value);
+            if (copy_of_value == NULL)
+            {
+                // 处理内存分配失败的情况
+                List_destroy(new_list);
+                return NULL;
+            }
+            List_push(new_list, copy_of_value);
+        }
+        else
+        {
+            // 如果当前节点的value为NULL,也可以选择将NULL推入新列表
+            List_push(new_list, NULL);
+        }
+    }
+
+    return new_list;
+
+error:
+    return NULL;
+}
+
+void List_join(List *first, List *second)
+{
+    check(first && second, "One of the lists is NULL.");
+
+    if (second->first == NULL)
+    {
+        return; // 第二个链表为空,无需操作。
+    }
+
+    if (first->last != NULL)
+    {
+        first->last->next = second->first; // 连接两个链表。
+        second->first->prev = first->last;
+    }
+    else
+    {
+        first->first = second->first; // 如果第一个链表为空,直接设置首尾指针。
+    }
+
+    first->last = second->last;
+    first->count += second->count;
+
+error:
+    return;
+}
+
+List *List_split(List *list, ListNode *node)
+{
+    check(list && node, "List or node is NULL.");
+
+    List *new_list = List_create();
+    check_mem(new_list);
+
+    ListNode *cur = node;
+    while (cur != NULL)
+    {
+        ListNode *next = cur->next;
+        List_push(new_list, cur->value);
+
+        if (cur == list->last)
+        {
+            list->last = cur->prev;
+        }
+
+        if (cur->prev)
+        {
+            cur->prev->next = cur->next;
+        }
+
+        if (cur->next)
+        {
+            cur->next->prev = cur->prev;
+        }
+
+        free(cur);
+        cur = next;
+        list->count--;
+    }
+
+    if (list->last)
+    {
+        list->last->next = NULL;
+    }
+
+    if (list->count == 0)
+    {
+        list->first = NULL;
+    }
+
+    return new_list;
+
+error:
+    return NULL;
+}
+

测试代码:

char *test_copy()
+{
+    // 保证有数据
+    List_push(list, test1);
+    List_push(list, test2);
+    List_push(list, test3);
+    list_copy = List_copy(list);
+    mu_assert(list_copy != NULL, "Failed to copy list.");
+    mu_assert(List_count(list_copy) == List_count(list), "Copy list has wrong count.");
+
+    List_clear_destroy(list_copy);
+
+    return NULL;
+}
+
+char *test_join()
+{
+    list_second = List_create();
+    List_push(list_second, test3);
+    int count1 = List_count(list);
+
+    List_join(list, list_second);
+    int count2 = List_count(list_second);
+
+    mu_assert(List_count(list) == (count1 + count2), "Join list has wrong count.");
+    mu_assert(List_last(list) == test3, "Joined list has wrong last element.");
+
+    return NULL;
+}
+
+char *test_split()
+{
+    ListNode *node = list->first->next; // test2
+    int count1 = List_count(list);
+    list_split = List_split(list, node);
+    mu_assert(List_count(list) == 1, "Original list has wrong count after split.");
+    mu_assert(List_count(list_split) == count1 - 1, "New list has wrong count after split.");
+    mu_assert(List_first(list_split) == test2, "Split list has wrong first element.");
+
+    return NULL;
+}
+
+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.11-\347\273\203\344\271\24033\357\274\232\351\223\276\350\241\250\347\256\227\346\263\225.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.11-\347\273\203\344\271\24033\357\274\232\351\223\276\350\241\250\347\256\227\346\263\225.html" new file mode 100644 index 0000000..b5ebf58 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.11-\347\273\203\344\271\24033\357\274\232\351\223\276\350\241\250\347\256\227\346\263\225.html" @@ -0,0 +1,485 @@ + + + + + + 2024.04.11-练习33:链表算法 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.11-练习33:链表算法

# 1. 归并排序

归并排序是一种高效、稳定的排序算法,使用分治法(Divide and Conquer)的一个非常典型的应用。它的基本思想是将两个或两个以上的有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

归并排序的过程可以分为两个主要部分:

  1. 拆分:从中间将待排序数组拆分成两个子数组,递归地对这两个子数组进行归并排序,直到子数组长度为1或0。
  2. 合并:将两个有序的子数组合并成一个有序数组。合并过程需要额外的空间来暂存数据。

归并排序的时间复杂度为,不管最坏情况还是平均情况都是这个时间复杂度,其中 是数组或列表的长度。这是因为归并排序总是把列表分成两半,然后进行合并,所以拆分的层数(递归深度)是 ,每层需要的比较和合并操作是 次,所以总的操作次数是

归并排序的稳定性来源于合并过程中,相等的元素会保持原有的先后顺序。这使得归并排序非常适合用于需要稳定排序算法的场景,比如数据库的排序等。

这个算法的空间复杂度是 ,因为合并过程需要与原始数组相等大小的空间来暂时存储合并后的数组。

归并排序虽然在时间复杂度上表现良好,但由于其空间复杂度较高,因此在对空间使用有严格要求的环境下需要慎用。

# 2. 代码

# 2.1 头文件

#ifndef lcthw_List_algos_h
+#define lcthw_List_algos_h
+
+#include <lcthw/list.h>
+
+typedef int (*List_compare)(const void *a, const void *b);
+
+int List_bubble_sort(List *list, List_compare cmp);
+
+List *List_merge_sort(List *list, List_compare cmp);
+
+static inline void ListNode_swap(ListNode *a, ListNode *b)
+{
+    void *temp = a->value;
+    a->value = b->value;
+    b->value = temp;
+}
+
+List *List_merge(List *left, List *right, List_compare cmp);
+
+#endif
+

# 2.2 实现

#include <lcthw/list_algos.h>
+#include <lcthw/dbg.h>
+
+int List_bubble_sort(List *list, List_compare cmp)
+{
+    int sorted = 1;
+
+    if(List_count(list) <= 1) {
+        return 0;  // already sorted
+    }
+
+    do {
+        sorted = 1;
+        LIST_FOREACH(list, first, next, cur) {
+            if(cur->next) {
+                if(cmp(cur->value, cur->next->value) > 0) {
+                    ListNode_swap(cur, cur->next);
+                    sorted = 0;
+                }
+            }
+        }
+    } while(!sorted);
+
+    return 0;
+}
+
+List *List_merge(List *left, List *right, List_compare cmp)
+{
+    List *result = List_create();
+    void *val = NULL;
+
+    while(List_count(left) > 0 || List_count(right) > 0) {
+        if(List_count(left) > 0 && List_count(right) > 0) {
+            if(cmp(List_first(left), List_first(right)) <= 0) {
+                val = List_shift(left);
+            } else {
+                val = List_shift(right);
+            }
+
+            List_push(result, val);
+        } else if(List_count(left) > 0) {
+            val = List_shift(left);
+            List_push(result, val);
+        } else if(List_count(right) > 0) {
+            val = List_shift(right);
+            List_push(result, val);
+        }
+    }
+
+    return result;
+}
+
+List *List_merge_sort(List *list, List_compare cmp)
+{
+    if(List_count(list) <= 1) {
+        return list;
+    }
+
+    List *left = List_create();
+    List *right = List_create();
+    int middle = List_count(list) / 2;
+
+    LIST_FOREACH(list, first, next, cur) {
+        if(middle > 0) {
+            List_push(left, cur->value);
+        } else {
+            List_push(right, cur->value);
+        }
+
+        middle--;
+    }
+
+    List *sort_left = List_merge_sort(left, cmp);
+    List *sort_right = List_merge_sort(right, cmp);
+
+    if(sort_left != left) List_destroy(left);
+    if(sort_right != right) List_destroy(right);
+
+    return List_merge(sort_left, sort_right, cmp);
+}
+

# 2.3 单元测试

#include "minunit.h"
+#include <lcthw/list_algos.h>
+#include <assert.h>
+#include <string.h>
+
+char *values[] = {"XXXX", "1234", "abcd", "xjvef", "NDSS"};
+#define NUM_VALUES 5
+
+List *create_words()
+{
+    int i = 0;
+    List *words = List_create();
+
+    for(i = 0; i < NUM_VALUES; i++) {
+        List_push(words, values[i]);
+    }
+
+    return words;
+}
+
+int is_sorted(List *words)
+{
+    LIST_FOREACH(words, first, next, cur) {
+        if(cur->next && strcmp(cur->value, cur->next->value) > 0) {
+            debug("%s %s", (char *)cur->value, (char *)cur->next->value);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+char *test_bubble_sort()
+{
+    List *words = create_words();
+
+    // should work on a list that needs sorting
+    int rc = List_bubble_sort(words, (List_compare)strcmp);
+    mu_assert(rc == 0, "Bubble sort failed.");
+    mu_assert(is_sorted(words), "Words are not sorted after bubble sort.");
+
+    // should work on an already sorted list
+    rc = List_bubble_sort(words, (List_compare)strcmp);
+    mu_assert(rc == 0, "Bubble sort of already sorted failed.");
+    mu_assert(is_sorted(words), "Words should be sort if already bubble sorted.");
+
+    List_destroy(words);
+
+    // should work on an empty list
+    words = List_create(words);
+    rc = List_bubble_sort(words, (List_compare)strcmp);
+    mu_assert(rc == 0, "Bubble sort failed on empty list.");
+    mu_assert(is_sorted(words), "Words should be sorted if empty.");
+
+    List_destroy(words);
+
+    return NULL;
+}
+
+char *test_merge_sort()
+{
+    List *words = create_words();
+
+    // should work on a list that needs sorting
+    List *res = List_merge_sort(words, (List_compare)strcmp);
+    mu_assert(is_sorted(res), "Words are not sorted after merge sort.");
+
+    List *res2 = List_merge_sort(res, (List_compare)strcmp);
+    mu_assert(is_sorted(res), "Should still be sorted after merge sort.");
+    List_destroy(res2);
+    List_destroy(res);
+
+    List_destroy(words);
+    return NULL;
+}
+
+char *all_tests()
+{
+    mu_suite_start();
+
+    mu_run_test(test_bubble_sort);
+    mu_run_test(test_merge_sort);
+
+    return NULL;
+}
+
+RUN_TESTS(all_tests);
+

# 2.4 inline

# 标准inline函数的使用

当你在头文件中使用inline关键字声明和定义一个函数时,你告诉编译器这个函数的调用可以被替换为其函数体,即内联展开。这可以减少函数调用的开销,特别是对于那些非常小且频繁调用的函数。

# 使用static inline

通过在头文件中将函数定义为static inline,你可以避免链接问题。这样做的结果是,每个包含此头文件的.c文件都会得到函数的一个私有副本。这种方法很简单,适用于大多数情况,特别是当函数非常短小时。

#ifndef EXAMPLE_H
+#define EXAMPLE_H
+
+// Inline function declaration
+static inline void myFunction(int x) {
+    // Function implementation
+}
+
+#endif // EXAMPLE_H
+

这种方式不需要在源文件中额外定义函数。

如果你的目的是确保有一个非内联的版本可用,你可能不需要在源文件中使用inlineextern关键字,因为static inline的使用通常已经足够。我之前的建议在这方面可能不完全准确,因为在C中使用inline函数的最佳实践可能因编译器和具体情况而异。如果确实需要在某个地方提供一个明确的外部定义,那么你应该在源文件中提供一个普通的函数定义(无inline关键字),但这在使用了static inline定义的情况下通常是不必要的。

# 3. 改进

归并排序做了大量的链表复制和创建操作,寻找减少它们的办法。

List *List_merge(List *left, List *right, List_compare cmp)
+{
+    List *result = List_create();
+
+    while (left->first && right->first)
+    {
+        if (cmp(left->first->value, right->first->value) <= 0)
+        {
+            List_push(result, List_shift(left));
+        }
+        else
+        {
+            List_push(result, List_shift(right));
+        }
+    }
+    while (left->first)
+    {
+        List_push(result, List_shift(left));
+    }
+    while (right->first)
+    {
+        List_push(result, List_shift(right));
+    }
+
+    return result;
+}
+
+List *List_merge_sort(List *list, List_compare cmp)
+{
+    if (List_count(list) <= 1)
+    {
+        return list;
+    }
+
+    List *secondHalf = List_split_mid(list);
+
+    List *sort_left = List_merge_sort(list, cmp);
+    List *sort_right = List_merge_sort(secondHalf, cmp);
+
+    if (sort_left != list)
+        List_destroy(list);
+    if (sort_right != secondHalf)
+        List_destroy(secondHalf);
+
+    return List_merge(sort_left, sort_right, cmp);
+}
+
+List *List_split_mid(List *list)
+{
+    if (!list || !list->first || !list->first->next)
+    {
+        return NULL;
+    }
+
+    int cnt = List_count(list);
+    int c1 = 1, c2 = 0;
+    ListNode *slow = list->first;
+    ListNode *fast = list->first->next;
+    while (fast && fast->next)
+    {
+        slow = slow->next;
+        fast = fast->next->next;
+        c1++;
+    }
+    c2 = cnt - c1;
+
+    List *listsecond = List_create();
+    listsecond->first = slow->next;
+    listsecond->first->prev = NULL;
+    listsecond->last = list->last;
+    listsecond->count = c2;
+    list->last = slow;
+    slow->next = NULL;
+    list->count = c1;
+
+    return listsecond;
+}
+

Untitled

# 4. 附加题

# 4.1 程序运行时间

double start = clock();
+mu_run_test(test_bubble_sort);
+double end = clock();
+double cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
+printf("test_bubble_sort took %f seconds to execute \n", cpu_time_used);
+start = clock();
+mu_run_test(test_merge_sort);
+end = clock();
+cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+printf("test_merge_sort took %f seconds to execute \n", cpu_time_used);
+

Untitled

# 4.2 List_insert_sorted

实现List_insert_sorted(有序链表),它使用List_compare,接收一个值,将其插入到正确的位置,使链表有序。

void List_insert_sorted(List *list, void *value, List_compare cmp){
+    ListNode *node = malloc(sizeof(ListNode));
+    node->value = value;
+    node->next = NULL;
+
+    if(list->first == NULL || cmp(value, list->first->value) < 0) {
+        // 插入到链表头部
+        node->next = list->first;
+        list->first = node;
+        if(list->last == NULL) {
+            list->last = node;
+        }
+    } else {
+        // 在链表中找到正确的插入位置
+        ListNode *current = list->first;
+        while(current->next != NULL && cmp(value, current->next->value) > 0) {
+            current = current->next;
+        }
+        // 插入到current节点之后
+        node->next = current->next;
+        current->next = node;
+        if(current->next == NULL) {
+            list->last = node;
+        }
+    }
+    list->count++;
+}
+

Untitled

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.11-\347\273\203\344\271\24042\357\274\232\346\240\210\345\222\214\351\230\237\345\210\227.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.11-\347\273\203\344\271\24042\357\274\232\346\240\210\345\222\214\351\230\237\345\210\227.html" new file mode 100644 index 0000000..1fe04e2 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.11-\347\273\203\344\271\24042\357\274\232\346\240\210\345\222\214\351\230\237\345\210\227.html" @@ -0,0 +1,263 @@ + + + + + + 2024.04.11-练习42:栈和队列 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.11-练习42:栈和队列

# 1. 栈

# 1.1 头文件

#ifndef STACK_H
+#define STACK_H
+#include "list.h"
+
+typedef List Stack;
+
+#define Stack_create() List_create()
+#define Stack_destroy(A) List_destroy(A)
+#define Stack_push(A, B) List_push(A, B)
+#define Stack_peek(A) A->last->value
+#define Stack_count(A) List_count(A)
+#define STACK_FOREACH(S, V) LIST_FOREACH(S, last, prev, V)
+#define Stack_pop(A) List_remove(A, A->last)
+
+#endif
+

# 1.2 单元测试

#include "minunit.h"
+#include <lcthw/stack.h>
+#include <assert.h>
+
+static Stack *stack = NULL;
+char *tests[] = {"test1 data", "test2 data", "test3 data"};
+#define NUM_TESTS 3
+
+char *test_create()
+{
+    stack = Stack_create();
+    mu_assert(stack != NULL, "Failed to create stack.");
+
+    return NULL;
+}
+
+char *test_destroy()
+{
+    mu_assert(stack != NULL, "Failed to make stack #2");
+    Stack_destroy(stack);
+
+    return NULL;
+}
+
+char *test_push_pop()
+{
+    int i = 0;
+    for(i = 0; i < NUM_TESTS; i++) {
+        Stack_push(stack, tests[i]);
+        mu_assert(Stack_peek(stack) == tests[i], "Wrong next value.");
+    }
+
+    mu_assert(Stack_count(stack) == NUM_TESTS, "Wrong count on push.");
+
+    STACK_FOREACH(stack, cur) {
+        debug("VAL: %s", (char *)cur->value);
+    }
+
+    for(i = NUM_TESTS - 1; i >= 0; i--) {
+        char *val = Stack_pop(stack);
+        mu_assert(val == tests[i], "Wrong value on pop.");
+    }
+
+    mu_assert(Stack_count(stack) == 0, "Wrong count after pop.");
+
+    return NULL;
+}
+
+char *all_tests() {
+    mu_suite_start();
+
+    mu_run_test(test_create);
+    mu_run_test(test_push_pop);
+    mu_run_test(test_destroy);
+
+    return NULL;
+}
+
+RUN_TESTS(all_tests);
+

Untitled

# 2. 队列

# 2.1 头文件

#ifndef QUEUE_H
+#define QUEUE_H
+#include "list.h"
+
+typedef List Queue;
+
+#define Queue_create() List_create()
+#define Queue_destroy(A) List_destroy(A)
+#define Queue_send(A, B) List_push(A, B)
+#define Queue_peek(A) A->first->value
+#define Queue_count(A) List_count(A)
+#define QUEUE_FOREACH(S, V) LIST_FOREACH(S, first, next, V)
+#define Queue_recv(A) List_remove(A, A->first)
+
+#endif
+

# 2.2 单元测试

Untitled

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.12-\347\273\203\344\271\24044\357\274\232\347\216\257\345\275\242\347\274\223\345\206\262\345\214\272.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.12-\347\273\203\344\271\24044\357\274\232\347\216\257\345\275\242\347\274\223\345\206\262\345\214\272.html" new file mode 100644 index 0000000..66c928b --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/Learn C the hard way/2024.04.12-\347\273\203\344\271\24044\357\274\232\347\216\257\345\275\242\347\274\223\345\206\262\345\214\272.html" @@ -0,0 +1,419 @@ + + + + + + 2024.04.12-练习44:环形缓冲区 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.12-练习44:环形缓冲区

# 1. 头文件

#ifndef _lcthw_RingBuffer_h
+#define _lcthw_RingBuffer_h
+
+#include <lcthw/bstrlib.h>
+
+typedef struct {
+    char *buffer;
+    int length;
+    int start;
+    int end;
+} RingBuffer;
+
+RingBuffer *RingBuffer_create(int length);
+
+void RingBuffer_destroy(RingBuffer *buffer);
+
+int RingBuffer_read(RingBuffer *buffer, char *target, int amount);
+
+int RingBuffer_write(RingBuffer *buffer, char *data, int length);
+
+int RingBuffer_empty(RingBuffer *buffer);
+
+int RingBuffer_full(RingBuffer *buffer);
+
+int RingBuffer_available_data(RingBuffer *buffer);
+
+int RingBuffer_available_space(RingBuffer *buffer);
+
+bstring RingBuffer_gets(RingBuffer *buffer, int amount);
+
+#define RingBuffer_available_data(B) (((B)->end + 1) % (B)->length - (B)->start - 1)
+
+#define RingBuffer_available_space(B) ((B)->length - (B)->end - 1)
+
+#define RingBuffer_full(B) (RingBuffer_available_data((B)) - (B)->length == 0)
+
+#define RingBuffer_empty(B) (RingBuffer_available_data((B)) == 0)
+
+#define RingBuffer_puts(B, D) RingBuffer_write((B), bdata((D)), blength((D)))
+
+#define RingBuffer_get_all(B) RingBuffer_gets((B), RingBuffer_available_data((B)))
+
+#define RingBuffer_starts_at(B) ((B)->buffer + (B)->start)
+
+#define RingBuffer_ends_at(B) ((B)->buffer + (B)->end)
+
+#define RingBuffer_commit_read(B, A) ((B)->start = ((B)->start + (A)) % (B)->length)
+
+#define RingBuffer_commit_write(B, A) ((B)->end = ((B)->end + (A)) % (B)->length)
+
+#endif
+

这段代码定义了一个环形缓冲区(Ring Buffer),它是一种数据结构,用于在有限的缓冲区空间中高效地处理数据流。这种结构非常适合于需要循环利用空间的场景,比如网络通信或文件流处理。以下是代码中各部分的详细解释:

# 头文件和宏定义

#ifndef _lcthw_RingBuffer_h
+#define _lcthw_RingBuffer_h
+#include <lcthw/bstrlib.h>
+

这部分代码使用预处理命令来防止头文件被重复包含。#include <lcthw/bstrlib.h>是引入一个字符串库,这个库可能提供了一些额外的字符串处理功能。

# 结构体定义

typedef struct {
+    char *buffer;
+    int length;
+    int start;
+    int end;
+} RingBuffer;
+

这是环形缓冲区的基础结构,包含了以下字段:

  • char *buffer:指向实际存储数据的内存区域。
  • int length:缓冲区的总长度。
  • int start:指示数据开始的位置。
  • int end:指示数据结束的位置。

# 函数原型

环形缓冲区的操作包括创建、销毁、读取、写入以及检查缓冲区的状态:

  • RingBuffer_create(int length):创建一个指定长度的环形缓冲区。
  • RingBuffer_destroy(RingBuffer *buffer):销毁缓冲区,释放资源。
  • RingBuffer_read(RingBuffer *buffer, char *target, int amount):从缓冲区读取数据到target数组。
  • RingBuffer_write(RingBuffer *buffer, char *data, int length):将数据写入缓冲区。
  • bstring RingBuffer_gets(RingBuffer *buffer, int amount):读取指定数量的数据为一个bstring

# 宏定义

这些宏定义提供了一种快速访问缓冲区状态的方式,比如检查缓冲区是否空或满:

  • RingBuffer_available_data(B):计算缓冲区中已存储的数据量。
  • RingBuffer_available_space(B):计算缓冲区中剩余的空间量。
  • RingBuffer_full(B):检查缓冲区是否已满。
  • RingBuffer_empty(B):检查缓冲区是否为空。
  • RingBuffer_puts(B, D):便捷函数,用于将bstring类型的数据写入缓冲区。
  • RingBuffer_get_all(B):获取缓冲区中的所有数据。

# 提交数据的宏

  • RingBuffer_commit_read(B, A):在读取操作后更新start位置。
  • RingBuffer_commit_write(B, A):在写入操作后更新end位置。

# 2. 源文件

#undef NDEBUG
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lcthw/dbg.h>
+#include <lcthw/ringbuffer.h>
+
+RingBuffer *RingBuffer_create(int length)
+{
+    RingBuffer *buffer = calloc(1, sizeof(RingBuffer));
+    buffer->length  = length + 1;
+    buffer->start = 0;
+    buffer->end = 0;
+    buffer->buffer = calloc(buffer->length, 1);
+
+    return buffer;
+}
+
+void RingBuffer_destroy(RingBuffer *buffer)
+{
+    if(buffer) {
+        free(buffer->buffer);
+        free(buffer);
+    }
+}
+
+int RingBuffer_write(RingBuffer *buffer, char *data, int length)
+{
+    if(RingBuffer_available_data(buffer) == 0) {
+        buffer->start = buffer->end = 0;
+    }
+
+    check(length <= RingBuffer_available_space(buffer),
+            "Not enough space: %d request, %d available",
+            RingBuffer_available_data(buffer), length);
+
+    void *result = memcpy(RingBuffer_ends_at(buffer), data, length);
+    check(result != NULL, "Failed to write data into buffer.");
+
+    RingBuffer_commit_write(buffer, length);
+
+    return length;
+error:
+    return -1;
+}
+
+int RingBuffer_read(RingBuffer *buffer, char *target, int amount)
+{
+    check_debug(amount <= RingBuffer_available_data(buffer),
+            "Not enough in the buffer: has %d, needs %d",
+            RingBuffer_available_data(buffer), amount);
+
+    void *result = memcpy(target, RingBuffer_starts_at(buffer), amount);
+    check(result != NULL, "Failed to write buffer into data.");
+
+    RingBuffer_commit_read(buffer, amount);
+
+    if(buffer->end == buffer->start) {
+        buffer->start = buffer->end = 0;
+    }
+
+    return amount;
+error:
+    return -1;
+}
+
+bstring RingBuffer_gets(RingBuffer *buffer, int amount)
+{
+    check(amount > 0, "Need more than 0 for gets, you gave: %d ", amount);
+    check_debug(amount <= RingBuffer_available_data(buffer),
+            "Not enough in the buffer.");
+
+    bstring result = blk2bstr(RingBuffer_starts_at(buffer), amount);
+    check(result != NULL, "Failed to create gets result.");
+    check(blength(result) == amount, "Wrong result length.");
+
+    RingBuffer_commit_read(buffer, amount);
+    assert(RingBuffer_available_data(buffer) >= 0 && "Error in read commit.");
+
+    return result;
+error:
+    return NULL;
+}
+

这个 RingBuffer_write 函数是一个环形缓冲区的写操作函数,其作用是将数据从一个指定的源(data 参数)写入到环形缓冲区中。这段代码涉及错误检查、内存复制以及更新缓冲区指针的操作。下面我将逐步解析这个函数的每一部分。

# RingBuffer_write函数签名

int RingBuffer_write(RingBuffer *buffer, char *data, int length)
+

这个函数接收三个参数:

  • buffer:指向 RingBuffer 类型的指针,代表目标环形缓冲区。
  • data:指向需要写入缓冲区的数据的指针。
  • length:指定要写入的数据长度。

函数返回写入的字节数,如果出现错误,则返回 -1

# 函数体

# 确定起始位置

if(RingBuffer_available_data(buffer) == 0) {
+    buffer->start = buffer->end = 0;
+}
+

这里检查缓冲区是否为空(没有数据)。如果是空的,将 startend 指针都重置为 0。这种重置是为了优化写入性能,确保从缓冲区的开始位置写入数据。

# 检查是否有足够空间

check(length <= RingBuffer_available_space(buffer),
+      "Not enough space: %d request, %d available",
+      RingBuffer_available_data(buffer), length);
+

使用 check 宏(这通常是一个错误处理宏)来确保要写入的数据长度不会超过缓冲区的可用空间。如果超出可用空间,则打印错误信息并跳转到错误处理代码(error: 标签)。

# 数据复制

void *result = memcpy(RingBuffer_ends_at(buffer), data, length);
+check(result != NULL, "Failed to write data into buffer.");
+

通过 memcpy 函数将数据从 data 指针复制到缓冲区中由 RingBuffer_ends_at(buffer) 返回的位置。memcpy 应该总是返回其目的地址,除非发生异常。这里的检查是为了确保数据确实被写入了。

# 提交写操作

RingBuffer_commit_write(buffer, length);
+

更新缓冲区的 end 指针,以反映新写入的数据量。这通过 RingBuffer_commit_write 宏实现,它会适当地调整 end 指针,包括处理可能的环形回绕。

# 成功返回

return length;
+

如果一切正常,函数返回写入的字节数。

# 错误处理

error:
+    return -1;
+

如果在检查或写操作中遇到任何问题,函数跳转到这里并返回 -1,表示发生了错误。

# RingBuffer_write总结

RingBuffer_write 是一个典型的环形缓冲区数据写入函数,它涵盖了错误处理、空间检查、数据复制和指针更新等关键操作。这种实现保证了数据的安全写入,并且能有效地利用缓冲区的空间。通过适当的指针和边界管理,环形缓冲区可以在有限的内存空间内循环使用,非常适用于如 I/O 数据流处理等场景。

RingBuffer_readRingBuffer_gets 都是环形缓冲区中用于从缓冲区读取数据的函数,但它们在处理数据的方式和返回类型上有所不同。这两个函数各有其特定的用途和行为,下面详细解释这两者之间的区别:

# RingBuffer_read

  • 功能:将数据从环形缓冲区复制到另一个缓冲区(通常是一个字符数组)。
  • 参数: +
    • buffer:指向 RingBuffer 结构的指针。
    • target:目标缓冲区,用于接收从环形缓冲区复制的数据。
    • amount:要从环形缓冲区读取的数据字节数。
  • 行为: +
    • 使用 memcpyRingBuffer_starts_at(buffer) 的位置开始,将 amount 字节的数据复制到 target 中。
    • 读取操作完成后,通过 RingBuffer_commit_read 更新 start 指针。
    • 如果 startend 指针相等,表示缓冲区变为空,将它们重置为0。
  • 返回值:成功时返回读取的字节数,失败时返回 1

# RingBuffer_gets

  • 功能:从环形缓冲区获取一定数量的数据,并返回一个 bstring 对象。
  • 参数: +
    • buffer:指向 RingBuffer 结构的指针。
    • amount:要从环形缓冲区读取的数据字节数。
  • 行为: +
    • 使用 blk2bstr 从环形缓冲区的 start 位置创建一个新的 bstring 对象,其中包含 amount 字节的数据。
    • 类似于 RingBuffer_read,读取操作后通过 RingBuffer_commit_read 更新 start 指针。
    • 检查返回的 bstring 的长度是否正确,并确保没有数据处理错误。
  • 返回值:成功时返回一个 bstring 对象,失败时返回 NULL

# 主要区别

  1. 返回类型: +
    • RingBuffer_read 返回一个整数(读取的字节数),并将数据直接写入提供的目标缓冲区。
    • RingBuffer_gets 返回一个 bstring 对象,这是一个封装了数据和长度的结构体,用于更方便的字符串处理。
  2. 数据处理方式: +
    • RingBuffer_read 直接操作原始字节数据。
    • RingBuffer_gets 则可能更适用于处理文本数据,因为它提供了一种易于管理和操作的字符串形式。
  3. 错误处理和安全性: +
    • RingBuffer_gets 在创建 bstring 时进行了额外的检查,如长度验证和空值检查,这可以提供更高的数据完整性保证。
  4. 使用场景: +
    • RingBuffer_read 更多地用于需要直接处理字节数据的场景,如文件读写、网络数据传输等。
    • RingBuffer_gets 适用于需要字符串操作的场景,比如解析文本命令或读取配置文件等。

总之,选择 RingBuffer_read 还是 RingBuffer_gets 取决于你的应用场景和对数据类型的需求。如果你需要直接处理原始数据,RingBuffer_read 是合适的;如果你需要处理和存储字符串数据,并可能在之后进行进一步的字符串操作,RingBuffer_gets 会是更好的选择。

# 3. 测试

#include "minunit.h"    // 引入MinUnit头文件
+#include "RingBuffer.h" // 引入环形缓冲区的实现
+#include <assert.h>
+
+#define NUM_TESTS 5
+static RingBuffer *rb = NULL;
+
+char *test_create()
+{
+    rb = RingBuffer_create(1024);
+    mu_assert(rb != NULL, "Failed to create RingBuffer");
+    mu_assert(rb->length == 1025, "RingBuffer length incorrect");
+    mu_assert(RingBuffer_empty(rb), "RingBuffer should be empty after creation");
+
+    return NULL;
+}
+
+char *test_write_read()
+{
+    char *data = "test";
+    int result = RingBuffer_write(rb, data, 4);
+    mu_assert(result == 4, "RingBuffer_write should write 4 bytes");
+
+    char output[5] = {0}; // 确保有足够的空间和零初始化
+    result = RingBuffer_read(rb, output, 4);
+    mu_assert(result == 4, "RingBuffer_read should read 4 bytes");
+    mu_assert(strcmp(output, "test") == 0, "RingBuffer_read did not read the correct data");
+
+    return NULL;
+}
+
+char *test_puts_get_all()
+{
+    bstring data = bfromcstr("test");
+    RingBuffer_puts(rb, data);
+    bstring result = RingBuffer_get_all(rb);
+    mu_assert(biseq(data, result), "RingBuffer_get_all did not return the correct data");
+    bdestroy(data);
+    bdestroy(result);
+
+    return NULL;
+}
+
+char *test_puts_gets()
+{
+    bstring data = bfromcstr("test");
+    RingBuffer_puts(rb, data);
+    bstring result = RingBuffer_gets(rb, 4);
+    mu_assert(biseq(data, result), "RingBuffer_gets did not return the correct data");
+    bdestroy(data);
+    bdestroy(result);
+
+    return NULL;
+}
+
+char *test_destroy()
+{
+    mu_assert(rb != NULL, "Failed to create RingBuffer#2");
+    RingBuffer_destroy(rb);
+
+    return NULL;
+}
+
+static char *all_tests()
+{
+    mu_suite_start(); // 初始化测试套件
+    mu_run_test(test_create);
+    mu_run_test(test_write_read);
+    mu_run_test(test_puts_get_all);
+    mu_run_test(test_puts_gets);
+    mu_run_test(test_destroy);
+    return NULL;
+}
+
+// 使用RUN_TESTS宏运行所有测试
+RUN_TESTS(all_tests);
+

Untitled

# 4. 一些修改

//#define RingBuffer_available_data(B) (((B)->end + 1) % (B)->length - (B)->start - 1)
+#define RingBuffer_available_data(B) (((B)->end >= (B)->start) ? ((B)->end - (B)->start) : ((B)->length - (B)->start + (B)->end))
+
+//#define RingBuffer_available_space(B) ((B)->length - (B)->end - 1)
+#define RingBuffer_available_space(B) ((B)->length - RingBuffer_available_data(B) - 1)
+
+//#define RingBuffer_full(B) (RingBuffer_available_data((B)) - (B)->length == 0)
+#define RingBuffer_full(B) (RingBuffer_available_space(B) == 0)
+

原来的宏并没有判断end与start的前后位置。

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester.html" new file mode 100644 index 0000000..aae13b3 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester.html" @@ -0,0 +1,170 @@ + + + + + + The Missing Semester | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.14-1.The Shell.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.14-1.The Shell.html" new file mode 100644 index 0000000..20e2f36 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.14-1.The Shell.html" @@ -0,0 +1,190 @@ + + + + + + 2024.03.14-1. The Shell | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.14-1. The Shell

# 1. echo

echo  程序将该参数打印出来。 shell 基于空格分割命令并进行解析,然后执行第一个单词代表的程序,并将后续的单词作为程序可以访问的参数。如果您希望传递的参数中包含空格(例如一个名为 My Photos 的文件夹),您要么用使用单引号,双引号将其包裹起来,要么使用转义符号  \  进行处理(My\ Photos)。

# 2. cd

切换到上次访问的目录:使用  cd -  可以切换到上次访问的目录。

cd -
+

# 3. 在程序间创建连接

在 shell 中,程序有两个主要的“流”:它们的输入流和输出流。 当程序尝试读取信息时,它们会从输入流中进行读取,当程序打印信息时,它们会将信息输出到输出流中。 通常,一个程序的输入输出流都是您的终端。也就是,您的键盘作为输入,显示器作为输出。 但是,我们也可以重定向这些流!

最简单的重定向是  < file  和  > file。这两个命令可以将程序的输入输出流分别重定向到文件:

missing:~$ echo hello > hello.txt
+missing:~$ cat hello.txt
+hello
+missing:~$ cat < hello.txt
+hello
+missing:~$ cat < hello.txt > hello2.txt
+missing:~$ cat hello2.txt
+hello
+

您还可以使用  >>  来向一个文件追加内容。

使用管道( pipes ),我们能够更好的利用文件重定向。 |  操作符允许我们将一个程序的输出和另外一个程序的输入连接起来:

missing:~$ ls -l / | tail -n1
+drwxr-xr-x 1 root  root  4096 Jun 20  2019 var
+missing:~$ curl --head --silent google.com | grep --ignore-case content-length | cut --delimiter=' ' -f2
+219
+

# 4. clear

ctrl+L

# 5. 权限

例如,您笔记本电脑的屏幕亮度写在  brightness  文件中,它位于 /sys/class/backlight

通过将数值写入该文件,我们可以改变屏幕的亮度。现在,蹦到您脑袋里的第一个想法可能是:

$ sudo find -L /sys/class/backlight -maxdepth 2 -name '*brightness*'
+/sys/class/backlight/thinkpad_screen/brightness
+$ cd /sys/class/backlight/thinkpad_screen
+$ sudo echo 3 > brightness
+An error occurred while redirecting file 'brightness'
+open: Permission denied
+

出乎意料的是,我们还是得到了一个错误信息。毕竟,我们已经使用了  sudo  命令!关于 shell,有件事我们必须要知道。|>、和  <  是通过 shell 执行的,而不是被各个程序单独执行。 echo  等程序并不知道  |  的存在,它们只知道从自己的输入输出流中进行读写。 对于上面这种情况,shell (权限为您的当前用户) 在设置  sudo echo  前尝试打开 brightness 文件并写入,但是系统拒绝了 shell 的操作因为此时 shell 不是根用户。

明白这一点后,我们可以这样操作:

$ echo 3 | sudo tee brightness

因为打开  /sys  文件的是  tee  这个程序,并且该程序以  root  权限在运行,因此操作可以进行。 这样您就可以在  /sys  中愉快地玩耍了,例如修改系统中各种 LED 的状态(路径可能会有所不同):

$ echo 1 | sudo tee /sys/class/leds/input6::scrolllock/brightness
+

# 6. 单引号与双引号

单引号是全引用,被单引号括起的内容不管是常量还是变量都不会发生替换。

也就是说单引号定义字符串所见即所得,将单引号内的内容输出,看到的是什么就会输出什么。

双引号引用的内容,如果内容中有命令、变量等,会先把变量、命令解析出结果,然后在输出最终内容。双引号是部分引用,被双引号括起的内容常量还是常量,变量则会发生替换,替换成变量内容。

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.19-2.Script.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.19-2.Script.html" new file mode 100644 index 0000000..5338821 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.19-2.Script.html" @@ -0,0 +1,320 @@ + + + + + + 2024.03.19-2. Script | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.19-2. Script

# 1. Shell

# 1.1 变量赋值

在 bash 中为变量赋值的语法是 foo=bar ,访问变量中存储的数值,其语法为  $foo。 需要注意的是,foo = bar (使用空格隔开)是不能正确工作的,因为解释器会调用程序foo  并将  =  和  bar作为参数。 总的来说,在 shell 脚本中使用空格会起到分割参数的作用,有时候可能会造成混淆,请务必多加检查。

Bash 中的字符串通过'  和  "分隔符来定义,但是它们的含义并不相同。以'定义的字符串为原义字符串,其中的变量不会被转义,而  "定义的字符串会将变量值进行替换。

Untitled

# 1.2 函数

// mcd.sh
+// 创建一个文件夹并使用cd进入该文件夹。
+mcd () {
+    mkdir -p "$1"
+    cd "$1"
+}
+

这里  $1  是脚本的第一个参数。与其他脚本语言不同的是,bash 使用了很多特殊的变量来表示参数、错误代码和相关变量。下面列举了其中一些变量,更完整的列表可以参考  这里 (opens new window)

  • $0 - 脚本名
  • $1  到  $9 - 脚本的参数。 $1  是第一个参数,依此类推。
  • $@ - 所有参数
  • $# - 参数个数
  • $? - 前一个命令的返回值
  • $$ - 当前脚本的进程识别码
  • !! - 完整的上一条命令,包括参数。常见应用:当你因为权限不足执行命令失败时,可以使用  sudo !!再尝试一次。
  • $_ - 上一条命令的最后一个参数。如果你正在使用的是交互式 shell,你可以通过按下  Esc  之后键入 . 来获取这个值。

使用 source mcd.sh 会将 mcd 函数加载进来,后面可以直接调用

# 1.3 返回码

命令通常使用  STDOUT来返回输出值,使用STDERR  来返回错误及错误码,便于脚本以更加友好的方式报告错误。 返回码或退出状态是脚本/命令之间交流执行状态的方式。返回值 0 表示正常执行,其他所有非 0 的返回值都表示有错误发生。

退出码可以搭配  &&(与操作符)和  ||(或操作符)使用,用来进行条件判断,决定是否执行其他程序。它们都属于短路运算符 (opens new window)(short-circuiting) 同一行的多个命令可以用  ;  分隔。程序  true  的返回码永远是0false  的返回码永远是1

false || echo "Oops, fail"
+# Oops, fail
+
+true || echo "Will not be printed"
+#
+
+true && echo "Things went well"
+# Things went well
+
+false && echo "Will not be printed"
+#
+
+false ; echo "This will always run"
+# This will always run
+

另一个常见的模式是以变量的形式获取一个命令的输出,这可以通过  命令替换command substitution)实现。

当您通过  $( CMD )  这样的方式来执行CMD  这个命令时,它的输出结果会替换掉  $( CMD ) 。例如,如果执行  for file in $(ls) ,shell 首先将调用ls ,然后遍历得到的这些返回值。还有一个冷门的类似特性是  进程替换process substitution), <( CMD )  会执行  CMD  并将结果输出到一个临时文件中,并将  <( CMD )  替换成临时文件名。这在我们希望返回值通过文件而不是 STDIN 传递时很有用。例如, diff <(ls foo) <(ls bar)  会显示文件夹  foo  和  bar  中文件的区别。

说了很多,现在该看例子了,下面这个例子展示了一部分上面提到的特性。这段脚本会遍历我们提供的参数,使用grep  搜索字符串  foobar,如果没有找到,则将其作为注释追加到文件中。

#!/bin/bash
+
+echo "Starting program at $(date)" # date会被替换成日期和时间
+
+echo "Running program $0 with $# arguments with pid $$"
+
+for file in "$@"; do
+    grep foobar "$file" > /dev/null 2> /dev/null
+    # 如果模式没有找到,则grep退出状态为 1
+    # 我们将标准输出流和标准错误流重定向到Null,因为我们并不关心这些信息
+    if [[ $? -ne 0 ]]; then
+        echo "File $file does not have any foobar, adding one"
+        echo "# foobar" >> "$file"
+    fi
+done
+

在条件语句中,我们比较  $?  是否等于 0。 Bash 实现了许多类似的比较操作,您可以查看  [test 手册](https://man7.org/linux/man-pages/man1/test.1.html)。 在 bash 中进行比较时,尽量使用双方括号  [[ ]]  而不是单方括号  [ ],这样会降低犯错的几率,尽管这样并不能兼容  sh。 更详细的说明参见这里 (opens new window)

# 1.4 通配

当执行脚本时,我们经常需要提供形式类似的参数。bash 使我们可以轻松的实现这一操作,它可以基于文件扩展名展开表达式。这一技术被称为 shell 的  通配globbing

  • 通配符 - 当你想要利用通配符进行匹配时,你可以分别使用  ?  和  * 来匹配一个或任意个字符。例如,对于文件foofoo1foo2foo10  和  barrm foo?这条命令会删除foo1  和  foo2 ,而rm foo*  则会删除除了bar之外的所有文件。
  • 花括号{} - 当你有一系列的指令,其中包含一段公共子串时,可以用花括号来自动展开这些命令。这在批量移动或转换文件时非常方便。
convert image.{png,jpg}
+# 会展开为
+convert image.png image.jpg
+
+cp /path/to/project/{foo,bar,baz}.sh /newpath
+# 会展开为
+cp /path/to/project/foo.sh /path/to/project/bar.sh /path/to/project/baz.sh /newpath
+
+# 也可以结合通配使用
+mv *{.py,.sh} folder
+# 会移动所有 *.py 和 *.sh 文件
+
+mkdir foo bar
+
+# 下面命令会创建foo/a, foo/b, ... foo/h, bar/a, bar/b, ... bar/h这些文件
+touch {foo,bar}/{a..h}
+touch foo/x bar/y
+# 比较文件夹 foo 和 bar 中包含文件的不同
+diff <(ls foo) <(ls bar)
+# 输出
+# < x
+# ---
+# > y
+

# 1.5 shebang

脚本并不一定只有用 bash 写才能在终端里调用。比如说,这是一段 Python 脚本,作用是将输入的参数倒序输出:

*#!/usr/local/bin/python  //* #!/usr/bin/env python
+import sys
+for arg in reversed(sys.argv[1:]):
+    print(arg)
+

内核知道去用 python 解释器而不是 shell 命令来运行这段脚本,是因为脚本的开头第一行的  shebang (opens new window)

在  shebang  行中使用  [env](https://man7.org/linux/man-pages/man1/env.1.html)  命令是一种好的实践,它会利用环境变量中的程序来解析该脚本,这样就提高了您的脚本的可移植性。env  会利用我们第一节讲座中介绍过的PATH  环境变量来进行定位。 例如,使用了env的 shebang 看上去是这样的#!/usr/bin/env python

# 1.6 shell 函数和脚本

shell 函数和脚本有如下一些不同点:

  • 函数只能与 shell 使用相同的语言,脚本可以使用任意语言。因此在脚本中包含  shebang  是很重要的。
  • 函数仅在定义时被加载,脚本会在每次被执行时加载。这让函数的加载比脚本略快一些,但每次修改函数定义,都要重新加载一次。
  • 函数会在当前的 shell 环境中执行,脚本会在单独的进程中执行。因此,函数可以对环境变量进行更改,比如改变当前工作目录,脚本则不行。脚本需要使用  [export](https://man7.org/linux/man-pages/man1/export.1p.html)  将环境变量导出,并将值传递给环境变量。
  • 与其他程序语言一样,函数可以提高代码模块性、代码复用性并创建清晰性的结构。shell 脚本中往往也会包含它们自己的函数定义。

# 1.7  shellcheck

编写  bash  脚本有时候会很别扭和反直觉。例如  shellcheck (opens new window)  这样的工具可以帮助你定位 sh/bash 脚本中的错误。

# 2. Shell 工具

# 2.1 查看命令如何使用

看到这里,您可能会有疑问,我们应该如何为特定的命令找到合适的标记呢?例如  ls -lmv -i  和  mkdir -p。更普遍的是,给您一个命令行,您应该怎样了解如何使用这个命令行并找出它的不同的选项呢? 一般来说,您可能会先去网上搜索答案,但是,UNIX 可比 StackOverflow 出现的早,因此我们的系统里其实早就包含了可以获取相关信息的方法。

在上一节中我们介绍过,最常用的方法是为对应的命令行添加-h  或  --help  标记。另外一个更详细的方法则是使用man  命令。[man](https://man7.org/linux/man-pages/man1/man.1.html)  命令是手册(manual)的缩写,它提供了命令的用户手册。

例如,man rm  会输出命令  rm  的说明,同时还有其标记列表,包括之前我们介绍过的-i。 事实上,目前我们给出的所有命令的说明链接,都是网页版的 Linux 命令手册。即使是您安装的第三方命令,前提是开发者编写了手册并将其包含在了安装包中。在交互式的、基于字符处理的终端窗口中,一般也可以通过  :help  命令或键入  ?  来获取帮助。

有时候手册内容太过详实,让我们难以在其中查找哪些最常用的标记和语法。 TLDR pages (opens new window)  是一个很不错的替代品,它提供了一些案例,可以帮助您快速找到正确的选项。

snap install tldr  # in Ubuntu
+

# 2.2 查找文件

程序员们面对的最常见的重复任务就是查找文件或目录。所有的类 UNIX 系统都包含一个名为  [find](https://man7.org/linux/man-pages/man1/find.1.html)  的工具,它是 shell 上用于查找文件的绝佳工具。find命令会递归地搜索符合条件的文件,例如:

# 查找所有名称为src的文件夹
+find . -name src -type d
+# 查找前一天修改的所有文件
+find . -mtime -1
+# 查找所有大小在500k至10M的tar.gz文件
+find . -size +500k -size -10M -name '*.tar.gz'
+
# 查找所有文件夹路径中包含test的python文件
+find . -path '/test/*.py' -type f
+
  1. find .:这个命令从当前目录(.代表当前目录)开始递归搜索。
  2. path '/test/*.py':这部分指定了搜索的路径模式: +
    • ``:这个模式匹配零个或多个目录;在/test/\*.py中,它表示可以匹配任何深度的目录层级,直到遇到test目录。
    • test是一个具体的目录名,表示在任何可能的位置中寻找名为test的目录。
    • .py:这个模式匹配所有以.py结尾的文件,即 Python 脚本文件。
  3. type f:这个参数告诉find命令只关心文件(f代表文件),不要在结果中包括目录或其他类型的文件系统对象。

除了列出所寻找的文件之外,find 还能对所有查找到的文件进行操作。这能极大地简化一些单调的任务。

*# 删除全部扩展名为.tmp 的文件*
+find . -name '*.tmp' -exec rm {} \;
+*# 查找全部的 PNG 文件并将其转换为 JPG*
+find . -name '*.png' -exec convert {} {}.jpg \;
+

这段代码是一个在 Unix 或类 Unix 系统中使用的 shell 命令,用于查找当前目录及其子目录中所有的.png文件,并将每个找到的文件转换为.jpg格式。这里一步一步解释这个命令:

  1. find . -name '*.png':这个命令从当前目录(.代表当前目录)开始递归搜索所有扩展名为.png的文件。name '*.png'指定了要匹配的文件名模式,星号``是一个通配符,表示任意数量的任意字符。
  2. exec convert {} {}.jpg \;:这部分指定了find命令找到每个文件后要执行的操作。exec后面跟的是要执行的命令,这里使用convert命令来转换图像格式。 +
    • convert:这是 ImageMagick 工具集中的一个命令,用于转换图像格式。
    • {}:这是一个特殊的占位符,对于每个匹配的文件,find命令都会在这个位置插入文件的路径。
    • {}.jpg:这指定了输出文件的名称。对于每个输入文件,这会在原文件名(即{})后添加.jpg扩展名,创建一个新的文件名。
    • \;:这个分号表示exec参数的结束,并且需要转义(\;)来避免被 shell 解释。

尽管  find  用途广泛,它的语法却比较难以记忆。例如,为了查找满足模式  PATTERN  的文件,您需要执行  find -name '*PATTERN*' (如果您希望模式匹配时是不区分大小写,可以使用-iname选项)

您当然可以使用 alias 设置别名来简化上述操作,但 shell 的哲学之一便是寻找(更好用的)替代方案。 记住,shell 最好的特性就是您只是在调用程序,因此您只要找到合适的替代程序即可(甚至自己编写)。

例如,[fd](https://github.com/sharkdp/fd)  就是一个更简单、更快速、更友好的程序,它可以用来作为find的替代品。它有很多不错的默认设置,例如输出着色、默认支持正则匹配、支持 unicode 并且我认为它的语法更符合直觉。以模式PATTERN  搜索的语法是  fd PATTERN

sudo apt install fdfind
+

下面是关于如何使用 fd 以及一些实际的例子:

# fd 基本用法

  • 查找文件:输入 fd 后跟你要搜索的文件名或模式,它会在当前目录及其子目录下查找匹配的文件。例如,要查找所有的 .txt 文件,你可以使用:
    fd '\.txt$'
    +
  • 指定搜索目录:你可以在命令中指定一个特定的目录来让 fd 在其中搜索。例如,要在 ~/Documents 目录中搜索 .pdf 文件:
    fd '\.pdf$' ~/Documents
    +

# fd 高级用法

  • 忽略大小写:fd 默认使用智能大小写搜索。如果你想强制执行不区分大小写的搜索,可以使用 i 选项。例如,查找所有的 README 文件(不区分大小写):
    fd -i 'readme'
    +
  • 使用正则表达式:fd 支持正则表达式,让你可以进行更复杂的搜索。例如,查找所有以 a 开头,以 z 结尾的文件:
    fd '^a.*z$'
    +
  • 排除特定目录:如果你想在搜索中排除特定的目录,可以使用 E 选项。例如,搜索所有 .js 文件,但排除掉 node_modules 目录:
    fd '\.js$' -E node_modules
    +
  • 输出搜索结果到其他命令:fd 的输出可以通过管道传递给其他命令。例如,你可以使用 xargs 结合 fd 来对找到的文件执行操作。下面的命令将找到所有 .tmp 文件并删除它们:
    fd '\.tmp$' | xargs rm
    +

# fd 实用示例

  1. 快速查找特定文件:如果你想找到所有的 JPEG 图片文件,可以使用如下命令:

    fd '\.jpg$'
    +
  2. 在特定目录下搜索:如果你需要在 /var/log 目录下查找扩展名为 .log 的文件,可以使用:

    fd '\.log$' /var/lo
    +

大多数人都认为  find  和  fd  已经很好用了,但是有的人可能想知道,我们是不是可以有更高效的方法,例如不要每次都搜索文件而是通过编译索引或建立数据库的方式来实现更加快速地搜索。

这就要靠  [locate](https://man7.org/linux/man-pages/man1/locate.1.html)  了。 locate  使用一个由  [updatedb](https://man7.org/linux/man-pages/man1/updatedb.1.html)负责更新的数据库,在大多数系统中  updatedb  都会通过  [cron](https://man7.org/linux/man-pages/man8/cron.8.html)  每日更新。这便需要我们在速度和时效性之间作出权衡。而且,find  和类似的工具可以通过别的属性比如文件大小、修改时间或是权限来查找文件,locate则只能通过文件名。 这里 (opens new window)有一个更详细的对比。

# 2.3 查找代码

查找文件是很有用的技能,但是很多时候您的目标其实是查看文件的内容。一个最常见的场景是您希望查找具有某种模式的全部文件,并找它们的位置。

为了实现这一点,很多类 UNIX 的系统都提供了[grep](https://man7.org/linux/man-pages/man1/grep.1.html)命令,它是用于对输入文本进行匹配的通用工具。它是一个非常重要的 shell 工具,我们会在后续的数据清理课程中深入的探讨它。

grep  有很多选项,这也使它成为一个非常全能的工具。其中我经常使用的有  -C :获取查找结果的上下文(Context);-v  将对结果进行反选(Invert),也就是输出不匹配的结果。举例来说, grep -C 5  会输出匹配结果前后五行。当需要搜索大量文件的时候,使用  -R  会递归地进入子目录并搜索所有的文本文件。

但是,我们有很多办法可以对  grep -R  进行改进,例如使其忽略.git  文件夹,使用多 CPU 等等。

因此也出现了很多它的替代品,包括  ack (opens new window)ag (opens new window)  和  rg (opens new window)。它们都特别好用,但是功能也都差不多,我比较常用的是 ripgrep (rg) ,因为它速度快,而且用法非常符合直觉。例子如下:

# 查找所有使用了 requests 库的文件
+rg -t py 'import requests'
+# 查找所有没有写 shebang 的文件(包含隐藏文件)
+rg -u --files-without-match "^#!"
+# 查找所有的foo字符串,并打印其之后的5行
+rg foo -A 5
+# 打印匹配的统计信息(匹配的行和文件的数量)
+rg --stats PATTERN
+

# 2.4 查找 shell 命令

首先,按向上的方向键会显示你使用过的上一条命令,继续按上键则会遍历整个历史记录。

history  命令允许您以程序员的方式来访问 shell 中输入的历史命令。这个命令会在标准输出中打印 shell 中的历史命令。如果我们要搜索历史记录,则可以利用管道将输出结果传递给  grep  进行模式搜索。 history | grep find  会打印包含 find 子串的命令。

对于大多数的 shell 来说,您可以使用  Ctrl+R  对命令历史记录进行回溯搜索。敲  Ctrl+R  后您可以输入子串来进行匹配,查找历史命令行。

反复按下就会在所有搜索结果中循环。在  zsh (opens new window)  中,使用方向键上或下也可以完成这项工作。

Ctrl+R  可以配合  fzf (opens new window)  使用。fzf  是一个通用的模糊查找工具,它可以和很多命令一起使用。这里我们可以对历史命令进行模糊查找并将结果以赏心悦目的格式输出。

  1. 搜索历史命令:

    你可以通过管道将 history 命令的输出送入 fzf,然后 fzf 会提供一个交互式界面让你模糊搜索历史命令:

    history | fzf
    +

    这将展示一个交互式列表,你可以开始输入来过滤历史命令。当你找到需要的命令时,按 Enter 键,fzf 将把这个命令输出到标准输出。

  2. 执行选中的历史命令:

    如果你想直接执行选择的命令,可以使用以下技巧结合 xargs

    history | fzf | awk '{print $2}' | xargs -I {} bash -c "{}"
    +

    这条命令的工作流程是:

    • history | fzf:从历史中选择一个命令。
    • awk '{print $2}':假设你的历史格式是编号后跟命令,这将抽取命令部分(根据你的 shell 历史格式可能需要调整)。
    • xargs -I {} bash -c "{}":执行选中的命令。

你可以修改 shell history 的行为,例如,如果在命令的开头加上一个空格,它就不会被加进 shell 记录中。当你输入包含密码或是其他敏感信息的命令时会用到这一特性。 为此你需要在.bashrc中添加HISTCONTROL=ignorespace或者向.zshrc  添加  setopt HIST_IGNORE_SPACE。 如果你不小心忘了在前面加空格,可以通过编辑  .bash_history或  .zhistory  来手动地从历史记录中移除那一项。

# 2.5 文件夹导航

之前对所有操作我们都默认一个前提,即您已经位于想要执行命令的目录下,但是如何才能高效地在目录间随意切换呢?有很多简便的方法可以做到,比如设置 alias,使用  ln -s (opens new window)  创建符号连接等。而开发者们已经想到了很多更为精妙的解决方案。

由于本课程的目的是尽可能对你的日常习惯进行优化。因此,我们可以使用[fasd](https://github.com/clvv/fasd)和  autojump (opens new window)  这两个工具来查找最常用或最近使用的文件和目录。

Fasd 基于  *frecency* (opens new window)  对文件和文件排序,也就是说它会同时针对频率(frequency)和时效(recency)进行排序。默认情况下,fasd使用命令  z  帮助我们快速切换到最常访问的目录。例如, 如果您经常访问/home/user/files/cool_project  目录,那么可以直接使用  z cool  跳转到该目录。对于 autojump,则使用j cool代替即可。

还有一些更复杂的工具可以用来概览目录结构,例如  [tree](https://linux.die.net/man/1/tree)[broot](https://github.com/Canop/broot)  或更加完整的文件管理器,例如  [nnn](https://github.com/jarun/nnn)  或  [ranger](https://github.com/ranger/ranger)

# 3. Exercise

# 3.1 ls

阅读  [man ls](https://man7.org/linux/man-pages/man1/ls.1.html) ,然后使用ls  命令进行如下操作:

  • 所有文件(包括隐藏文件)
  • 文件打印以人类可以理解的格式输出 (例如,使用 454M 而不是 454279954)
  • 文件以最近访问顺序排序
  • 以彩色文本显示输出结果

典型输出如下:

 -rw-r--r--   1 user group 1.1M Jan 14 09:53 baz
+ drwxr-xr-x   5 user group  160 Jan 14 09:53 .
+ -rw-r--r--   1 user group  514 Jan 14 06:42 bar
+ -rw-r--r--   1 user group 106M Jan 13 12:12 foo
+ drwx------+ 47 user group 1.5K Jan 12 18:08 ..
+

Untitled

# 3.2 函数

编写两个 bash 函数  marco  和  polo  执行下面的操作。 每当你执行  marco  时,当前的工作目录应当以某种形式保存,当执行  polo  时,无论现在处在什么目录下,都应当  cd  回到当时执行  marco  的目录。 为了方便 debug,你可以把代码写在单独的文件  marco.sh  中,并通过  source marco.sh命令,(重新)加载函数。

#!/usr/bin/env zsh
+ marco(){
+     echo "$(pwd)" > $HOME/marco_history.log
+     echo "save pwd $(pwd)"
+ }
+ polo(){
+     cd "$(cat "$HOME/marco_history.log")"
+ }
+
#!/usr/bin/env zsh
+marco() {
+    export MARCO=$(pwd)
+}
+polo() {
+    cd "$MARCO"
+}
+

Answer:

marco(){
+    current_dir=$(pwd)
+}
+polo(){
+    cd $current_dir
+}
+

Untitled

# 3.3 返回码

假设您有一个命令,它很少出错。因此为了在出错时能够对其进行调试,需要花费大量的时间重现错误并捕获输出。 编写一段 bash 脚本,运行如下的脚本直到它出错,将它的标准输出和标准错误流记录到文件,并在最后输出所有内容。

加分项:报告脚本在失败前共运行了多少次。

#!/usr/bin/env zsh
+
+n=$(( RANDOM % 100 ))
+
+if [[ n -eq 42 ]]; then
+   echo "Something went wrong"
+   >&2 echo "The error was using magic numbers"
+   exit 1
+fi
+
+echo "Everything went according to plan"
+

Answer:

#!/usr/bin/env zsh
+
+chmod 777 3script.sh
+normCnt=0
+while true; do
+    ./3script.sh >> 3log.txt 2> 3err.txt
+    if [[ $? -eq 1 ]]; then
+        echo "The script failed"
+        echo "The script succeeded $normCnt times before failed"
+        break
+    fi
+    ((normCnt++))
+done
+

Untitled

# 3.4 find

本节课我们讲解的  find  命令中的  exec  参数非常强大,它可以对我们查找的文件进行操作。但是,如果我们要对所有文件进行操作呢?例如创建一个 zip 压缩文件?我们已经知道,命令行可以从参数或标准输入接受输入。在用管道连接命令时,我们将标准输出和标准输入连接起来,但是有些命令,例如tar  则需要从参数接受输入。这里我们可以使用[xargs](https://man7.org/linux/man-pages/man1/xargs.1.html)  命令,它可以使用标准输入中的内容作为参数。 例如  ls | xargs rm  会删除当前目录中的所有文件。

您的任务是编写一个命令,它可以递归地查找文件夹中所有的 HTML 文件,并将它们压缩成 zip 文件。注意,即使文件名中包含空格,您的命令也应该能够正确执行(提示:查看  xargs的参数-d,译注:MacOS 上的  xargs没有-d查看这个 issue (opens new window)

如果您使用的是 MacOS,请注意默认的 BSD find  与  GNU coreutils (opens new window)  中的是不一样的。你可以为find添加-print0选项,并为xargs添加-0选项。作为 Mac 用户,您需要注意 mac 系统自带的命令行工具和 GNU 中对应的工具是有区别的;如果你想使用 GNU 版本的工具,也可以使用  brew 来安装 (opens new window)

Untitled

# 3.5 LRU

(进阶)编写一个命令或脚本递归的查找文件夹中最近使用的文件。更通用的做法,你可以按照最近的使用时间列出文件吗?

Untitled

管道实现的是将前面的输出stdout作为后面的输入stdin,但是有些命令不接受管道的传递方式。例如:ls,这是为什么呢?

因为有些命令希望管道传递过来的是参数,但是直接使用管道有时无法传递到命令的参数位。这时候就需要xargsxargs实现的是将管道传递过来的stdin进行处理然后传递到命令的参数位置上。

xargs -0  可以处理接收到的stdin中的 null 字符(\0)。如果不使用-0选项或-null选项,检测到\0后会给出警告提醒,并只向命令传递非\0段。

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.20-3.Vim.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.20-3.Vim.html" new file mode 100644 index 0000000..3d4a7f2 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.20-3.Vim.html" @@ -0,0 +1,187 @@ + + + + + + 2024.03.20-3. Vim | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.20-3. Vim

# 1. 编辑模式

Vim 的设计以大多数时间都花在阅读、浏览和进行少量编辑改动为基础,因此它具有多种操作模式:

  • 正常模式:在文件中四处移动光标进行修改
  • 插入模式:插入文本
  • 替换模式:替换文本
  • 可视化模式(一般,行,块):选中文本块
  • 命令模式:用于执行命令

在不同的操作模式下,键盘敲击的含义也不同。比如,x  在插入模式会插入字母  x,但是在正常模式 会删除当前光标所在的字母,在可视模式下则会删除选中文块。

在默认设置下,Vim 会在左下角显示当前的模式。Vim 启动时的默认模式是正常模式。通常你会把大部分 时间花在正常模式和插入模式。

你可以按下  <ESC>(退出键)从任何其他模式返回正常模式。在正常模式,键入  i  进入插入 模式,R  进入替换模式,v  进入可视(一般)模式,V  进入可视(行)模式,<C-v> (Ctrl-V, 有时也写作  ^V)进入可视(块)模式,:  进入命令模式。

因为你会在使用 Vim 时大量使用  <ESC>  键,所以可以考虑把大小写锁定键重定义成  <ESC>  键(MacOS 教程 (opens new window))。

# 2. 基本操作

# 2.1 插入文本

在正常模式,键入  i  进入插入模式。现在 Vim 跟很多其他的编辑器一样,直到你键入  <ESC>  返回正常模式。你只需要掌握这一点和上面介绍的所有基础知识就可以使用 Vim 来编辑文件了 (虽然如果你一直停留在插入模式内不一定高效)。

# 2.2 缓存, 标签页, 窗口

Vim 会维护一系列打开的文件,称为“缓存”。一个 Vim 会话包含一系列标签页,每个标签页包含 一系列窗口(分隔面板)。每个窗口显示一个缓存。跟网页浏览器等其他你熟悉的程序不一样的是, 缓存和窗口不是一一对应的关系;窗口只是视角。一个缓存可以在多个窗口打开,甚至在同一 个标签页内的多个窗口打开。这个功能其实很好用,比如在查看同一个文件的不同部分的时候。

Vim 默认打开一个标签页,这个标签也包含一个窗口。

# 2.3 命令行

在正常模式下键入  :  进入命令行模式。 在键入  :  后,你的光标会立即跳到屏幕下方的命令行。 这个模式有很多功能,包括打开,保存,关闭文件,以及  退出 Vim (opens new window)

  • :q  退出(关闭窗口)
  • :w  保存(写)
  • :wq  保存然后退出
  • :e {文件名}  打开要编辑的文件
  • :ls  显示打开的缓存
  • :help {标题}  打开帮助文档 +
    • :help :w  打开  :w  命令的帮助文档
    • :help w  打开  w  移动的帮助文档

# 3. Vim 的接口其实是一种编程语言

# 3.1 移动

多数时候你会在正常模式下,使用移动命令在缓存中导航。在 Vim 里面移动也被称为 “名词”, 因为它们指向文字块。

  • 基本移动: hjkl (左, 下, 上, 右)
  • 词: w (下一个词), b (词初), e (词尾)
  • 行: 0 (行初), ^ (第一个非空格字符), $ (行尾)
  • 屏幕: H (屏幕首行), M (屏幕中间), L (屏幕底部)
  • 翻页: Ctrl-u (上翻), Ctrl-d (下翻)
  • 文件: gg (文件头), G (文件尾)
  • 行数: :{行数}<CR>  或者  {行数}G ({行数}为行数)
  • 杂项: % (找到配对,比如括号或者 /* */ 之类的注释对)
  • 查找: f{字符}, t{字符}, F{字符}, T{字符}
    • 查找/到 向前/向后 在本行的{字符}
    • , / ;  用于导航匹配
  • 搜索: /{正则表达式}n / N  用于导航匹配

# 3.2 编辑

所有你需要用鼠标做的事, 你现在都可以用键盘:采用编辑命令和移动命令的组合来完成。 这就是 Vim 的界面开始看起来像一个程序语言的时候。Vim 的编辑命令也被称为 “动词”, 因为动词可以施动于名词。

  • i  进入插入模式 +
    • 但是对于操纵/编辑文本,不单想用退格键完成
  • O / o  在之上/之下插入行
  • d{移动命令}  删除 {移动命令} +
    • 例如,dw  删除词, d$  删除到行尾, d0  删除到行头。
  • c{移动命令}  改变 {移动命令} +
    • 例如,cw  改变词
    • 比如  d{移动命令}  再  i
  • x  删除字符(等同于  dl
  • s  替换字符(等同于  xi
  • 可视化模式 + 操作 +
    • 选中文字, d  删除 或者  c  改变
  • u  撤销, <C-r>  重做
  • y  复制 / “yank” (其他一些命令比如  d  也会复制)yy 复制一行
  • p  粘贴
  • 更多值得学习的: 比如  ~  改变字符的大小写

# 3.3 计数

你可以用一个计数来结合“名词”和“动词”,这会执行指定操作若干次。

  • 3w  向后移动三个词
  • 5j  向下移动 5 行
  • 7dw  删除 7 个词

# 3.4 修饰语

你可以用修饰语改变“名词”的意义。修饰语有  i,表示“内部”或者“在内”,和  a, 表示“周围”。

  • ci(  改变当前括号内的内容
  • ci[  改变当前方括号内的内容
  • da'  删除一个单引号字符串, 包括周围的单引号

# 4. 自定义 Vim

Vim 由一个位于  ~/.vimrc  的文本配置文件(包含 Vim 脚本命令)。你可能会启用很多基本 设置。

我们提供一个文档详细的基本设置,你可以用它当作你的初始设置。我们推荐使用这个设置因为 它修复了一些 Vim 默认设置奇怪行为。  在这儿 (opens new window)  下载我们的设置,然后将它保存成  ~/.vimrc.

Vim 能够被重度自定义,花时间探索自定义选项是值得的。你可以参考其他人的在 GitHub 上共享的设置文件,比如,你的授课人的 Vim 设置 (Anish (opens new window)Jon (opens new window) (uses neovim (opens new window)), Jose (opens new window))。 有很多好的博客文章也聊到了这个话题。尽量不要复制粘贴别人的整个设置文件, 而是阅读和理解它,然后采用对你有用的部分。

# 5. 扩展 Vim

Vim 有很多扩展插件。跟很多互联网上已经过时的建议相反,你需要在 Vim 使用一个插件 管理器(从 Vim 8.0 开始)。你可以使用内置的插件管理系统。只需要创建一个  ~/.vim/pack/vendor/start/  的文件夹,然后把插件放到这里(比如通过  git clone)。

以下是一些我们最爱的插件:

我们尽量避免在这里提供一份冗长的插件列表。你可以查看讲师们的开源的配置文件 (Anish (opens new window)Jon (opens new window)Jose (opens new window)) 来看看我们使用的其他插件。 浏览  Vim Awesome (opens new window)  来了解一些很棒的插件。 这个话题也有很多博客文章:搜索 “best Vim plugins”。

# 6. Vim 进阶

这里我们提供了一些展示这个编辑器能力的例子。我们无法把所有的这样的事情都教给你,但是你可以在使用中学习。一个好的对策是: 当你在使用你的编辑器的时候感觉 “一定有更好的方法来做这个”, 那么很可能真的有:上网搜寻一下。

# 6.1 搜索和替换

:s (替换)命令(文档 (opens new window))。

  • %s/foo/bar/g
    • 在整个文件中将 foo 全局替换成 bar
  • %s/\[.*\](\(.*\))/\1/g
    • 将有命名的 Markdown 链接替换成简单 URLs

# 6.2 多窗口

  • 用  :sp / :vsp  来分割窗口
  • 同一个缓存可以在多个窗口中显示。

# 6.3 宏

  • q{字符}  来开始在寄存器{字符}中录制宏
  • q停止录制
  • @{字符}  重放宏
  • 宏的执行遇错误会停止
  • {计数}@{字符}执行一个宏{计数}次
  • 宏可以递归 +
    • 首先用q{字符}q清除宏
    • 录制该宏,用  @{字符}  来递归调用该宏 (在录制完成之前不会有任何操作)
  • 例子:将 xml 转成 json (file (opens new window)) +
    • 一个有 “name” / “email” 键对象的数组
    • 用一个 Python 程序?
    • 用 sed / 正则表达式 +
      • g/people/d
      • %s/<person>/{/g
      • %s/<name>\(.*\)<\/name>/"name": "\1",/g
    • Vim 命令 / 宏 +
      • ggddGdd  删除第一行和最后一行
      • 格式化最后一个元素的宏 (寄存器  e) +
        • 跳转到有  <name>  的行
        • qe^r"f>s": "<ESC>f<C"<ESC>q
      • 格式化一个的宏 +
        • 跳转到有  <person>  的行
        • qpS{<ESC>j@eA,<ESC>j@ejS},<ESC>q
      • 格式化一个标签然后转到另外一个的宏 +
        • 跳转到有  <person>  的行
        • qq@pjq
      • 执行宏到文件尾 +
        • 999@q
      • 手动移除最后的  ,  然后加上  [  和  ]  分隔符

# 7. 扩展资料

+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.21-4.Data Wrangling.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.21-4.Data Wrangling.html" new file mode 100644 index 0000000..476f809 --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.21-4.Data Wrangling.html" @@ -0,0 +1,275 @@ + + + + + + 2024.03.21-4. Data Wrangling | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.21-4. Data Wrangling

# 1. journalctl

查看所有日志(默认情况下 ,只保存本次启动的日志)

journalctl

查看内核日志(不显示应用日志)

journalctl -k

查看系统本次启动的日志

journalctl -b

journalctl -b -0

查看上一次启动的日志(需更改设置)

journalctl -b -1

ssh myserver journalctl | grep sshd
+

这里我们使用管道将一个远程服务器上的文件传递给本机的  grep  程序! ssh  太牛了,下一节课我们会讲授命令行环境,届时我们会详细讨论  ssh  的相关内容。此时我们打印出的内容,仍然比我们需要的要多得多,读起来也非常费劲。我们来改进一下:

ssh myserver 'journalctl | grep sshd | grep "Disconnected from"' | less
+

多出来的引号是什么作用呢?这么说吧,我们的日志是一个非常大的文件,把这么大的文件流直接传输到我们本地的电脑上再进行过滤是对流量的一种浪费。因此我们采取另外一种方式,我们先在远端机器上过滤文本内容,然后再将结果传输到本机。 less  为我们创建来一个文件分页器,使我们可以通过翻页的方式浏览较长的文本。

为了进一步节省流量,我们甚至可以将当前过滤出的日志保存到文件中,这样后续就不需要再次通过网络访问该文件了:

ssh myserver 'journalctl | grep sshd | grep "Disconnected from"' > ssh.log
+less ssh.log
+

过滤结果中仍然包含不少没用的数据。我们有很多办法可以删除这些无用的数据,但是让我们先研究一下  sed  这个非常强大的工具。

sed  是一个基于文本编辑器ed构建的”流编辑器” 。在  sed  中,您基本上是利用一些简短的命令来修改文件,而不是直接操作文件的内容(尽管您也可以选择这样做)。相关的命令行非常多,但是最常用的是  s,即替换命令,例如我们可以这样写:

ssh myserver journalctl
+ | grep sshd
+ | grep "Disconnected from"
+ | sed 's/.*Disconnected from //'
+

上面这段命令中,我们使用了一段简单的正则表达式。正则表达式是一种非常强大的工具,可以让我们基于某种模式来对字符串进行匹配。s  命令的语法如下:s/REGEX/SUBSTITUTION/, 其中  REGEX  部分是我们需要使用的正则表达式,而  SUBSTITUTION  是用于替换匹配结果的文本。

# 2. 正则表达式

正则表达式通常以(尽管并不总是) / 开始和结束。大多数的 ASCII 字符都表示它们本来的含义,但是有一些字符确实具有表示匹配行为的“特殊”含义。不同字符所表示的含义,根据正则表达式的实现方式不同,也会有所变化,这一点确实令人沮丧。常见的模式有:

  • .  除换行符之外的”任意单个字符”
  • ``  匹配前面字符零次或多次
  • +  匹配前面字符一次或多次
  • [abc]  匹配  ab  和  c  中的任意一个
  • (RX1|RX2)  任何能够匹配RX1  或  RX2的结果
  • ^  行首
  • $  行尾

正则表达式会如何匹配?*  和  +  在默认情况下是贪婪模式,也就是说,它们会尽可能多的匹配文本。对于某些正则表达式的实现来说,您可以给  *  或  +  增加一个?  后缀使其变成非贪婪模式

sed -E 's/.*Disconnected from (invalid |authenticating )?user .* [^ ]+ port [0-9]+( \[preauth\])?$//'
+

IP 地址正则表达式:

 (?:(?:1[0-9][0-9]\.)|(?:2[0-4][0-9]\.)|(?:25[0-5]\.)|(?:[1-9][0-9]\.)|(?:[0-9]\.)){3}(?:(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5])|(?:[1-9][0-9])|(?:[0-9]))
+

我们实际上希望能够将用户名保留下来。对此,我们可以使用“捕获组(capture groups)”来完成。被圆括号内的正则表达式匹配到的文本,都会被存入一系列以编号区分的捕获组中。捕获组的内容可以在替换字符串时使用(有些正则表达式的引擎甚至支持替换表达式本身),例如\1、 \2\3等等,因此可以使用如下命令:

sed -E 's/.*Disconnected from (invalid |authenticating )?user (.*) [^ ]+ port [0-9]+( \[preauth\])?$/\2/'
+

# 2.1 正则匹配基本知识及概念

在练习之前,需要大家知道一些基本知识,如果有一定基础的可以跳过该步骤,直接往下看。

# 2.2 正则表达式-字符类

[abc]:代表a或者b,或者c字符中的一个。
+[^abc]:代表除a,b,c以外的任何字符。
+[a-z]:代表a-z的所有小写字符中的一个。
+[A-Z]:代表A-Z的所有大写字符中的一个。
+[0-9]:代表0-9之间的某一个数字字符。
+[a-zA-Z0-9]:代表a-z或者A-Z或者0-9之间的任意一个字符。
+[a-dm-p]:a 到 d 或 m 到 p之间的任意一个字符。
+

# 2.3 正则表达式-逻辑运算符

&&:并且
+| :或者(可以省略)
+

# 2.4 正则表达式-预定义字符

“.” : 匹配任何字符。
+“\d”:任何数字[0-9]的简写;
+“\D”:任何非数字[^0-9]的简写;
+“\s”: 空白字符:[ \t\n\x0B\f\r] 的简写
+“\S”: 非空白字符:[^\s] 的简写
+“\w”:单词字符:[a-zA-Z_0-9]的简写
+“\W”:非单词字符:[^\w]
+

# 2.5 正则表达式-数量词

x? : 0次或1次
+x* : 0次到多次
+x+ : 1次或多次
+X{n} : 恰好n次
+X{n,} : 至少n次
+X{n,m}: n到m次(n和m都是包含的,最少n次,最多m次。
+

# 3. 数据整理

ssh myserver journalctl
+ | grep sshd
+ | grep "Disconnected from"
+ | sed -E 's/.*Disconnected from (invalid |authenticating )?user (.*) [^ ]+ port [0-9]+( \[preauth\])?$/\2/'
+ | sort | uniq -c
+

sort  会对其输入数据进行排序。uniq -c  会把连续出现的行折叠为一行并使用出现次数作为前缀。我们希望按照出现次数排序,过滤出最常出现的用户名:

ssh myserver journalctl
+ | grep sshd
+ | grep "Disconnected from"
+ | sed -E 's/.*Disconnected from (invalid |authenticating )?user (.*) [^ ]+ port [0-9]+( \[preauth\])?$/\2/'
+ | sort | uniq -c
+ | sort -nk1,1 | tail -n10
+

sort -n  会按照数字顺序对输入进行排序(默认情况下是按照字典序排序) -k1,1  则表示“仅基于以空格分割的第一列进行排序”。,n  部分表示“仅排序到第 n 个部分”,默认情况是到行尾。就本例来说,针对整个行进行排序也没有任何问题,我们这里主要是为了学习这一用法!

如果我们希望得到登录次数最少的用户,我们可以使用  head  来代替tail。或者使用sort -r来进行倒序排序。

相当不错。但我们只想获取用户名,而且不要一行一个地显示:

ssh myserver journalctl
+ | grep sshd
+ | grep "Disconnected from"
+ | sed -E 's/.*Disconnected from (invalid |authenticating )?user (.*) [^ ]+ port [0-9]+( \[preauth\])?$/\2/'
+ | sort | uniq -c
+ | sort -nk1,1 | tail -n10
+ | awk '{print $2}' | paste -sd,
+

# 4. awk – 另外一种编辑器

awk  其实是一种编程语言,只不过它碰巧非常善于处理文本。

首先, {print $2}  的作用是什么? awk  程序接受一个模式串(可选),以及一个代码块,指定当模式匹配时应该做何种操作。默认当模式串即匹配所有行(上面命令中当用法)。 在代码块中,$0  表示整行的内容,$1  到  $n  为一行中的 n 个区域,区域的分割基于  awk  的域分隔符(默认是空格,可以通过-F来修改)。在这个例子中,我们的代码意思是:对于每一行文本,打印其第二个部分,也就是用户名。

让我们康康,还有什么炫酷的操作可以做。让我们统计一下所有以c  开头,以  e  结尾,并且仅尝试过一次登录的用户。

 | awk '$1 == 1 && $2 ~ /^c[^ ]*e$/ { print $2 }' | wc -l
+

让我们好好分析一下。首先,注意这次我们为  awk指定了一个匹配模式串(也就是{...}前面的那部分内容)。该匹配要求文本的第一部分需要等于 1(这部分刚好是uniq -c得到的计数值),然后其第二部分必须满足给定的一个正则表达式。代码块中的内容则表示打印用户名。然后我们使用  wc -l  统计输出结果的行数。

不过,既然  awk  是一种编程语言,那么则可以这样:

BEGIN { rows = 0 }
+$1 == 1 && $2 ~ /^c[^ ]*e$/ { rows += $1 }
+END { print rows }
+

BEGIN  也是一种模式,它会匹配输入的开头( END  则匹配结尾)。然后,对每一行第一个部分进行累加,最后将结果输出。事实上,我们完全可以抛弃  grep  和  sed ,因为  awk  就可以解决所有问题 (opens new window)。至于怎么做,就留给读者们做课后练习吧。

# 5. 分析数据

想做数学计算也是可以的!例如这样,您可以将每行的数字加起来:

 | paste -sd+ | bc -l
+

下面这种更加复杂的表达式也可以:

echo "2*($(data | paste -sd+))" | bc -l
+

如果您希望绘制一些简单的图表, gnuplot  可以帮助到您:

ssh myserver journalctl
+ | grep sshd
+ | grep "Disconnected from"
+ | sed -E 's/.*Disconnected from (invalid |authenticating )?user (.*) [^ ]+ port [0-9]+( \[preauth\])?$/\2/'
+ | sort | uniq -c
+ | sort -nk1,1 | tail -n10
+ | gnuplot -p -e 'set boxwidth 0.5; plot "-" using 1:xtic(2) with boxes'
+

# 6. Exercise

# 6.1 学习这篇简短的  交互式正则表达式教程 (opens new window)

# 6.2 sed

统计 words 文件 (/usr/share/dict/words) 中包含至少三个a  且不以's  结尾的单词个数。这些单词中,出现频率前三的末尾两个字母是什么? sed的  y命令,或者  tr  程序也许可以帮你解决大小写的问题。共存在多少种词尾两字母组合?还有一个很 有挑战性的问题:哪个组合从未出现过?

Untitled

Untitled

#! /usr/bin/env zsh
+# 2.sh
+
+for i in {a..z}; do
+    for j in {a..z}; do
+        echo $i$j
+    done
+done > allcomb.txt
+
+cat words.txt | grep -P '(?:a.*){3,}' | sed -E "/'s$/d" | sed -E 's/.*(..)$/\1/' | tr '[:upper:]' '[:lower:]' | sort -u > appcomb.txt
+
+grep -vxFf appcomb.txt allcomb.txt | sort | uniq > notappcomb.txt
+

# 6.3 in-place

进行原地替换听上去很有诱惑力,例如: sed s/REGEX/SUBSTITUTION/ input.txt > input.txt。但是这并不是一个明智的做法,为什么呢?还是说只有  sed是这样的? 查看  man sed  来完成这个问题

Answer:

当你尝试使用 sed 命令进行原地替换,如使用命令 sed s/REGEX/SUBSTITUTION/ input.txt > input.txt,看似想要直接在源文件上执行替换操作,实际上这样做是有问题的。这个命令的问题在于它试图将输出重定向回输入文件,这并不是 sed 命令或其他文本处理命令特有的问题,而是 Unix/Linux shell 处理重定向的方式所导致的。

当你执行上述命令时,shell 会先处理重定向(>),这导致 input.txt 被打开用于写入并且立即被截断(即文件内容被清空),然后 sed 才开始从这个现在已经是空的文件读取数据。结果是,sed 没有数据可供处理,因此也就没有任何数据写回到 input.txt 中,导致文件内容丢失。

对于 sed,如果你想进行原地编辑,应该使用 -i 选项(或 --in-place),这样可以直接在文件上执行修改操作而不需要重定向输出到新文件:

sed -i 's/REGEX/SUBSTITUTION/' input.txt
+

这个 -i 选项告诉 sed 直接修改文件内容,而不是输出到标准输出。注意,-i 选项在不同的系统中可能稍有不同,某些系统可能要求为 -i 指定一个扩展名,用于在修改前保存原文件的备份。

例如,如果你希望备份原文件,可以这样做:

sed -i.bak 's/REGEX/SUBSTITUTION/' input.txt
+

这会将原始的 input.txt 保存为 input.txt.bak,并直接修改 input.txt

总结,这并不是只有 sed 会遇到的问题,任何尝试将输出重定向回输入文件的操作都可能遇到同样的问题,因为 Unix/Linux shell 会先处理重定向,导致输入文件被清空。所以,当需要原地编辑文件时,应该使用工具提供的原地编辑功能(比如 sed-i 选项),而不是使用重定向。

# 6.4 开机时间

找出您最近十次开机的开机时间平均数、中位数和最长时间。在 Linux 上需要用到  journalctl ,而在 macOS 上使用  log show。找到每次起到开始和结束时的时间戳。

在 Linux 上类似这样:Logs begin at ...systemd[577]: Startup finished in ...

在 macOS 上, 查找 (opens new window): === system boot:Previous shutdown cause: 5

#! /usr/bin/env zsh
+# 4.sh
+
+for i in {0..9}; do
+    journalctl -b -$i | grep "Startup finished" | grep "kernel" | sed -E 's/.*= (.*)s\.$/\1/'
+done > ./startTime.txt
+
+minTime=$(cat startTime.txt | sort -n | head -1)
+echo "Minimum time: ${minTime}s"
+maxTime=$(cat startTime.txt | sort -n | tail -1)
+echo "Maximum time: ${maxTime}s"
+avgTime=$(cat startTime.txt | paste -sd+ | bc -l | awk '{print $1/10}')
+echo "Average time: ${avgTime}s"
+midTime=$(cat startTime.txt | sort -n | paste -sd\  | awk '{print ($5+$6)/2}')
+echo "Median time: ${midTime}s"
+

Untitled

# 6.5 awk

查看之前三次重启启动信息中不同的部分(参见  journalctl-b  选项)。将这一任务分为几个步骤,首先获取之前三次启动的启动日志,也许获取启动日志的命令就有合适的选项可以帮助您提取前三次启动的日志,亦或者您可以使用sed '0,/STRING/d'  来删除STRING匹配到的字符串前面的全部内容。然后,过滤掉每次都不相同的部分,例如时间戳。下一步,重复记录输入行并对其计数(可以使用uniq )。最后,删除所有出现过 3 次的内容(因为这些内容是三次启动日志中的重复部分)。

#! /usr/bin/env zsh
+# 5.sh
+
+for i in {0..2}; do
+    journalctl -b -$i >> ./last3.txt
+done
+
+cat last3.txt | sed -E "s/.*pi\ (.*)/\1/" | sort | uniq -c | sort -n | awk '$1!=3 {print}' > 2.5.txt
+
+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.21-5.Command Line Interface.html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.21-5.Command Line Interface.html" new file mode 100644 index 0000000..87d9e1f --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.21-5.Command Line Interface.html" @@ -0,0 +1,333 @@ + + + + + + 2024.03.21-5. Command Line Interface | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.21-5. Command Line Interface

# 1. 任务控制

# 1.1 结束进程

您的 shell 会使用 UNIX 提供的信号机制执行进程间通信。当一个进程接收到信号时,它会停止执行、处理该信号并基于信号传递的信息来改变其执行。就这一点而言,信号是一种软件中断

在上面的例子中,当我们输入  Ctrl-C  时,shell 会发送一个SIGINT  信号到进程。

下面这个 Python 程序向您展示了捕获信号SIGINT  并忽略它的基本操作,它并不会让程序停止。为了停止这个程序,我们需要使用SIGQUIT  信号,通过输入Ctrl-\可以发送该信号。

#!/usr/bin/env python
+import signal, time
+
+def handler(signum, time):
+    print("\nI got a SIGINT, but I am not stopping")
+
+signal.signal(signal.SIGINT, handler)
+i = 0
+while True:
+    time.sleep(.1)
+    print("\r{}".format(i), end="")
+    i += 1
+

如果我们向这个程序发送两次  SIGINT ,然后再发送一次  SIGQUIT,程序会有什么反应?注意  ^  是我们在终端输入Ctrl  时的表示形式:

$ python sigint.py
+24^C
+I got a SIGINT, but I am not stopping
+26^C
+I got a SIGINT, but I am not stopping
+30^\[1]    39913 quit       python sigint.pyƒ
+

尽管  SIGINT  和  SIGQUIT  都常常用来发出和终止程序相关的请求。SIGTERM  则是一个更加通用的、也更加优雅地退出信号。为了发出这个信号我们需要使用  [kill](https://www.man7.org/linux/man-pages/man1/kill.1.html)  命令, 它的语法是: kill -TERM <PID>

# 1.2 暂停和后台执行进程

信号可以让进程做其他的事情,而不仅仅是终止它们。例如,SIGSTOP  会让进程暂停。在终端中,键入  Ctrl-Z  会让 shell 发送  SIGTSTP  信号,SIGTSTP是 Terminal Stop 的缩写(即terminal版本的 SIGSTOP)。

我们可以使用  [fg](https://www.man7.org/linux/man-pages/man1/fg.1p.html)  或  [bg](http://man7.org/linux/man-pages/man1/bg.1p.html)  命令恢复暂停的工作。它们分别表示在前台继续或在后台继续。

[jobs](http://man7.org/linux/man-pages/man1/jobs.1p.html)  命令会列出当前终端会话中尚未完成的全部任务。您可以使用 pid 引用这些任务(也可以用  [pgrep](https://www.man7.org/linux/man-pages/man1/pgrep.1.html)  找出 pid)。更加符合直觉的操作是您可以使用百分号 + 任务编号(jobs  会打印任务编号)来选取该任务。如果要选择最近的一个任务,可以使用  $!  这一特殊参数。

还有一件事情需要掌握,那就是命令中的  &  后缀可以让命令在直接在后台运行,这使得您可以直接在 shell 中继续做其他操作,不过它此时还是会使用 shell 的标准输出,这一点有时会比较恼人(这种情况可以使用 shell 重定向处理)。

让已经在运行的进程转到后台运行,您可以键入Ctrl-Z ,然后紧接着再输入bg。注意,后台的进程仍然是您的终端进程的子进程,一旦您关闭终端(会发送另外一个信号SIGHUP),这些后台的进程也会终止。为了防止这种情况发生,您可以使用  [nohup](https://www.man7.org/linux/man-pages/man1/nohup.1.html) (一个用来忽略  SIGHUP  的封装) 来运行程序。针对已经运行的程序,可以使用disown 。除此之外,您可以使用终端多路复用器来实现,下一章节我们会进行详细地探讨。

下面这个简单的会话中展示来了些概念的应用:

$ sleep 1000
+^Z
+[1]  + 18653 suspended  sleep 1000
+
+$ nohup sleep 2000 &
+[2] 18745
+appending output to nohup.out
+
+$ jobs
+[1]  + suspended  sleep 1000
+[2]  - running    nohup sleep 2000
+
+$ bg %1
+[1]  - 18653 continued  sleep 1000
+
+$ jobs
+[1]  - running    sleep 1000
+[2]  + running    nohup sleep 2000
+
+$ kill -STOP %1
+[1]  + 18653 suspended (signal)  sleep 1000
+
+$ jobs
+[1]  + suspended (signal)  sleep 1000
+[2]  - running    nohup sleep 2000
+
+$ kill -SIGHUP %1
+[1]  + 18653 hangup     sleep 1000
+
+$ jobs
+[2]  + running    nohup sleep 2000
+
+$ kill -SIGHUP %2
+
+$ jobs
+[2]  + running    nohup sleep 2000
+
+$ kill %2
+[2]  + 18745 terminated  nohup sleep 2000
+
+$ jobs
+

SIGKILL  是一个特殊的信号,它不能被进程捕获并且它会马上结束该进程。不过这样做会有一些副作用,例如留下孤儿进程。

您可以在  这里 (opens new window)  或输入  [man signal](https://www.man7.org/linux/man-pages/man7/signal.7.html)  或使用  kill -l  来获取更多关于信号的信息。

# 2. 终端多路复用

当您在使用命令行时,您通常会希望同时执行多个任务。举例来说,您可以想要同时运行您的编辑器,并在终端的另外一侧执行程序。尽管再打开一个新的终端窗口也能达到目的,使用终端多路复用器则是一种更好的办法。

像  [tmux](https://www.man7.org/linux/man-pages/man1/tmux.1.html)  这类的终端多路复用器可以允许我们基于面板和标签分割出多个终端窗口,这样您便可以同时与多个 shell 会话进行交互。

不仅如此,终端多路复用使我们可以分离当前终端会话并在将来重新连接。

这让您操作远端设备时的工作流大大改善,避免了  nohup  和其他类似技巧的使用。

现在最流行的终端多路器是  [tmux](https://www.man7.org/linux/man-pages/man1/tmux.1.html)tmux  是一个高度可定制的工具,您可以使用相关快捷键创建多个标签页并在它们间导航。

tmux  的快捷键需要我们掌握,它们都是类似  <C-b> x  这样的组合,即需要先按下Ctrl+b,松开后再按下  xtmux  中对象的继承结构如下:

  • 会话  - 每个会话都是一个独立的工作区,其中包含一个或多个窗口 +
    • tmux  开始一个新的会话
    • tmux new -s NAME  以指定名称开始一个新的会话
    • tmux ls  列出当前所有会话
    • 在  tmux  中输入  <C-b> d ,将当前会话分离
    • tmux a  重新连接最后一个会话。您也可以通过  t  来指定具体的会话
  • 窗口  - 相当于编辑器或是浏览器中的标签页,从视觉上将一个会话分割为多个部分 +
    • <C-b> c  创建一个新的窗口,使用  <C-d>关闭
    • <C-b> N  跳转到第  N  个窗口,注意每个窗口都是有编号的
    • <C-b> p  切换到前一个窗口
    • <C-b> n  切换到下一个窗口
    • <C-b> ,  重命名当前窗口
    • <C-b> w  列出当前所有窗口
  • 面板  - 像 vim 中的分屏一样,面板使我们可以在一个屏幕里显示多个 shell +
    • <C-b> "  水平分割
    • <C-b> %  垂直分割
    • <C-b> <方向>  切换到指定方向的面板,<方向> 指的是键盘上的方向键
    • <C-b> z  切换当前面板的缩放
    • <C-b> [  开始往回卷动屏幕。您可以按下空格键来开始选择,回车键复制选中的部分
    • <C-b> <空格>  在不同的面板排布间切换

扩展阅读: 这里 (opens new window)  是一份  tmux  快速入门教程, 而这一篇 (opens new window)  文章则更加详细,它包含了  screen  命令。您也许想要掌握  [screen](https://www.man7.org/linux/man-pages/man1/screen.1.html)  命令,因为在大多数 UNIX 系统中都默认安装有该程序。

# 3. 别名

输入一长串包含许多选项的命令会非常麻烦。因此,大多数 shell 都支持设置别名。shell 的别名相当于一个长命令的缩写,shell 会自动将其替换成原本的命令。例如,bash 中的别名语法如下:

alias alias_name="command_to_alias arg1 arg2"
+

注意, =两边是没有空格的,因为  [alias](https://www.man7.org/linux/man-pages/man1/alias.1p.html)  是一个 shell 命令,它只接受一个参数。

# 创建常用命令的缩写
+alias ll="ls -lh"
+
+# 能够少输入很多
+alias gs="git status"
+alias gc="git commit"
+alias v="vim"
+
+# 手误打错命令也没关系
+alias sl=ls
+
+# 重新定义一些命令行的默认行为
+alias mv="mv -i"           # -i prompts before overwrite
+alias mkdir="mkdir -p"     # -p make parent dirs as needed
+alias df="df -h"           # -h prints human readable format
+
+# 别名可以组合使用
+alias la="ls -A"
+alias lla="la -l"
+
+# 在忽略某个别名: 命令前加上反斜杠 \
+\ls
+# 或者禁用别名
+unalias la
+
+# 获取别名的定义
+alias ll
+# 会打印 ll='ls -lh'
+

值得注意的是,在默认情况下 shell 并不会保存别名。为了让别名持续生效,您需要将配置放进 shell 的启动文件里,像是.bashrc  或  .zshrc

# 4. 配置文件(Dotfiles)

很多程序的配置都是通过纯文本格式的被称作点文件的配置文件来完成的(之所以称为点文件,是因为它们的文件名以  .  开头,例如  ~/.vimrc。也正因为此,它们默认是隐藏文件,ls并不会显示它们)。

shell 的配置也是通过这类文件完成的。在启动时,您的 shell 程序会读取很多文件以加载其配置项。根据 shell 本身的不同,您从登录开始还是以交互的方式完成这一过程可能会有很大的不同。关于这一话题,这里 (opens new window)  有非常好的资源

对于  bash来说,在大多数系统下,您可以通过编辑  .bashrc  或  .bash_profile  来进行配置。在文件中您可以添加需要在启动时执行的命令,例如上文我们讲到过的别名,或者是您的环境变量。

实际上,很多程序都要求您在 shell 的配置文件中包含一行类似  export PATH="$PATH:/path/to/program/bin"  的命令,这样才能确保这些程序能够被 shell 找到。

还有一些其他的工具也可以通过点文件进行配置:

  • bash - ~/.bashrc~/.bash_profile
  • git - ~/.gitconfig
  • vim - ~/.vimrc  和  ~/.vim  目录
  • ssh - ~/.ssh/config
  • tmux - ~/.tmux.conf

我们应该如何管理这些配置文件呢,它们应该在它们的文件夹下,并使用版本控制系统进行管理,然后通过脚本将其   符号链接   到需要的地方。这么做有如下好处:

  • 安装简单: 如果您登录了一台新的设备,在这台设备上应用您的配置只需要几分钟的时间;
  • 可移植性: 您的工具在任何地方都以相同的配置工作
  • 同步: 在一处更新配置文件,可以同步到其他所有地方
  • 变更追踪: 您可能要在整个程序员生涯中持续维护这些配置文件,而对于长期项目而言,版本历史是非常重要的

配置文件中需要放些什么?您可以通过在线文档和帮助手册 (opens new window)了解所使用工具的设置项。另一个方法是在网上搜索有关特定程序的文章,作者们在文章中会分享他们的配置。还有一种方法就是直接浏览其他人的配置文件:您可以在这里找到无数的dotfiles 仓库 (opens new window) —— 其中最受欢迎的那些可以在这里 (opens new window)找到(我们建议您不要直接复制别人的配置)。这里 (opens new window)  也有一些非常有用的资源。

本课程的老师们也在 GitHub 上开源了他们的配置文件: Anish (opens new window)Jon (opens new window)Jose (opens new window).

# 4.1 可移植性

配置文件的一个常见的痛点是它可能并不能在多种设备上生效。例如,如果您在不同设备上使用的操作系统或者 shell 是不同的,则配置文件是无法生效的。或者,有时您仅希望特定的配置只在某些设备上生效。

有一些技巧可以轻松达成这些目的。如果配置文件 if 语句,则您可以借助它针对不同的设备编写不同的配置。例如,您的 shell 可以这样做:

if [[ "$(uname)" == "Linux" ]]; then {do_something}; fi
+
+# 使用和 shell 相关的配置时先检查当前 shell 类型
+if [[ "$SHELL" == "zsh" ]]; then {do_something}; fi
+
+# 您也可以针对特定的设备进行配置
+if [[ "$(hostname)" == "myServer" ]]; then {do_something}; fi
+

如果配置文件支持 include 功能,您也可以多加利用。例如:~/.gitconfig  可以这样编写:

[include]
+    path = ~/.gitconfig_local
+

然后我们可以在日常使用的设备上创建配置文件  ~/.gitconfig_local  来包含与该设备相关的特定配置。您甚至应该创建一个单独的代码仓库来管理这些与设备相关的配置。

如果您希望在不同的程序之间共享某些配置,该方法也适用。例如,如果您想要在  bash  和  zsh  中同时启用一些别名,您可以把它们写在  .aliases  里,然后在这两个 shell 里应用:

# Test if ~/.aliases exists and source it
+if [ -f ~/.aliases ]; then
+    source ~/.aliases
+fi
+

# 5. 远端设备

对于程序员来说,在他们的日常工作中使用远程服务器已经非常普遍了。如果您需要使用远程服务器来部署后端软件或您需要一些计算能力强大的服务器,您就会用到安全 shell(SSH)。和其他工具一样,SSH 也是可以高度定制的,也值得我们花时间学习它。

通过如下命令,您可以使用  ssh  连接到其他服务器:

ssh foo@bar.mit.edu
+

这里我们尝试以用户名  foo  登录服务器  bar.mit.edu。服务器可以通过 URL 指定(例如bar.mit.edu),也可以使用 IP 指定(例如foobar@192.168.1.42)。后面我们会介绍如何修改 ssh 配置文件使我们可以用类似  ssh bar  这样的命令来登录服务器。

# 5.1 执行命令

ssh  的一个经常被忽视的特性是它可以直接远程执行命令。 ssh foobar@server ls  可以直接在用 foobar 的命令下执行  ls  命令。 想要配合管道来使用也可以, ssh foobar@server ls | grep PATTERN  会在本地查询远端  ls  的输出而  ls | ssh foobar@server grep PATTERN  会在远端对本地  ls  输出的结果进行查询。

# 5.2 SSH 密钥

基于密钥的验证机制使用了密码学中的公钥,我们只需要向服务器证明客户端持有对应的私钥,而不需要公开其私钥。这样您就可以避免每次登录都输入密码的麻烦了秘密就可以登录。不过,私钥(通常是  ~/.ssh/id_rsa  或者  ~/.ssh/id_ed25519) 等效于您的密码,所以一定要好好保存它。

# 5.2.1 密钥生成

使用  [ssh-keygen](http://man7.org/linux/man-pages/man1/ssh-keygen.1.html)  命令可以生成一对密钥:

ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519
+

您可以为密钥设置密码,防止有人持有您的私钥并使用它访问您的服务器。您可以使用  [ssh-agent](https://www.man7.org/linux/man-pages/man1/ssh-agent.1.html)  或  [gpg-agent](https://linux.die.net/man/1/gpg-agent) ,这样就不需要每次都输入该密码了。

如果您曾经配置过使用 SSH 密钥推送到 GitHub,那么可能您已经完成了这里 (opens new window)  介绍的这些步骤,并且已经有了一个可用的密钥对。要检查您是否持有密码并验证它,您可以运行  ssh-keygen -y -f /path/to/key.

# 5.2.2 基于密钥的认证机制

ssh  会查询  .ssh/authorized_keys  来确认那些用户可以被允许登录。您可以通过下面的命令将一个公钥拷贝到这里:

cat .ssh/id_ed25519.pub | ssh foobar@remote 'cat >> ~/.ssh/authorized_keys'
+
+# 如果支持 ssh-copy-id 的话,可以使用下面这种更简单的解决方案:
+ssh-copy-id -i .ssh/id_ed25519.pub foobar@remote
+

在 GitHub(或其他类似的服务)上使用 SSH 密钥时,邮箱地址作为一个注释或标识附加到公钥的末尾。这并不是 SSH 密钥本身所必需的,而是为了帮助识别公钥的所有者。当你在多个设备上生成不同的 SSH 密钥并将它们添加到 GitHub 时,邮箱地址可以帮助你区分每个密钥对应的设备或用途。

在使用 ssh-keygen 生成密钥时,通常在命令行最后提示你输入一个文件名来保存新的密钥时,你可以附加一个注释,如你的电子邮箱。例如:

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
+

这里 -C "your_email@example.com" 就是为生成的公钥添加一个标签或注释,通常是你的电子邮件地址。当你将公钥添加到 GitHub 时,这个邮箱地址会一同显示,但它不影响密钥的功能。这个注释在公钥的末尾,不参与密钥认证过程,仅仅是为了方便用户识别。

一个电脑可以拥有多个 SSH 密钥对,而不仅限于一个。SSH 密钥对通常包括两部分:一个私钥和一个公钥。私钥应该保密不外泄,而公钥可以安全地分享给任何人或任何服务。

在同一台电脑上生成多个 SSH 密钥对可以用于不同目的,比如你可能想为不同的服务器或服务使用不同的密钥对,或者你可能需要不同类型或不同加密强度的密钥对。生成不同的密钥对可以提高安全性,因为即使一个密钥对被破解或泄露,其他密钥对仍然是安全的。

使用 ssh-keygen 命令生成密钥对时,如果不指定输出文件(使用 -f 选项),默认会在 ~/.ssh 目录下生成名为 id_rsa 的私钥和名为 id_rsa.pub 的公钥。如果该文件已经存在,ssh-keygen 会提示是否覆盖。为了生成多个密钥对,你可以指定不同的文件名来保存新的密钥对,例如:

ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_github
+ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_gitlab
+

这样,你就可以为不同的服务创建专用的密钥对。在连接时,你可以在 SSH 客户端配置文件(~/.ssh/config)中指定使用哪个密钥对,或者在使用 ssh 命令时通过 -i 选项指定私钥的路径。

记得,每个生成的公钥(例如 id_rsa_github.pubid_ed25519_gitlab.pub)可以上传到相应的服务上(如 GitHub 或 GitLab),而对应的私钥则应该安全地存储在你的设备上,不应该泄露或被无关人员访问。

# 5.3 通过 SSH 复制文件

使用 ssh 复制文件有很多方法:

  • ssh+tee, 最简单的方法是执行  ssh  命令,然后通过这样的方法利用标准输入实现  cat localfile | ssh remote_server tee serverfile。回忆一下,[tee](https://www.man7.org/linux/man-pages/man1/tee.1.html)  命令会将标准输出写入到一个文件;
  • [scp](https://www.man7.org/linux/man-pages/man1/scp.1.html) :当需要拷贝大量的文件或目录时,使用scp  命令则更加方便,因为它可以方便的遍历相关路径。语法如下:scp path/to/local_file remote_host:path/to/remote_file
  • [rsync](https://www.man7.org/linux/man-pages/man1/rsync.1.html)  对  scp  进行了改进,它可以检测本地和远端的文件以防止重复拷贝。它还可以提供一些诸如符号连接、权限管理等精心打磨的功能。甚至还可以基于  -partial标记实现断点续传。rsync  的语法和scp类似;

# 5.4 端口转发

LocalForward 9999 localhost:8888
+

LocalForward 9999 localhost:8888 是 SSH 配置文件中的一个指令,用于设置本地端口转发。这一行指令的出现在 SSH 配置文件(通常是 ~/.ssh/config)中表示以下行为:

  • 当你通过 SSH 连接到指定的主机时,SSH 客户端会创建一个本地监听端口(在这个例子中是 9999)。
  • 任何发送到你本地机器上的 9999 端口的数据都会被转发到通过 SSH 连接的远程机器上的 localhost:8888 地址和端口上。
  • 在这个上下文中,localhost 是指远程机器的本地回环接口,而不是你的本地机器。所以,实际上数据是从本地机器的 9999 端口转发到远程机器的 8888 端口。

在实际应用中,这种端口转发可以用于多种情况,例如:

  • 访问在远程主机上运行的 web 应用或服务,就像它们在本地主机上一样。
  • 通过 SSH 保护未加密的网络通信,因为数据传输会在 SSH 的加密隧道中进行。
  • 绕过防火墙或网络限制,访问仅在远程网络上可访问的资源。

在你提供的配置中,如果有服务在远程主机的 localhost:8888 上监听,你可以简单地通过访问你本地机器上的 localhost:9999 来访问它,所有通信都会安全地通过 SSH 隧道转发。

# 5.5 SSH 配置

使用  ~/.ssh/config

Host vm
+    User foobar
+    HostName 172.16.174.141
+    Port 2222
+    IdentityFile ~/.ssh/id_ed25519
+    LocalForward 9999 localhost:8888
+
+# 在配置文件中也可以使用通配符
+Host *.mit.edu
+    User foobaz
+

这么做的好处是,使用  ~/.ssh/config  文件来创建别名,类似  scprsyncmosh的这些命令都可以读取这个配置并将设置转换为对应的命令行选项。

注意,~/.ssh/config  文件也可以被当作配置文件,而且一般情况下也是可以被导入其他配置文件的。不过,如果您将其公开到互联网上,那么其他人都将会看到您的服务器地址、用户名、开放端口等等。这些信息可能会帮助到那些企图攻击您系统的黑客,所以请务必三思。

服务器侧的配置通常放在  /etc/ssh/sshd_config。您可以在这里配置免密认证、修改 ssh 端口、开启 X11 转发等等。 您也可以为每个用户单独指定配置。

# 6. Exercise

# 6.1 任务控制

# 6.1.1 pgrep & pkill

我们可以使用类似  ps aux | grep  这样的命令来获取任务的 pid ,然后您可以基于 pid 来结束这些进程。但我们其实有更好的方法来做这件事。在终端中执行  sleep 10000  这个任务。然后用  Ctrl-Z  将其切换到后台并使用  bg来继续允许它。现在,使用  [pgrep](https://www.man7.org/linux/man-pages/man1/pgrep.1.html)  来查找 pid 并使用  [pkill](https://www.man7.org/linux/man-pages/man1/pgrep.1.html)  结束进程而不需要手动输入 pid。(提示:: 使用  -af  标记)。

Untitled

# 6.1.2 pidwait

如果您希望某个进程结束后再开始另外一个进程, 应该如何实现呢?在这个练习中,我们使用  sleep 60 &  作为先执行的程序。一种方法是使用  [wait](http://man7.org/linux/man-pages/man1/wait.1p.html)  命令。尝试启动这个休眠命令,然后待其结束后再执行  ls  命令。

但是,如果我们在不同的 bash 会话中进行操作,则上述方法就不起作用了。因为  wait  只能对子进程起作用。之前我们没有提过的一个特性是,kill  命令成功退出时其状态码为 0 ,其他状态则是非 0。kill -0  则不会发送信号,但是会在进程不存在时返回一个不为 0 的状态码。请编写一个 bash 函数  pidwait ,它接受一个 pid 作为输入参数,然后一直等待直到该进程结束。您需要使用  sleep  来避免浪费 CPU 性能。

#! /usr/bin/env zsh
+pidwait(){
+    # here while loop will keep checking if the process is still running
+    # if the process is still running, it will sleep for 1 second and then check again
+    # if the process is not running, it will list the files in the current directory
+    # kill -0 returns 0 if the process is running, 1 if the process is not running
+    # while 0 is returned, the loop will keep running
+    while kill -0 $1; do
+        sleep 1
+    done
+    ls
+}
+

Untitled

# 6.2 配置文件

#!/usr/bin/env zsh
+
+# copy.sh
+
+# copy all dotfiles to ./dotfiles
+# mkdir ./dotfiles if it doesn't exist
+if [ ! -d "./dotfiles" ]; then
+  mkdir ./dotfiles
+fi
+cp ~/.zshrc ./dotfiles
+cp ~/.vimrc ./dotfiles
+
+echo "Copied dotfiles to ./dotfiles"
+ls -lah ./dotfiles
+
#!/bin/bash
+
+# autoconfig.sh
+
+files=$(ls -a $1 | grep -E '.[^.]+' |grep -v .git)
+# 去掉 ls -a 返回结果中的 ". .. .git"
+for file in `echo $files`; do
+    ln -s $1/$file ~/$file # 创建软链接
+done
+
+ + + diff --git "a/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.25-6.Version Control (Git).html" "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.25-6.Version Control (Git).html" new file mode 100644 index 0000000..61051ab --- /dev/null +++ "b/Chip/Chip/\344\270\200\347\224\237\344\270\200\350\212\257\350\256\241\345\210\222/\351\242\204\345\255\246\344\271\240\351\230\266\346\256\265/The Missing Semester/2024.03.25-6.Version Control (Git).html" @@ -0,0 +1,235 @@ + + + + + + 2024.03.25-6. Version Control (Git) | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.25-6. Version Control (Git)

版本控制系统 (VCSs) 是一类用于追踪源代码(或其他文件、文件夹)改动的工具。顾名思义,这些工具可以帮助我们管理代码的修改历史;不仅如此,它还可以让协作编码变得更方便。VCS 通过一系列的快照将某个文件夹及其内容保存了起来,每个快照都包含了文件或文件夹的完整状态。同时它还维护了快照创建者的信息以及每个快照的相关信息等等。

为什么说版本控制系统非常有用?即使您只是一个人进行编程工作,它也可以帮您创建项目的快照,记录每个改动的目的、基于多分支并行开发等等。和别人协作开发时,它更是一个无价之宝,您可以看到别人对代码进行的修改,同时解决由于并行开发引起的冲突。

现代的版本控制系统可以帮助您轻松地(甚至自动地)回答以下问题:

  • 当前模块是谁编写的?
  • 这个文件的这一行是什么时候被编辑的?是谁作出的修改?修改原因是什么呢?
  • 最近的 1000 个版本中,何时/为什么导致了单元测试失败?

尽管版本控制系统有很多, 其事实上的标准则是  Git 。

# 1. Git 的数据模型

# 1.1 快照

Git 将顶级目录中的文件和文件夹作为集合,并通过一系列快照来管理其历史记录。在 Git 的术语里,文件被称作 Blob 对象(数据对象),也就是一组数据。目录则被称之为“树”,它将名字与 Blob 对象或树对象进行映射(使得目录中可以包含其他目录)。快照则是被追踪的最顶层的树。例如,一个树看起来可能是这样的:

<root> (tree)
+|
++- foo (tree)
+|  |
+|  + bar.txt (blob, contents = "hello world")
+|
++- baz.txt (blob, contents = "git is wonderful")
+

这个顶层的树包含了两个元素,一个名为 “foo” 的树(它本身包含了一个 blob 对象 “bar.txt”),以及一个 blob 对象 “baz.txt”。

# 1.2 历史记录建模:关联快照

版本控制系统和快照有什么关系呢?线性历史记录是一种最简单的模型,它包含了一组按照时间顺序线性排列的快照。不过出于种种原因,Git 并没有采用这样的模型。

在 Git 中,历史记录是一个由快照组成的有向无环图。有向无环图,听上去似乎是什么高大上的数学名词。不过不要怕,您只需要知道这代表 Git 中的每个快照都有一系列的“父辈”,也就是其之前的一系列快照。注意,快照具有多个“父辈”而非一个,因为某个快照可能由多个父辈而来。例如,经过合并后的两条分支。

在 Git 中,这些快照被称为“提交”。通过可视化的方式来表示这些历史提交记录时,看起来差不多是这样的:

o <-- o <-- o <-- o
+            ^
+             \
+              --- o <-- o
+

上面是一个 ASCII 码构成的简图,其中的  o  表示一次提交(快照)。

箭头指向了当前提交的父辈(这是一种“在…之前”,而不是“在…之后”的关系)。在第三次提交之后,历史记录分岔成了两条独立的分支。这可能因为此时需要同时开发两个不同的特性,它们之间是相互独立的。开发完成后,这些分支可能会被合并并创建一个新的提交,这个新的提交会同时包含这些特性。新的提交会创建一个新的历史记录,看上去像这样(最新的合并提交用粗体标记):

o <-- o <-- o <-- o <---- o
+            ^            /
+             \          v
+              --- o <-- o
+

Git 中的提交是不可改变的。但这并不代表错误不能被修改,只不过这种“修改”实际上是创建了一个全新的提交记录。而引用(参见下文)则被更新为指向这些新的提交。

# 1.3 数据模型及其伪代码表示

以伪代码的形式来学习 Git 的数据模型,可能更加清晰:

// 文件就是一组数据
+type blob = array<byte>
+
+// 一个包含文件和目录的目录
+type tree = map<string, tree | blob>
+
+// 每个提交都包含一个父辈,元数据和顶层树
+type commit = struct {
+    parent: array<commit>
+    author: string
+    message: string
+    snapshot: tree
+}
+

这是一种简洁的历史模型。

# 1.4 对象和内存寻址

Git 中的对象可以是 blob、树或提交:

type object = blob | tree | commit
+

Git 在储存数据时,所有的对象都会基于它们的  SHA-1 哈希 (opens new window)  进行寻址。

objects = map<string, object>
+
+def store(object):
+    id = sha1(object)
+    objects[id] = object
+
+def load(id):
+    return objects[id]
+

Blobs、树和提交都一样,它们都是对象。当它们引用其他对象时,它们并没有真正的在硬盘上保存这些对象,而是仅仅保存了它们的哈希值作为引用。

例如,上面 (opens new window)例子中的树(可以通过  git cat-file -p 698281bc680d1995c5f4caaf3359721a5a58d48d  来进行可视化),看上去是这样的:

100644 blob 4448adbf7ecd394f42ae135bbeed9676e894af85    baz.txt
+040000 tree c68d233a33c5c06e0340e4c224f0afca87c8ce87    foo
+

树本身会包含一些指向其他内容的指针,例如  baz.txt (blob) 和  foo (树)。如果我们用  git cat-file -p 4448adbf7ecd394f42ae135bbeed9676e894af85,即通过哈希值查看 baz.txt 的内容,会得到以下信息:

git is wonderful
+

# 1.5 引用

现在,所有的快照都可以通过它们的 SHA-1 哈希值来标记了。但这也太不方便了,谁也记不住一串 40 位的十六进制字符。

针对这一问题,Git 的解决方法是给这些哈希值赋予人类可读的名字,也就是引用(references)。引用是指向提交的指针。与对象不同的是,它是可变的(引用可以被更新,指向新的提交)。例如,master  引用通常会指向主分支的最新一次提交。

references = map<string, string>
+
+def update_reference(name, id):
+    references[name] = id
+
+def read_reference(name):
+    return references[name]
+
+def load_reference(name_or_id):
+    if name_or_id in references:
+        return load(references[name_or_id])
+    else:
+        return load(name_or_id)
+

这样,Git 就可以使用诸如 “master” 这样人类可读的名称来表示历史记录中某个特定的提交,而不需要在使用一长串十六进制字符了。

有一个细节需要我们注意, 通常情况下,我们会想要知道“我们当前所在位置”,并将其标记下来。这样当我们创建新的快照的时候,我们就可以知道它的相对位置(如何设置它的“父辈”)。在 Git 中,我们当前的位置有一个特殊的索引,它就是 “HEAD”。

# 1.6 仓库

最后,我们可以粗略地给出 Git 仓库的定义了:对象  和  引用

在硬盘上,Git 仅存储对象和引用:因为其数据模型仅包含这些东西。所有的  git  命令都对应着对提交树的操作,例如增加对象,增加或删除引用。

当您输入某个指令时,请思考一下这条命令是如何对底层的图数据结构进行操作的。另一方面,如果您希望修改提交树,例如“丢弃未提交的修改和将 ‘master’ 引用指向提交  5d83f9e  时,有什么命令可以完成该操作(针对这个具体问题,您可以使用  git checkout master; git reset --hard 5d83f9e

# 2. 暂存区

Git 中还包括一个和数据模型完全不相关的概念,但它确是创建提交的接口的一部分。

就上面介绍的快照系统来说,您也许会期望它的实现里包括一个 “创建快照” 的命令,该命令能够基于当前工作目录的当前状态创建一个全新的快照。有些版本控制系统确实是这样工作的,但 Git 不是。我们希望简洁的快照,而且每次从当前状态创建快照可能效果并不理想。例如,考虑如下场景,您开发了两个独立的特性,然后您希望创建两个独立的提交,其中第一个提交仅包含第一个特性,而第二个提交仅包含第二个特性。或者,假设您在调试代码时添加了很多打印语句,然后您仅仅希望提交和修复 bug 相关的代码而丢弃所有的打印语句。

Git 处理这些场景的方法是使用一种叫做 “暂存区(staging area)”的机制,它允许您指定下次快照中要包括那些改动。

# 3. Git 的命令行接口

# 3.1 基础

  • git help <command>: 获取 git 命令的帮助信息
  • git init: 创建一个新的 git 仓库,其数据会存放在一个名为  .git  的目录下
  • git status: 显示当前的仓库状态
  • git add <filename>: 添加文件到暂存区
  • git commit: 创建一个新的提交 +
  • git log: 显示历史日志
  • git log --all --graph --decorate: 可视化历史记录(有向无环图) --oneline 一行
  • git diff <filename>: 显示与暂存区文件的差异
  • git diff <revision> <filename>: 显示某个文件两个版本之间的差异
  • git checkout <revision>: 更新 HEAD 和目前的分支
  • git checkout <filename>: 把文件回到之前(HEAD)版本

# 3.2 分支和合并

  • git branch: 显示分支
  • git branch <name>: 创建分支
  • git checkout -b <name>: 创建分支并切换到该分支 +
    • 相当于  git branch <name>; git checkout <name>
  • git merge <revision>: 合并到当前分支
  • git mergetool: 使用工具来处理合并冲突
  • git rebase: 将一系列补丁变基(rebase)为新的基线

# 3.3 远端操作

  • git remote: 列出远端
  • git remote add <name> <url>: 添加一个远端
  • git push <remote> <local branch>:<remote branch>: 将对象传送至远端并更新远端引用
  • git branch --set-upstream-to=<remote>/<remote branch>: 创建本地和远端分支的关联关系
  • git fetch: 从远端获取对象/索引
  • git pull: 相当于  git fetch; git merge
  • git clone: 从远端下载仓库

# 3.4 撤销

  • git commit --amend: 编辑提交的内容或信息
  • git reset HEAD <file>: 恢复暂存的文件
  • git checkout -- <file>: 丢弃修改
  • git restore: git2.32 版本后取代 git reset 进行许多撤销操作

# 4. Git 高级操作

  • git config: Git 是一个  高度可定制的 (opens new window)  工具
  • git clone --depth=1: 浅克隆(shallow clone),不包括完整的版本历史信息
  • git add -p: 交互式暂存
  • git rebase -i: 交互式变基
  • git blame: 查看最后修改某行的人
  • git stash: 暂时移除工作目录下的修改内容
  • git bisect: 通过二分查找搜索历史记录
  • .gitignore指定 (opens new window)  故意不追踪的文件

# 5. 杂项

# 6. 资源

# 7. Exercise

# 7.1 Fork 本课程网站的仓库 (opens new window)

  1. 将版本历史可视化并进行探索

    Untitled

  2. 是谁最后修改了  README.md文件?(提示:使用  git log  命令并添加合适的参数)

    Untitled

  3. 最后一次修改_config.yml  文件中  collections:  行时的提交信息是什么?(提示:使用  git blame  和  git show

    Untitled

# 7.2 从 Git 历史中删除

使用 Git 时的一个常见错误是提交本不应该由 Git 管理的大文件,或是将含有敏感信息的文件提交给 Git 。尝试向仓库中添加一个文件并添加提交信息,然后将其从历史中删除 ( 这篇文章也许会有帮助 (opens new window));

从历史记录中删除文件

要从历史记录中彻底删除 secret.txt 文件,你可以使用 git filter-branch 命令或更新的 git filter-repogit filter-repogit filter-branch 的替代品,效率更高但需要单独安装。这里我将展示使用 git filter-branch 的方法,因为它不需要额外安装。

  1. 使用 git filter-branch 删除文件:

    git filter-branch --force --index-filter \
    +"git rm --cached --ignore-unmatch secret.txt" \
    +--prune-empty --tag-name-filter cat -- --all
    +
    • -force: 强制运行,覆盖备份。
    • -index-filter: 对每个修订版本使用的过滤器,这里用于删除 secret.txt
    • git rm --cached --ignore-unmatch secret.txt: 删除指定的文件,即使它在某些修订版本中不存在。
    • -prune-empty: 删除因为文件删除而变成空的提交。
    • -tag-name-filter cat: 保留标签名称不变。
    • -all: 应用于所有分支和标签。

    Untitled

    Untitled

  2. 推送更改到远程仓库:

    删除文件后,你需要强制推送更改到远程仓库,因为这是一次重写历史的操作:

    git push origin --force --all
    +

    这会强制更新所有分支到远程仓库。

  3. 清理和回收空间:

    在本地,运行以下命令来清理 Git 对象并回收空间:

    git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
    +git reflog expire --expire=now --all
    +git gc --prune=now
    +

    Untitled

# 7.3 git stash

从 GitHub 上克隆某个仓库,修改一些文件。当您使用  git stash  会发生什么?当您执行  git log --all --oneline  时会显示什么?通过  git stash pop  命令来撤销  git stash  操作,什么时候会用到这一技巧?

Untitled

Untitled

执行git stash后,添加到暂存区的内容不会再提示需要提交(Changes to be committed)。而且,尽管执行git stash使得提交记录新增了两项,但是可以发现HEAD引用并没有变动。

当我们将改动添加到暂存区(git add)后,通过执行git stash后,可以自由地切换到其他分支(注意:在暂存区存有改动时,切换分支(checkout)是不被允许的)

另外,运用stashstash pop,可以自由选择  stash 存储的改动  即将提交到的分支

# 7.4 .gitconfig

与其他的命令行工具一样,Git 也提供了一个名为 ~/.gitconfig 配置文件 (或 dotfile)。请在 ~/.gitconfig 中创建一个别名,使您在运行 git graph 时,您可以得到 git log –all –graph –decorate –oneline 的输出结果;

[alias]
+    graph = log --all --graph --decorate --oneline
+

Untitled

# 7.5 .gitignore_global

您可以通过执行 git config –global core.excludesfile ~/.gitignore_global 在 ~/.gitignore_global 中创建全局忽略规则。配置您的全局 gitignore 文件来自动忽略系统或编辑器的临时文件,例如 .DS_Store;

git config --global core.excludesfile ~/.gitignore .DS_Store
+
+ + + diff --git a/Chip/index.html b/Chip/index.html new file mode 100644 index 0000000..94a8c11 --- /dev/null +++ b/Chip/index.html @@ -0,0 +1,166 @@ + + + + + + SoC Design | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git a/LeetCode/LeetCode/2024.02.22-BFS.html b/LeetCode/LeetCode/2024.02.22-BFS.html new file mode 100644 index 0000000..4edf05a --- /dev/null +++ b/LeetCode/LeetCode/2024.02.22-BFS.html @@ -0,0 +1,170 @@ + + + + + + 2024.02.22-BFS | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git "a/LeetCode/LeetCode/2024.02.22-BFS/2024.02.22-752.\346\211\223\345\274\200\350\275\254\347\233\230\351\224\201\357\274\210BFS\357\274\211.html" "b/LeetCode/LeetCode/2024.02.22-BFS/2024.02.22-752.\346\211\223\345\274\200\350\275\254\347\233\230\351\224\201\357\274\210BFS\357\274\211.html" new file mode 100644 index 0000000..d8b31d4 --- /dev/null +++ "b/LeetCode/LeetCode/2024.02.22-BFS/2024.02.22-752.\346\211\223\345\274\200\350\275\254\347\233\230\351\224\201\357\274\210BFS\357\274\211.html" @@ -0,0 +1,342 @@ + + + + + + 2024.02.22-752.打开转盘锁(BFS) | Personal Blog --from Outis Li + + + + + + + + +

# 2024.02.22-752.打开转盘锁(BFS)

/*
+ * @lc app=leetcode.cn id=752 lang=cpp
+ *
+ * [752] 打开转盘锁
+ *
+ * https://leetcode.cn/problems/open-the-lock/description/
+ *
+ * algorithms
+ * Medium (52.77%)
+ * Likes:    653
+ * Dislikes: 0
+ * Total Accepted:    128.3K
+ * Total Submissions: 243.1K
+ * Testcase Example:  '["0201","0101","0102","1212","2002"]\n"0202"'
+ *
+ * 你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字: '0', '1', '2', '3', '4', '5', '6', '7', '8',
+ * '9' 。每个拨轮可以自由旋转:例如把 '9' 变为 '0','0' 变为 '9' 。每次旋转都只能旋转一个拨轮的一位数字。
+ *
+ * 锁的初始数字为 '0000' ,一个代表四个拨轮的数字的字符串。
+ *
+ * 列表 deadends 包含了一组死亡数字,一旦拨轮的数字和列表里的任何一个元素相同,这个锁将会被永久锁定,无法再被旋转。
+ *
+ * 字符串 target 代表可以解锁的数字,你需要给出解锁需要的最小旋转次数,如果无论如何不能解锁,返回 -1 。
+ *
+ *
+ *
+ * 示例 1:
+ *
+ *
+ * 输入:deadends = ["0201","0101","0102","1212","2002"], target = "0202"
+ * 输出:6
+ * 解释:
+ * 可能的移动序列为 "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202"。
+ * 注意 "0000" -> "0001" -> "0002" -> "0102" -> "0202" 这样的序列是不能解锁的,
+ * 因为当拨动到 "0102" 时这个锁就会被锁定。
+ *
+ *
+ * 示例 2:
+ *
+ *
+ * 输入: deadends = ["8888"], target = "0009"
+ * 输出:1
+ * 解释:把最后一位反向旋转一次即可 "0000" -> "0009"。
+ *
+ *
+ * 示例 3:
+ *
+ *
+ * 输入: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"],
+ * target = "8888"
+ * 输出:-1
+ * 解释:无法旋转到目标数字且不被锁定。
+ *
+ *
+ *
+ *
+ * 提示:
+ *
+ *
+ * 1 <= deadends.length <= 500
+ * deadends[i].length == 4
+ * target.length == 4
+ * target 不在 deadends 之中
+ * target 和 deadends[i] 仅由若干位数字组成
+ *
+ *
+ */
+
class Solution
+{
+public:
+    int openLock(vector<string> &deadends, string target)
+    {
+        int num = 0;
+        queue<string> q;
+        set<string> visited(deadends.begin(), deadends.end());
+        if (visited.find("0000") != visited.end())
+            return -1;
+        q.push("0000");
+        visited.insert("0000");
+        while (!q.empty())
+        {
+            int ssize = q.size();
+            for (int i = 0; i < ssize; i++)
+            {
+                string str = q.front();
+                q.pop();
+                // if (visited.find(str) != visited.end())
+                //     continue;
+                if (str == target)
+                    return num;
+                for (int j = 0; j < 4; j++)
+                {
+                    string up = turnUp(str, j);
+                    string down = turnDown(str, j);
+                    if (visited.find(up) == visited.end())
+                    {
+                        q.push(up);
+                        visited.insert(up);
+                    }
+                    if (visited.find(down) == visited.end())
+                    {
+                        q.push(down);
+                        visited.insert(down);
+                    }
+                }
+            }
+            num++;
+        }
+        return -1;
+    }
+    string turnUp(string str, int index)
+    {
+        char old = str[index];
+        char nnew = (old != '9') ? (old + 1) : '0';
+        string newString = str;
+        newString[index] = nnew;
+        return newString;
+    }
+    string turnDown(string str, int index)
+    {
+        char old = str[index];
+        char nnew = (old != '0') ? (old - 1) : '9';
+        string newString = str;
+        newString[index] = nnew;
+        return newString;
+    }
+};
+

# Hint:

  1. 修改string的某一个字符直接使用[]索引修改即可
  2. 字符’0‘到’1‘直接加一
  3. deadends中的字符串以及已经访问过的字符串应该在尝试加入队列之前就被过滤掉,以防止它们被进一步处理。而不是从队列中拿出来的时候检查是不是在visited
  4. 起始的“0000”也要检查
  5. 使用双向 BFS 可以加快速度,但是 queue 修改为 set,如下:
int openLock(vector<string> &deadends, string target)
+    {
+        unordered_set<string> dead(deadends.begin(), deadends.end());
+        unordered_set<string> begin, end, *set1, *set2;
+
+        if (dead.find("0000") != dead.end() || dead.find(target) != dead.end())
+            return -1;
+
+        int step = 0;
+        begin.insert("0000");
+        end.insert(target);
+
+        while (!begin.empty() && !end.empty())
+        {
+            // 优化搜索,总是从较小的集合开始扩展
+            if (begin.size() > end.size())
+            {
+                set1 = &end;
+                set2 = &begin;
+            }
+            else
+            {
+                set1 = &begin;
+                set2 = &end;
+            }
+            unordered_set<string> temp;
+            for (auto it = set1->begin(); it != set1->end(); ++it)
+            {
+                string str = *it;
+                if (set2->find(str) != set2->end())
+                    return step;
+                if (dead.find(str) != dead.end())
+                    continue;
+                dead.insert(str); // 标记为已访问
+                for (int j = 0; j < 4; ++j)
+                {
+                    string up = turnUp(str, j);
+                    string down = turnDown(str, j);
+                    if (dead.find(up) == dead.end())
+                        temp.insert(up);
+                    if (dead.find(down) == dead.end())
+                        temp.insert(down);
+                }
+            }
+            step++;
+            *set1 = temp; // 更新当前正在扩展的集合
+        }
+        return -1; // 如果没有找到有效路径
+    }
+
  1. 创建一个临时集合(temp)的原因是在每一轮搜索中,我们需要更新当前层次的节点。由于在遍历当前层次的节点时不能直接修改正在遍历的集合(这会影响迭代器的有效性),因此我们先将新发现的节点存储在一个临时集合中。在当前层次的所有节点都遍历完毕后,我们再用这个临时集合来更新主集合,为下一轮搜索做准备。
+ + + diff --git "a/LeetCode/LeetCode/2024.03.05-\344\272\214\345\217\211\346\240\221.html" "b/LeetCode/LeetCode/2024.03.05-\344\272\214\345\217\211\346\240\221.html" new file mode 100644 index 0000000..21ff42a --- /dev/null +++ "b/LeetCode/LeetCode/2024.03.05-\344\272\214\345\217\211\346\240\221.html" @@ -0,0 +1,174 @@ + + + + + + 2024.03.05-二叉树 | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git "a/LeetCode/LeetCode/2024.03.05-\344\272\214\345\217\211\346\240\221/2024.03.05-104.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\346\267\261\345\272\246.html" "b/LeetCode/LeetCode/2024.03.05-\344\272\214\345\217\211\346\240\221/2024.03.05-104.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\346\267\261\345\272\246.html" new file mode 100644 index 0000000..7353d36 --- /dev/null +++ "b/LeetCode/LeetCode/2024.03.05-\344\272\214\345\217\211\346\240\221/2024.03.05-104.\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\244\247\346\267\261\345\272\246.html" @@ -0,0 +1,265 @@ + + + + + + 2024.03.05-104.二叉树的最大深度 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.05-104.二叉树的最大深度

/*
+ * @lc app=leetcode.cn id=104 lang=cpp
+ *
+ * [104] 二叉树的最大深度
+ *
+ * https://leetcode.cn/problems/maximum-depth-of-binary-tree/description/
+ *
+ * algorithms
+ * Easy (77.10%)
+ * Likes:    1786
+ * Dislikes: 0
+ * Total Accepted:    1.2M
+ * Total Submissions: 1.6M
+ * Testcase Example:  '[3,9,20,null,null,15,7]'
+ *
+ * 给定一个二叉树 root ,返回其最大深度。
+ *
+ * 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
+ *
+ *
+ *
+ * 示例 1:
+ *
+ *
+ *
+ *
+ *
+ *
+ * 输入:root = [3,9,20,null,null,15,7]
+ * 输出:3
+ *
+ *
+ * 示例 2:
+ *
+ *
+ * 输入:root = [1,null,2]
+ * 输出:2
+ *
+ *
+ *
+ *
+ * 提示:
+ *
+ *
+ * 树中节点的数量在 [0, 10^4] 区间内。
+ * -100 <= Node.val <= 100
+ *
+ *
+ */
+
+// @lc code=start
+/
+ * Definition for a binary tree node.
+ * struct TreeNode {
+ *     int val;
+ *     TreeNode *left;
+ *     TreeNode *right;
+ *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
+ *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
+ *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
+ * };
+ */
+// @lc code=end
+
  1. 递归:分解成左右子树
class Solution
+{
+public:
+    int res;
+    int maxDepth(TreeNode *root)
+    {
+        if (root == nullptr)
+            return 0;
+        int tempLeft = maxDepth(root->left);
+        int tempRight = maxDepth(root->right);
+        return res = max(tempLeft, tempRight) + 1;
+    }
+};
+
  1. 遍历:进入节点(前序)加深度,离开节点(后序)减深度,叶子结点处更新结果
class Solution {
+public:
+    int res, temp;
+    int maxDepth(TreeNode* root) {
+        traverse(root);
+        return res;
+    }
+private:
+    void traverse(TreeNode* node){
+        if(node == nullptr){
+            res = max(res,temp);
+            return;
+        }
+        temp++;
+        traverse(node->left);
+        traverse(node->right);
+        temp--;
+    }
+};
+
+ + + diff --git "a/LeetCode/LeetCode/2024.03.05-\344\272\214\345\217\211\346\240\221/2024.03.05-144.\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.html" "b/LeetCode/LeetCode/2024.03.05-\344\272\214\345\217\211\346\240\221/2024.03.05-144.\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.html" new file mode 100644 index 0000000..0fff1e2 --- /dev/null +++ "b/LeetCode/LeetCode/2024.03.05-\344\272\214\345\217\211\346\240\221/2024.03.05-144.\344\272\214\345\217\211\346\240\221\347\232\204\345\211\215\345\272\217\351\201\215\345\216\206.html" @@ -0,0 +1,292 @@ + + + + + + 2024.03.05-144.二叉树的前序遍历 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.05-144.二叉树的前序遍历

/*
+ * @lc app=leetcode.cn id=144 lang=cpp
+ *
+ * [144] 二叉树的前序遍历
+ *
+ * https://leetcode.cn/problems/binary-tree-preorder-traversal/description/
+ *
+ * algorithms
+ * Easy (71.71%)
+ * Likes:    1230
+ * Dislikes: 0
+ * Total Accepted:    1M
+ * Total Submissions: 1.4M
+ * Testcase Example:  '[1,null,2,3]'
+ *
+ * 给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
+ * 
+ * 
+ * 
+ * 示例 1:
+ * 
+ * 
+ * 输入:root = [1,null,2,3]
+ * 输出:[1,2,3]
+ * 
+ * 
+ * 示例 2:
+ * 
+ * 
+ * 输入:root = []
+ * 输出:[]
+ * 
+ * 
+ * 示例 3:
+ * 
+ * 
+ * 输入:root = [1]
+ * 输出:[1]
+ * 
+ * 
+ * 示例 4:
+ * 
+ * 
+ * 输入:root = [1,2]
+ * 输出:[1,2]
+ * 
+ * 
+ * 示例 5:
+ * 
+ * 
+ * 输入:root = [1,null,2]
+ * 输出:[1,2]
+ * 
+ * 
+ * 
+ * 
+ * 提示:
+ * 
+ * 
+ * 树中节点数目在范围 [0, 100] 内
+ * -100 
+ * 
+ * 
+ * 
+ * 
+ * 进阶:递归算法很简单,你可以通过迭代算法完成吗?
+ * 
+ */
+
+// @lc code=start
+/**
+ * Definition for a binary tree node.
+ * struct TreeNode {
+ *     int val;
+ *     TreeNode *left;
+ *     TreeNode *right;
+ *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
+ *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
+ *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
+ * };
+ */
+// @lc code=end
+
  1. 递归
class Solution {
+public:
+    vector<int> res;
+    vector<int> preorderTraversal(TreeNode* root) {
+        if(root == nullptr){
+            return res;
+        }
+        res.push_back(root->val);
+        preorderTraversal(root->left);
+        preorderTraversal(root->right);
+        return res;
+    }
+};
+
  1. 迭代(使用栈)
class Solution {
+public:
+    vector<int> preorderTraversal(TreeNode* root) {
+        vector<int> res;
+        if (root == nullptr) {
+            return res;
+        }
+        stack<TreeNode*> stk;
+        stk.push(root);
+        while (!stk.empty()) {
+            TreeNode* node = stk.top();
+            stk.pop();
+            res.push_back(node->val);
+            if (node->right != nullptr) {
+                stk.push(node->right);  // 先压入右子树
+            }
+            if (node->left != nullptr) {
+                stk.push(node->left);  // 再压入左子树
+            }
+        }
+        return res;
+    }
+};
+
+ + + diff --git "a/LeetCode/LeetCode/2024.03.05-\344\272\214\345\217\211\346\240\221/2024.03.05-543.\344\272\214\345\217\211\346\240\221\347\232\204\347\233\264\345\276\204.html" "b/LeetCode/LeetCode/2024.03.05-\344\272\214\345\217\211\346\240\221/2024.03.05-543.\344\272\214\345\217\211\346\240\221\347\232\204\347\233\264\345\276\204.html" new file mode 100644 index 0000000..f2a4624 --- /dev/null +++ "b/LeetCode/LeetCode/2024.03.05-\344\272\214\345\217\211\346\240\221/2024.03.05-543.\344\272\214\345\217\211\346\240\221\347\232\204\347\233\264\345\276\204.html" @@ -0,0 +1,250 @@ + + + + + + 2024.03.05-543.二叉树的直径 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.05-543.二叉树的直径

/*
+ * @lc app=leetcode.cn id=543 lang=cpp
+ *
+ * [543] 二叉树的直径
+ *
+ * https://leetcode.cn/problems/diameter-of-binary-tree/description/
+ *
+ * algorithms
+ * Easy (59.72%)
+ * Likes:    1495
+ * Dislikes: 0
+ * Total Accepted:    387.9K
+ * Total Submissions: 649.5K
+ * Testcase Example:  '[1,2,3,4,5]'
+ *
+ * 给你一棵二叉树的根节点,返回该树的 直径 。
+ *
+ * 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。
+ *
+ * 两节点之间路径的 长度 由它们之间边数表示。
+ *
+ *
+ *
+ * 示例 1:
+ *
+ *
+ * 输入:root = [1,2,3,4,5]
+ * 输出:3
+ * 解释:3 ,取路径 [4,2,1,3] 或 [5,2,1,3] 的长度。
+ *
+ *
+ * 示例 2:
+ *
+ *
+ * 输入:root = [1,2]
+ * 输出:1
+ *
+ *
+ *
+ *
+ * 提示:
+ *
+ *
+ * 树中节点数目在范围 [1, 10^4] 内
+ * -100 <= Node.val <= 100
+ *
+ *
+ */
+
+// @lc code=start
+/* Definition for a binary tree node.
+ * struct TreeNode {
+ *     int val;
+ *     TreeNode *left;
+ *     TreeNode *right;
+ *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
+ *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
+ *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
+ * };
+ */
+class Solution {
+public:
+    int res = 0;
+    int diameterOfBinaryTree(TreeNode* root) {
+        traverse(root,res);
+        return res;
+    }
+    // cal the maxDepth
+    int traverse(TreeNode* node,int& res){
+        if(node == nullptr){
+            return 0;
+        }
+        int leftMax = traverse(node->left,res);
+        int rightMax = traverse(node->right,res);
+        int nodeMax = max(leftMax,rightMax)+1;
+        res = max(res,leftMax+rightMax);
+        return nodeMax;
+    }
+};
+// @lc code=end
+
+ + + diff --git "a/LeetCode/LeetCode/2024.03.11-\344\272\214\345\210\206\346\220\234\347\264\242.html" "b/LeetCode/LeetCode/2024.03.11-\344\272\214\345\210\206\346\220\234\347\264\242.html" new file mode 100644 index 0000000..bc015b9 --- /dev/null +++ "b/LeetCode/LeetCode/2024.03.11-\344\272\214\345\210\206\346\220\234\347\264\242.html" @@ -0,0 +1,174 @@ + + + + + + 2024.03.11-二分搜索 | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git "a/LeetCode/LeetCode/2024.03.11-\344\272\214\345\210\206\346\220\234\347\264\242/2024.03.11-34.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256.html" "b/LeetCode/LeetCode/2024.03.11-\344\272\214\345\210\206\346\220\234\347\264\242/2024.03.11-34.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256.html" new file mode 100644 index 0000000..4c97c69 --- /dev/null +++ "b/LeetCode/LeetCode/2024.03.11-\344\272\214\345\210\206\346\220\234\347\264\242/2024.03.11-34.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256.html" @@ -0,0 +1,274 @@ + + + + + + 2024.03.11-34.在排序数组中查找元素的第一个和最后一个位置 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.11-34.在排序数组中查找元素的第一个和最后一个位置

/*
+ * @lc app=leetcode.cn id=34 lang=cpp
+ *
+ * [34] 在排序数组中查找元素的第一个和最后一个位置
+ *
+ * https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/description/
+ *
+ * algorithms
+ * Medium (43.05%)
+ * Likes:    2636
+ * Dislikes: 0
+ * Total Accepted:    936.9K
+ * Total Submissions: 2.2M
+ * Testcase Example:  '[5,7,7,8,8,10]\n8'
+ *
+ * 给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
+ *
+ * 如果数组中不存在目标值 target,返回 [-1, -1]。
+ *
+ * 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
+ *
+ *
+ *
+ * 示例 1:
+ *
+ *
+ * 输入:nums = [5,7,7,8,8,10], target = 8
+ * 输出:[3,4]
+ *
+ * 示例 2:
+ *
+ *
+ * 输入:nums = [5,7,7,8,8,10], target = 6
+ * 输出:[-1,-1]
+ *
+ * 示例 3:
+ *
+ *
+ * 输入:nums = [], target = 0
+ * 输出:[-1,-1]
+ *
+ *
+ *
+ * 提示:
+ *
+ *
+ * 0 <= nums.length <= 10^5
+ * -10^9 <= nums[i] <= 10^9
+ * nums 是一个非递减数组
+ * -10^9 <= target <= 10^9
+ *
+ *
+ */
+
+// @lc code=start
+class Solution
+{
+public:
+    vector<int> searchRange(vector<int> &nums, int target)
+    {
+        int left = leftRange(nums, target);
+        int right = rightRange(nums, target);
+        vector<int> res = {left, right};
+        return res;
+    }
+    int leftRange(vector<int> &nums, int target)
+    {
+        int left = 0, right = nums.size() - 1, res = -1;
+        while (left <= right)
+        {
+            int mid = left + (right - left) / 2;
+            if (nums[mid] >= target)
+            {
+                if (nums[mid] == target)
+                    res = mid;
+                right = mid - 1;
+            }
+            else
+            {
+                left = mid + 1;
+            }
+        }
+        return res;
+    }
+    int rightRange(vector<int> &nums, int target)
+    {
+        int left = 0, right = nums.size() - 1, res = -1;
+        while (left <= right)
+        {
+            int mid = left + (right - left) / 2;
+            if (nums[mid] <= target)
+            {
+                if (nums[mid] == target)
+                    res = mid;
+                left = mid + 1;
+            }
+            else
+            {
+                right = mid - 1;
+            }
+        }
+        return res;
+    }
+};
+
+ + + diff --git "a/LeetCode/LeetCode/2024.03.11-\344\272\214\345\210\206\346\220\234\347\264\242/2024.03.11-704.\344\272\214\345\210\206\346\220\234\347\264\242.html" "b/LeetCode/LeetCode/2024.03.11-\344\272\214\345\210\206\346\220\234\347\264\242/2024.03.11-704.\344\272\214\345\210\206\346\220\234\347\264\242.html" new file mode 100644 index 0000000..1fb1aaf --- /dev/null +++ "b/LeetCode/LeetCode/2024.03.11-\344\272\214\345\210\206\346\220\234\347\264\242/2024.03.11-704.\344\272\214\345\210\206\346\220\234\347\264\242.html" @@ -0,0 +1,236 @@ + + + + + + 2024.03.11-704.二分搜索 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.11-704.二分搜索

/*
+ * @lc app=leetcode.cn id=704 lang=cpp
+ *
+ * [704] 二分查找
+ *
+ * https://leetcode.cn/problems/binary-search/description/
+ *
+ * algorithms
+ * Easy (55.07%)
+ * Likes:    1541
+ * Dislikes: 0
+ * Total Accepted:    1.2M
+ * Total Submissions: 2.1M
+ * Testcase Example:  '[-1,0,3,5,9,12]\n9'
+ *
+ * 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的
+ * target,如果目标值存在返回下标,否则返回 -1。
+ * 
+ * 
+ * 示例 1:
+ * 
+ * 输入: nums = [-1,0,3,5,9,12], target = 9
+ * 输出: 4
+ * 解释: 9 出现在 nums 中并且下标为 4
+ * 
+ * 
+ * 示例 2:
+ * 
+ * 输入: nums = [-1,0,3,5,9,12], target = 2
+ * 输出: -1
+ * 解释: 2 不存在 nums 中因此返回 -1
+ * 
+ * 
+ * 
+ * 
+ * 提示:
+ * 
+ * 
+ * 你可以假设 nums 中的所有元素是不重复的。
+ * n 将在 [1, 10000]之间。
+ * nums 的每个元素都将在 [-9999, 9999]之间。
+ * 
+ * 
+ */
+
+// @lc code=start
+
+class Solution {
+public:
+    int search(vector<int>& nums, int target) {
+        int left = 0;
+        int right = nums.size() - 1;
+        while(left <= right){
+            int mid = left + (right - left) / 2;
+            if(nums[mid] == target)
+                return mid;
+            else if(nums[mid] < target){
+                left = mid + 1;
+            }else{
+                right = mid - 1;
+            }
+        }
+        return -1;
+    }
+};
+// @lc code=end
+
  1. 注意 int right = nums.size() - 1;
  2. left ≤ right,有个等号。即当while中那个区间为空的时候就该跳出while了
  3. left + (right - left) / 2 的目的是避免溢出,而不是直接 left + right / 2
  4. left = mid + 1; 由于闭区间,所以更新边界的时候要考虑到不能包含原来的边界值
+ + + diff --git "a/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243.html" "b/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243.html" new file mode 100644 index 0000000..75d3eba --- /dev/null +++ "b/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243.html" @@ -0,0 +1,170 @@ + + + + + + 2024.03.18-滑动窗口 | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git "a/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243/2024.03.18-76.\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.html" "b/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243/2024.03.18-76.\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.html" new file mode 100644 index 0000000..0bfe3cd --- /dev/null +++ "b/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243/2024.03.18-76.\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.html" @@ -0,0 +1,280 @@ + + + + + + 2024.03.18-76.最小覆盖子串 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.03.18-76.最小覆盖子串

/*
+ * @lc app=leetcode.cn id=76 lang=cpp
+ *
+ * [76] 最小覆盖子串
+ *
+ * https://leetcode.cn/problems/minimum-window-substring/description/
+ *
+ * algorithms
+ * Hard (45.57%)
+ * Likes:    2847
+ * Dislikes: 0
+ * Total Accepted:    534.5K
+ * Total Submissions: 1.2M
+ * Testcase Example:  '"ADOBECODEBANC"\n"ABC"'
+ *
+ * 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""
+ * 。
+ *
+ *
+ *
+ * 注意:
+ *
+ *
+ * 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
+ * 如果 s 中存在这样的子串,我们保证它是唯一的答案。
+ *
+ *
+ *
+ *
+ * 示例 1:
+ *
+ *
+ * 输入:s = "ADOBECODEBANC", t = "ABC"
+ * 输出:"BANC"
+ * 解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A'、'B' 和 'C'。
+ *
+ *
+ * 示例 2:
+ *
+ *
+ * 输入:s = "a", t = "a"
+ * 输出:"a"
+ * 解释:整个字符串 s 是最小覆盖子串。
+ *
+ *
+ * 示例 3:
+ *
+ *
+ * 输入: s = "a", t = "aa"
+ * 输出: ""
+ * 解释: t 中两个字符 'a' 均应包含在 s 的子串中,
+ * 因此没有符合条件的子字符串,返回空字符串。
+ *
+ *
+ *
+ * 提示:
+ *
+ *
+ * ^m == s.length
+ * ^n == t.length
+ * 1 <= m, n <= 10^5
+ * s 和 t 由英文字母组成
+ *
+ *
+ *
+ * 进阶:你能设计一个在 o(m+n) 时间内解决此问题的算法吗?
+ */
+
+// @lc code=start
+class Solution
+{
+public:
+    string minWindow(string s, string t)
+    {
+        // 左闭右开区间 [left, right)
+        int left = 0, right = 0;
+        unordered_map<char, int> target, window;
+        for (char c : t)
+            target[c]++;
+        int hit = 0, resStart = 0, resLen = INT_MAX;
+        while (right < s.size())
+        {
+            right++;
+            char in = s[right - 1];
+            if (target.count(in))
+            {
+                window[in]++;
+                if (window[in] == target[in])
+                    hit += 1;
+            }
+            while (hit == target.size())
+            {
+                left++;
+                if ((right - left + 1) < resLen)
+                {
+                    resStart = left - 1;
+                    resLen = right - left + 1;
+                }
+                char out = s[left - 1];
+                if (target.count(out)){
+                    if (window[out] == target[out])
+                        hit -= 1;
+                    window[out]--;
+                }
+            }
+        }
+        return resLen == INT_MAX ? "" : s.substr(resStart, resLen);
+    }
+};
+// @lc code=end
+
+ + + diff --git "a/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243/2024.04.02-3.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.html" "b/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243/2024.04.02-3.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.html" new file mode 100644 index 0000000..b0fe5a6 --- /dev/null +++ "b/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243/2024.04.02-3.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.html" @@ -0,0 +1,275 @@ + + + + + + 2024.04.02-3.无重复字符的最长子串 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.02-3.无重复字符的最长子串

/*
+ * @lc app=leetcode.cn id=3 lang=cpp
+ *
+ * [3] 无重复字符的最长子串
+ *
+ * https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/
+ *
+ * algorithms
+ * Medium (39.02%)
+ * Likes:    8247
+ * Dislikes: 0
+ * Total Accepted:    2M
+ * Total Submissions: 5.2M
+ * Testcase Example:  '"abcabcbb"'
+ *
+ * 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
+ *
+ *
+ *
+ * 示例 1:
+ *
+ *
+ * 输入: s = "abcabcbb"
+ * 输出: 3
+ * 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
+ *
+ *
+ * 示例 2:
+ *
+ *
+ * 输入: s = "bbbbb"
+ * 输出: 1
+ * 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
+ *
+ *
+ * 示例 3:
+ *
+ *
+ * 输入: s = "pwwkew"
+ * 输出: 3
+ * 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
+ * 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
+ *
+ *
+ *
+ *
+ * 提示:
+ *
+ *
+ * 0 <= s.length <= 5 * 10^4
+ * s 由英文字母、数字、符号和空格组成
+ *
+ *
+ */
+
+// @lc code=start
+// class Solution
+// {
+// public:
+//     int lengthOfLongestSubstring(string s)
+//     {
+//         int result = 0;
+//         unordered_map<char, int> num;
+//         int l = 0;
+//         for (int r = 0; r < s.length(); ++r)
+//         {
+//             num[s[r]]++;
+//             while (num[s[r]] >= 2)
+//             {
+//                 num[s[l++]]--;
+//             }
+//             result = max(r - l + 1, result);
+//         }
+//         return result;
+//     }
+// };
+class Solution
+{
+public:
+    int lengthOfLongestSubstring(string s)
+    {
+        unordered_map<char, int> window;
+        int left = 0, right = 0;
+        int res = 0;
+        while (right < s.size())
+        {
+            char in = s[right];
+            right++;
+            window[in]++;
+            while (window[in] > 1)
+            {
+                char out = s[left];
+                left++;
+                window[out]--;
+            }
+            res = max(res, right - left);
+        }
+        return res;
+    }
+};
+// @lc code=end
+
+ + + diff --git "a/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243/2024.04.02-438.\346\211\276\345\210\260\345\255\227\347\254\246\344\270\262\344\270\255\346\211\200\346\234\211\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.html" "b/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243/2024.04.02-438.\346\211\276\345\210\260\345\255\227\347\254\246\344\270\262\344\270\255\346\211\200\346\234\211\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.html" new file mode 100644 index 0000000..2ac0098 --- /dev/null +++ "b/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243/2024.04.02-438.\346\211\276\345\210\260\345\255\227\347\254\246\344\270\262\344\270\255\346\211\200\346\234\211\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.html" @@ -0,0 +1,265 @@ + + + + + + 2024.04.02-438.找到字符串中所有字母异位词 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.02-438.找到字符串中所有字母异位词

/*
+ * @lc app=leetcode.cn id=438 lang=cpp
+ *
+ * [438] 找到字符串中所有字母异位词
+ *
+ * https://leetcode.cn/problems/find-all-anagrams-in-a-string/description/
+ *
+ * algorithms
+ * Medium (53.57%)
+ * Likes:    1413
+ * Dislikes: 0
+ * Total Accepted:    407.9K
+ * Total Submissions: 761.5K
+ * Testcase Example:  '"cbaebabacd"\n"abc"'
+ *
+ * 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
+ * 
+ * 异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。
+ * 
+ * 
+ * 
+ * 示例 1:
+ * 
+ * 
+ * 输入: s = "cbaebabacd", p = "abc"
+ * 输出: [0,6]
+ * 解释:
+ * 起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
+ * 起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
+ * 
+ * 
+ * 示例 2:
+ * 
+ * 
+ * 输入: s = "abab", p = "ab"
+ * 输出: [0,1,2]
+ * 解释:
+ * 起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
+ * 起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
+ * 起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。
+ * 
+ * 
+ * 
+ * 
+ * 提示:
+ * 
+ * 
+ * 1 <= s.length, p.length <= 3 * 10^4
+ * s 和 p 仅包含小写字母
+ * 
+ * 
+ */
+
+// @lc code=start
+class Solution {
+public:
+    vector<int> findAnagrams(string s, string p) {
+        unordered_map<char, int> target, window;
+        for (char c : p)
+            target[c]++;
+        int left = 0, right = 0;
+        int hit = 0;
+        vector<int> res;
+        while (right < s.size())
+        {
+            char in = s[right];
+            right++;
+            if (target.count(in))
+            {
+                window[in]++;
+                if (window[in] == target[in])
+                    hit++;
+            }
+            while (hit == target.size())
+            {
+                if ((right - left) == p.size())
+                    res.push_back(left);
+                char out = s[left];
+                left++;
+                if (target.count(out))
+                {
+                    if (window[out] == target[out])
+                        hit--;
+                    window[out]--;
+                }
+            }
+        }
+        return res;
+    }
+};
+// @lc code=end
+
+ + + diff --git "a/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243/2024.04.02-567.\345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227.html" "b/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243/2024.04.02-567.\345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227.html" new file mode 100644 index 0000000..4327224 --- /dev/null +++ "b/LeetCode/LeetCode/2024.03.18-\346\273\221\345\212\250\347\252\227\345\217\243/2024.04.02-567.\345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227.html" @@ -0,0 +1,256 @@ + + + + + + 2024.04.02-567.字符串的排列 | Personal Blog --from Outis Li + + + + + + + + +

# 2024.04.02-567.字符串的排列

/*
+ * @lc app=leetcode.cn id=567 lang=cpp
+ *
+ * [567] 字符串的排列
+ *
+ * https://leetcode.cn/problems/permutation-in-string/description/
+ *
+ * algorithms
+ * Medium (44.96%)
+ * Likes:    996
+ * Dislikes: 0
+ * Total Accepted:    286.4K
+ * Total Submissions: 637.1K
+ * Testcase Example:  '"ab"\n"eidbaooo"'
+ *
+ * 给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。
+ *
+ * 换句话说,s1 的排列之一是 s2 的 子串 。
+ *
+ *
+ *
+ * 示例 1:
+ *
+ *
+ * 输入:s1 = "ab" s2 = "eidbaooo"
+ * 输出:true
+ * 解释:s2 包含 s1 的排列之一 ("ba").
+ *
+ *
+ * 示例 2:
+ *
+ *
+ * 输入:s1= "ab" s2 = "eidboaoo"
+ * 输出:false
+ *
+ *
+ *
+ *
+ * 提示:
+ *
+ *
+ * 1 <= s1.length, s2.length <= 10^4
+ * s1 和 s2 仅包含小写字母
+ *
+ *
+ */
+
+// @lc code=start
+class Solution
+{
+public:
+    bool checkInclusion(string s1, string s2)
+    {
+        unordered_map<char, int> target, window;
+        for (char c : s1)
+            target[c]++;
+        int left = 0, right = 0;
+        int hit = 0;
+        while (right < s2.size())
+        {
+            char in = s2[right];
+            right++;
+            if (target.count(in))
+            {
+                window[in]++;
+                if (window[in] == target[in])
+                    hit++;
+            }
+            while (hit == target.size())
+            {
+                if ((right - left) == s1.size())
+                    return true;
+                char out = s2[left];
+                left++;
+                if (target.count(out))
+                {
+                    if (window[out] == target[out])
+                        hit--;
+                    window[out]--;
+                }
+            }
+        }
+        return false;
+    }
+};
+// @lc code=end
+
+ + + diff --git a/LeetCode/index.html b/LeetCode/index.html new file mode 100644 index 0000000..75f659b --- /dev/null +++ b/LeetCode/index.html @@ -0,0 +1,166 @@ + + + + + + LeetCode | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git a/Research/Research/2023-Geant4.html b/Research/Research/2023-Geant4.html new file mode 100644 index 0000000..83cde17 --- /dev/null +++ b/Research/Research/2023-Geant4.html @@ -0,0 +1,170 @@ + + + + + + 2023-Geant4 | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git "a/Research/Research/2023-Geant4/2023.02.13-\345\234\250\350\266\205\347\256\227\344\270\212\346\220\255\345\273\272Singularity\347\216\257\345\242\203\345\271\266\351\205\215\347\275\256Geant4.html" "b/Research/Research/2023-Geant4/2023.02.13-\345\234\250\350\266\205\347\256\227\344\270\212\346\220\255\345\273\272Singularity\347\216\257\345\242\203\345\271\266\351\205\215\347\275\256Geant4.html" new file mode 100644 index 0000000..4cf17c6 --- /dev/null +++ "b/Research/Research/2023-Geant4/2023.02.13-\345\234\250\350\266\205\347\256\227\344\270\212\346\220\255\345\273\272Singularity\347\216\257\345\242\203\345\271\266\351\205\215\347\275\256Geant4.html" @@ -0,0 +1,243 @@ + + + + + + 2023.02.13-在超算上搭建Singularity环境并配置Geant4 | Personal Blog --from Outis Li + + + + + + + + +

# 2023.02.13-在超算上搭建Singularity环境并配置Geant4

# I. 制作singularity包

# 1. 进入fakeroot节点

ssh <user_id>@162.105.133.209
+

# 2. 制作并进入sandbox镜像

  1. 搭建ubuntu

    singularity build --fakeroot --sandbox Geant4 docker://ubuntu:22.04
    +
  2. 进入Geant4环境(sandbox)

    singularity shell --fakeroot -w Geant4
    +

# 3. 配置geant4环境

  1. 安装基本环境

    apt-get install build-essential
    +apt-get install wget
    +
  2. 下载geant4

    mkdir geant4
    +wget https://geant4-data.web.cern.ch/releases/geant4-v11.1.0.tar.gz
    +tar -xzvf geant4-v11.1.0.tar.gz
    +
  3. 安装依赖包(若报错,则分别单独安装)

    sudo apt-get install -y cmake libx11-dev libxext-dev libxtst-dev libxrender-dev libxmu-dev libxmuu-dev libhdf5-serial-dev hdf5-tools
    +sudo apt-get install -y libexpat1-dev
    +sudo apt install -y qt5*
    +
  4. 编译安装

    mkdir build
    +cd build
    +cmake -DCMAKE_INSTALL_PREFIX=/root/Geant4/home/geant4 /root/Geant4/home/geant4-v11.1.0
    +cmake -DGEANT4_INSTALL_DATA=ON .
    +make -jN  # N表示处理器数量,需修改为实际值
    +make install
    +
  5. 配置环境变量

    cd /root/Geant4/etc/skel/
    +vim .bashrc
    +

    将下列内容添加到 .bashrc

    source /root/Geant4/home/geant4/bin/geant4.sh
    +source /root/Geant4/home/geant4/share/Geant4/geant4make/geant4make.sh
    +

    配置

    cp /root/Geant4/etc/skel/.bashrc /root/Geant4/home
    +cd /root/Geant4/home
    +source .bashrc
    +
  6. 检验geant4是否配置成功

    cd /root/Geant4/home/geant4/share/Geant4/examples/basic/B1
    +mkdir build && cd build
    +cmake ..
    +make
    +./exampleB1 run1.mac
    +

    若无报错则配置成功

  7. 退出

    exit
    +

# 4. 打包

singularity build --fakeroot s-Geant4.sif Geant4/
+

# II. 配置go&singularity

# 1. 配置go环境

# 超算Data节点
+export VERSION=1.17.2 OS=linux ARCH=amd64
+wget https://dl.google.com/go/go$VERSION.$OS-$ARCH.tar.gz
+tar -xzvf go1.17.2.linux-amd64.tar.gz
+rm -f go1.17.2.linux-amd64.tar.gz
+export PATH=/lustre/home/<user_id>/go/bin:$PATH
+

# 2. 安装singularity

module load singularity/3.11.3
+

# 3. 环境变量

cd $HOME
+vim .bashrc
+# 将下列语句添加到.bashrc中
+# export PATH=/lustre/home/<user_id>/go/bin:$PATH
+source .bashrc
+

# III. 启用singularity

# 1. 将SIF镜像下载到常规节点

scp -r <user_id>@162.105.133.209:/home/<user_id>/s-Geant4.sif /gpfs/share/home/<user_id>/
+

# 2. 转换成sandbox镜像并启用

singularity build --sandbox Geant4 s-Geant4.sif
+singularity shell -w Geant4
+

# 3. 配置环境变量

cd Geant4/home
+vim .bashrc
+
+# 将下列语句添加到文件末尾
+# source /lustre/home/2201210084/singularity/Geant4/home/geant4/bin/geant4.sh
+# source /lustre/home/2201210084/singularity/Geant4/home/geant4/share/Geant4/geant4make/geant4make.sh
+
+source .bashrc
+

看见如下字样表示成功

Untitled

# IV. 附录

# 1. SIF容器与sandbox相互转换

# 1. 将SIF格式的容器转换成sandbox;
+singularity build --sandbox XXX XXX.sif
+
+# 2. 将sandbox容器镜像转化成SIF格式;
+singularity build XXX.sif XXX
+

# 2. 在fakeroot节点上删除sandbox镜像

# 假设要删除的为文件夹名为molspin的sandbox镜像
+
+# 首先,以可读的模式进入要删除的镜像
+singularity shell --fakeroot -w molspin
+
+# 删除掉容器中,基于fakeroot创建的所有文件
+rm -rf /* 1>/dev/null 2>&1
+
+# 退出镜像
+exit
+
+# 将创建好的软件镜像上传到高性能计算集群,加载singularity软件环境
+# 删除掉剩下的
+rm -rf molspin
+
+ + + diff --git "a/Research/Research/2023-Geant4/2023.02.27-\345\244\204\347\220\206Geant4\350\216\267\345\217\226\347\232\204\346\225\260\346\215\256.html" "b/Research/Research/2023-Geant4/2023.02.27-\345\244\204\347\220\206Geant4\350\216\267\345\217\226\347\232\204\346\225\260\346\215\256.html" new file mode 100644 index 0000000..6bc546a --- /dev/null +++ "b/Research/Research/2023-Geant4/2023.02.27-\345\244\204\347\220\206Geant4\350\216\267\345\217\226\347\232\204\346\225\260\346\215\256.html" @@ -0,0 +1,477 @@ + + + + + + 2023.02.27-处理Geant4获取的数据 | Personal Blog --from Outis Li + + + + + + + + +

# 2023.02.27-处理Geant4获取的数据

# 直方图 Histogram

import copy
+import os
+import sys
+import pandas as pd
+import numpy as np
+import matplotlib.pyplot as plt
+
+# Path of the file to read
+path = "../output_below.csv"
+# open the csv file
+df = pd.read_csv(path)
+
+# columns of the csv file
+particleName = df.iloc[:, 0].values.tolist()
+eventID = df.iloc[:, 1].values.tolist()
+trackID = df.iloc[:, 2].values.tolist()
+preVolumeName = df.iloc[:, 3].values.tolist()
+preX = df.iloc[:, 4].values.tolist()
+preY = df.iloc[:, 5].values.tolist()
+preZ = df.iloc[:, 6].values.tolist()
+preKE = df.iloc[:, 7].values.tolist()
+preProcessName = df.iloc[:, 8].values.tolist()
+postProcessName = df.iloc[:, 9].values.tolist()
+postVolumeName = df.iloc[:, 10].values.tolist()
+postX = df.iloc[:, 11].values.tolist()
+postY = df.iloc[:, 12].values.tolist()
+postZ = df.iloc[:, 13].values.tolist()
+postKE = df.iloc[:, 14].values.tolist()
+depositEnergy = df.iloc[:, 15].values.tolist()
+stepLength = df.iloc[:, 16].values.tolist()
+trackLength = df.iloc[:, 17].values.tolist()
+
+# get the energy density
+unit = 'MeV*cm^2/g'
+densitySiC = 3.217 * 1e-3import os
+import sys
+import pandas as pd
+import numpy as np
+import matplotlib.pyplot as plt
+
+# Path of the file to read
+path = "../output_below.csv"
+
+# open the csv file
+df = pd.read_csv(path)
+
+# columns of the csv file
+particleName = df.iloc[:, 0].values.tolist()
+eventID = df.iloc[:, 1].values.tolist()
+trackID = df.iloc[:, 2].values.tolist()
+preVolumeName = df.iloc[:, 3].values.tolist()
+preX = df.iloc[:, 4].values.tolist()
+preY = df.iloc[:, 5].values.tolist()
+preZ = df.iloc[:, 6].values.tolist()
+preKE = df.iloc[:, 7].values.tolist()
+preProcessName = df.iloc[:, 8].values.tolist()
+postProcessName = df.iloc[:, 9].values.tolist()
+postVolumeName = df.iloc[:, 10].values.tolist()
+postX = df.iloc[:, 11].values.tolist()
+postY = df.iloc[:, 12].values.tolist()
+postZ = df.iloc[:, 13].values.tolist()
+postKE = df.iloc[:, 14].values.tolist()
+depositEnergy = df.iloc[:, 15].values.tolist()
+stepLength = df.iloc[:, 16].values.tolist()
+trackLength = df.iloc[:, 17].values.tolist()
+
+# get the energy density
+unit = 'MeV*cm^2/g'
+densitySiC = 3.217 * 1e-3
+densityAl = 2.6989 * 1e-3
+densitySi = 2.3296 * 1e-3
+densitySiO2 = 2.2 * 1e-3
+depositEnergy = np.array(depositEnergy)
+stepLength = np.array(stepLength)
+depositEnergyDensity = depositEnergy / stepLength
+for i in range(len(preVolumeName)):
+    if preVolumeName[i].strip() == 'V1':
+        depositEnergyDensity[i] = depositEnergyDensity[i] / densitySi
+        continue
+    if preVolumeName[i].strip() == 'V2':
+        depositEnergyDensity[i] = depositEnergyDensity[i] / densitySiO2
+        continue
+    if (preVolumeName[i].strip() == 'Vs1') or (preVolumeName[i].strip() == 'Vs2') or (preVolumeName[i].strip() == 'VD'):
+        depositEnergyDensity[i] = depositEnergyDensity[i] / densityAl
+        continue
+    else:
+        depositEnergyDensity[i] = depositEnergyDensity[i] / densitySiC
+depositEnergyDensity = depositEnergyDensity.tolist()
+depositEnergyDensity250000 = []
+preX_250000=[]
+preZ_250000=[]
+for i in range(len(depositEnergyDensity)):
+    if depositEnergyDensity[i] < 250000:
+        depositEnergyDensity250000.append(depositEnergyDensity[i])
+        preX_250000.append(preX[i])
+        preZ_250000.append(preZ[i])
+
+# draw the heatmap according to the coordinates and the energy deposit
+# the energy deposit is the color of the heatmap
+# the coordinates are the x and y axis of the heatmap
+# the z axis is the energy deposit
+# the colorbar is the energy deposit
+# draw the heatmap
+plt.scatter(preX, preZ, c=depositEnergy, s=0.1, cmap='jet',marker='.')
+plt.xlabel("preX")
+plt.ylabel("preZ")
+plt.title("heatmap_total")
+plt.colorbar()
+plt.savefig("heatmap_total.png", dpi=500)
+plt.show()
+
+plt.scatter(preX, preZ, c=depositEnergyDensity, s=0.1, cmap='jet',marker='.')
+plt.xlabel("preX")
+plt.ylabel("preZ")
+plt.title("heatmap_total")
+plt.colorbar()
+plt.savefig("heatmap_density_total.png", dpi=500)
+plt.show()
+
+plt.scatter(preX_250000, preZ_250000, c=depositEnergyDensity250000, s=1, cmap='jet',marker='.')
+plt.xlabel("preX")
+plt.ylabel("preZ")
+plt.title("heatmap_<250000")
+plt.colorbar()
+plt.savefig("heatmap_density_2500000.png", dpi=500)
+plt.show(
+densityAl = 2.6989 * 1e-3
+densitySi = 2.3296 * 1e-3
+densitySiO2 = 2.2 * 1e-3
+depositEnergy = np.array(depositEnergy)
+stepLength = np.array(stepLength)
+depositEnergyDensity = depositEnergy / stepLength
+for i in range(len(preVolumeName)):
+    if preVolumeName[i].strip() == 'V1':
+        depositEnergyDensity[i] = depositEnergyDensity[i] / densitySi
+        continue
+    if preVolumeName[i].strip() == 'V2':
+        depositEnergyDensity[i] = depositEnergyDensity[i] / densitySiO2
+        continue
+    if (preVolumeName[i].strip() == 'Vs1') or (preVolumeName[i].strip() == 'Vs2') or (preVolumeName[i].strip() == 'VD'):
+        depositEnergyDensity[i] = depositEnergyDensity[i] / densityAl
+        continue
+    else:
+        depositEnergyDensity[i] = depositEnergyDensity[i] / densitySiC
+depositEnergyDensity = depositEnergyDensity.tolist()
+depositEnergyDensity250000 = []
+for i in range(len(depositEnergyDensity)):
+    if depositEnergyDensity[i] < 250000:
+        depositEnergyDensity250000.append(depositEnergyDensity[i])
+        
+# draw the histogram of the energy deposit
+plt.hist(depositEnergy, bins=50, facecolor="blue",
+         edgecolor="black", alpha=0.7)
+# plt.yscale('log')
+plt.xlabel("depositEnergy(MeV)")
+plt.ylabel("Number")
+plt.title("depositEnergy_total")
+plt.savefig("depositEnergy_total.png", dpi=500)
+plt.show()
+
+# draw the histogram of the energy deposit density
+plt.hist(depositEnergyDensity, bins=50, facecolor="blue",
+         edgecolor="black", alpha=0.7)
+plt.yscale('log')
+plt.xlabel("depositEnergyDensity(MeV*cm^2/g)")
+plt.ylabel("Number")
+plt.title("depositEnergyDensity_total")
+plt.savefig("depositEnergyDensity_total.png", dpi=500)
+plt.show()
+
+# make a dictionary of the columns
+names = [('V1', []), ('V2', []), ('V31', []), ('V32', []), ('V51', []), ('V52', []), ('V66', []), ('VD', []),
+         ('Vs1', []), ('Vs2', []), ('V7', [])]
+dict_dp = dict(names)
+dict_dpd = copy.deepcopy(dict_dp)
+# extract the keys of the dictionary to a list
+volumeNames = list(dict_dp.keys())
+
+# for every column, determine the preVolumeName and fill the dictionary
+for i in range(len(preVolumeName)):
+    for j in volumeNames:
+        if preVolumeName[i].strip() == j:
+            dict_dp[j].append(depositEnergy[i])
+            dict_dpd[j].append(depositEnergyDensity[i])
+            break
+
+# draw the histogram of the energy deposit for each volume and merge in one page
+plt.figure(figsize=(16, 16))
+for i in range(len(volumeNames)):
+    plt.subplot(3, 4, i + 1)
+    plt.hist(dict_dp[volumeNames[i]], bins=50,
+             facecolor="blue", edgecolor="black", alpha=0.7)
+    # plt.yscale('log')
+    plt.xlabel("depositEnergy(MeV)")
+    plt.ylabel("Number")
+    plt.title(volumeNames[i])
+plt.savefig("depositEnergy_each.png", dpi=500)
+plt.show()
+
+# draw the histogram of the energy deposit density for each volume and merge in one page
+plt.figure(figsize=(16, 16))
+for i in range(len(volumeNames)):
+    plt.subplot(3, 4, i + 1)
+    plt.hist(dict_dpd[volumeNames[i]], bins=50,
+             facecolor="blue", edgecolor="black", alpha=0.7)
+    # plt.yscale('log')
+    plt.xlabel("depositEnergyDensity(MeV*cm^2/g)")
+    plt.ylabel("Number")
+    plt.title(volumeNames[i])
+plt.savefig("depositEnergyDensity_each.png", dpi=500)
+plt.show()
+

# 热力图 Heatmap

import os
+import sys
+import pandas as pd
+import numpy as np
+import matplotlib.pyplot as plt
+
+# Path of the file to read
+path = "../output_below.csv"
+
+# open the csv file
+df = pd.read_csv(path)
+
+# columns of the csv file
+particleName = df.iloc[:, 0].values.tolist()
+eventID = df.iloc[:, 1].values.tolist()
+trackID = df.iloc[:, 2].values.tolist()
+preVolumeName = df.iloc[:, 3].values.tolist()
+preX = df.iloc[:, 4].values.tolist()
+preY = df.iloc[:, 5].values.tolist()
+preZ = df.iloc[:, 6].values.tolist()
+preKE = df.iloc[:, 7].values.tolist()
+preProcessName = df.iloc[:, 8].values.tolist()
+postProcessName = df.iloc[:, 9].values.tolist()
+postVolumeName = df.iloc[:, 10].values.tolist()
+postX = df.iloc[:, 11].values.tolist()
+postY = df.iloc[:, 12].values.tolist()
+postZ = df.iloc[:, 13].values.tolist()
+postKE = df.iloc[:, 14].values.tolist()
+depositEnergy = df.iloc[:, 15].values.tolist()
+stepLength = df.iloc[:, 16].values.tolist()
+trackLength = df.iloc[:, 17].values.tolist()
+
+# get the energy density
+unit = 'MeV*cm^2/g'
+densitySiC = 3.217 * 1e-3
+densityAl = 2.6989 * 1e-3
+densitySi = 2.3296 * 1e-3
+densitySiO2 = 2.2 * 1e-3
+depositEnergy = np.array(depositEnergy)
+stepLength = np.array(stepLength)
+depositEnergyDensity = depositEnergy / stepLength
+for i in range(len(preVolumeName)):
+    if preVolumeName[i].strip() == 'V1':
+        depositEnergyDensity[i] = depositEnergyDensity[i] / densitySi
+        continue
+    if preVolumeName[i].strip() == 'V2':
+        depositEnergyDensity[i] = depositEnergyDensity[i] / densitySiO2
+        continue
+    if (preVolumeName[i].strip() == 'Vs1') or (preVolumeName[i].strip() == 'Vs2') or (preVolumeName[i].strip() == 'VD'):
+        depositEnergyDensity[i] = depositEnergyDensity[i] / densityAl
+        continue
+    else:
+        depositEnergyDensity[i] = depositEnergyDensity[i] / densitySiC
+depositEnergyDensity = depositEnergyDensity.tolist()
+depositEnergyDensity250000 = []
+preX_250000=[]
+preZ_250000=[]
+for i in range(len(depositEnergyDensity)):
+    if depositEnergyDensity[i] < 250000:
+        depositEnergyDensity250000.append(depositEnergyDensity[i])
+        preX_250000.append(preX[i])
+        preZ_250000.append(preZ[i])
+
+# draw the heatmap according to the coordinates and the energy deposit
+# the energy deposit is the color of the heatmap
+# the coordinates are the x and y axis of the heatmap
+# the z axis is the energy deposit
+# the colorbar is the energy deposit
+# draw the heatmap
+plt.scatter(preX, preZ, c=depositEnergy, s=0.1, cmap='jet',marker='.')
+plt.xlabel("preX")
+plt.ylabel("preZ")
+plt.title("heatmap_total")
+plt.colorbar()
+plt.savefig("heatmap_total.png", dpi=500)
+plt.show()
+
+plt.scatter(preX, preZ, c=depositEnergyDensity, s=0.1, cmap='jet',marker='.')
+plt.xlabel("preX")
+plt.ylabel("preZ")
+plt.title("heatmap_total")
+plt.colorbar()
+plt.savefig("heatmap_density_total.png", dpi=500)
+plt.show()
+
+plt.scatter(preX_250000, preZ_250000, c=depositEnergyDensity250000, s=1, cmap='jet',marker='.')
+plt.xlabel("preX")
+plt.ylabel("preZ")
+plt.title("heatmap_<250000")
+plt.colorbar()
+plt.savefig("heatmap_density_2500000.png", dpi=500)
+plt.show()
+
+ + + diff --git "a/Research/Research/2023-Geant4/2023.03.12-PKA\346\225\260\346\215\256\345\244\204\347\220\206.html" "b/Research/Research/2023-Geant4/2023.03.12-PKA\346\225\260\346\215\256\345\244\204\347\220\206.html" new file mode 100644 index 0000000..27d6802 --- /dev/null +++ "b/Research/Research/2023-Geant4/2023.03.12-PKA\346\225\260\346\215\256\345\244\204\347\220\206.html" @@ -0,0 +1,174 @@ + + + + + + 2023.03.12-PKA数据处理 | Personal Blog --from Outis Li + + + + + + + + +

# 2023.03.12-PKA数据处理

23-03-12_Geant4_PKA_Data.pdf

+ + + diff --git "a/Research/Research/2023-Geant4/2023.05.23-Geant4\345\244\232\347\262\222\345\255\220\346\272\220\350\256\276\347\275\256.html" "b/Research/Research/2023-Geant4/2023.05.23-Geant4\345\244\232\347\262\222\345\255\220\346\272\220\350\256\276\347\275\256.html" new file mode 100644 index 0000000..0e69c08 --- /dev/null +++ "b/Research/Research/2023-Geant4/2023.05.23-Geant4\345\244\232\347\262\222\345\255\220\346\272\220\350\256\276\347\275\256.html" @@ -0,0 +1,203 @@ + + + + + + 2023.05.23-Geant4多粒子源设置 | Personal Blog --from Outis Li + + + + + + + + +

# 2023.05.23-Geant4多粒子源设置

源代码:

// Create particle source
+G4GeneralParticleSource* particleSource = new G4GeneralParticleSource();
+
+// First particle source
+particleSource->SetCurrentSourceto(particleSource->GetNumberofSource() - 1);
+particleSource->GetCurrentSource()->GetPosDist()->SetCentreCoords(G4ThreeVector(-5.0*cm, 0.0, 0.0));
+particleSource->GetCurrentSource()->GetAngDist()->SetAngDistType("iso");
+particleSource->GetCurrentSource()->GetEneDist()->SetEnergyDisType("Mono");
+particleSource->GetCurrentSource()->GetEneDist()->SetMonoEnergy(10*MeV);
+particleSource->GetCurrentSource()->SetParticleDefinition(G4Neutron::NeutronDefinition());
+
+// Point source
+particleSource->GetCurrentSource()->GetPosDist()->SetPosDisType("Point");
+
+// Second particle source
+particleSource->AddaSource(1.0);
+particleSource->SetCurrentSourceto(particleSource->GetNumberofSource() - 1);
+particleSource->GetCurrentSource()->GetPosDist()->SetCentreCoords(G4ThreeVector(5.0*cm, 0.0, 0.0));
+particleSource->GetCurrentSource()->GetAngDist()->SetAngDistType("iso");
+particleSource->GetCurrentSource()->GetEneDist()->SetEnergyDisType("Mono");
+particleSource->GetCurrentSource()->GetEneDist()->SetMonoEnergy(20*MeV);
+particleSource->GetCurrentSource()->SetParticleDefinition(G4Proton::ProtonDefinition());
+
+// Plane source
+particleSource->GetCurrentSource()->GetPosDist()->SetPosDisType("Plane");
+particleSource->GetCurrentSource()->GetPosDist()->SetPosDisShape("Circle");
+particleSource->GetCurrentSource()->GetPosDist()->SetRadius(2*cm);
+

mac文件内:

/gps/source/0/intensity 500
+/gps/source/1/intensity 1000
+
+ + + diff --git "a/Research/Research/2023-Geant4/2023.06.14-Geant4\345\220\204\347\211\210\346\234\254\347\232\204\345\256\211\350\243\205.html" "b/Research/Research/2023-Geant4/2023.06.14-Geant4\345\220\204\347\211\210\346\234\254\347\232\204\345\256\211\350\243\205.html" new file mode 100644 index 0000000..648b739 --- /dev/null +++ "b/Research/Research/2023-Geant4/2023.06.14-Geant4\345\220\204\347\211\210\346\234\254\347\232\204\345\256\211\350\243\205.html" @@ -0,0 +1,194 @@ + + + + + + 2023.06.14-Geant4各版本的安装 | Personal Blog --from Outis Li + + + + + + + + +

# 2023.06.14-Geant4各版本的安装

# 安装依赖

sudo apt-get install -y build-essential
+sudo apt-get install -y wget
+// sudo apt-get install -y aptitude
+sudo apt-get install -y cmake libx11-dev libxext-dev libxtst-dev libxrender-dev libxmu-dev libxmuu-dev libhdf5-serial-dev hdf5-tools
+sudo apt-get install -y libexpat1-dev libxerces-c-dev libxt-dev libmotif-dev
+sudo apt install qt5* qt6* libqt5opengl5-dev
+

# 下载安装Geant4

mkdir Geant4_11.1.1
+wget https://geant4-data.web.cern.ch/releases/geant4-v11.1.1.tar.gz
+// https://gitlab.cern.ch/geant4/geant4/-/archive/v10.5.1/geant4-v10.5.1.tar.gz
+tar -xzvf geant4-v11.1.1.tar.gz
+
+mkdir build
+cd build
+cmake -DCMAKE_INSTALL_PREFIX=/home/tiancheng/Geant4_11.1.1 /home/tiancheng/geant4-v11.1.1
+cmake -DGEANT4_INSTALL_DATA=ON -DGEANT4_BUILD_MULTITHREADED=ON -DGEANT4_USE_GDML=ON -DGEANT4_USE_QT=ON -DGEANT4_USE_OPENGL_X11=ON -DGEANT4_USE_RAYTRACER_X11=ON -DGEANT4_USE_NETWORKDAWN=ON -DGEANT4_USE_XM=ON -DGEANT4_USE_NETWORKVRML=ON .
+
+make -jN
+make install
+source /root/Geant4/home/geant4/bin/geant4.sh
+source /root/Geant4/home/geant4/share/Geant4/geant4make/geant4make.sh
+
+ + + diff --git "a/Research/Research/2023-Geant4/2023.08.28-Geant4\350\207\252\345\256\232\344\271\211PhysicsList.html" "b/Research/Research/2023-Geant4/2023.08.28-Geant4\350\207\252\345\256\232\344\271\211PhysicsList.html" new file mode 100644 index 0000000..f8d8274 --- /dev/null +++ "b/Research/Research/2023-Geant4/2023.08.28-Geant4\350\207\252\345\256\232\344\271\211PhysicsList.html" @@ -0,0 +1,341 @@ + + + + + + 2023.08.28-Geant4 自定义 PhysicsList | Personal Blog --from Outis Li + + + + + + + + +

# 2023.08.28-Geant4 自定义 PhysicsList

# 一个最简单的例子

# main:

#include "G4RunManager.hh"
+
+int main()
+{
+    // 初始化 run manager
+    G4RunManager runManager;
+
+    // 设置物理列表
+    runManager.SetUserInitialization(new SimplePhysicsList());
+
+    // ... 其他初始化和设置
+
+    // 开始模拟
+    runManager.BeamOn();
+
+    return 0;
+}
+

# 自定义物理列表类:

#include "G4VModularPhysicsList.hh"
+#include "G4ParticleDefinition.hh"
+#include "G4ProcessManager.hh"
+#include "G4Proton.hh"  // 或其他你关心的粒子
+
+class SimplePhysicsList : public G4VModularPhysicsList
+{
+public:
+    void ConstructParticle() override
+    {
+        // 创建或获取粒子类型
+        G4Proton::ProtonDefinition();
+        // ... 其他粒子
+    }
+
+    void ConstructProcess() override
+    {
+        // 获取粒子的过程管理器
+        G4ProcessManager* pManager = G4Proton::Proton()->GetProcessManager();
+
+        // 添加自定义的碰撞过程
+        pManager->AddDiscreteProcess(new SimpleCollisionProcess());
+    }
+};
+
+void YourCustomPhysicsList::ConstructProcess()
+{
+    // ... other processes
+
+    auto particleIterator = GetParticleIterator();
+    particleIterator->reset();
+
+    while ((*particleIterator)())
+    {
+        G4ParticleDefinition* particle = particleIterator->value();
+        G4ProcessManager* pmanager = particle->GetProcessManager();
+
+        if (YourCustomProcess::IsApplicable(*particle))
+        {
+            pmanager->AddDiscreteProcess(new YourCustomProcess());
+        }
+    }
+}
+

# 自定义碰撞过程类:

#include "G4VDiscreteProcess.hh"
+#include "G4Step.hh"
+#include "G4VParticleChange.hh"
+
+class SimpleCollisionProcess : public G4VDiscreteProcess
+{
+public:
+    G4VParticleChange* PostStepDoIt(const G4Track& track, const G4Step& /*step*/) override
+    {
+        // 这里执行碰撞后的粒子状态更改
+        // 例如,改变动量、能量等
+
+        aParticleChange.Initialize(track);
+        // aParticleChange.SetXXX(...);  // 设置粒子状态
+        return &aParticleChange;
+    }
+
+    G4double GetMeanFreePath(const G4Track& /*track*/, G4double /*previousStepSize*/, G4ForceCondition* /*condition*/) override
+    {
+        // 返回这个过程的平均自由路径
+        // 这里只返回一个固定的值作为示例
+        return 1.0 * cm;
+    }
+};
+

# 1. 关于必须重新定义的函数:

  • PostStepDoIt: 这个函数用于描述在一步运动后粒子的状态如何改变。这通常是必须要重写的。
  • GetMeanFreePath: 这个函数返回给定粒子在特定条件下的平均自由路径。这通常也需要重写以适应你的模型。

这两个函数通常是最主要需要重写的。然而,根据你的具体需求,有时还可能需要重写其他函数,比如:

  • AlongStepDoIt: 如果你从 G4VContinuousProcess 继承,这个函数用于描述粒子在一步中如何连续地改变。
  • IsApplicable: 这个函数决定这个过程是否应用于某个粒子。
  • AtRestDoIt: 用于描述一个静止粒子如何起始一个新的过程(如果适用)。
  • StartTrackingEndTracking: 这些是在粒子轨迹开始和结束时被调用的。

# 2. 关于 aParticleChange

aParticleChange 是一个 G4VParticleChange 对象,它用于保存由这个过程产生的粒子状态改变。当 PostStepDoIt 被调用时,你需要用它来设置新的粒子状态(如位置、动量、能量等)。这个对象通常是 G4VDiscreteProcessG4VContinuousProcess 的成员变量,由基类初始化。

例如,你可以这样设置新的动量方向:

aParticleChange.ProposeMomentumDirection(newDirection);
+

或者,设置新的能量:

aParticleChange.ProposeEnergy(newEnergy)
+

这样,在 PostStepDoIt 函数返回后,Geant4 会用 aParticleChange 中的信息来更新粒子状态。

  • aParticleChange.Initialize(track)

这个函数初始化 aParticleChange 对象,使其包含给定轨迹(track)的当前状态。这通常是你开始修改粒子状态之前的第一步。

# 3. GetMeanFreePath 的作用

GetMeanFreePath 函数是用来告知 Geant4 在多长的距离后应该调用 PostStepDoIt 函数的。简单地说,这个函数决定了一个物理过程发生的"频率"或者概率。在每一步结束后,Geant4 会评估所有的离散过程来看哪一个将被下一个执行,这一决定是基于每个过程的平均自由路径和其他概率性因素来的。

比如说,如果 GetMeanFreePath 返回了一个很小的数值,这表示该过程非常可能在下一步就会发生。相反地,一个大的返回值意味着该过程相对较不可能发生。

# 4. 多物理过程情形

# 说明:

在 Geant4 中,一粒子的轨迹(track)被分解为多个连续的 "步"(steps)。在每一步结束时,Geant4 会评估所有应用于该粒子类型的离散物理过程(例如电离、散射等)。这个评估的目的是为了决定下一步应该执行哪个过程。

假设我们有三个不同的物理过程 A、B 和 C。每一个都有自己的 GetMeanFreePath 函数,这个函数返回一个距离值,该值表示粒子在该距离后大概会经历该过程。

  1. 计算平均自由路径: 在每一步的结束,Geant4 会调用所有过程的 GetMeanFreePath 函数,获得 A、B、C 的平均自由路径,分别记作λA,λB,λC
  2. 概率性决策: 基于这些平均自由路径和其他概率性因素,Geant4 会计算哪一个过程应该下一个被执行。一种简单的方式是,选择平均自由路径最小的那个过程,因为它更可能发生。但实际的算法可能更加复杂,并考虑其他因素。
  3. 执行过程: 选定了要执行的过程(比如说是过程 A)后,Geant4 就会调用 A 的 PostStepDoIt 函数来实际模拟该过程,更新粒子的状态。
  4. 进入下一步: 根据 PostStepDoIt 的结果,粒子的状态被更新,然后开始下一步的模拟。

这样,通过在每一步结束时动态评估哪一个过程应该被执行,Geant4 能够模拟一个粒子轨迹中多种物理过程的竞争和相互作用。这是为什么需要定义 GetMeanFreePath 的原因:它为这个概率性决策提供了必要的信息。

# 示例:

#include "G4VDiscreteProcess.hh"
+#include "G4Step.hh"
+#include "G4ParticleChange.hh"
+
+class SimpleElasticScattering : public G4VDiscreteProcess {
+public:
+    // ... Constructors, destructor, etc.
+
+    G4VParticleChange* PostStepDoIt(const G4Track& track, const G4Step& step) override {
+        aParticleChange.Initialize(track);
+        // ... Do some calculations for scattering, modify aParticleChange
+        return &aParticleChange;
+    }
+
+    G4double GetMeanFreePath(const G4Track&, G4double, G4ForceCondition*) override {
+        return 1.0;  // Just a constant mean free path for demonstration
+    }
+};
+
+class EnergyAbsorption : public G4VDiscreteProcess {
+public:
+    // ... Constructors, destructor, etc.
+
+    G4VParticleChange* PostStepDoIt(const G4Track& track, const G4Step& step) override {
+        aParticleChange.Initialize(track);
+        // ... Do some calculations for energy absorption, modify aParticleChange
+        return &aParticleChange;
+    }
+
+    G4double GetMeanFreePath(const G4Track&, G4double, G4ForceCondition*) override {
+        return 2.0;  // Another constant mean free path for demonstration
+    }
+};
+

在物理列表中添加:

#include "MyPhysicsList.hh"
+#include "G4ParticleDefinition.hh"
+#include "G4ProcessManager.hh"
+
+void MyPhysicsList::ConstructProcess() {
+    // ... Other setup code
+
+    // Get the process manager for ions (or whatever particle you're interested in)
+    G4ParticleDefinition* ion = G4Ion::IonDefinition();
+    G4ProcessManager* pmanager = ion->GetProcessManager();
+
+    // Add the custom processes
+    SimpleElasticScattering* elasticScattering = new SimpleElasticScattering();
+    EnergyAbsorption* energyAbsorption = new EnergyAbsorption();
+
+    pmanager->AddDiscreteProcess(elasticScattering);
+    pmanager->AddDiscreteProcess(energyAbsorption);
+
+    // ... Other code for adding standard processes
+}
+

# 蒙特卡洛程序嵌入

G4VParticleChange* YourProcess::PostStepDoIt(const G4Track& track, const G4Step& step)
+{
+    aParticleChange.Initialize(track);
+
+    // Execute your methods
+    FreeLength();
+    ChoseCollisionAtom();
+    EleEnergyLoss();
+    EmissionAngle();
+    IonNewCondition();
+
+    // Update particle state in aParticleChange (not shown)
+    // ...
+
+    // Check whether the ion is still under processing
+    int IonFlag = 1;
+    OutOrNot(IonFlag);
+
+    // If IonFlag is changed by OutOrNot() to indicate the ion's journey is done,
+    // you might need additional logic here to finalize the ion's record.
+    // ...
+
+    return &aParticleChange;
+}
+

在 Geant4 中,如果一个粒子已经不再需要进一步处理,你通常需要更新这个粒子的状态,以便 Geant4 知道不再需要追踪这个粒子。这通常是通过设置 G4Track 的状态来完成的,具体来说,是通过 aParticleChange 对象(这通常是 G4VParticleChange 类型或其子类)。

一个简单的例子:

if (some_condition) { // Replace this with your actual stopping condition
+    aParticleChange.ProposeTrackStatus(fStopAndKill);
+}
+
+

在这里,fStopAndKill 是一个枚举值,表示该粒子应停止并被“杀死”,即不再被追踪。其他可用的状态还包括 fStopButAlive(停止但仍然“存活”,可能在以后的时间步重新开始)和 fAlive(继续运动)。

如果在 PostStepDoIt 函数中确定粒子需要被停止,你可以通过上面的代码片段来告诉 Geant4。这样,Geant4 在执行完该步骤后就会知道不再需要对这个粒子进行后续计算。

+ + + diff --git "a/Research/Research/2023-Geant4/2023.09.05-C++ Trim\347\250\213\345\272\217.html" "b/Research/Research/2023-Geant4/2023.09.05-C++ Trim\347\250\213\345\272\217.html" new file mode 100644 index 0000000..5fd8e8e --- /dev/null +++ "b/Research/Research/2023-Geant4/2023.09.05-C++ Trim\347\250\213\345\272\217.html" @@ -0,0 +1,444 @@ + + + + + + 2023.09.05-C++ Trim 程序 | Personal Blog --from Outis Li + + + + + + + + +

# 2023.09.05-C++ Trim 程序

# 每个粒子端到端的计算

void PKU_MC::DoOneIon()
+{
+	int IonFlag;
+	// init the orginal paramters for current ions
+	InitialIon();
+	IonFlag = 1;
+
+	while (IonFlag == 1) // the current ion are under processing
+	{
+		FreeLength();
+		ChoseCollisionAtom();
+		EleEnergyLoss();
+		EmissionAngle();
+		IonNewCondition();
+		ProcessRecorder();
+		OutOrNot(IonFlag);
+	} // end of one ions
+
+	CollisionRecording(); // add the results of this ion to the recording arraies
+}
+

# InitialIon()

void PKU_MC::InitialIon()
+{
+
+	E = IonEnergyEV;	// Energy
+	COSIN = cos(ALPHA); // direction to the normal
+	SINY = COSIN;
+
+	SINE = sin(ALPHA);
+	COSY = SINE;
+
+	CurrentLayer = 1;
+	IonWayLength = 0;
+	IonCollisionNo = 0;
+	X = 0;
+	Y = 0;
+}
+

# 具体计算

# 1. FreeLength()

double PKU_MC::FreeLength()
+{
+	float tempvalue;
+
+	// when the ion energy is high
+	IonCollisionNo++;
+	ReducedCollEnergy = E * F[CurrentLayer];
+	EEG = sqrt(ReducedCollEnergy * EPSDG[CurrentLayer]);
+	PMAX[CurrentLayer] = A[CurrentLayer] / (EEG + sqrt(EEG) + 0.125 * pow(EEG, 0.1));
+	IonFreeLength = 1.0 / (PI * PMAX[CurrentLayer] * PMAX[CurrentLayer] * ARHO[CurrentLayer]);
+
+	// when the ion enrgy is low
+
+	tempvalue = PKURandom();
+
+	if (IonCollisionNo == 1)
+		IonFreeLength = tempvalue * AMIN1(IonFreeLength, channelwidth);
+
+	return IonFreeLength;
+}
+
  • ReducedCollEnergy: 同样表示与被选中的原子碰撞后的"减少的"能量。
  • E: 未定义在这个函数中,但似乎是离子或粒子的能量。
  • F[CurrentLayer]: 当前层对应的一个因子,用于计算ReducedCollEnergy
  • EEG: 一个与ReducedCollEnergyEPSDG[CurrentLayer]有关的参数。
  • EPSDG[CurrentLayer]: 与当前层有关的一个常数或参数。
  • PMAX[CurrentLayer]: 当前层中的最大动量或概率。
  • A[CurrentLayer]: 当前层对应的一个参数或常数。
  • IonFreeLength: 离子的自由路径长度。
  • ARHO[CurrentLayer]: 当前层的密度或者与密度相关的一个参数。
  • channelwidth: 一个与离子自由路径长度有关的参数或者常数。

# 使用到的变量:

E, F, EPSDG, A, ARHO

# 输出(改变)的变量:

IonCollisionNo, ReducedCollEnergy, IonFreeLength, PMAX

# 2. ChoseCollisionAtom()

double PKU_MC::ChoseCollisionAtom()
+{
+
+	int MaxElement;
+	float tempRandValue;
+
+	tempRandValue = PKURandom();
+	while (tempRandValue == 0)
+	{
+		tempRandValue = PKURandom();
+	}
+	P = PMAX[CurrentLayer] * sqrt(tempRandValue);
+	MaxElement = LayerElementNo[CurrentLayer];
+
+	// decided which kinds of atoms to be knocked!
+
+	tempRandValue = PKURandom();
+
+	for (CurrentElement = 1; CurrentElement <= MaxElement; CurrentElement++)
+	{
+		tempRandValue = tempRandValue - TargetAtomConc[CurrentLayer][CurrentElement];
+		if (tempRandValue < 0)
+			break;
+	}
+	if (tempRandValue >= 0)
+		CurrentElement = LayerElementNo[CurrentLayer];
+
+	ReducedCollEnergy = FItemp[CurrentLayer][CurrentElement] * E;
+	B = P / ScreenLen[CurrentLayer][CurrentElement];
+
+	return TargetAtomNumber[CurrentLayer][CurrentElement];
+}
+
  • P: 未定义在这个函数中,但在函数内部进行了计算。可能是与粒子动量或概率有关的一个参数。
  • PMAX[CurrentLayer]: 当前层中的最大动量或概率。
  • CurrentLayer: 当前所在的层编号。
  • LayerElementNo[CurrentLayer]: 当前层包含的元素(原子)种类数量。
  • CurrentElement: 当前正在考虑的元素(原子)的编号。
  • TargetAtomConc[CurrentLayer][CurrentElement]: 当前层和元素对应的原子浓度或概率。
  • ReducedCollEnergy: 表示与被选中的原子碰撞后的"减少的"能量。
  • FItemp[CurrentLayer][CurrentElement]: 与当前层和元素有关的一个因子,用于计算ReducedCollEnergy
  • E: 未定义在这个函数中,但用于计算ReducedCollEnergy,可能是粒子的能量。
  • B: 另一个与碰撞有关的参数。
  • ScreenLen[CurrentLayer][CurrentElement]: 与当前层和元素有关的一个参数,用于计算B
  • TargetAtomNumber[CurrentLayer][CurrentElement]: 返回的是当前层和元素对应的目标原子的编号。

# 使用到的变量:

PMAX, FItemp, E, ScreenLen

# 改变的变量:

P, ReducedCollEnergy, B

# 3. EleEnergyLoss()

double PKU_MC::EleEnergyLoss()
+{
+	double Ion_Se;
+
+	IE = int(E / IonEnergyKeV + .5);
+	if (IE != 0)
+		SEE = SE[CurrentLayer][IE];
+	if (E < IonEnergyKeV)
+		SEE = SE[CurrentLayer][1] * sqrt(E / IonEnergyKeV);
+	DEE = IonFreeLength * SEE;
+	Ion_Se = DEE;
+	return Ion_Se;
+}
+
  • double Ion_Se: 存储电子或离子的能量损失。
  • IE: 一个与离子或粒子能量E有关的整数变量。
  • E: 离子或粒子的能量,未在此函数内定义。
  • IonEnergyKeV: 离子能量的一个特定单位(千电子伏特,KeV)。
  • SEE: 与离子或粒子能量损失有关的一个参数。
  • SE[CurrentLayer][IE]: 当前层和能量级对应的能量损失率。
  • DEE: 实际能量损失,是IonFreeLength(离子的自由路径长度)和SEE(能量损失率)的乘积。

# 使用的变量:

E, IonEnergyKeV, SE, IonFreeLength

# 改变的变量:

DEE,

# 4. EmissionAngle()

double PKU_MC::EmissionAngle()
+{
+	double AngleValue, R, Q;
+	// using the magic method
+
+	if (ReducedCollEnergy <= 10)
+	{
+		R = B;
+		RR = -2.7 * log(ReducedCollEnergy * B);
+		if (RR >= B)
+		{
+			RR = -2.7 * log(ReducedCollEnergy * RR);
+			if (RR >= B)
+				R = RR;
+		}
+		do
+		{
+			EX1 = 0.18175 * exp(-3.1998 * R);
+			EX2 = 0.50986 * exp(-0.94229 * R);
+			EX3 = 0.28022 * exp(-0.4029 * R);
+			EX4 = 0.028171 * exp(-0.20162 * R);
+			V = (EX1 + EX2 + EX3 + EX4) / R;
+			V1 = -(V + 3.1998 * EX1 + 0.94229 * EX2 + 0.4092 * EX3 + 0.20162 * EX4) / R;
+
+			FR = B * B / R + V * R / ReducedCollEnergy - R;
+			FR1 = -B * B / (R * R) + (V + V1 * R) / ReducedCollEnergy - 1;
+			Q = FR / FR1;
+			R = R - Q;
+		} while (fabs(Q / R) > 0.001);
+
+		ROC = -2.0 * (ReducedCollEnergy - V) / V1;
+		SQE = sqrt(ReducedCollEnergy);
+		CC = (0.011615 + SQE) / (0.0071222 + SQE);
+		AA = 2.0 * ReducedCollEnergy * (1.0 + (0.99229 / SQE)) * pow(B, CC);
+		FF = (sqrt(AA * AA + 1.0) - AA) * ((9.3066 + ReducedCollEnergy) / (14.813 + ReducedCollEnergy));
+		DELTA = (R - B) * AA * FF / (FF + 1.0);
+		CO = (B + DELTA + ROC) / (R + ROC);
+		C2 = CO * CO;
+		S2 = 1.0 - C2;
+		if (S2 < -1)
+			printf("\n%d  %lf\n", ElapsedIonNo, B);
+		CT = 2.0 * C2 - 1.0;
+		ST = sqrt(1.0 - CT * CT);
+	}
+	// using the RusefScattering methods
+	else{
+		S2 = 1.0 / (1.0 + (1.0 + B * (1.0 + B)) * (2.0 * ReducedCollEnergy * B) * (2.0 * ReducedCollEnergy * B));
+		if (S2 < -1)
+			printf("\n%d  %lf\n", ElapsedIonNo, B);
+		C2 = 1.0 - S2;
+		CT = 2.0 * C2 - 1.0;
+		ST = sqrt(1.0 - CT * CT);
+	}
+	AngleValue = acos(CT);
+	return AngleValue;
+}
+

# 使用的变量:

ReducedCollEnergy, B,

# 改变的变量:

RR, ST, S2, CT,

# 5. IonNewCondition()

double PKU_MC::IonNewCondition()
+{
+	double MAX(0), X1; // MAX is not OK!!!!!!!!!!!!!!!!!!!!!!!!!
+	float tempvalue;
+
+	DEN = recoilfactor[CurrentLayer][CurrentElement] * S2 * E;
+	E = E - DEN - DEE;
+	if (DEE > MAX)
+		MAX = DEE;
+	IonWayLength = IonWayLength + IonFreeLength - DistanceNuclear;
+
+	X = X + (IonFreeLength - DistanceNuclear) * COSIN;
+	Y = Y + (IonFreeLength - DistanceNuclear) * COSY;
+
+	I = AMIN1(fabs(X / channelwidth) + 1.0, 100.0);
+	J = AMIN1(fabs(Y / channelwidth) + 1.0, 50.0);
+
+	if ((ALPHA != 0) && (Y <= 0))
+		J = 1;
+
+	tempvalue = PKURandom();
+	PHI = 2.0 * PI * tempvalue;
+
+	PSI = atan(ST / (CT + M1_to_M2[CurrentLayer][CurrentElement]));
+	if (PSI < 0)
+		PSI = PSI + PI;
+	X1 = -COSIN * COSY / (SINE * SINY + pow(10, -8));
+	if (fabs(X1) > 1.0)
+		X1 = X1 / fabs(X1);
+	DELTA = PHI - acos(X1);
+
+	COSIN = COSIN * cos(PSI) + SINE * sin(PSI) * cos(PHI);
+	COSY = COSY * cos(PSI) + SINY * sin(PSI) * cos(DELTA);
+
+	SINY = sqrt(1.0 - COSY * COSY);
+	SINE = sqrt(1.0 - COSIN * COSIN);
+	return 1;
+}
+

# 使用的变量:

recoilfactor, DistanceNuclear, IonFreeLength, channelwidth, ALPHA, M1_to_M2,

if (channelwidth == 0)
+		channelwidth = 0.01 * LayertoSurface[3]; // for recording, the total sample are dividied into 100 segment
+

# 改变的变量:

DEN, E, IonWayLength, COSIN, COSY, X, Y, I, J, PHI, PSI, SINE, SINY, DELTA,

# 6. ProcessRecorder()

void PKU_MC::ProcessRecorder()
+{
+
+	double EPSD, EN;
+
+	// total energy
+	MTOT[I - 1][J] = MTOT[I - 1][J] + DEN + DEE;
+
+	// the nuclear energy loss treamting process
+	if (DEN < DisEnergy)
+		PhoneEDis[I] = PhoneEDis[I] + DEN;
+	else
+	{
+		EPSD = DamageEFract[CurrentLayer] * DEN;
+
+		// Modified Kinchin-Pease  model
+		EN = DEN / (1.0 + ElectronEFract[CurrentLayer] * (EPSD + 0.4 * pow(EPSD, 0.75) + 3.4 * pow(EPSD, (1.0 / 6.0))));
+
+		if (EN < DisEnergy)
+			PhoneEDis[I] = PhoneEDis[I] + DEN;
+		else
+		{
+
+			MVAC[I - 1][J] = MVAC[I - 1][J] + 1;
+			IVAC[I] = IVAC[I] + 1;
+			if (EN > 0) //!!!!
+				RPHON[I] = RPHON[I] + EN - DisEnergy;
+
+			// Multi-defect production!
+			if (EN >= 2.5 * DisEnergy)
+			{
+				MVAC[I - 1][J] = MVAC[I - 1][J] - 1.0 + 0.4 * EN / DisEnergy;
+				RPHON[I] = RPHON[I] + DisEnergy - 0.4 * EN;
+				RVAC[I] = RVAC[I] - 1.0 + 0.4 * EN / DisEnergy;
+			}
+
+			MION[I - 1][J] = MION[I - 1][J] + DEN - EN;
+			RION[I] = RION[I] + DEN - EN;
+		}
+	}
+
+	// eletric energy loss treating process
+	IonizatinEDis[I] = IonizatinEDis[I] + DEE;
+
+	MION[I - 1][J] = MION[I - 1][J] + DEE;
+}
+

# 使用的变量:

I, J, DEN, DEE, DisEnergy, DamageEFract, ElectronEFract,

# 改变的变量:

MTOT, PhoneEDis, MVAC, IVAC, RPHON, RVAC, MION, RION, IonizatinEDis,

# 7. OutOrNot(int &Ionflag)

int PKU_MC::OutOrNot(int &Ionflag)
+{
+	if (X < 0)
+	{
+		Ionflag = 0;
+		return 1;
+	}
+	else
+	{
+		if (X <= LayertoSurface[1])
+			CurrentLayer = 1;
+		else if (X <= LayertoSurface[2])
+			CurrentLayer = 2;
+		else
+			CurrentLayer = 3;
+		if (X >= LayertoSurface[CurrentLayer])
+		{
+			Ionflag = 0;
+			return 1;
+		}
+	}
+	if (E <= StoppingEnergy)
+	{
+		Ionflag = 0;
+		return 1;
+	}
+}
+

# 使用的变量:

X, LayertoSurface, StoppingEnergy, E,

# 改变的变量:

Ionflag,

# 一些注意点

  1. while 大循环内部其实就是一个 step,那这些 step 里使用到的变量应该是继承在 event 里一直用的,但是在 event 结束后这些变量在哪里初始化的
+ + + diff --git "a/Research/Research/2023-Geant4/2023.12.18-Geant4\350\207\252\345\212\250\345\214\226.html" "b/Research/Research/2023-Geant4/2023.12.18-Geant4\350\207\252\345\212\250\345\214\226.html" new file mode 100644 index 0000000..27ac19e --- /dev/null +++ "b/Research/Research/2023-Geant4/2023.12.18-Geant4\350\207\252\345\212\250\345\214\226.html" @@ -0,0 +1,357 @@ + + + + + + 2023.12.18-Geant4自动化 | Personal Blog --from Outis Li + + + + + + + + +

# 2023.12.18-Geant4自动化

# 1. CMakeLists.txtrun.mac的自动创建

# Python script to generate CMakeLists.txt and run.mac files with customizable parameters.
+
+def create_cmake_lists(project_name, executable_name, files_to_copy):
+    """
+    Creates a CMakeLists.txt with customizable project and executable names.
+    Args:
+    - project_name: Name of the project
+    - executable_name: Name of the executable
+    - files_to_copy: List of files to copy
+    Returns:
+    - A string containing the contents of the CMakeLists.txt file
+    """
+    cmake_template = f"""cmake_minimum_required(VERSION 3.16)
+project({project_name})
+
+# default build type: Debug
+if(NOT CMAKE_BUILD_TYPE)
+  set(CMAKE_BUILD_TYPE Debug)
+endif()
+
+#----------------------------------------------------------------------------
+# Find Geant4 package, activating all available UI and Vis drivers by default
+# You can set WITH_GEANT4_UIVIS to OFF via the command line or ccmake/cmake-gui
+# to build a batch mode only executable
+#
+option(WITH_GEANT4_UIVIS "Build example with Geant4 UI and Vis drivers" ON)
+if(WITH_GEANT4_UIVIS)
+  find_package(Geant4 REQUIRED ui_all vis_all)
+else()
+  find_package(Geant4 REQUIRED)
+endif()
+
+#----------------------------------------------------------------------------
+# Setup Geant4 include directories and compile definitions
+# Setup include directory for this project
+#
+include_directories(${{PROJECT_SOURCE_DIR}}/include)
+include(${{Geant4_USE_FILE}})
+
+#----------------------------------------------------------------------------
+# Locate sources and headers for this project
+# NB: headers are included so they will show up in IDEs
+#
+file(GLOB sources ${{PROJECT_SOURCE_DIR}}/src/*.cc)
+file(GLOB headers ${{PROJECT_SOURCE_DIR}}/include/*.hh)
+
+#----------------------------------------------------------------------------
+# Add the executable, and link it to the Geant4 libraries
+#
+add_executable({executable_name} main.cc ${{sources}} ${{headers}})
+# target_compile_definitions({executable_name} PUBLIC G4GEOM_USE_USOLIDS)
+target_link_libraries({executable_name} ${{Geant4_LIBRARIES}})
+
+#----------------------------------------------------------------------------
+# Copy all scripts to the build directory, i.e. the directory in which we
+# build PKU_Trim_Geant4. This is so that we can run the executable directly
+# because it relies on these scripts being in the current working directory.
+#
+set(FILES_TO_COPY{files_to_copy})
+foreach(_script ${{FILES_TO_COPY}})
+  configure_file(
+    ${{PROJECT_SOURCE_DIR}}/${{_script}}
+    ${{PROJECT_BINARY_DIR}}/${{_script}}
+    COPYONLY
+    )
+endforeach()
+"""
+    return cmake_template
+
+def create_run_mac(
+    numberOfThreads, outputFileName, iondefinition, ionenergy, numberOfIons
+):
+    """
+    Creates a run.mac file with customizable parameters.
+    Args:
+    - numberOfThreads: Number of threads
+    - outputFileName: Name of the output file
+    - iondefinition: Ion definition (Z A Q E)
+    - ionenergy: Ion energy
+    - numberOfIons: Number of ions
+    Returns:
+    - A string containing the contents of the run.mac file
+    """
+    run_mac_content = f"""# Macro file for the runtime control of the example
+
+# Minimal run.mac file for testing the application
+
+# Set number of threads
+# /run/numberOfThreads {numberOfThreads}
+# /tracking/verbose 2
+
+# Initialize kernel
+/run/initialize
+/myApp/setOutputFileName {outputFileName}
+
+# Start simulation
+/gun/particle ion
+/gun/ion {iondefinition}
+/gun/energy {ionenergy}
+/run/beamOn {numberOfIons}
+"""
+    return run_mac_content
+
+if __name__ == "__main__":
+    # Default values
+    project_name = "PKU_Trim_Geant4"
+    executable_name = "PKU_Trim_Geant4"
+    files_to_copy = """
+    init_vis.mac
+    vis.mac
+    run.mac
+    scoef.data
+    scoefh.data
+    thresholds.txt
+  """
+
+    # Generate CMakeLists.txt
+    cmake_content = create_cmake_lists(project_name, executable_name, files_to_copy)
+
+    outputFileName = "FinFET_p_2MeV.txt"
+    iondefinition = "1 1 0 0"  # Z A Q E
+    ionenergy = "2 MeV"
+    numberOfIons = 10000
+
+    # Generate run.mac
+    run_mac_content = create_run_mac(
+        4, outputFileName, iondefinition, ionenergy, numberOfIons
+    )
+
+    # Define the paths for the output files
+    cmake_lists_path = "./CMakeLists.txt"
+    run_mac_path = "./run.mac"
+
+    # Write the contents to the respective files
+    with open(cmake_lists_path, "w") as cmake_file:
+        cmake_file.write(cmake_content)
+
+    with open(run_mac_path, "w") as run_mac_file:
+        run_mac_file.write(run_mac_content)
+

# CMakeLists.txt中:

executable_name:生成的可执行文件名

files_to_copy:需要复制到build文件夹中的内容

# run.mac

numberOfThreads:Geant4运行时使用的核心数(若使用Docker可不填)

outputFileName:Geant4产生的数据文件名

iondefinition:入射离子类型 # Z A Q E

ionenergy:入射离子能量

numberOfIons:入射离子数

# 2. Docker自动化

# Dockerfile

# 原单Geant4镜像
+FROM outispku/geant4:v1
+
+# 指定启动脚本
+COPY start.sh /
+RUN chmod +x /start.sh
+RUN mkdir program
+ENTRYPOINT ["/start.sh"]
+

# start.sh

#!/bin/bash
+
+# Source Geant4 environment scripts
+source /geant4/bin/geant4.sh
+source /geant4/share/Geant4/geant4make/geant4make.sh
+
+# 获取系统的线程数
+NUM_THREADS=$(expr $(nproc) - 1)
+
+cd /program
+
+# 构建命令
+CMD_TO_ADD="/run/numberOfThreads $NUM_THREADS"
+
+# 将命令添加到 run.mac 的第一行
+# 注意不要重复添加
+sed -i "1i $CMD_TO_ADD" ./run.mac
+
+# 定义目录路径
+BUILD_DIR="/program/build"
+
+# 检查目录是否存在
+if [ -d "$BUILD_DIR" ]; then
+    # 如果目录存在,删除它
+    rm -rf "$BUILD_DIR"
+fi
+
+# 创建新的目录
+mkdir -p "$BUILD_DIR"
+cd build
+cmake ..
+make -j $NUM_THREADS
+# PKU_Trim_Geant4 为程序名称(可执行文件),由CMakeLists.txt中的add_executable(PKU_Trim_Geant4 PKU_Trim_Geant4.cc)决定
+# 使用前请修改
+./PKU_Trim_Geant4 run.mac > /dev/null 2>>error.txt
+
  1. 默认采用处理器最大核心数减1作为使用的核心数量

  2. 默认程序名为PKU_Trim_Geant4,若在CMakeLists中修改,请重新使用Dockerfile创建镜像

    docker build -t outispku/geant4:v2 . 
    +# -t 后为新镜像名
    +
  3. 创建共享文件路径并运行容器

    docker run -v D:\FinFET:/program --name geant4_program outispku/geant4:v2
    +# -v 后为映射本地路径到容器内(共享项目文件)(program为容器内路径,请不要修改)
    +# --name 为容器名
    +
+ + + diff --git a/Research/Research/2023.12.12-Docker.html b/Research/Research/2023.12.12-Docker.html new file mode 100644 index 0000000..272ae8f --- /dev/null +++ b/Research/Research/2023.12.12-Docker.html @@ -0,0 +1,170 @@ + + + + + + 2023.12.12-Docker | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git "a/Research/Research/2023.12.12-Docker/01.Docker \347\256\200\344\273\213\345\222\214\345\256\211\350\243\205.html" "b/Research/Research/2023.12.12-Docker/01.Docker \347\256\200\344\273\213\345\222\214\345\256\211\350\243\205.html" new file mode 100644 index 0000000..132382e --- /dev/null +++ "b/Research/Research/2023.12.12-Docker/01.Docker \347\256\200\344\273\213\345\222\214\345\256\211\350\243\205.html" @@ -0,0 +1,170 @@ + + + + + + 01. 🎉 Docker 简介和安装 | Personal Blog --from Outis Li + + + + + + + + +

# 01. 🎉 Docker 简介和安装

# Docker 是什么

Docker 是一个应用打包、分发、部署的工具

你也可以把它理解为一个轻量的虚拟机,它只虚拟你软件需要的运行环境,多余的一点都不要,

而普通虚拟机则是一个完整而庞大的系统,包含各种不管你要不要的软件。

# 跟普通虚拟机的对比

特性 普通虚拟机 Docker
跨平台 通常只能在桌面级系统运行,例如 Windows/Mac,无法在不带图形界面的服务器上运行 支持的系统非常多,各类 windows 和 Linux 都支持
性能 性能损耗大,内存占用高,因为是把整个完整系统都虚拟出来了 性能好,只虚拟软件所需运行环境,最大化减少没用的配置
自动化 需要手动安装所有东西 一个命令就可以自动部署好所需环境
稳定性 稳定性不高,不同系统差异大 稳定性好,不同系统都一样部署方式

# 打包、分发、部署

打包:就是把你软件运行所需的依赖、第三方库、软件打包到一起,变成一个安装包

分发:你可以把你打包好的“安装包”上传到一个镜像仓库,其他人可以非常方便的获取和安装

部署:拿着“安装包”就可以一个命令运行起来你的应用,自动模拟出一摸一样的运行环境,不管是在 Windows/Mac/Linux。

Untitled

# Docker 部署的优势

常规应用开发部署方式:自己在 Windows 上开发、测试 --> 到 Linux 服务器配置运行环境部署。

问题:我机器上跑都没问题,怎么到服务器就各种问题了

用 Docker 开发部署流程:自己在 Windows 上开发、测试 --> 打包为 Docker 镜像(可以理解为软件安装包) --> 各种服务器上只需要一个命令部署好

优点:确保了不同机器上跑都是一致的运行环境,不会出现我机器上跑正常,你机器跑就有问题的情况。

例如 易文档 (opens new window)SVNBucket (opens new window) 的私有化部署就是用 Docker,轻松应对客户的各种服务器。

# Docker 通常用来做什么

  • 应用分发、部署,方便传播给他人安装。特别是开源软件和提供私有部署的应用
  • 快速安装测试/学习软件,用完就丢(类似小程序),不把时间浪费在安装软件上。例如 Redis / MongoDB / ElasticSearch / ELK
  • 多个版本软件共存,不污染系统,例如 Python2、Python3,Redis4.0,Redis5.0
  • Windows 上体验/学习各种 Linux 系统

# 重要概念:镜像、容器

镜像:可以理解为软件安装包,可以方便的进行传播和安装。

容器:软件安装后的状态,每个软件运行环境都是独立的、隔离的,称之为容器。

# 安装

桌面版:https://www.docker.com/products/docker-desktop (opens new window)

服务器版:https://docs.docker.com/engine/install/#server (opens new window)

# 启动报错解决

报错截图

Untitled

解决方法

控制面板->程序->启用或关闭 windows 功能,开启 Windows 虚拟化和 Linux 子系统(WSL2)

Untitled

命令行安装 Linux 内核

wsl.exe --install -d Ubuntu

你也可以打开微软商店 Microsoft Store 搜索 Linux 进行安装,选择一个最新版本的 Ubuntu 或者 Debian 都可以

上面命令很可能你安装不了,微软商店你也可能打不开,如果遇到这个问题,参考:https://blog.csdn.net/qq_42220935/article/details/104714114

设置开机启动 Hypervisor

bcdedit /set hypervisorlaunchtype auto

注意要用管理员权限打开 PowerShell

设置默认使用版本2

wsl.exe --set-default-version 2

查看 WSL 是否安装正确

wsl.exe --list --verbose

应该如下图,可以看到一个 Linux 系统,名字你的不一定跟我的一样,看你安装的是什么版本。

并且 VERSION 是 2

Untitled

确保 BIOS 已开启虚拟化,下图检查是否已开启好

如果是已禁用,请在开机时按 F2 进入 BIOS 开启一下,不会设置的可以网上搜索下自己主板的设置方法,Intel 和 AMD 的设置可能稍有不同

Untitled

出现下图错误,点击链接安装最新版本的 WSL2

https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi (opens new window)

Untitled

# 镜像加速源

镜像加速器 镜像加速器地址
Docker 中国官方镜像 https://registry.docker-cn.com
DaoCloud 镜像站 http://f1361db2.m.daocloud.io
Azure 中国镜像 https://dockerhub.azk8s.cn
科大镜像站 https://docker.mirrors.ustc.edu.cn
阿里云 https://ud6340vz.mirror.aliyuncs.com
七牛云 https://reg-mirror.qiniu.com
网易云 https://hub-mirror.c.163.com
腾讯云 https://mirror.ccs.tencentyun.com

"registry-mirrors": ["https://registry.docker-cn.com"]

Untitled

+ + + diff --git "a/Research/Research/2023.12.12-Docker/02.Docker \345\277\253\351\200\237\345\256\211\350\243\205\350\275\257\344\273\266.html" "b/Research/Research/2023.12.12-Docker/02.Docker \345\277\253\351\200\237\345\256\211\350\243\205\350\275\257\344\273\266.html" new file mode 100644 index 0000000..e304e91 --- /dev/null +++ "b/Research/Research/2023.12.12-Docker/02.Docker \345\277\253\351\200\237\345\256\211\350\243\205\350\275\257\344\273\266.html" @@ -0,0 +1,208 @@ + + + + + + 02. 💻 Docker 快速安装软件 | Personal Blog --from Outis Li + + + + + + + + +

# 02. 💻 Docker 快速安装软件

# 直接安装的缺点

  • 安装麻烦,可能有各种依赖,运行报错。例如:WordPress,ElasticSearch,Redis,ELK
  • 可能对 Windows 并不友好,运行有各种兼容问题,软件只支持 Linux 上跑
  • 不方便安装多版本软件,不能共存。
  • 电脑安装了一堆软件,拖慢电脑速度。
  • 不同系统和硬件,安装方式不一样

本文档课件配套 视频教程

# Docker 安装的优点

  • 一个命令就可以安装好,快速方便
  • 有大量的镜像,可直接使用
  • 没有系统兼容问题,Linux 专享软件也照样跑
  • 支持软件多版本共存
  • 用完就丢,不拖慢电脑速度
  • 不同系统和硬件,只要安装好 Docker 其他都一样了,一个命令搞定所有

# 演示 Docker 安装 Redis

Redis 官网:https://redis.io/ (opens new window)

官网下载安装教程只有源码安装方式,没有 Windows 版本。想要自己安装 windows 版本需要去找别人编译好的安装包。

Docker 官方镜像仓库查找 Redis :https://hub.docker.com/ (opens new window)

https://cos.easydoc.net/46901064/files/kv8zs4qr.png

一个命令跑起来:docker run -d -p 6379:6379 --name redis redis:latest

命令参考:https://docs.docker.com/engine/reference/commandline/run/ (opens new window)

https://cos.easydoc.net/46901064/files/kv8zy4xn.png

# 安装 Wordpress

docker-compose.yml

version: '3.1'
+
+services:
+
+  wordpress:
+    image: wordpress
+    restart: always
+    ports:
+      - 8080:80
+    environment:
+      WORDPRESS_DB_HOST: db
+      WORDPRESS_DB_USER: exampleuser
+      WORDPRESS_DB_PASSWORD: examplepass
+      WORDPRESS_DB_NAME: exampledb
+    volumes:
+      - wordpress:/var/www/html
+
+  db:
+    image: mysql:5.7
+    restart: always
+    environment:
+      MYSQL_DATABASE: exampledb
+      MYSQL_USER: exampleuser
+      MYSQL_PASSWORD: examplepass
+      MYSQL_RANDOM_ROOT_PASSWORD: '1'
+    volumes:
+      - db:/var/lib/mysql
+
+volumes:
+  wordpress:
+  db:
+

# 安装 ELK

docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -it --name elk sebp/elk

内存不够解决方法 (opens new window)

转到用户目录 cd ~,路径类似这个:C:\Users\<UserName>

创建 .wslconfig 文件填入以下内容

[wsl2]
+memory=10GB # Limits VM memory in WSL 2 to 4 GB
+processors=2 # Makes the WSL 2 VM use two virtual processors
+

生效配置,命令行运行 wsl --shutdown

# 更多相关命令

docker ps 查看当前运行中的容器

docker images 查看镜像列表

docker rm container-id 删除指定 id 的容器

docker stop/start container-id 停止/启动指定 id 的容器

docker rmi image-id 删除指定 id 的镜像

docker volume ls 查看 volume 列表

docker network ls 查看网络列表

+ + + diff --git "a/Research/Research/2023.12.12-Docker/03.\345\210\266\344\275\234\350\207\252\345\267\261\347\232\204\351\225\234\345\203\217.html" "b/Research/Research/2023.12.12-Docker/03.\345\210\266\344\275\234\350\207\252\345\267\261\347\232\204\351\225\234\345\203\217.html" new file mode 100644 index 0000000..26b681c --- /dev/null +++ "b/Research/Research/2023.12.12-Docker/03.\345\210\266\344\275\234\350\207\252\345\267\261\347\232\204\351\225\234\345\203\217.html" @@ -0,0 +1,192 @@ + + + + + + 03. 💽 制作自己的镜像 | Personal Blog --from Outis Li + + + + + + + + +

# 03. 💽 制作自己的镜像

# 为自己的 Web 项目构建镜像

示例项目代码:https://github.com/gzyunke/test-docker (opens new window)

这是一个 Nodejs + Koa2 写的 Web 项目,提供了简单的两个演示页面。

软件依赖:nodejs (opens new window)

项目依赖库:koa、log4js、koa-router

本文档课件配套 视频教程

# 编写 Dockerfile

FROM node:11
+MAINTAINER easydoc.net
+
+# 复制代码
+ADD . /app
+
+# 设置容器启动后的默认运行目录
+WORKDIR /app
+
+# 运行命令,安装依赖
+# RUN 命令可以有多个,但是可以用 && 连接多个命令来减少层级。
+# 例如 RUN npm install && cd /app && mkdir logs
+RUN npm install --registry=https://registry.npm.taobao.org
+
+# CMD 指令只能一个,是容器启动后执行的命令,算是程序的入口。
+# 如果还需要运行其他命令可以用 && 连接,也可以写成一个shell脚本去执行。
+# 例如 CMD cd /app && ./start.sh
+CMD node app.js
+

Dockerfile文档 (opens new window)

实用技巧:

如果你写 Dockerfile 时经常遇到一些运行错误,依赖错误等,你可以直接运行一个依赖的底,然后进入终端进行配置环境,成功后再把做过的步骤命令写道 Dockerfile 文件中,这样编写调试会快很多。

例如上面的底是node:11,我们可以运行docker run -it -d node:11 bash,跑起来后进入容器终端配置依赖的软件,然后尝试跑起来自己的软件,最后把所有做过的步骤写入到 Dockerfile 就好了。

掌握好这个技巧,你的 Dockerfile 文件编写起来就非常的得心应手了。

# Build 为镜像(安装包)和运行

编译 docker build -t test:v1 .

-t 设置镜像名字和版本号

命令参考:https://docs.docker.com/engine/reference/commandline/build/ (opens new window)

运行 docker run -p 8080:8080 --name test-hello test:v1

-p 映射容器内端口到宿主机

  • -name 容器名字
  • d 后台运行

命令参考文档:https://docs.docker.com/engine/reference/run/ (opens new window)

# 更多相关命令

docker ps 查看当前运行中的容器

docker images 查看镜像列表

docker rm container-id 删除指定 id 的容器

docker stop/start container-id 停止/启动指定 id 的容器

docker rmi image-id 删除指定 id 的镜像

docker volume ls 查看 volume 列表

docker network ls 查看网络列表

+ + + diff --git "a/Research/Research/2023.12.12-Docker/04.\347\233\256\345\275\225\346\214\202\350\275\275.html" "b/Research/Research/2023.12.12-Docker/04.\347\233\256\345\275\225\346\214\202\350\275\275.html" new file mode 100644 index 0000000..a82d2b5 --- /dev/null +++ "b/Research/Research/2023.12.12-Docker/04.\347\233\256\345\275\225\346\214\202\350\275\275.html" @@ -0,0 +1,174 @@ + + + + + + 04. 🥙 目录挂载 | Personal Blog --from Outis Li + + + + + + + + +

# 04. 🥙 目录挂载

# 现存问题

  • 使用 Docker 运行后,我们改了项目代码不会立刻生效,需要重新buildrun,很是麻烦。
  • 容器里面产生的数据,例如 log 文件,数据库备份文件,容器删除后就丢失了。

目录挂载解决以上问题

本文档课件配套 视频教程

# 几种挂载方式

  • bind mount 直接把宿主机目录映射到容器内,适合挂代码目录和配置文件。可挂到多个容器上
  • volume 由容器创建和管理,创建在宿主机,所以删除容器不会丢失,官方推荐,更高效,Linux 文件系统,适合存储数据库数据。可挂到多个容器上
  • tmpfs mount 适合存储临时文件,存宿主机内存中。不可多容器共享。

文档参考:https://docs.docker.com/storage/ (opens new window)

Untitled

# 挂载演示

bind mount 方式用绝对路径 -v D:/code:/app

volume 方式,只需要一个名字 -v db-data:/app

示例:

docker run -p 8080:8080 --name test-hello -v D:/code:/app -d test:v1

注意!

因为挂载后,容器里的代码就会替换为你本机的代码了,如果你代码目录没有node_modules目录,你需要在代码目录执行下npm install --registry=https://registry.npm.taobao.org确保依赖库都已经安装,否则可能会提示“Error: Cannot find module ‘koa’”

如果你的电脑没有安装 nodejs (opens new window),你需要安装一下才能执行上面的命令。

+ + + diff --git "a/Research/Research/2023.12.12-Docker/05.\345\244\232\345\256\271\345\231\250\351\200\232\344\277\241.html" "b/Research/Research/2023.12.12-Docker/05.\345\244\232\345\256\271\345\231\250\351\200\232\344\277\241.html" new file mode 100644 index 0000000..31d595d --- /dev/null +++ "b/Research/Research/2023.12.12-Docker/05.\345\244\232\345\256\271\345\231\250\351\200\232\344\277\241.html" @@ -0,0 +1,174 @@ + + + + + + 05. 👨‍👦‍👦 多容器通信 | Personal Blog --from Outis Li + + + + + + + + +

# 05. 👨‍👦‍👦 多容器通信

# 学习目标

项目往往都不是独立运行的,需要数据库、缓存这些东西配合运作。

这节我们把前面的 Web 项目增加一个 Redis 依赖,多跑一个 Redis 容器,演示如何多容器之间的通信。

本文档课件配套 视频教程

# 创建虚拟网络

要想多容器之间互通,从 Web 容器访问 Redis 容器,我们只需要把他们放到同个网络中就可以了。

文档参考:https://docs.docker.com/engine/reference/commandline/network/ (opens new window)

# 演示

# 创建一个名为test-net的网络:

docker network create test-net

# 运行 Redis 在 test-net 网络中,别名redis

docker run -d --name redis --network test-net --network-alias redis redis:latest

# 修改代码中访问redis的地址为网络别名

https://cos.easydoc.net/46901064/files/kv98rfvb.png

# 运行 Web 项目,使用同个网络

docker run -p 8080:8080 --name test -v D:/test:/app --network test-net -d test:v1

# 查看数据

http://localhost:8080/redis

容器终端查看数据是否一致

# 更多相关命令

docker ps 查看当前运行中的容器

docker images 查看镜像列表

docker rm container-id 删除指定 id 的容器

docker stop/start container-id 停止/启动指定 id 的容器

docker rmi image-id 删除指定 id 的镜像

docker volume ls 查看 volume 列表

docker network ls 查看网络列表

+ + + diff --git a/Research/Research/2023.12.12-Docker/06.Docker-Compose.html b/Research/Research/2023.12.12-Docker/06.Docker-Compose.html new file mode 100644 index 0000000..740dd21 --- /dev/null +++ b/Research/Research/2023.12.12-Docker/06.Docker-Compose.html @@ -0,0 +1,194 @@ + + + + + + 06. 🍁 Docker-Compose | Personal Blog --from Outis Li + + + + + + + + +

# 06. 🍁 Docker-Compose

# 现存问题

在上节,我们运行了两个容器:Web 项目 + Redis

如果项目依赖更多的第三方软件,我们需要管理的容器就更加多,每个都要单独配置运行,指定网络。

这节,我们使用 docker-compose 把项目的多个服务集合到一起,一键运行。

本文档课件配套 视频教程

# 安装 Docker Compose

  • 如果你是安装的桌面版 Docker,不需要额外安装,已经包含了。
  • 如果是没图形界面的服务器版 Docker,你需要单独安装 安装文档 (opens new window)
  • 运行docker-compose检查是否安装成功

# 编写脚本

要把项目依赖的多个服务集合到一起,我们需要编写一个docker-compose.yml文件,描述依赖哪些服务

参考文档:https://docs.docker.com/compose/ (opens new window)

version: "3.7"
+
+services:
+  app:
+    build: ./
+    ports:
+      - 80:8080
+    volumes:
+      - ./:/app
+    environment:
+      - TZ=Asia/Shanghai
+  redis:
+    image: redis:5.0.13
+    volumes:
+      - redis:/data
+    environment:
+      - TZ=Asia/Shanghai
+
+volumes:
+  redis:
+

容器默认时间不是北京时间,增加 TZ=Asia/Shanghai 可以改为北京时间

# 跑起来

docker-compose.yml 文件所在目录,执行:docker-compose up就可以跑起来了。

命令参考:https://docs.docker.com/compose/reference/up/ (opens new window)

在后台运行只需要加一个 -d 参数docker-compose up -d

查看运行状态:docker-compose ps

停止运行:docker-compose stop

重启:docker-compose restart

重启单个服务:docker-compose restart service-name

进入容器命令行:docker-compose exec service-name sh

查看容器运行log:docker-compose logs [service-name]

+ + + diff --git "a/Research/Research/2023.12.12-Docker/07.\345\217\221\345\270\203\345\222\214\351\203\250\347\275\262.html" "b/Research/Research/2023.12.12-Docker/07.\345\217\221\345\270\203\345\222\214\351\203\250\347\275\262.html" new file mode 100644 index 0000000..a8ac049 --- /dev/null +++ "b/Research/Research/2023.12.12-Docker/07.\345\217\221\345\270\203\345\222\214\351\203\250\347\275\262.html" @@ -0,0 +1,195 @@ + + + + + + 07. 🚚 发布和部署 | Personal Blog --from Outis Li + + + + + + + + +

# 07. 🚚 发布和部署

# 🚚 发布和部署

# 镜像仓库介绍

镜像仓库用来存储我们 build 出来的“安装包”,Docker 官方提供了一个 镜像库 (opens new window),里面包含了大量镜像,基本各种软件所需依赖都有,要什么直接上去搜索。

我们也可以把自己 build 出来的镜像上传到 docker 提供的镜像库中,方便传播。

当然你也可以搭建自己的私有镜像库,或者使用国内各种大厂提供的镜像托管服务,例如:阿里云、腾讯云

本文档课件配套 视频教程

# 上传我们的镜像

  • 首先你要先 注册一个账号 (opens new window)

  • 创建一个镜像库

    https://cos.easydoc.net/46901064/files/kv9a2wty.png

  • 命令行登录账号:docker login -u username

  • 新建一个tag,名字必须跟你注册账号一样docker tag test:v1 username/test:v1

  • 推上去docker push username/test:v1

  • 部署试下docker run -dp 8080:8080 username/test:v1

# docker-compose 中也可以直接用这个镜像了

version: "3.7"
+
+services:
+  app:
+#    build: ./
+    image: helloguguji/test:v1
+    ports:
+      - 80:8080
+    volumes:
+      - ./:/app
+    environment:
+      - TZ=Asia/Shanghai
+  redis:
+    image: redis:5.0.13
+    volumes:
+      - redis:/data
+    environment:
+      - TZ=Asia/Shanghai
+
+volumes:
+  redis:
+

# 阿里云容器托管

docker 官方的镜像托管有时候上传和下载都太慢了,如果你想要更快的速度,可以使用阿里云的免费镜像托管

登录 阿里云 (opens new window)

https://cos.easydoc.net/46901064/files/kv9dqxuo.png

+ + + diff --git "a/Research/Research/2023.12.12-Docker/08.\345\244\207\344\273\275\345\222\214\350\277\201\347\247\273\346\225\260\346\215\256.html" "b/Research/Research/2023.12.12-Docker/08.\345\244\207\344\273\275\345\222\214\350\277\201\347\247\273\346\225\260\346\215\256.html" new file mode 100644 index 0000000..656b9f2 --- /dev/null +++ "b/Research/Research/2023.12.12-Docker/08.\345\244\207\344\273\275\345\222\214\350\277\201\347\247\273\346\225\260\346\215\256.html" @@ -0,0 +1,174 @@ + + + + + + 08. 🎯 备份和迁移数据 | Personal Blog --from Outis Li + + + + + + + + +

# 08. 🎯 备份和迁移数据

# 迁移方式介绍

容器中的数据,如果没有用挂载目录,删除容器后就会丢失数据。

前面我们已经讲解了如何 挂载目录

如果你是用bind mount直接把宿主机的目录挂进去容器,那迁移数据很方便,直接复制目录就好了

如果你是用volume方式挂载的,由于数据是由容器创建和管理的,需要用特殊的方式把数据弄出来。

本文档课件配套 视频教程

# 备份和导入 Volume 的流程

备份:

  • 运行一个 ubuntu 的容器,挂载需要备份的 volume 到容器,并且挂载宿主机目录到容器里的备份目录。
  • 运行 tar 命令把数据压缩为一个文件
  • 把备份文件复制到需要导入的机器

导入:

  • 运行 ubuntu 容器,挂载容器的 volume,并且挂载宿主机备份文件所在目录到容器里
  • 运行 tar 命令解压备份文件到指定目录

# 备份 MongoDB 数据演示

  • 运行一个 mongodb,创建一个名叫mongo-data的 volume 指向容器的 /data 目录

    docker run -p 27018:27017 --name mongo -v mongo-data:/data -d mongo:4.4

  • 运行一个 Ubuntu 的容器,挂载mongo容器的所有 volume,映射宿主机的 backup 目录到容器里面的 /backup 目录,然后运行 tar 命令把数据压缩打包

    docker run --rm --volumes-from mongo -v d:/backup:/backup ubuntu tar cvf /backup/backup.tar /data/

最后你就可以拿着这个 backup.tar 文件去其他地方导入了。

# 恢复 Volume 数据演示

  • 运行一个 ubuntu 容器,挂载 mongo 容器的所有 volumes,然后读取 /backup 目录中的备份文件,解压到 /data/ 目录docker run --rm --volumes-from mongo -v d:/backup:/backup ubuntu bash -c "cd /data/ && tar xvf /backup/backup.tar --strip 1"

注意,volumes-from 指定的是容器名字

strip 1 表示解压时去掉前面1层目录,因为压缩时包含了绝对路径


+ + + diff --git "a/Research/Research/2023.12.12-Docker/2023.12.12-\345\210\266\344\275\234\345\256\232\345\210\266\351\225\234\345\203\217.html" "b/Research/Research/2023.12.12-Docker/2023.12.12-\345\210\266\344\275\234\345\256\232\345\210\266\351\225\234\345\203\217.html" new file mode 100644 index 0000000..d3b1dbf --- /dev/null +++ "b/Research/Research/2023.12.12-Docker/2023.12.12-\345\210\266\344\275\234\345\256\232\345\210\266\351\225\234\345\203\217.html" @@ -0,0 +1,218 @@ + + + + + + 2023.12.12-制作定制镜像 | Personal Blog --from Outis Li + + + + + + + + +

# 2023.12.12-制作定制镜像

# 1. 获取Ubuntu系统

docker run -it ubuntu:22.04 /bin/bash
+

Untitled

# 2. 在容器内配置容器

apt-get update && apt-get upgrade
+

# 3. 将容器打包成镜像

docker commit -m="geant4 installed" -a="OutisPKU" f87240cdb380 outispku/geant4:v1
+

# 4. 将镜像实例化为容器并运行终端

docker run -it -v D:\BaiduSyncdisk\Postgraduate\Research\Geant4\Project:/home --name geant4_test outispku/geant4:v1 /bin/bash
+

其中-v D:\BaiduSyncdisk\Postgraduate\Research\Geant4\Project:/home为将主机的目录映射到容器中

# 使用Dockerfile创建镜像

# 1. 编写容器启动脚本start.sh

#!/bin/bash
+
+# Source Geant4 environment scripts
+source /geant4/bin/geant4.sh
+source /geant4/share/Geant4/geant4make/geant4make.sh
+
+# 获取系统的线程数
+NUM_THREADS=$(expr $(nproc) - 1)
+
+cd /program
+
+# 构建命令
+CMD_TO_ADD="/run/numberOfThreads $NUM_THREADS"
+
+# 将命令添加到 run.mac 的第一行
+sed -i "1i $CMD_TO_ADD" ./run.mac
+
+# 定义目录路径
+BUILD_DIR="/program/build"
+
+# 检查目录是否存在
+if [ -d "$BUILD_DIR" ]; then
+    # 如果目录存在,删除它
+    rm -rf "$BUILD_DIR"
+fi
+
+# 创建新的目录
+mkdir -p "$BUILD_DIR"
+cd build
+cmake ..
+make -j $NUM_THREADS
+# PKU_Trim_Geant4 为程序名称(可执行文件),由CMakeLists.txt中的add_executable(PKU_Trim_Geant4 PKU_Trim_Geant4.cc)决定
+# 使用前请修改
+./PKU_Trim_Geant4 run.mac > /dev/null 2>>error.txt
+

# 2. 编写Dockerfile

# 原单Geant4镜像
+FROM outispku/geant4:v1
+
+# 指定启动脚本
+COPY start.sh /
+RUN chmod +x /start.sh
+RUN mkdir program
+ENTRYPOINT ["/start.sh"]
+

# 3. 构建镜像

docker build -t outispku/geant4:v2 .
+

# 4. 运行容器

docker run -v D:\FinFET:/program --name geant4_program outispku/geant4:v2
+
+ + + diff --git a/Research/index.html b/Research/index.html new file mode 100644 index 0000000..11ab366 --- /dev/null +++ b/Research/index.html @@ -0,0 +1,166 @@ + + + + + + Research | Personal Blog --from Outis Li + + + + + + + + +
+ + + diff --git a/about/index.html b/about/index.html new file mode 100644 index 0000000..543309c --- /dev/null +++ b/about/index.html @@ -0,0 +1,166 @@ + + + + + + Helloworld | Personal Blog --from Outis Li + + + + + + + + +

# Helloworld

+ + + diff --git a/assets/css/0.styles.9501ef99.css b/assets/css/0.styles.9501ef99.css new file mode 100644 index 0000000..db4460f --- /dev/null +++ b/assets/css/0.styles.9501ef99.css @@ -0,0 +1 @@ +code[class*=language-],pre[class*=language-]{color:#ccc;background:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}.theme-default-content code{color:#476582;padding:.25rem .5rem;margin:0;font-size:.85em;background-color:rgba(27,31,35,.05);border-radius:3px}.theme-default-content code .token.deleted{color:#ec5975}.theme-default-content code .token.inserted{color:#3eaf7c}.theme-default-content pre,.theme-default-content pre[class*=language-]{line-height:1.4;padding:1.25rem 1.5rem;margin:.85rem 0;background-color:#282c34;border-radius:6px;overflow:auto}.theme-default-content pre[class*=language-] code,.theme-default-content pre code{color:#fff;padding:0;background-color:transparent;border-radius:0}div[class*=language-]{position:relative;background-color:#282c34;border-radius:6px}div[class*=language-] .highlight-lines{-webkit-user-select:none;user-select:none;padding-top:1.3rem;position:absolute;top:0;left:0;width:100%;line-height:1.4}div[class*=language-] .highlight-lines .highlighted{background-color:rgba(0,0,0,.66)}div[class*=language-] pre,div[class*=language-] pre[class*=language-]{background:transparent;position:relative;z-index:1}div[class*=language-]:before{position:absolute;z-index:3;top:.8em;right:1em;font-size:.75rem;color:hsla(0,0%,100%,.4)}div[class*=language-]:not(.line-numbers-mode) .line-numbers-wrapper{display:none}div[class*=language-].line-numbers-mode .highlight-lines .highlighted{position:relative}div[class*=language-].line-numbers-mode .highlight-lines .highlighted:before{content:" ";position:absolute;z-index:3;left:0;top:0;display:block;width:3.5rem;height:100%;background-color:rgba(0,0,0,.66)}div[class*=language-].line-numbers-mode pre{padding-left:4.5rem;vertical-align:middle}div[class*=language-].line-numbers-mode .line-numbers-wrapper{position:absolute;top:0;width:3.5rem;text-align:center;color:hsla(0,0%,100%,.3);padding:1.25rem 0;line-height:1.4}div[class*=language-].line-numbers-mode .line-numbers-wrapper br{-webkit-user-select:none;user-select:none}div[class*=language-].line-numbers-mode .line-numbers-wrapper .line-number{position:relative;z-index:4;-webkit-user-select:none;user-select:none;font-size:.85em}div[class*=language-].line-numbers-mode:after{content:"";position:absolute;z-index:2;top:0;left:0;width:3.5rem;height:100%;border-radius:6px 0 0 6px;border-right:1px solid rgba(0,0,0,.66);background-color:#282c34}div[class~=language-js]:before{content:"js"}div[class~=language-ts]:before{content:"ts"}div[class~=language-html]:before{content:"html"}div[class~=language-md]:before{content:"md"}div[class~=language-vue]:before{content:"vue"}div[class~=language-css]:before{content:"css"}div[class~=language-sass]:before{content:"sass"}div[class~=language-scss]:before{content:"scss"}div[class~=language-less]:before{content:"less"}div[class~=language-stylus]:before{content:"stylus"}div[class~=language-go]:before{content:"go"}div[class~=language-java]:before{content:"java"}div[class~=language-c]:before{content:"c"}div[class~=language-sh]:before{content:"sh"}div[class~=language-yaml]:before{content:"yaml"}div[class~=language-py]:before{content:"py"}div[class~=language-docker]:before{content:"docker"}div[class~=language-dockerfile]:before{content:"dockerfile"}div[class~=language-makefile]:before{content:"makefile"}div[class~=language-javascript]:before{content:"js"}div[class~=language-typescript]:before{content:"ts"}div[class~=language-markup]:before{content:"html"}div[class~=language-markdown]:before{content:"md"}div[class~=language-json]:before{content:"json"}div[class~=language-ruby]:before{content:"rb"}div[class~=language-python]:before{content:"py"}div[class~=language-bash]:before{content:"sh"}div[class~=language-php]:before{content:"php"}.custom-block .custom-block-title{font-weight:600;margin-bottom:-.4rem}.custom-block.danger,.custom-block.tip,.custom-block.warning{padding:.1rem 1.5rem;border-left-width:.5rem;border-left-style:solid;margin:1rem 0}.custom-block.tip{background-color:#f3f5f7;border-color:#42b983}.custom-block.warning{background-color:rgba(255,229,100,.3);border-color:#e7c000;color:#6b5900}.custom-block.warning .custom-block-title{color:#b29400}.custom-block.warning a{color:#2c3e50}.custom-block.danger{background-color:#ffe6e6;border-color:#c00;color:#4d0000}.custom-block.danger .custom-block-title{color:#900}.custom-block.danger a{color:#2c3e50}.custom-block.details{display:block;position:relative;border-radius:2px;margin:1.6em 0;padding:1.6em;background-color:#eee}.custom-block.details h4{margin-top:0}.custom-block.details figure:last-child,.custom-block.details p:last-child{margin-bottom:0;padding-bottom:0}.custom-block.details summary{outline:none;cursor:pointer}.arrow{display:inline-block;width:0;height:0}.arrow.up{border-bottom:6px solid #ccc}.arrow.down,.arrow.up{border-left:4px solid transparent;border-right:4px solid transparent}.arrow.down{border-top:6px solid #ccc}.arrow.right{border-left:6px solid #ccc}.arrow.left,.arrow.right{border-top:4px solid transparent;border-bottom:4px solid transparent}.arrow.left{border-right:6px solid #ccc}.theme-default-content:not(.custom){max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.theme-default-content:not(.custom){padding:2rem}}@media (max-width:419px){.theme-default-content:not(.custom){padding:1.5rem}}.table-of-contents .badge{vertical-align:middle}body,html{padding:0;margin:0;background-color:#fff}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:16px;color:#2c3e50}.page{padding-left:20rem}.navbar{z-index:20;right:0;height:3.6rem;background-color:#fff;box-sizing:border-box;border-bottom:1px solid #eaecef}.navbar,.sidebar-mask{position:fixed;top:0;left:0}.sidebar-mask{z-index:9;width:100vw;height:100vh;display:none}.sidebar{font-size:16px;background-color:#fff;width:20rem;position:fixed;z-index:10;margin:0;top:3.6rem;left:0;bottom:0;box-sizing:border-box;border-right:1px solid #eaecef;overflow-y:auto}.theme-default-content:not(.custom)>:first-child{margin-top:3.6rem}.theme-default-content:not(.custom) a:hover{text-decoration:underline}.theme-default-content:not(.custom) p.demo{padding:1rem 1.5rem;border:1px solid #ddd;border-radius:4px}.theme-default-content:not(.custom) img{max-width:100%}.theme-default-content.custom{padding:0;margin:0}.theme-default-content.custom img{max-width:100%}a{font-weight:500;text-decoration:none}a,p a code{color:#3eaf7c}p a code{font-weight:400}kbd{background:#eee;border:.15rem solid #ddd;border-bottom:.25rem solid #ddd;border-radius:.15rem;padding:0 .15em}blockquote{font-size:1rem;color:#999;border-left:.2rem solid #dfe2e5;margin:1rem 0;padding:.25rem 0 .25rem 1rem}blockquote>p{margin:0}ol,ul{padding-left:1.2em}strong{font-weight:600}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25}.theme-default-content:not(.custom)>h1,.theme-default-content:not(.custom)>h2,.theme-default-content:not(.custom)>h3,.theme-default-content:not(.custom)>h4,.theme-default-content:not(.custom)>h5,.theme-default-content:not(.custom)>h6{margin-top:-3.1rem;padding-top:4.6rem;margin-bottom:0}.theme-default-content:not(.custom)>h1:first-child,.theme-default-content:not(.custom)>h2:first-child,.theme-default-content:not(.custom)>h3:first-child,.theme-default-content:not(.custom)>h4:first-child,.theme-default-content:not(.custom)>h5:first-child,.theme-default-content:not(.custom)>h6:first-child{margin-top:-1.5rem;margin-bottom:1rem}.theme-default-content:not(.custom)>h1:first-child+.custom-block,.theme-default-content:not(.custom)>h1:first-child+p,.theme-default-content:not(.custom)>h1:first-child+pre,.theme-default-content:not(.custom)>h2:first-child+.custom-block,.theme-default-content:not(.custom)>h2:first-child+p,.theme-default-content:not(.custom)>h2:first-child+pre,.theme-default-content:not(.custom)>h3:first-child+.custom-block,.theme-default-content:not(.custom)>h3:first-child+p,.theme-default-content:not(.custom)>h3:first-child+pre,.theme-default-content:not(.custom)>h4:first-child+.custom-block,.theme-default-content:not(.custom)>h4:first-child+p,.theme-default-content:not(.custom)>h4:first-child+pre,.theme-default-content:not(.custom)>h5:first-child+.custom-block,.theme-default-content:not(.custom)>h5:first-child+p,.theme-default-content:not(.custom)>h5:first-child+pre,.theme-default-content:not(.custom)>h6:first-child+.custom-block,.theme-default-content:not(.custom)>h6:first-child+p,.theme-default-content:not(.custom)>h6:first-child+pre{margin-top:2rem}h1:focus .header-anchor,h1:hover .header-anchor,h2:focus .header-anchor,h2:hover .header-anchor,h3:focus .header-anchor,h3:hover .header-anchor,h4:focus .header-anchor,h4:hover .header-anchor,h5:focus .header-anchor,h5:hover .header-anchor,h6:focus .header-anchor,h6:hover .header-anchor{opacity:1}h1{font-size:2.2rem}h2{font-size:1.65rem;padding-bottom:.3rem;border-bottom:1px solid #eaecef}h3{font-size:1.35rem}a.header-anchor{font-size:.85em;float:left;margin-left:-.87em;padding-right:.23em;margin-top:.125em;-webkit-user-select:none;user-select:none;opacity:0}a.header-anchor:focus,a.header-anchor:hover{text-decoration:none}.line-number,code,kbd{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}ol,p,ul{line-height:1.7}hr{border:0;border-top:1px solid #eaecef}table{border-collapse:collapse;margin:1rem 0;display:block;overflow-x:auto}tr{border-top:1px solid #dfe2e5}tr:nth-child(2n){background-color:#f6f8fa}td,th{border:1px solid #dfe2e5;padding:.6em 1em}.theme-container.sidebar-open .sidebar-mask{display:block}.theme-container.no-navbar .theme-default-content:not(.custom)>h1,.theme-container.no-navbar h2,.theme-container.no-navbar h3,.theme-container.no-navbar h4,.theme-container.no-navbar h5,.theme-container.no-navbar h6{margin-top:1.5rem;padding-top:0}.theme-container.no-navbar .sidebar{top:0}@media (min-width:720px){.theme-container.no-sidebar .sidebar{display:none}.theme-container.no-sidebar .page{padding-left:0}}@media (max-width:959px){.sidebar{font-size:15px;width:16.4rem}.page{padding-left:16.4rem}}@media (max-width:719px){.sidebar{top:0;padding-top:3.6rem;transform:translateX(-100%);transition:transform .2s ease}.page{padding-left:0}.theme-container.sidebar-open .sidebar{transform:translateX(0)}.theme-container.no-navbar .sidebar{padding-top:0}}@media (max-width:419px){h1{font-size:1.9rem}.theme-default-content div[class*=language-]{margin:.85rem -1.5rem;border-radius:0}}#nprogress{pointer-events:none}#nprogress .bar{background:#3eaf7c;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #3eaf7c,0 0 5px #3eaf7c;opacity:1;transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border-color:#3eaf7c transparent transparent #3eaf7c;border-style:solid;border-width:2px;border-radius:50%;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}mjx-math{display:inline-block;text-align:left;line-height:0;text-indent:0;font-style:normal;font-weight:400;font-size:100%;font-size-adjust:none;letter-spacing:normal;word-wrap:normal;word-spacing:normal;white-space:nowrap;direction:ltr;padding:1px 0}mjx-container[jax=CHTML][display=true]{display:block;text-align:center;margin:1em 0}mjx-container[jax=CHTML][display=true] mjx-math{padding:0}mjx-container[jax=CHTML][justify=left]{text-align:left}mjx-container[jax=CHTML][justify=right]{text-align:right}mjx-mrow{display:inline-block;text-align:left}mjx-container [space="1"]{margin-left:.111em}mjx-container [space="2"]{margin-left:.167em}mjx-container [space="3"]{margin-left:.222em}mjx-container [space="4"]{margin-left:.278em}mjx-container [space="5"]{margin-left:.333em}mjx-container [rspace="1"]{margin-right:.111em}mjx-container [rspace="2"]{margin-right:.167em}mjx-container [rspace="3"]{margin-right:.222em}mjx-container [rspace="4"]{margin-right:.278em}mjx-container [rspace="5"]{margin-right:.333em}mjx-container [size=s]{font-size:70.7%}mjx-container [size=ss]{font-size:50%}mjx-container [size=Tn]{font-size:60%}mjx-container [size=sm]{font-size:85%}mjx-container [size=lg]{font-size:120%}mjx-container [size=Lg]{font-size:144%}mjx-container [size=LG]{font-size:173%}mjx-container [size=hg]{font-size:207%}mjx-container [size=HG]{font-size:249%}mjx-container [width=full]{width:100%}mjx-box{display:inline-block}mjx-block{display:block}mjx-itable{display:inline-table}mjx-row{display:table-row}mjx-row>*{display:table-cell}mjx-merror,mjx-mstyle,mjx-mtext{display:inline-block}mjx-merror{color:red;background-color:#ff0}mjx-mphantom{visibility:hidden}mjx-inferredMrow,mjx-mi,mjx-mo{display:inline-block;text-align:left}mjx-stretchy-h{display:inline-table;width:100%}mjx-stretchy-h>mjx-beg,mjx-stretchy-h>mjx-end{display:table-cell;width:0}mjx-stretchy-h>mjx-ext{display:table-cell;overflow:hidden;width:100%}mjx-stretchy-h>mjx-ext>mjx-c{transform:scalex(500);margin-right:-2em}mjx-stretchy-h>mjx-ext>mjx-c:before{padding:.001em 0}mjx-stretchy-h>mjx-beg>mjx-c{margin-right:-.1em}mjx-stretchy-h>mjx-end>mjx-c{margin-left:-.1em}mjx-stretchy-v{display:inline-block}mjx-stretchy-v>*{display:block}mjx-stretchy-v>mjx-beg{height:0}mjx-stretchy-v>mjx-end>mjx-c{display:block}mjx-stretchy-v>*>mjx-c{transform:scale(1);transform-origin:left center;overflow:hidden}mjx-stretchy-v>mjx-ext{display:block;height:100%;box-sizing:border-box;border:0 solid transparent;overflow:hidden}mjx-stretchy-v>mjx-ext>mjx-c{transform:scaleY(500) translateY(.1em);overflow:visible}mjx-mark{display:inline-block;height:0}mjx-mn,mjx-mpadded,mjx-ms,mjx-mspace{display:inline-block;text-align:left}mjx-menclose,mjx-rbox{display:inline-block;position:relative}mjx-menclose{text-align:left}mjx-menclose>mjx-dstrike{top:0;transform-origin:top left}mjx-menclose>mjx-dstrike,mjx-menclose>mjx-ustrike{display:inline-block;left:0;position:absolute;border-top:.067em solid}mjx-menclose>mjx-ustrike{bottom:0;transform-origin:bottom left}mjx-menclose>mjx-hstrike{border-top:.067em solid;position:absolute;left:0;right:0;bottom:50%;transform:translateY(.034em)}mjx-menclose>mjx-vstrike{border-left:.067em solid;position:absolute;top:0;bottom:0;right:50%;transform:translateX(.034em)}mjx-menclose>mjx-rbox{border:.067em solid;border-radius:.267em}mjx-menclose>mjx-cbox,mjx-menclose>mjx-rbox{position:absolute;top:0;bottom:0;right:0;left:0}mjx-menclose>mjx-cbox{border:.067em solid;border-radius:50%}mjx-menclose>mjx-arrow{position:absolute;left:0;bottom:50%;height:0;width:0}mjx-menclose>mjx-arrow>*{display:block;position:absolute;transform-origin:bottom;border-left:.268em solid;border-right:0;box-sizing:border-box}mjx-menclose>mjx-arrow>mjx-aline{left:0;top:-.034em;right:.201em;height:0;border-top:.067em solid;border-left:0}mjx-menclose>mjx-arrow[double]>mjx-aline{left:.201em;height:0}mjx-menclose>mjx-arrow>mjx-rthead{transform:skewX(.464rad);right:0;bottom:-1px;border-bottom:1px solid transparent;border-top:.134em solid transparent}mjx-menclose>mjx-arrow>mjx-rbhead{transform:skewX(-.464rad);transform-origin:top;right:0;top:-1px;border-top:1px solid transparent;border-bottom:.134em solid transparent}mjx-menclose>mjx-arrow>mjx-lthead{transform:skewX(-.464rad);left:0;bottom:-1px;border-left:0;border-right:.268em solid;border-bottom:1px solid transparent;border-top:.134em solid transparent}mjx-menclose>mjx-arrow>mjx-lbhead{transform:skewX(.464rad);transform-origin:top;left:0;top:-1px;border-left:0;border-right:.268em solid;border-top:1px solid transparent;border-bottom:.134em solid transparent}mjx-menclose>dbox{position:absolute;top:0;bottom:0;left:-.3em;width:.6em;border:.067em solid;border-radius:50%;-webkit-clip-path:inset(0 0 0 .3em);clip-path:inset(0 0 0 .3em);box-sizing:border-box}mjx-mfrac{text-align:left}mjx-frac,mjx-mfrac{display:inline-block}mjx-frac{vertical-align:.17em;padding:0 .22em}mjx-frac[type=d]{vertical-align:.04em}mjx-frac[delims]{padding:0 .1em}mjx-frac[atop]{padding:0 .12em}mjx-frac[atop][delims]{padding:0}mjx-dtable{display:inline-table;width:100%}mjx-dtable>*{font-size:2000%}mjx-dbox{display:block;font-size:5%}mjx-den,mjx-num{display:block;text-align:center}mjx-mfrac[bevelled]>mjx-den,mjx-mfrac[bevelled]>mjx-num{display:inline-block}mjx-den[align=right],mjx-num[align=right]{text-align:right}mjx-den[align=left],mjx-num[align=left]{text-align:left}mjx-nstrut{display:inline-block;height:.054em;width:0;vertical-align:-.054em}mjx-nstrut[type=d]{height:.217em;vertical-align:-.217em}mjx-dstrut{display:inline-block;height:.505em;width:0}mjx-dstrut[type=d]{height:.726em}mjx-line{display:block;box-sizing:border-box;min-height:1px;height:.06em;border-top:.06em solid;margin:.06em -.1em;overflow:hidden}mjx-line[type=d]{margin:.18em -.1em}mjx-msqrt{text-align:left}mjx-msqrt,mjx-root{display:inline-block}mjx-root{white-space:nowrap}mjx-surd{vertical-align:top}mjx-sqrt,mjx-surd{display:inline-block}mjx-sqrt{padding-top:.07em}mjx-sqrt>mjx-box{border-top:.07em solid}mjx-sqrt.mjx-tall>mjx-box{padding-left:.3em;margin-left:-.3em}mjx-mroot,mjx-msub,mjx-msubsup,mjx-msup{display:inline-block;text-align:left}mjx-script{display:inline-block;padding-right:.05em}mjx-script>*{display:block}mjx-munder{display:inline-block}mjx-munder,mjx-over{text-align:left}mjx-munder:not([limits=false]){display:inline-table}mjx-munder>mjx-row{text-align:left}mjx-under{padding-bottom:.1em}mjx-mover{display:inline-block;text-align:left}mjx-mover:not([limits=false]){padding-top:.1em}mjx-mover:not([limits=false])>*{display:block;text-align:left}mjx-munderover{display:inline-block;text-align:left}mjx-munderover:not([limits=false]){padding-top:.1em}mjx-munderover:not([limits=false])>*{display:block}mjx-mmultiscripts{display:inline-block;text-align:left}mjx-prescripts{display:inline-table;padding-left:.05em}mjx-scripts{display:inline-table;padding-right:.05em}mjx-prescripts>mjx-row>mjx-cell{text-align:right}mjx-mfenced{display:inline-block;text-align:left}mjx-mtable{display:inline-block;text-align:center;vertical-align:.25em;position:relative;box-sizing:border-box}mjx-labels{position:absolute;left:0;top:0}mjx-table{display:inline-block}mjx-table>mjx-itable{vertical-align:middle;text-align:left;box-sizing:border-box}mjx-labels>mjx-itable{position:absolute;top:0}mjx-mtable[justify=left]{text-align:left}mjx-mtable[justify=right]{text-align:right}mjx-mtable[justify=left][side=left]{padding-right:0!important}mjx-mtable[justify=left][side=right]{padding-left:0!important}mjx-mtable[justify=right][side=left]{padding-right:0!important}mjx-mtable[justify=right][side=right]{padding-left:0!important}mjx-mtable[align]{vertical-align:baseline}mjx-mtable[align=top]>mjx-table{vertical-align:top}mjx-mtable[align=bottom]>mjx-table{vertical-align:bottom}mjx-mtable[align=baseline]>mjx-table,mjx-mtable[align=center]>mjx-table{vertical-align:middle}mjx-mtr{display:table-row;text-align:left}mjx-mtr[rowalign=top]>mjx-mtd{vertical-align:top}mjx-mtr[rowalign=center]>mjx-mtd{vertical-align:middle}mjx-mtr[rowalign=bottom]>mjx-mtd{vertical-align:bottom}mjx-mtr[rowalign=baseline]>mjx-mtd{vertical-align:baseline}mjx-mtr[rowalign=axis]>mjx-mtd{vertical-align:.25em}mjx-mlabeledtr{display:table-row;text-align:left}mjx-mlabeledtr[rowalign=top]>mjx-mtd{vertical-align:top}mjx-mlabeledtr[rowalign=center]>mjx-mtd{vertical-align:middle}mjx-mlabeledtr[rowalign=bottom]>mjx-mtd{vertical-align:bottom}mjx-mlabeledtr[rowalign=baseline]>mjx-mtd{vertical-align:baseline}mjx-mlabeledtr[rowalign=axis]>mjx-mtd{vertical-align:.25em}mjx-mtd{display:table-cell;text-align:center;padding:.215em .4em}mjx-mtd:first-child{padding-left:0}mjx-mtd:last-child{padding-right:0}mjx-mtable>*>mjx-itable>:first-child>mjx-mtd{padding-top:0}mjx-mtable>*>mjx-itable>:last-child>mjx-mtd{padding-bottom:0}mjx-tstrut{display:inline-block;height:1em;vertical-align:-.25em}mjx-labels[align=left]>mjx-mtr>mjx-mtd{text-align:left}mjx-labels[align=right]>mjx-mtr>mjx-mtd{text-align:right}mjx-mlabeledtr mjx-mtd[rowalign=top],mjx-mtr mjx-mtd[rowalign=top]{vertical-align:top}mjx-mlabeledtr mjx-mtd[rowalign=center],mjx-mtr mjx-mtd[rowalign=center]{vertical-align:middle}mjx-mlabeledtr mjx-mtd[rowalign=bottom],mjx-mtr mjx-mtd[rowalign=bottom]{vertical-align:bottom}mjx-mlabeledtr mjx-mtd[rowalign=baseline],mjx-mtr mjx-mtd[rowalign=baseline]{vertical-align:baseline}mjx-mlabeledtr mjx-mtd[rowalign=axis],mjx-mtr mjx-mtd[rowalign=axis]{vertical-align:.25em}mjx-maction{display:inline-block;text-align:left;position:relative}mjx-maction>mjx-tool{display:none;position:absolute;bottom:0;right:0;Width:0;height:0}mjx-tool>mjx-tip{display:inline-block;padding:.2em;border:1px solid #888;font-size:70%;background-color:#f8f8f8;color:#000;box-shadow:2px 2px 5px #aaa}mjx-maction[toggle]{cursor:pointer}mjx-status{display:block;position:fixed;left:1em;bottom:1em;min-width:25%;padding:.2em .4em;border:1px solid #888;font-size:90%;background-color:#f8f8f8;color:#000}mjx-mglyph{display:inline-block;text-align:left}mjx-mglyph>img{display:inline-block;border:0;padding:0}mjx-annotation,mjx-annotation-xml,mjx-semantics,mjx-TeXAtom{display:inline-block;text-align:left}mjx-c,mjx-c:before,mjx-utext{display:inline-block}mjx-utext{padding:.75em 0 .25em}mjx-measure-text{position:absolute;font-family:MJXZERO;white-space:nowrap;height:1px;width:1px;overflow:hidden}.MJX-TEX .mjx-n mjx-c{font-family:MJXZERO,MJXTEX,MJXTEX-I,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-i mjx-c{font-family:MJXZERO,MJXTEX-I,MJXTEX,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-b mjx-c{font-family:MJXZERO,MJXTEX-B,MJXTEX-BI,MJXTEX,MJXTEX-I,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-b.mjx-i mjx-c{font-family:MJXZERO,MJXTEX-BI,MJXTEX-B,MJXTEX-I,MJXTEX,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-cal mjx-c{font-family:MJXZERO,MJXTEX-C,MJXTEX-I,MJXTEX,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-cal.mjx-b mjx-c{font-family:MJXZERO,MJXTEX-C-B,MJXTEX-C,MJXTEX-B,MJXTEX-BI,MJXTEX,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-ds mjx-c{font-family:MJXZERO,MJXTEX-A,MJXTEX-B,MJXTEX-BI,MJXTEX,MJXTEX-I,MJXTEX-S1}.MJX-TEX .mjx-fr mjx-c{font-family:MJXZERO,MJXTEX-FR,MJXTEX,MJXTEX-I,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-fr.mjx-b mjx-c{font-family:MJXZERO,MJXTEX-FR-B,MJXTEX-FR,MJXTEX-B,MJXTEX-BI,MJXTEX,MJXTEX-I,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-sc mjx-c{font-family:MJXZERO,MJXTEX-SC,MJXTEX,MJXTEX-I,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-sc.mjx-b mjx-c{font-family:MJXZERO,MJXTEX-SC-B,MJXTEX-SC,MJXTEX-B,MJXTEX-BI,MJXTEX,MJXTEX-I,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-ss mjx-c{font-family:MJXZERO,MJXTEX-SS,MJXTEX,MJXTEX-I,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-ss.mjx-b mjx-c{font-family:MJXZERO,MJXTEX-SS-B,MJXTEX-SS,MJXTEX-B,MJXTEX-BI,MJXTEX,MJXTEX-I,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-ss.mjx-i mjx-c{font-family:MJXZERO,MJXTEX-SS-I,MJXTEX-I,MJXTEX,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-ss.mjx-b.mjx-i mjx-c{font-family:MJXZERO,MJXTEX-SS-B,MJXTEX-SS-I,MJXTEX-BI,MJXTEX-B,MJXTEX-I,MJXTEX,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-ty mjx-c{font-family:MJXZERO,MJXTEX-T,MJXTEX,MJXTEX-I,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-var mjx-c{font-family:MJXZERO,MJXTEX-A,MJXTEX,MJXTEX-I,MJXTEX-S1}.MJX-TEX .mjx-os mjx-c{font-family:MJXZERO,MJXTEX-C,MJXTEX,MJXTEX-I,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-os.mjx-b mjx-c{font-family:MJXZERO,MJXTEX-C-B,MJXTEX-C,MJXTEX-B,MJXTEX-BI,MJXTEX,MJXTEX-I,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-mit mjx-c{font-family:MJXZERO,MJXTEX-MI,MJXTEX-I,MJXTEX,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-lop mjx-c{font-family:MJXZERO,MJXTEX-S2,MJXTEX-S1,MJXTEX,MJXTEX-I,MJXTEX-A}.MJX-TEX .mjx-sop mjx-c{font-family:MJXZERO,MJXTEX-S1,MJXTEX,MJXTEX-I,MJXTEX-A}.MJX-TEX .mjx-s3 mjx-c{font-family:MJXZERO,MJXTEX-S3,MJXTEX,MJXTEX-I,MJXTEX-S1,MJXTEX-A}.MJX-TEX .mjx-s4 mjx-c{font-family:MJXZERO,MJXTEX-S4,MJXTEX,MJXTEX-I,MJXTEX-S1,MJXTEX-A}.MJX-TEX{font-family:MJXZERO}.MJX-TEX mjx-stretchy-h mjx-c,.MJX-TEX mjx-stretchy-v mjx-c{font-family:MJXZERO,MJXTEX-S1,MJXTEX-S4,MJXTEX,MJXTEX-A!important}@font-face{font-family:MJXZERO;src:url(data:font/otf;base64,T1RUTwALAIAAAwAwQ0ZGIA9zN9cAAAhgAAAArUZGVE12+H9qAAAJEAAAABxHREVGACoAHgAACSwAAAAgT1MvMkDE54cAAAEgAAAAYGNtYXAADfKiAAAG/AAAAUJoZWFkCdzO7wAAALwAAAA2aGhlYQBmAJgAAAD0AAAAJGhtdHgA+gAAAAAJTAAAAAZtYXhwAAJQAAAAARgAAAAGbmFtZeMFXGAAAAGAAAAFenBvc3T/hgAzAAAIQAAAACAAAQAAAAMAAO7o+YVfDzz1AAsD6AAAAADVXaFMAAAAANVe7L4AAAAAAAAAAAAAAAgAAgAAAAAAAAABAAAAZP+cAAAA+gAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQA+gGQAAUAAAKKArwAAACMAooCvAAAAeAAMQECAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAFBmRWQAwO/87/wAZP+cAAAAZABkIAAAAAAAAAAAAAAAACAAIAABAAAAFgEOAAEAAAAAAAAAKgAAAAEAAAAAAAEADAAqAAEAAAAAAAIABwA2AAEAAAAAAAMAIwA9AAEAAAAAAAQADAAqAAEAAAAAAAUACwBgAAEAAAAAAAYADAAqAAEAAAAAAA0A9QBrAAEAAAAAAA4AGgFgAAEAAAAAABAADAAqAAEAAAAAABEABwA2AAMAAQQJAAAAUgF6AAMAAQQJAAEAGAHMAAMAAQQJAAIADgHkAAMAAQQJAAMARgHyAAMAAQQJAAQAGAHMAAMAAQQJAAUAFgI4AAMAAQQJAAYAGAHMAAMAAQQJAA0B6gJOAAMAAQQJAA4ANAQ4AAMAAQQJABAAGAHMAAMAAQQJABEADgHkQ29weXJpZ2h0IChjKSAyMDE3IFRoZSBNYXRoSmF4IENvbnNvcnRpdW0uTWF0aEpheF9aZXJvUmVndWxhckZvbnRGb3JnZSA6IE1hdGhKYXhfWmVybyA6IDctNi0yMDE3VmVyc2lvbiAxLjFDb3B5cmlnaHQgKGMpIDIwMTcsIFRoZSBNYXRoSmF4IENvbnNvcnRpdW0uICg8d3d3Lm1hdGhqYXgub3JnPiksCndpdGggUmVzZXJ2ZWQgRm9udCBOYW1lIE1hdGhKYXhfWmVyby4KClRoaXMgRm9udCBTb2Z0d2FyZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgU0lMIE9wZW4gRm9udCBMaWNlbnNlLCBWZXJzaW9uIDEuMS4KVGhpcyBsaWNlbnNlIGF2YWlsYWJsZSB3aXRoIGEgRkFRIGF0OgpodHRwOi8vc2NyaXB0cy5zaWwub3JnL09GTGh0dHA6Ly9zY3JpcHRzLnNpbC5vcmcvT0ZMAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABjACkAIAAyADAAMQA3ACAAVABoAGUAIABNAGEAdABoAEoAQQB4ACAAQwBvAG4AcwBvAHIAdABpAHUAbQBNAGEAdABoAEoAYQB4AF8AWgBlAHIAbwBSAGUAZwB1AGwAYQByAEYAbwBuAHQARgBvAHIAZwBlACAAOgAgAE0AYQB0AGgASgBhAHgAXwBaAGUAcgBvACAAOgAgADcALQA2AC0AMgAwADEANwBWAGUAcgBzAGkAbwBuACAAMQAuADEAQwBvAHAAeQByAGkAZwBoAHQAIAAoAGMAKQAgADIAMAAxADcALAAgAFQAaABlACAATQBhAHQAaABKAGEAeAAgAEMAbwBuAHMAbwByAHQAaQB1AG0ALgAgACgAPAB3AHcAdwAuAG0AYQB0AGgAagBhAHgALgBvAHIAZwA+ACkALAAKAHcAaQB0AGgAIABSAGUAcwBlAHIAdgBlAGQAIABGAG8AbgB0ACAATgBhAG0AZQAgAE0AYQB0AGgASgBhAHgAXwBaAGUAcgBvAC4ACgAKAFQAaABpAHMAIABGAG8AbgB0ACAAUwBvAGYAdAB3AGEAcgBlACAAaQBzACAAbABpAGMAZQBuAHMAZQBkACAAdQBuAGQAZQByACAAdABoAGUAIABTAEkATAAgAE8AcABlAG4AIABGAG8AbgB0ACAATABpAGMAZQBuAHMAZQAsACAAVgBlAHIAcwBpAG8AbgAgADEALgAxAC4ACgBUAGgAaQBzACAAbABpAGMAZQBuAHMAZQAgAGEAdgBhAGkAbABhAGIAbABlACAAdwBpAHQAaAAgAGEAIABGAEEAUQAgAGEAdAA6AAoAaAB0AHQAcAA6AC8ALwBzAGMAcgBpAHAAdABzAC4AcwBpAGwALgBvAHIAZwAvAE8ARgBMAGgAdAB0AHAAOgAvAC8AcwBjAHIAaQBwAHQAcwAuAHMAaQBsAC4AbwByAGcALwBPAEYATAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAA7/z//wAA7/z//xAFAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAAAAABAAQBAAEBAQ1NYXRoSmF4X1plcm8AAQEBHfgcAPgdAfgeAvgeA/gYBIwMAfcTD673HhL3FhEABAEBCAs0QHVuaUVGRkMzLjBDb3B5cmlnaHQgKGMpIDIwMTcgVGhlIE1hdGhKYXggQ29uc29ydGl1bU1hdGhKYXhfWmVybwAAAAGHAAIBAQIDDg51ofhDnPdtjJmkBvtijQceoDlj/wwJiwwKvQq9Cx0AAATiFAAAAAAAAAEAAAAAzD2izwAAAADVXW5NAAAAANVdbk0AAQAAAAwAAAAUABwAAQABAAEAAQAEAAAAAQAAAAIAAAD6AAAAAAAA) format("opentype")}@font-face{font-family:MJXTEX;src:url(/Blog/assets/fonts/MathJax_Main-Regular.9995de47.woff) format("woff")}@font-face{font-family:MJXTEX-B;src:url(/Blog/assets/fonts/MathJax_Main-Bold.c9423d5d.woff) format("woff")}@font-face{font-family:MJXTEX-MI;src:url(/Blog/assets/fonts/MathJax_Main-Italic.7e83626b.woff) format("woff")}@font-face{font-family:MJXTEX-I;src:url(/Blog/assets/fonts/MathJax_Math-Italic.5589d1a8.woff) format("woff")}@font-face{font-family:MJXTEX-BI;src:url(/Blog/assets/fonts/MathJax_Math-BoldItalic.77dbcee3.woff) format("woff")}@font-face{font-family:MJXTEX-S1;src:url(data:font/woff;base64,d09GRk9UVE8AABagAAsAAAAAIDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAABCAAAEF0AABULkl+DEUZGVE0AABFoAAAAHAAAABxdKvsAR0RFRgAAEYQAAAAdAAAAIABeAARPUy8yAAARpAAAAE0AAABgPshXF2NtYXAAABH0AAAA6QAAAhoVJZqOaGVhZAAAEuAAAAAzAAAANgy+mDloaGVhAAATFAAAACAAAAAkAwUEGGhtdHgAABM0AAAAjQAAAMR0yQmkbWF4cAAAE8QAAAAGAAAABgAxUABuYW1lAAATzAAAAr0AAAZv+wCdtHBvc3QAABaMAAAAEwAAACD/hgAyeJylNwl0VFWW/1P85JFgUGKhrRlAQBYPaAgjyowiIIER0UTAFggCIYmQmJ1slaT2ql9V//5afu2VykYIIGGREDaBgLIFNS6AIratoPZg2840Kj39fniF3a+qgMaZtmfOmXq//v3vvnvvu+++d5fHMoMHMyzLjngut2rdgty6VYsL6wumTllUsLa6OLeSYQcxLDNFvpORZ7Hy7EHyHIX89ODIafJjGnfvwGUubdCdw9IY5s60QRV3pTEj04bPHs5MirIgZhhzLzOKGc88wsxgMpmFzGJmBZPHFDEVjIrRMRbGwfiYZmYj08V0MweYo8wp5j3mI+Yz5ivmW+Z7BjM/sRw7lE1ln2KXsLns2urSwvT02elRMC09o6qwOL8gr6xkDe1npE+dnltZWVZbXR4D+WW1pfGPNcU3UWuKo9jyyrL86ryqKE/G1PT11SUluVWFZaWVufmFebnFMXTGtDh4tLC0qmBt5U3s03EwNw4yY+Dp9DiYGgcZcRDjn5b+eBzMiIPZcTAnBubG+B7LfDwOYiSz09PjYGocZMTBP8fBdAoy582bGweZcTDv6bJyVWXh2nVVoyfmTRqdkZ4+Ywo1RfrouQXrC9eWjl6cV1hQmlcwefQzpXkP/93N/Rny+bLKktxihv5YZgiTxNzJPME8ycykm7aStTAaRstaWRsrsMCKrJ11sE7WxUqsm/WwXtbH+tkAG2RDbBMbZpvZFraVbWPb2Q1sB7uR7WQ3sZvZLexr7Fa2i93GTI2ejzHMg0wd8zYTYdPYLLZ80HzFBMVDihmKXEW5IqTYr/jL4HmDz3DLuHcS/jWBJBYkrk98K/HjxD+hkUN8Q64nlSTfkTwq+bHk7OR1ybpkKfmLoQ8NPXhHVsqUlEPDJg2bMyxnWFGkHHrlzF62l/4UvSPwQ/JW8lBCb6RWSbGRzMSUSHkKaceTLyrwZOxUAmn/muTiiSQVbUmw251OcIBDsBt8JBnfvwhnA3YBlo7jbDwU3+/1ifbouMVps6OyBEK5ppHVVASKiqygIk9GReK2aTiXTMSpSJPQwINulGhzmSQTTib3HSNZQFxAnEtIFqF9s4k3CTakdwrNI4MJeBJO/QqvBryBCpwoVw/8RslrI4+nEZNgAbXf4Ac3eJxOjysgP542uFF0Qkjn1YEeeLPFTFneJj/0XLvaw+KVPQq8kvygxEt6yORrV/HkHrIkISqylfxGKTgjUW4+YHEbXUbQgEEj6kWLHJ3HpXUaPRY3+MHvhdDtIuf0KDYMHFHiyT9dJZPz8JK0wa/HZI69SeD4QiFXkO+UoUQIC3aT/aXQwm0NPXwIeMAz4Ec4KkjWFkO7LlzVlbspqx01SgEndzjcs6Gzs60t2OncJEpwlNJRYt4VCve8s+1oyG2nBg8jCJklNXAmMAoCCGCwGqyza5dXVBTp1KYGvhYJZDonkEwxYG7QlpSVranW8VqzytRgBoB6aAAIm1tMAbOfR3uqt5QFSqQGISCSTCSSRzlXjdQQUG8sPlDZX7dD7xBCgILRZf0J1z12MVWHBw38u9JiFazUTo2iTbI5BLfVYztd21MWLEKps1xqoNs5A8bBS6LZofLW+Bs6ig+U9dWigKXRzGXV5FZUFesaDDVWlWCGlygduRNKBLOl3qRpbKytLa5fo0E1ZkGwWVGqTrCBBQxQJwqtEASnuN3X33qgc2NXICSFXe1IxI9yIs4UtFI4vPfEnhPNbkfUPtBE7e1Y1LxoT8Nec1jUCjgTCXg6x7eZw9rQ+q6VnQtaC31WUQPICDydA8WcYKZ8CL/I4m0DU5Wjk6Ldb9+1vjs8VXdsYJrygaTUWWOSUnVjKdSG9AYuVTeOfj6YlHK9KMZGtsbZaPcGW8T2D/mOttew2LcPz9unwL4R++Q/rk7AFZE/KmNfKdnR0X469Fv5a+WKObMWZJQg3gar6BF5r/NUd+8hFAxARNwHIItBLdebc6rgvUpqYtjP27lHu2adWv4JMvm5v8np/06pCXDLDmV3P9OJtE5Y5bJxXxafzz78FHLrXF7u4Efn+3+3FbnssF9r4Z6pzC5YloM0Wip+NXC3KyvfJX+mXDp2evq47Hp9QV29GWl4WM15nFt8Ld5DHQe79mxHPg9EmKhukwIBrqOzs6v1NZfHJQF0FG1+ZXMpCmghMomO4wUiXuAzcj1FB4sPVbUYtug9FgT7NC6uXiporfeNOzX98tKrFi91QPqzmCwGlHJ0w212wzql3sOt2b6iK6dD5S3zGZ0IVgd5rtncXdes/zH7UvqRsU6D0xRld7qd3iNXL13+8VSzr7u1WUJBF+zjjJYyvcqQU7WiOK8I6Y0CXkC1Wg1UP62Wq6qsLK4r5Y08dZyq7eW7yl9D2gBdVdQkuJQ4eq5Npo6egQfLEzCnGNhMHlEOHE30vd7Z9KYDhXquf5wXSjhs3aT2lyCHCa4ftRo5XUmFerkVqfPw2R51wq8dFU2GXUiQ54KcKU8AuP5fv0Tzf5mQnP35hH+OUJFypihncr9I8zOlBj6+fcIviOPtayN62NMDurjLq5Gow88RD/cDGX2RJIKAyLOkhBtPhj42UbDZrNSVbGB18A7BYXsD5BRA8hPil9iTB5y50VBj1LzyQvbqOTUva5abZ1sbBTIYCAuIMGNAHIWfwUXcFZz0+X+KosMpuCySYCefyNkWJ4h98AngYYAfE5qEM/wbpj1q9HnFmaytT6A2oQ04S7Bhb+WHaA0eFHkCuEgG6MBqo/pvvlbUrcBhbFeSySR5UwUnQlOgJYR2bKJfhwnXR0YhzBIpIHBNYBclyW7Hw3Ezfhh/hPA2+TOQOMFt8uvACCbeYhYsBBEzGU0OIOKJbOZsdrJKLotFj3/CD9LjOF6WleOjkYP28PxbCFw5AmwCmQyxR6Rvm93gNfvAC17J7qURC0++9Qh2ZPUaJANNYkaTzUgzzqld1zbsYo+dlJ89qbhKxisnJKX8/hYS7z35TfR1YwRfGUGH5YX/bXzU/ySKU96i27n70reY270jTlNWU1syChqddR5187rXyw9DK7Q6W7zbwpu2tO3d+YH796Hvkejj/I5Wh9/1ZvvuPc1vudvFAHTCRiFgam88+Gr36g28XeUBEQG43nfs9GDOvS+0PdDV0r4DQhCy+I0SXSdNXoLaYrOhBqOxHupRRVvVa1va27aOhHdy9j3vNNAEx0M1TRwq7YriwnkN6TZtI+Gs1UjQczprnVXH/7omf039i6YaQQvroVLUumuaVmwr2FfttLUa6fkEEFS2Ki3J4Fep842VGlWjwWDWWbWgBrVT5zE7DN6ojmLIabeHPZ5maEabajtKR+Kl8g6l4Sndw/x8QU2bBZkTV3bkHYB+OHf4reNNTtEuiiBS8QAIzydjlPDM6qU5KoNFa6UoUfTbQ95PPedc74hBMSTSsCR5LNye2teXQRZK+fOxC3L/BcV/ELuyBbxuj9/h3HoJK/A5hEfL4/EDkfEcHkTObZ3usHh0XlMLbISWFugA6ha02cnZaxN5j9GvcasB1YNGb9bZLOTcT+OsOuqk0VYdrt0Et+Y5NrBUCbxoEXm75Rwp+Jo48eyIWbvDb/SYJZsfYjr4XB5M5Yp2JLpEFzihQ9WyHlRgMBl1VkvJdEIVQoSqRqiKHKHKllyyOo1+naeeWr6+DqrofAMPf8Eeuygf/UKBR5ESWvmdF/En9iDX9PXxDz/e1dO2zX8CvoF3XzmU053fscL7IrJr7Nd/xUkqn7oTNkAw6ArbJTo37ge8CvAQwWP6bdHZxSdfPpi9Y2EzKvJUOQrBKJrBTKsoCwh0ufRLII/XkzHkjgbyb4IRyBAgqxCQfrDYza6GoGYDPZfeJk8z1Y/YY/r1XlKcGahTTkxKGThyW3XYkzbYgvN6CCTE8aobJV5eGlH1ROs7OkCru9vKSegheZQp7waeMmAVeVtJ8vIwUIa82xJ5fzzHp2C5WyEPGbisNICFt5jMdUSKHKferscUSnVOo2Txgg88HtEHkuAgw3E3InfjPZj+ORqeukUHxXuNXi3d4AvdigsDHynBLFrxcNKN8N1kD6F/jtBe1Dii3mOMBhqJVslSK5bk41S2j1BobrV4eIdRRFowGgSaWGUlcVzC39BbwDeX2OMX8WUaBy9fVNwdkdHAKuWkJPkPkQIlvCqo+fJSMpPOkkKm5L9qLLUWwKugFstdGU2PHsx+//n3132qu4wEHzTHm+jrxEvxWDwaZ24N29sdnfS80Q0R8PIqPItMA9KIIroRK7cVHziwrevAwcLXVuQVFa0eSfXB+Rdl9CUr+y4qbuiAHyB6JXk+ghJFFxfCSad//O7MkV0fdJ2PFcYiIBEKyMRRmMULlKcN75YfWfuHzNPjQiQJiXyEBgMZuQTODj7BY0OEvd6v5EWODApOODbvy5y+ko8NnyLBJSPg5BxeWU2eo4cqg6ysQrxAOaP4mJEuDpyLGmjg7N/UqluqPG/4sLxvJQrpyT3kXtroG99D7sH3hnzcmz1vb+r33754RHSRfcoomSHIvdxX/oHh09st5v108wdv9CFvEFMKKuZeTk6jN6kDWVsyvTNFPS3iY03QG54sn/9yFjJobs6GKTl37qO+U9HkvDiyTBnlVuu5rJXzy2ca9EK9EOOkF5yZ3vmbsw4gtQ9H2SgjF/MP+cGL1EWw9iLW3PQSPCWSr4QGnyZg9pmd0Afo2KIEKIT1otVZ16JuoZ4bDjub6cHcCDvQiWOJfdSFfVJA8gVpMd6sb1K7kdlJ7gA4wcFpEHmfKahz19u1YBJ4nreajFae19NQ+jxaRIYmNhgatVB9w1tPfC4fuRjTw2zhjTajLer5kVXRh6fu3eg3NPFo4MGEFrfk9YSRXJAI8hzYaZMsYXWoGqpBo+Eb4kzzUWRh5Ii8kFLMB5dNMjdrgtVAj7/FTC+LkZlwhYUrV64oYPCVKxMS8IoJyij85YHrCbGBG+gUufjugSLlyCSF/6mhQ2BoUm9Sb/LIpIS/DB2exoxMZZKit/1/YRYyrzA6ponZyvyO7Rg0bZCXBrsAQXbBLoh2ugBvC+nBU8kDT3JP5j67Nnq7iz60YrBIWuRVcW47ljDyAUqGF/PNo0CI3qRRQO3zcsn7d+xt6aHXL9qEzdYWvre6S01vejxKDlqDtiDsgT3N+3cAvLUbJLoLbrMbJa8qzFXlxYIpL5Y5VK5lG9a01khVTpTMiyYaXNEyWKfKLaLT/Z0SJhqo/vcSJvkflhPN2/27Pfud7a14rLsPhXCidMaH7wviedLB8O7/d71gqVaR0cbn1CTRPFdP7kNa8qR5xS9XAvFCAN1eCSTfOneWaE4hq2iCEU3uGdvnHn/hUE7fuvcbuowdtp2AdkKHfZvnvXDfzkOHjp/cftb9ueimKSyWyPrBaZP4cPS8ofWgV5vqke36r2wazrCkakVBfk7OwlcejioiGkRyV8sjX9XiZGQLCvg84E+sLs7cpA7U3jypyWTE0vHjlxJl1Qu65TATZvqXdSw6QpTfj8cjlh6v6tVegAtwOHCyA2Hlke+/P4KVHSf8vRTXBq2C3/hOw/GKt+biMeT+KyR9c6mkEl+l12DRQPc6CxY3Lq1FyX8FL9FaYwAAAAAAAAEAAAAAzD2izwAAAADG+TJPAAAAAMn0JeF4nGNgZGBg4ANiCQYQYGJgBEIDIGYB8xgABloAYwAAAHicY2BhamGcwMDKwMDUxbSHgYGhB0IzPmAwZGRiQAINDAzvBRjevIXxA9JcUxgOMCi8/88g9/8RUECOQU6BgaE/jhmqQAEIGQEjQxBnAAAAeJxjYGBgZoBgGQZGIMnAKALkMYL5LAw/gLQVgwKQJQUkNRn0GWIZqhlqGRYwHWO6w8ysIKY4UXGy4kXFy0qCSlJKykqqSnpKh5W5lS+ov9Ri0mLRYnv///9/oBkKDBpAvdFIepmQ9PJD9WorHVDmAOp9ocUA1vsXqPnh/1v/r/5f9b/3f8//rL+ufw3+ct//ea/+Xt09x3sO91jv/r379e6Xu+/vxt2VuhN2w/6a5jWNa+oChhC/kAsY2RgIGgCTZ2IGUywkGM/Kxo5XnoOBkwTTUIGYCDCqoEAcQnGRoJ2bB8YCAHUmSSwAAAB4nGNgZGBgAOLLEuvZ4vltvjJwM78AijBcjV21AUb/PfNvEasEcxCQy8HABBIFAGdaDTUAeJxjYGRgYJD7/4iBgaXv75n/ZawSDCARZGAIAJW9BiB4nGP4xWDE8IuBgfEUwwwgVmZyYjBnXMhwCkibAWkxJneGTBAGqWHS+f+DSYeBkYHh7xkgvsrMxcjINJuhAISZuRgswXgDgzkIsygwWDC/YMhn9GWYCNQzkfEGUNwYKN4HNB/EdkTFQLFTQCwGo5lmM1oA6UQg9mUJZ7CAYbh6HaCbgZghhYEBAAF/KMQAAAAAAFAAADEAAHicrVTLTttAFD2GBNRUiWBBF2w6m0pQOc5D3RAQEgJFCkpBEITabpBxhniQ40S2kwBS1/2CfkDVL+gndNlFu+sX9Ae67LLHk6GQilSibSx7zty5c+65984EwCOrAAvjn41XBlvI473BM5jHR4Nn8cRaMjiDJatjcBYPrbcGz9H+2eA8fsx+NbiA5WzG4AXks+sGL2I++5LMVuYBZy90lBRbWMYbg2e4+4PBs9jFJ4MzeGqtG5xlLq8NnqP9ncF567v1zeACnmW+GLxAPY8NXkQh28A2eujjEhEUOvCRQGAFHlY5VlHms4aiRhW+AjuQiLVvyFmLnoqWkKNkLQUaGjvAdq9/GamOn4gVb1VUy+W1YrVcKYsdGatOKFqekqEnbdEIPXo/h8vQPtN0cYETEitckbLCJTfxd92Lk5a6kpwe0trBAAE9I05lZxC4BHUmEpIjHSN6SJ2Ao0XX+E6PUPyds94Lk3ov6khRdcqiJiYUFH9FvAfjFIZjekW6nD1dzgr1MsVjGcWqF4qKU/kfUe7XYvseTU55NjDSj4OuUXqulTqmD5uMYyNHD6VXhVYd68yH/LZpue6dwB73dnXvpuftkC2HI64p8tze3SI6IxrpeqQsY4+Ao6cziE3EAXFbaxA6itS7G2hy3Ge1pM78hrk5wZDW4O7eORPKJuMKqhryVbpfp/ymtpu6uDriFg40Tnhqc7pbCfXUUOITky3tYp+2mLFizXVd6RKV16l02tWz77x7YmVjNBo5XZ6dc/fC4bHfXLVzI5X44lDGMhrKtkgvhNhzu3LyKji53JGv4vFyq3eWjNxIChoC5ckw5sZB2JaRSHwpWo2m2O/LcOzcHDvY4tZRd8ZkZq9wh64K3NNACq3FFfWtA+EmtZyfJP1aqRR7keonsROrIBVd2q8z878q158I//l/6ScbPUGCAAAAeJxjYGYAg//NDEYMWAAAKEQBuAA=) format("woff")}@font-face{font-family:MJXTEX-S2;src:url(data:font/woff;base64,d09GRk9UVE8AABVYAAsAAAAAHbQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAABCAAAD1cAABLoUO+TM0ZGVE0AABBgAAAAHAAAABxdKvsAR0RFRgAAEHwAAAAdAAAAIABWAARPUy8yAAAQnAAAAE0AAABgPshX0mNtYXAAABDsAAAAwwAAAdqEtw5laGVhZAAAEbAAAAAzAAAANg2pmDdoaGVhAAAR5AAAACAAAAAkA/AEwGhtdHgAABIEAAAAdQAAAKR8fAIEbWF4cAAAEnwAAAAGAAAABgApUABuYW1lAAAShAAAAr0AAAZv/gOhtnBvc3QAABVEAAAAEwAAACD/hgAyeJyNVwlYU9e2PsdwwgYqVdv02jbiPD6riHVAW+tEi9WOovVzRkShChEIAgGSABnPOhkgAwkJM4rUMijaOiAOaG/Vtl/vs77a6fW2771qWymt7e0+YYfetwP1u7Zf77svCfk5e62119pr773+FZYJC2NYln3ouWRl2rPJ+dvWpqtS4x57OXV37t7kbIYdxrDMLHEEIy5kxfhh4iKJuDjsl5KBO/LwLjn3Iidnz94vZ5gR8mEjRsqZGPmI50Yx40M2iLmfGc2MZaYws5n5zBImgVnDrGU2MslMGqNg9jPFjI4BpoLxMnVMM9PGHGe6mB7mCvMXZoAdxY5lJ+dmpsfGLosNwdzYOGX63p2pKYqMHfuyFTtzU5R0OC5uTmxObkZGsjJdkZmdvDM9JXlveqYydXd28t5BcdyKIVg5BAmDsCJ2COYMQdwQzA3B3NiFQxA/BMuGYHkIFiQsHIJB2bLY2CGYMwRxQ/D4EMynkPD00yuHIGEInl6h2FeQnb47TTluWsr0cXGxsfGPxcXOiR23MjUnfXfmuLUp6amZKakzx63KTJn1h3vxm8HnFdkZyXsZ+mKZCCaSGcE8wTxJ07yZ2coaGTWjYU2smeVZYAXWwlpZG2tny9kK1sE6WRfrZitZD+tlq1gf62er2Rq2lq1j69kGtpGZHtq9Ccxkxs+OYJezKVSpaxhINku2STIkxRJeUhU2KkzgNnFHuavcHemUcD8KR1kRD0VMjVgasTEiJ0KI+CxyQeRXUR33lQ+fOfzg8LPDbwy/Sa7AGTHhDHuGviRnHsIzxBYyQ3ommCejo8GE8GhyJboDJ96UiJcGHpSBjRc0HjITL5yDs7LwSd17/En4DD4VTla8V4+t7+PNOBzPrm/2+g80o0qPIIANrEab2YIUUjKGRE4iS5LI5jTygIrcD2Q+kHl+MqKNjLpANt0hS/EYEoGapRaLjVoh6vbGTUmbPCxbJvDlunLdwUxPYb0Ch5PZ75PN9cRakShsgUUQz2/RJWaRk3NIFplJFiK9Tq/jeaS18tUxHikegyPv4CUX8OY2/IAf3w94HuD5KjwiDY9Kwpsm4aVkDI5AammhATRjo7Hto4ExMge4bJZyqzUwXi69BlVQVepQC2VQYjTrTaaB8fLALCiEImeZh0fRcwfGdMul9d0sVnZLsJJa48JukkiHcGI3KZTSKQObj0sChgFOBj5qLP13k9VYobPqoAi0GqFY0AXGyQMzbHqL3mWsAA+4nFB177wbuiW+/s9lOFEe2EYSN+BCeXh4aOKfcSfdljcH/iTzhoMfQGvLc2T48r2bWhWdJaeQ2c1jHcdjt1BkqFX+z+KL8a8jTbnLylXaX/N5Ky62Xeiq/ou9li8SsBsJWG9xca5TzZ2nW2u8Lb5ah9sGAH4EXn15MXBaMPJGfotqnzpT9cKunVuKN+iVQh1P/IgnerOWMxWZNHp1btKGjav2qI28KZQfweQxvrune2N9UrnaqrEWI4tWIAZOIH6+rlxZu/T6Gox2VBqBLhl56HIGxpySS1tOsfjILSy5JMFR/b/IIMdh95VdVVxN8q6gO1AkkP0C8YXs7fnunEpV92IcsR14tEe9Y39WflJKxq7Cp03ZlmCSKbt4xeqk1YrCsjI75EC+wNcAqgQBPPaj3qM1LbXn2lvf8HTZ66EEsBXwbPhIqKh46/Vzl95Afk+j1++otIcSAD4Ajf3Vql0Hsg6kdeQdM5zgK+Ajqo9CZiWGenVX+hvr2zNqd9bs9KrtPGggH3iAPBS6OeIa8fIRtl8r9snGRYae8Ft1l1h8MVAiGx8ZHbwYktqGhPRhUDiwZkgY2BFcf17O3XeexfvwE6IZPynpf4NclfXjcN/lnvpPAbnOy0nOOpe0HVr1DaXtRZV5nnQEv2BTKZe/dl3ek4BK1om68yXSRfBSffEVxIt9IH4vmgHkZNU/U/p/+Q3qfu9WThKDZvH7cEH8nvs/1H4XnTzMco/nfhRcf0se9u1p9s/9iTKDCUxQgIQiXBNkOTyFbMbDSbxgtpiCh4M/AvBmesp4MFkNVt5qfgfEVkBir3AJz+bavql/u9yLUqTabE1OgXLtqiXbZuS8VLxWP8Og4omdJy8DIhGPgTAW+/E5Dk/C8TgKywVBsILAW3jrZDye/CKWoTI3PgEc7uCr4YwJjy/9NufjTYdU9aqG3Mbs6myvAlUUdwKnd+eeT/sUvYQfDX4HXPBzeq9NZkR3u39Ph6S/WB6mlumgzGAyoKBDHjhKdgZ2cQA5WYp0NIUMP5j1zkeYDUZzl8nek2SBTYMqpV6wW+x2hFv7ozgMgYbDP9DC69Q5tYCijQN3jshRSgd7AYcFHsNhErx4oEA2gZ6uunsk4uM4jJa+QbyrITY9RNX6/X+ghqfSvzn0edzv1EV7yCbkM/DmMXHrscCJQbsrx8RtnZfv6r6e3ZCxKy97d4x1zcn1b8MpOPpaw+HWE4evtfQ1ffEW1r+BX0bON13AfeW4cbrz6qHj/uPwLnh5L+8o+ibp2tIOnU1vBUC1OJxrxotdF2q/bcH/VvNh47t1lxra68otggWs4AKv0akvN3rVPKCMMqUadqNXm5QtR2qaOmKMV5LPJoCRvk38Tl1mdm5m2ta9CRlTsxe9QGA7SUKl20qAiy17atOONZnbVDtgFazyJx9Kbt7WmXFSmUUWbCeabBK+iyzfMzstDWlLDCatoIKicrXXaDXT4FocDR5oR9jfv0FWtq1gtiGDL+P1NJJcD7fx8O4u9UVDDe+BBmgQPPYa37snei63NFa2ueoA2aVGzaskXvUkwmcPyEDNa/gy1YxnVszdrzEVmPSAjFJb5es43v+xs9v3lbPj/Z2XVsMkFH3hZuDiTUl/Z3CyjC7fRk+5M7hBzo022cq8KpcK8qBQqys26YPr5f29phKerh2MKKteeTCmGvwuh99ivYVrsARfR3ir+AneGvyEwxJy/RapsZicKn9JNTRDbRM03nV1oX+0LDSHYLKWiKFJrQZnYUitGnzuCo/VJobcW5z0moQIujGvSRFTAKqS0kKzcRapIXRuRKgXQr1xhPqdhWvMtjJfgasAMiE/C3Joebl1m73QGzjRKxH9/atkRFI6LWV+wuMrVk9UkRheA6l8cB6QL4EMF4w2ZZ2KJhRq/fZ6JNgAjwR8DfBZwNMElxtP/w7L8NTzJ/1dztOAlYDjyRIPeVEoATINyFkE5BqQkYLRnls7OE2d39YQmmU44C950Sgk647m48hEPGzadbSsZ17rDLdGyIBceseC62iQ3wXe7JX09E+UTYyM3tP/+T0ET3n5A6ztJp3SXwX2XxlaKw/M7A6xc0hC+fuenqCzm2ip2Ya7AmqC7cFvZES7AXdSEyroxmHn8NtnJPQqmmR4YGCAq1A7dG7wgruS9yKoIM+IK7npuHQRfgUsIHyKX+nFpQg/IyZABSd4SitVUAxGnU6NyMBAkIvu/vIkfuccnY8G4ASH3eawWD7Dm/qwHuFV4rPgJavEVdxUrI/Hm8wWo6PUXkJrV0mRoLGpMB74GsxgXkRemU5KEXkmuBJ0nLnYq6FsHd2/mqZIdNJZKnrZnl7RgRNFR6/kQXkgtn+lbFIkHv+Y7GbpXxUfb8ZzZuJHyPNANPBU0ZLM5S+TifScSMkjzyXufVa1VFfK5/H5gPIpQ5cKZF8tWYjvj8Vxr9za9yPcgSuuq7VvH8PSnv/84voXH+BhXTi8Crktr1kOQh20gJtHZFLwtgzKhDJB79r92p5TcBaOdMA5OL+jdYt1PaTsgnWhcPGWXvH0d2xPn3iqVzzVJ3lw4a+RHhl4WEaapUSxltIBWK0HLZXHcSV+Aa/BRWcPlLfZ6yzIIsWjTLIf1L0pnz+HR0/9gsyoJotDHmnjwa8FooghzeJpaTnP2cDJO2lQo+RkrUwvcETqnnw07j3ycN88PKMAL+YdfDkISOgBrIjBzdKAnKc3zrTPrNFtV29UJf8jO6szVqtW6BCtMOJp3ExJSNED/NihxMvDOkNZl4cd7ZXck/CftX27vnjep23Ko3EFRwcfDo4WH+ZAaKr1ub+88vORvzkcgpNWElQjvZu8ETR5IU2Oh8IarU/jL64tqaa5/wF+hA+rbhz6wHO4/nj1IV9jc7sFUH+cRlabU6Ooyjo76+BkmDi0o+o9uckFmYU5it1mQCGXYsgt7fwNdh1aPHCDLnBL+n71gvVxmVNLh7Y7H/Lobk91xh1aeC7Xs6WVFhNB/JM4WogJXT3xv3vp7cM/9eK/3b2A4iskIKN8nwbL0YQJ4cvpPyY+z5ifT1s7Wl38ZW69m6+ndapR6AD003gpEAT2co2jqEpbGypfLqevvBIMgBH620/hHdBIKb0e3IK73O9whQpcY35Nns0kUAeAJvwkhQ+gjbcaGvb7lJANqnxD3lBV6LkdOHF7MCgaAPkMBj8C/TbZCzzqWh0St/Ic/i/AI8AuVNt8VbYasAr4Mxj88PTbaqjP8ytBCXkqQy6iRZushOBGNBAxcCIQEQ7iRsAredtvPRMP9LHQ19cngbC+vqlSvHmqLIT/XBDcPij4dTi6/9sHxYuymEiJ+6n7IuC+yDORZ6JiIqV/v2+UnIl5gOFCPy2XMd1sKvv3YQqDEDThJygfE9t8jozdQrhU2tCaXGm0OwI8rAU/2o4f6cCSFgEQNidy+NHdeFiGEKLoNrqTUduNO8u2FG0tSit6IQPtLnAUcvZSaxlQY7u1wnrYd6L6sPtC7RHnO1BD35Xm44YDZR9koTcLK41N+tbSA8Z2wFL46tjXp1B7dZmPMzhNDtrvgcGkM+0p3FqwR5uUl1r6LITOkcaSbM9yrDiAEht2VC0AFPWHvcihIwd7mj70dVWdb/jqpij9M267Js5uxFMq3675Gv2LVuOPO40cyNUWqB9fs5Uk7iBzZwUjXyAtK4OPZ5In8icqx//LNiKKN1CGozwnBI388Yqd3rnHFlx++sYCzL6EwwtfM7igFW7CO9Xvv45un/7wetfXB7p9Zx1XhEo4Ioj0B+yXlMV4u7F+/29P0shByjtL+Y8v0ZLp04iMTFm3RbWxdCMQJZB4vESNX+RdlD8pi6JBMh35j7OWn2/KQ1Hk4UIyMmnSvBmLl5JhO0hU9jL1ElgChGka1zX9NknCL5NYDK+2GbxwHNBxyk7tdvyQH4+88MNfv/3kP/CwYziq6brnBtwAzGT/vLF3JZ5AwnEYmfgeWta2pHaeU0tvWQ5kgMJcYEJR/wtA42GBAAAAAAEAAAAAzD2izwAAAADG+TJPAAAAAMn0JeF4nGNgZGBg4ANiCQYQYGJgBEINIGYB8xgABgIAWwAAAHicY2BhtmecwMDKwMDUxbSHgYGhB0IzPmAwZGRiQAINDAzvBRjevIXxA9JcUxgOMCi8/88g9/8RUECOQU6BgaE/jhmqQAEIGQEKkBAjAAAAeJxjYGBgZoBgGQZGBhC4AuQxgvksDDuAtBaDApDFBSQ1GfQZYhmqGWoZFjAdY7rDzKwkqCSlpKd0WJlb/aUWkxaLFtv7////A/UoMGgA1UYjqWVS4geq1VY6oMyh/kKLAaz2L1Dxw/+3/l/9v+p/7/+e/1l/Xf8a/OW+x3D3x90Xd8PvCt8wv6Z4TeGavIAm1G1EAkY2BoIaYPJMzGCKhQTjWdnY8cpzMHCSYBoqEORnEIaxhSAUFwnauXlgLACmbzOJAHicY2BkYGAA4ti7W+/G89t8ZeBmfgEUYbgau2oDjP4j/GcR+x7WACCXg4EJJAoAleMOSwB4nGNgZGBgkPv/iIGBzeKP8L8a9j0MIBFkoAkAiYgFtXicY/jFYMTwi4GBKZRhCxArM2szWDDeYHgApM2AtADTbIZyEAapYX7x/zfzCwYg+CMMxBIs/xgsQJh1CYM5UDyfSYfBnMWGwZzNgsEczA5HxUwCDA+AWABOJzMUAHEo63OgGVAMU8uow8AAwgwpDAwAR5Eh3gAAAAAAUAAAKQAAeJytVMtO20AUPYYEVFeJYEEXbDqbSlAlzkNsCAgJgSIFpSAIqtpukHGGeJDjRLaTAFLX/YJ+QNUv6Cd02UW76xf0B7rssseToZCKVKJtLHvO3Llz7rn3zgTAIysPC+NfAa8MtpDDe4NnMI+PBs/iibVkcAZLVsfgLB5abw2eo/2zwTn8mP1qcB7L2YzBC8hlNwxexHz2JZmtzAPOXugoKbawjDcGz3D3B4NnsYdPBmfw1NowOMtcXhs8R/s7g3PWd+ubwXmsZb4YvEA9jw1eRD7bwA566OMSERQ68JFAYAUeVjlWUeazjqJGFb4Cu5CItW/IWYueipaQo2QtBRoaO8BOr38ZqY6fiBVvVVTL5fVitVwpi10Zq04oWp6SoScLohF69H4Gl6F9puniAickVrgiZZVLbuLvuRcnLXUlOT2itYMBAnpGnMrOIHAJ6kwkJEc6RvSQOgFHi67xnR6h+DtnvRcm9V7UkaLqlEVNTCgo/op4D8YpDM/pFely9nQ5K9RboVlGseqFouJU/keU+7W4cI8mpzybGOnHQdcoPddKHdOHLcYpwKaH0qtCq4515kN+27Rc905gn3u7unfT83bIZuOYa4o8t3e3iM6IRroeKcvYI+Do6QxiE3FA3NYahI4i9e4GmhwPWC2pM79hbk4wpDW4u3fOhLLJuIKqhnyV7tcpv6ntpi6ujriNQ40TnlpbdyuhnhpKfGKypV3s0xYzVqy5ritdovI6lU67eoU7755Y2RyNRk6XZ+fcvXB47LdWC/ZIJb44krGMhrIt0gsh9t2unLwKjm0f+yoeL7d6Z8nIjaSgIVCeDGNuHIRtGYnEl6LVaIqDvgzHzs2xQ0HcOurOmMzsFe7QVYF7Gkihtbiivn0o3KRm+0nSr5VKsRepfhI7sQpS0aWDOjP/q3L9ifCf/5d+AkCAQY4AAAB4nGNgZgCD/80MRgxYAAAoRAG4AA==) format("woff")}@font-face{font-family:MJXTEX-S3;src:url(data:font/woff;base64,d09GRk9UVE8AAAysAAsAAAAAEmgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAABCAAABu8AAAgJfCKV3kZGVE0AAAf4AAAAHAAAABxdKvsBR0RFRgAACBQAAAAdAAAAIABGAARPUy8yAAAINAAAAE4AAABgPshXPmNtYXAAAAiEAAAAngAAAar6/I+1aGVhZAAACSQAAAAzAAAANgnZmDloaGVhAAAJWAAAACAAAAAkACAFjGhtdHgAAAl4AAAAVwAAAGQ7uPuabWF4cAAACdAAAAAGAAAABgAZUABuYW1lAAAJ2AAAAr0AAAZvAQaluHBvc3QAAAyYAAAAEwAAACD/hgAyeJx1VXtQVNcZP9fdixfU9VHX2s4NruNYjQ2GaBwx1UaTYEI6aGpKTdWAm5XCIiwqEHnuyrIP9n737oNdFnZhQbQ+oDYY08xgLTFWZ2Q7dlIndSjTDjqxHdO0lhmNfBfOZtuzYqeTmfbcP373+33ne5xzf99cjmi1hOO4JfnG6tLXjbVFb5rri9dn7SouqSk3HiHcLMKRZ9UFRF3NqU/PUtdo1O9qxem3kq+L/BmRH+BFLmu+SMgCkStcKJJMcXbWIrIwFSSQ+WQpWUa+Q7LI8+R75CWSR94gu0khkUgvOUcu1FjM2dnbslOwPntdtbn8QLGpsuKdI8YDZpOxnNHr1mfnzMCmGdg2Ay+lYGNuzgykfLnbt78yA7kzsP3lykN1R8wlpdWG1aanDeuyszdlrct+LtvwSnGVucRieNNkLraYip8x5FlMa//nyb9G7qg8UmEsJ2xxJJ1kkAVkM9lCvk/2kULOTazExrVyHk7igJM5hfNyPs7PBbg2Lki+lbqK5WQFOc7N5X7M1XKfcA9nxTWKxqfp07yv+VhzU5ul3a41auu0Ae0Dfi9fxQMfuQbDau4wN8yWZngJrlH76Zq04cRRPWMTubN113TqB1j8D83UD5Nb9eCT5OYwXYvPr8Dd+SgZcXMN/gDwCKg/w4WqDjuwrz0sy+ADr9vnUYRycLv5uqbCwqrDtIhW0fn0RnlinjNXKoQc2CgXBrYPJHTIWGTek4eHCmNNgs89ALyi+FgOgRVXt97XqFvRp4fEnmfoI1pA28v2l71jMgnHvFJPZhR8Pj4WGRo6eQqLsArn440BVRf4vTwEt2FcGnLeLFfnUcZS5q06VThUFxHcvkbg611gW4bdtBuXJJ6CxGlBN3XvN5c0f07m6UMQ8vsCijKJg7hDdQlqvqjt4D/DphHcJHvliDXaAM1gd3hcHneSEyfvuK2SB1KPNdwYBUGHd5N5cVG4G+cQ4hoElhP74tTEKDTFaV8aq3X1V1NjlzTTh5Jr9RBwh+hKdamQeFyIspoGHPQo7kCLzyE3gK0ZGsDhtePKxNJUM9TM446Ea5IOKh6fM+QKQQQ6OiHytcKWuCYs8uV6NIn4FDXlY5+YXpQqrV5J5g2J6fwQh2PsapPJl/XR2dAB7HuB7PK6lLrQoa76zp0XjdetI84zskXChxJ+KVscZ4V3//7iZzTtqlAfCnl5nzfsD/m/vHpzvPde21nJIuMjGR9IlsCZzpEPr1+/2N15uisWEvyK3wuyojBRdAgQdQYqoMHB08U/2rSxarXDIvdLFCX6EVRLx+y7avaUvF1RYjIba6wOSYZaAWplpdPxl323nusyyMegWqYfyWx/f1vlyVW3N+DiAiHi7AeenQpHJzT4TZFv14MdnLIke3ytYdfdvZ+81mPwlnkS97xlx+nCz3Mmdgu9zUftfFl9ZV1lTYP1YLmtsbTo3bftBa1lSuJea1ktJa/mrd/b4JAUaBTACQ7eKkvHMyMQDfC46Mr4nZP3gwNSmYzTgoy3lAjf/ttTH18cPnX2g/5fdLf7QYYYdIPc7K8LHo7Vd77x6z03rH8VPBEJ/8BLOC2XtQxU3c+5QxddERoDTeACvkGSji5jsyZq76ojF764xYl8rzqiN2Q8ZiYvv3eZC6uT+uUZOlows8E142bmY684XTLjn7qkbh7UqJuTr+k9AB2s6TbZG/T71cti+kZol0LNwRZwQIur1eVxJvwiRsEt0OLpfTSLujutfFtLwAXsBJGTsTN9g+1R8HhbsTzZ5m0VdExOTFgSU7TEFB0X05djV5yOpT1xnP6P4rrEydvxlNqYi+nxvyE4FqddLCz/Cc8i8HRyjp525eMYC8hPqVP92zUNLkKXHm2J2zzq6egjGpM9bY5QSxiEaDTcuwxCtFEdZRrCT1dghHUrP8QIMkvARvWPEORj1s76TBs0t7gckmc5jVGWRaC2xHhKKF+w/AtZN1FoC/hDsvwIY6jHUQFt6m3opjZ1nKfMXo4xSXG12YNN0Aj2ZpeNzTiwGT/WtwtLEn24mH76kEZAEkBaQSOUmQJtTIyCna8L23oydZMwwcHExIQGtBMTq9Jw3yp9Cv8vv/Yx/4TVqX9ajAX6zAxN+MW56TA3YzhjeE5mRtq/5i5iv75vkFkct+EiyMHzIEvwlRm3SCB8VUq38CAFfwpscnBDP751Hn9ynr0oEIKpnfTbIRDmyBBUon584QrqT2EavAfnPOdcHzov2H9X+6Dil/a4s0PqgxMgnIA+6JD/Gfy8B+e93+6d/Dn4wdt8AtokaPE0uugLBVR/mKaBYAazctC/P3AglNezst8Y2hmwyaVQBfuhrPWga1tzTu2zFuFYq+Eg03lrezU4hDn/Bn5x3UoAAAAAAQAAAADMPaLPAAAAAMb5Mk8AAAAAyfQl4nicY2BkYGDgA2IJBhBgYmAEQgkgZgHzGAAFUgBLAAAAeJxjYGFazTiBgZWBgamLaQ8DA0MPhGZ8wGDIyMSABBoYGN4LMLx5C+MHpLmmMBxgUHj/n0Hu/yOggByDnAIDQ38cM1SBAhAyAgAxbhCOAAB4nGNgYGBmgGAZBkYGEFgC5DGC+SwMHUBajkEAKMLHoMCgyaDPEMtQzVDLsIDpGNMdZmYlKWVu9Zfv////D1SnwKABlI9GkmcCynOov3j/F6jg4f9b/6/+X/W/93/P/6y/rn8N/nLf/XqX44aOgCTUXjyAkY2BoCKYPBMzmGIhZCYSYGVjxyvPwcBJgmm4AT+E4iJBCzcPjAUAwEAoHgAAeJxjYGRgYADipW/uh8Tz23xl4GZ+ARRhuBq7agOM/hXxx4t1OesqIJeDgQkkCgCXpQ5xAHicY2BkYGCQ+/+IgYF1ya+I/29YlzOARJCBJAChfAateJxj+MVgxPCLgYHpAcNFIFZiEWEwZxJg+A6kLYA0N9M7hiYgbgapYV3y/w/rEgZGBoZfEUAcy/yCIZ/JneEbEHPD6XcMdUAcx6jDwADCDCkMDAAipRhzAAAAUAAAGQAAeJytVM1OE1EU/gZaiDVtYIELNt6NCZjp9Ec3FEJCIE1KKgRKjLohw/TSuWQ6bWamLZC49gl8AOMT+AguXejOJ/AFXLr0m9uLUENNUDuZud8999zvfOecewvggVWAhfHPxiuDLeTx3uAZzOOjwbN4ZC0ZnMGS1TE4i/vWW4PnaP9scB4/Zr8aXMByNmPwAvLZdYMXMZ99SWYrc4+zFzpKii0s443BM9z9weBZ7OKTwRk8ttYNzjKX1wbP0f7O4Lz13fpmcAFPM18MXqCehwYvopBtYBs99HGBCAod+EggsAIPqxyrKPNZQ1GjCl+BHUjE2jfkrEVPRUvIUbKWAg2NHWC717+IVMdPxIq3Kqrl8lqxWq6UxY6MVScULU/J0JO2aIQevZ/BZWifabo4xzGJFS5J+YRLbuLvuufHLXUpOT2ktYMBAnpGnMrOIHAJ6kwkJEc6RvSQOgFHi67xnR6h+DtnvRcm9V7UkaLqlEVNTCgo/op4B8YpDM/pFely9nQ5K9RboVlGseqFouJU/keUu7XYvkOTU54NjPTjoGuUnmmljunDJuPYyNFD6VWhVcc68yG/bVqueiewx71d3bvpeTtky+GIa4o8N3e3iE6JRroeKcvYI+Do6QxiE3FA3NYahI4i9e4Gmhz3WS2pM79mbk4wpDW4vXfOhLLJuIKqhnyV7tcJv6ntui6ujriFA40Tntqc7lZCPTWU+MRkS7vYpy1mrFhzXVW6ROV1Kp129exb755Y2RiNRk6XZ+fMPXd47DdX7dxIJb44lLGMhrIt0gsh9tyunLwKTi535Kt4vNzqnSYjN5KChkB5Moy5cRC2ZSQSX4pWoyn2+zIcOzfHDra4cdSdMZnZK9yhqwL3JJBCa3FFfetAuEkt5ydJv1YqxV6k+knsxCpIRZf268z8r8r1J8J//l/6CWXDQZoAAAB4nGNgZgCD/80MRgxYAAAoRAG4AA==) format("woff")}@font-face{font-family:MJXTEX-S4;src:url(data:font/woff;base64,d09GRk9UVE8AABQcAAsAAAAAHMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAABCAAADg4AABHZr+S44UZGVE0AAA8YAAAAHAAAABxdKvsBR0RFRgAADzQAAAAdAAAAIABhAARPUy8yAAAPVAAAAE0AAABgPshXmGNtYXAAAA+kAAAAtQAAAcr935afaGVhZAAAEFwAAAAzAAAANgnZmDloaGVhAAAQkAAAACAAAAAkACAHYGhtdHgAABCwAAAAjwAAANCVFRBcbWF4cAAAEUAAAAAGAAAABgA0UABuYW1lAAARSAAAAr0AAAZvBAmpunBvc3QAABQIAAAAEwAAACD/hgAyeJx1Vwl8FOXZn2GPjLmkwiLqGCI1ylEkBDDkRwEDJBULVIkVq6gNENhASCAkhGyy2ew1uzPPzN6bZLMJIRzKGRKRD/jC8ZX78OBID8XPRcWf/moVtbTvJO8G+04m2GLbmf3Ns+/xPP/neZ9jnqEprZaiaXrEgsIK4zOFG18rKDYVTZmwqGhlZUlhOUUPoWgqUx5KyXNoee4QOU8j52tZ2c/iNDahlNX/QccOeeRelqKGskPcP2GpNHbohvuonylcDHUvNZIaRT1GTaCmUNOp2dQ86llqMfUqVUSVUOspE2Wl3JSXaqBaqW3UbupN6jD1f9RZ6l3q99SH1KfUn6lvKZn6ntbTKfRw+iH6F/QSupguqywtzszMzVTI5MysiuKS5UXLytYsLS9cXryssIRMZ03OnKaSHJXkqmT2AMkZJHNUMlcleSrJHyADwgmZpJIslUxWyRSVTFXJkyrJVokKm6vC5qqwuSperoqXq+LNHmDIzpumEoUhLzMzUyUKbN6kqZkqGRxlqWSyShQl8vLz56okTyX5c8rWVpcXrzRWpI9ZNjY9KzMzZ0JW5qTM9LlF64tXlqYXLCsuKl1W9LP0eaXLnviP3r5rcmFZ+ZrCEopcNHUPlUgNpX5OzaBmUkuoV2kXVUdZaDfN0wINtEhLtIf20j7aTwfoIB2iw3QD3Ug30RG6mY7SLXQrvYluozfT7fQWeiu9jd5Ov06/Qe+gd9K76N30Hnov3UFNUWJmNJVBvU6PJn6W6Ku0POQLzXuaK5qY5lstpR2mtWij2kPaHu03uhd0y3Rv63P0+fpO/Xn9B/q/JiQnPJzwZEKImclsYf58zwuJVOLyxK4kJuk3SXzSueT05LXJb6dMSslNeSllfYot3gxH5byj9FFyaY6OQOPknXic/mi8ykBm43kJqfHm1K3IijSaXoHFYwzg4T2WKB6KJk5E+c+gFTNQYAU6BnIiyPd0omPvo8DbaMXnKB+RHY1RyQMeBjwuLy8xJn0duIAXeH5taW017saf4vR4JfSnkB9Kj1ehbvxJS9X2MkkQhSCEgYnqJcnrJQJSt8q/IgrsYfXvGMDt4SImNAQ/fAPnnMcLP8NtB/BFiP8U4o8W4ouTcNsCvDAL52Cyw2xyc8AztoAQTvPrgxAUJZDE7W+0tKFu9ClKlyuhNxV6k3G6XIW70SemtnVv8KIgOsEBjF1vcQj2Ualy4OSJvv0nNKzWw+ovGNzc7RvsLY63KZYAD7URc5QoG/b5Ah5f3w02ySSFCAgBYqK1TaY0K9idnJNJxQtYPKqHTcrooVF7jwa1k6EBnevBFjKHLD34nP4HqJOs/pABBJHIl2x9CpyH8znCXBiiEIlAM0gCkc+Hbitwbh/DBeu9VjCBpRZq70Zy9Gh8rF4yIAt76xq2zEbn2KSDClQX+kZx6VgWZxigBRp1EBLA5q33r4+aG01NpTvqWl773aoeR0wIARoBKDzwu18IMY6Y8cNnL1ua1uysa6hp3NhcE2Ze3qE7t7P7rUPdZy53fBiIiYTlfkDk2UB4xZC3u/FQ24Hdl05ffGcfE/KKACEGGqHF6V8FlfW61aYKc/nGvMUv/rJsdn2ZYy1nFJzC44BPMkI8gzfp+A2uKs5UnjE/a0qBxSp4YANUiZ5G6ycFF7K2ZfhM3ippAyPViPEMHeBT4uOiM/TL1pc6Xjj8i7cLPlrKtNr2gI7Y+xWxFz3K6o8boBqEEPf1sx9hKozTRBvgNMASYA8oI3/Onpmn8ptqdq2Jmpmd5bsrujYaTasqVq+rMZesqatZlL9qpjNHUJk8A3xpgo1xTC6esXBexbrlJWU1dk4QoJqpANia1gxtYd2x7W/t6Oo8c6rrYssVb5OnWWoV/eI3gE6K8gKhKPDmJsRcuvXlWaYxDE5ohy3gtITHn82/tRExjjfFIkFeCOiE8I3g51vdza4mpvKzgmvZF8o3lUdXR5mqcA3Ug84C/IZRSrL2/U0+fZGu69UZ0hOVwTWkjSItLf+197zhkcTU/pCyzMoBdQMZDm5g+26rO1Ct/PN9clunpm81q79o4LlleDlexWKBwQG276hOkJagbQXo+iIUI38EkZmJx8/CE7avu4iGIU3/A7pzGB3DB0Eg0UsyIwIB0RP0+eTjbFIAAkLIFrSBHRycW8kKA4nOf80IErel6GBPnNL/sHbkTgwfZG8FyPrBwUUS5P/CKFM9+CBhnv3PNcKIjrDYaMAHZ8sUYSRrf0cH0X2a3vdZrc1QrSfJCQK5HA6HDUfwZTwxPvnX8Z1mPNqOR/N4JuSD6HdLwj7YBcwWaCOJ7ZdAhANwUPpCPL6pdwxKlG1oh/xwIOzxgQe8Lg+pdIMo8iSbYXTiHchY/72keLpJHmMT+gAPlyctlffXI9aJZgIaQ0SKTokXq6ACSmAFKS4M5yZI+R68sgHPacezLpAKOT4+DLnxkYAt4CBliqQmqZItSpUkyARVfoUA7WK1VQaRl1werqVi7+LGKvQCfgfR8WGdcXsDfthPrMJjoBBINElCGwk2ZhfsUwzzEI9dcqOV9WhOJXpqvrwBj5eHYTc64gg5AgRNdChlsV5f7xSsowbB5D+qJg4MTvaPNIQgCCK5AoFACEXQZTRRnvw7eWcEjQ6i0RIx9RIITg8vroUyYMrIgxeInQIsJUo58ax6/NCKuAMTbTHR2lJVvNhU4XLwbnAzdp/Qlpb6WN+JGI2uxjToav8Dhhir34+iMXxTn/rY5g2D8yNi8tfZZKJ/5A87RxrQzRiOkt3KwoCIaEzTd0KLomzvghibkPCDCDKPoneJGJiJnzLgaDa6SbaSBXk4StL0Lum732CEOofu1fLlZcWrp03Px0Ns+BFSGyYCzgAchFbljFthL5wkrpT8DHktnAM0T0TNQq2/azN68DJivrsS8Pp8ypkB8SfTkqBIT9bID7Bal8Hl0glu+A3gPEVilmCx4hlz8WiclOXgOE6JXVCSyQ42UWBA8HEBDumy/4gfasDzRAtkDejhUfXYDuotiQwJ4mpAXkDp8AUphX+ourzy3Vev5/0++zhjDkVCujOdx//3wIkLH3V+FfiOVPMvlI1ke7USoRuhEkrBqERoqmxAKZrepbd/YmhJILEYUqKEvKm8008siK3+ytLh6OD+R4jAFgGtBfQ0nBMkhvcLUADLwAJugVHM4wFPADwSxsJU0eqdH31ux3NHH7uW8+3zTIOzg1RuK+qhB08EnTeoHEbAiYCnQ/huu4hZVkDTlZ/VSaB+rGuSBs3pG2FwuYmIarLVriQROTPXtefPZ+8e22gMGH2/Fc1QIeIyBvA8WEjyyCkS7+2FVlU+ObYgoAz4nBzbB2v+tOos8+JHcy5NOsLU+01KEeZUrLs9SEwcB3gEjIcnRavvqba8fU8fevJybmwxE7GZbbpnVyxeUvj8/GkrxjoeJcHzBOB0wN7/4jSPgn5DbAyjGVfQaJR0I+Dz+UCNHtLhKD5gQHGCD+tis9BD9Wie0Ag3FC7C++8eVDUNGQTSlwlKS7MQ8NMCbhYjzqIq/OBczDw61+HiOKVMKnHGlANsS4tCg1/32ZGrl47F9p7e8YHvfRIlnw9gBP8dA73Vu2i/ptfUr1T07xNcQWfASk6fs7s4RujnoJ+Lz2N14/AT+GJTnS5g93NA0mXTm1sOMweuyxVs36JG0G0SRV8wyKR29d77rgalI86AhP71OsTGxyAtvi7yAWvQ0QLM5khk8ygxFDezun1yLavrgJAO2muaqkUXcMQ8q9vh5OwCjwkTJswMFvrLSX/wHZGaxuJ0QwsEA4GwKCEtuo5YeQyDhN710IqF3nIdJmNM5gXJEbYGa4CpMtduGAU2AtS3KE4ez4FNtyFi3px2x+gVZkMD+PzeICP//UeW4zOAz+i8dp+zAZRDks/vp3/Mcx5dTQh6Az5ogAaHz+5l8JfAuXUOt+Air8/4xwl32PEVQMl0NS42tOjbyOn5gr5Qc3uo4U9/QcNPoomhkNgIfmgCjyj5SBUiIcUoD0HifW4S8Q6oFxwwzTmtbOGK7JfnznlpKmM3g1E3IDeRtp41wDpYR7KB8whNJBu6uS77/9dcLjn1yp7yjuWbjD67SN6OTAv4/dBhj+he+nju1ezup9+avGscCRpy7iTXBUvNqEE916NrBjAGzbojU6/Mib3cWr/P1Go/Xfme+STpC/+poqoho6hYB8Xwsq8omBPN27XocE3jmp2WqC1c286FuKAAVUC+LgZly0b0sUH51iCpyJMO2s27OVttpc1qqVmzpsYyY36GEac4rIKF9FpMHalCvBIW69RbtbCRZPx7kdPtrcF9La0NTKz7ytUjHzPBCHToUuNaBcQ6Qp6GkuPT9KlxI9yk4ebNmxrQ3rz5uB4tedyg0P++0J85sDA4ndqXMrw3ZEhL1DTMSr4HkhOPJh5NSkvUf598H0ulDaM0yrfgr6g4PZ1oKZAPKE60S3W+Sq8tABKglQdQwzFGLv5SXjleh8IvImOhRBztC3m3Sg1SgPwN8B4X1HtvP4WKeVJ1b+fiEreLSZrmwFR1emlmJc56pdJSY68yg5PnAi9K9ZJyBrwXAC62MWjBSTShAxma2qXd0k4gN9/KX7IfMv+l6Lqxq/6EbY+z070fGNLNpm5CGZ032lHW4fbG5mBbBPykKEmkKWrmOvkQL7l9pDVyEbHPVOH5BfgJI76vbj1fwpeQhqdU2ijlB1+LjO+a2lHUUBBiSvyveX6rdPpCtcAkeUFCD45CXycgFoBLc8NGcf2dNkl9Rc4DXM/g3ATAY8VmH+8RXofXYQdsE33AJP0DWbiWLwAAAAAAAQAAAADMPaLPAAAAAMb5Mk8AAAAAyfQl4nicY2BkYGDgA2IJBhBgYmAEQmMgZgHzGAAGewBmAAAAeJxjYGFmZZzAwMrAwNTFtIeBgaEHQjM+YDBkZGJAAg0MDO8FGN68hfED0lxTGA4wKLz/zyD3/xFQQI5BToGBoT+OGapAAQgZAfVvD+kAAAB4nGNgYGBmgGAZBkYGEDgC5DGC+SwMK4C0GoMCkMUGJDUZ9BliGaoZahkWMB1jusPMrCSlzK28Vnm7+ssHjA9D3v///x+oXoFBA6guGkkdE1Adh/JsoLoXDxgeBrz/C1T48P+t/1f/r/rf+7/nf9Zf178Gf7nvfr3LcafyTsENBwUtuTsCJlD3EAEY2RgIKobJMzGDKRZizQYCVjZ2vPIcDJwkmIYb8EMoLhK0cPPAWAAKajPsAAAAeJxjYGRgYADi+gqdffH8Nl8ZuJlfAEUYrsau2gCjf0z8Lceex3YNyOVgYAKJAgBvnw2OAHicY2BkYGCQ+/+IgYE98cfE/y/Y8xhAIsjABACbyAaDeJxj+MVgxPCLgYFZguEtECuy/GOwYHJn5IXQDKzMagwTQBikhj3x/yf2RAZGBoYfE4F4IfMLhnymekZepnoGVhjNnM2ojMAM8kD6JIhmms1oj8AMDECaHUQzVzI2MFcyrILQyGyGVSwKDPlAu3uAOJ1FgWkfCDMe+v8CiL/B6QlArMPAAMIMKQwMACkWM+QAAABQAAA0AAB4nK1Uy07bQBQ9hgTUVIlgQRdsOptKUCXOQ2wICAmBIgWlIAiq2m6QcYZ4kONEthMDUtf9gn5A1S/oJ3TZRbvrF/QHuuyyx5OhkIpUom0se87cuXPuuffOBMAjqwAL418Rrwy2kMd7g2cwj48Gz+KJtWRwBktW1+AsHlpvDZ6j/bPBefyY/WpwAcvZjMELyGc3DF7EfPYlma3MA85e6CgptrCMNwbPcPcHg2exh08GZ/DU2jA4y1xeGzxH+zuD89Z365vBBaxlvhi8QD2PDV5EIdvEDvoY4BIhFLrwEENgBS5WOdZQ4bOOkkZVvgK7kIi0b8BZm56KloCjZC0FmhrbwE5/cBmqrheLFXdV1CqV9VKtUq2IXRmpbiDarpKBK4uiGbj0fgaHoT2m6eACJyRWuCLlGpec2NtzLk7a6kpyekRrF0P49Aw5ld2h7xA0mEhAjnQM6SF1ArYWXec7PULpd85GP4gb/bArRc2uiLqYUFD6FfEejFMYntMr1OXs63JWqbdKswwj1Q9E1a7+jyj3a3HxHk1OeTaR6MdGzyg910pt04ctxikiRw+lV4VWHenMR/x2aLnuncA+9/Z076bnbZMth2OuKfLc3t0mOiNKdD1SlrGHz9HVGUQm4pC4ozUIHUXq3U20OB6wWlJnfsPcmmBIa3B37+wJZZNxBVWN+Crdr1N+U9tNXRwdcRuHGsc8tTndrZh66ijziciWdnFAW8RYkea6rnSZyhtUOu3qFe+8e2JlM0kSu8ezc+5c2Dz2W6vFXKJiTxzJSIYj2RHphRD7Tk9OXgU7lzv2VDRebvfP4sQJpaDBV64MIm4cBh0ZitiTot1siYOBDMbOrbFDUdw66vaYzOwVzshRvnPqS6G1OKKxfSicuJ7z4nhQL5cjN1SDOLIj5aeiywcNZv5X5foT4T//L/0EiwZBpgAAAHicY2BmAIP/zQxGDFgAAChEAbgA) format("woff")}@font-face{font-family:MJXTEX-A;src:url(/Blog/assets/fonts/MathJax_AMS-Regular.07173fb7.woff) format("woff")}@font-face{font-family:MJXTEX-C;src:url(data:font/woff;base64,d09GRk9UVE8AACWEAAsAAAAALvgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAABCAAAH50AACQyJmMC1UZGVE0AACCoAAAAHAAAABxdKvrmR0RFRgAAIMQAAAAdAAAAIABXAARPUy8yAAAg5AAAAFAAAABgQXJW9GNtYXAAACE0AAAAfwAAAWLiwp1NaGVhZAAAIbQAAAAzAAAANg4tmIBoaGVhAAAh6AAAACAAAAAkBHQDnmhtdHgAACIIAAAAlAAAAKhijgTFbWF4cAAAIpwAAAAGAAAABgAqUABuYW1lAAAipAAAAskAAAbbFaN4pXBvc3QAACVwAAAAEwAAACD/hgAyeJx9mgl0FGX67juGDp+o0UkbHWecBFEHRFRUFFFHREERFJVNdghk39OdXtJ7V3dXd9VbS+/7ls6ekB1Cwq6CIIwSVJTrKIrOjDODY3CtZspz7/9rnHvPuefe+afOSeeku9Lf8r7P83u+To5k2jRJTk7O7S+VNFeuKNFsf7aktqpCXtJYWbXrvtVlFcraErkk5xpJjmRe5iZJpjgnM/OazB25mVnT6sTa26c1XemR3i75+423SyQ33Z7z5K9ul8y6/a6bCiQoeweS3Ci5RfI7yQuSUolaYlDWV82fv2Q+flj23HNLf3lY9svDc882NLbIqyoqm2fO2XXPzIfmz19030PzH5w/c2mZoqqifuaaXVVl9bvK5s18oX7X/f/NSP8/T61qkNeV1ErwV47kV5ICiUxys6QQD+tWya8lt0l+I5kluVNyl+Ruye8lsyVzJPdI5krulcyT3Ce5X/KAZL7kQclDkoclCySPSB6VLJQ8JlkkeVzyRI4jx5lD5dCSudlZzsI3czmynHeuOZ1bPu0V6R+kn+R9MP0IOjHjkRn/uO7Q9ZEbWvNHb8q96btfnSm4JDtfePct82+97tZLt13/m8d+u/b23N/Jfnei6LPir2Z+MOuxWU/MWjurbpb+511wKLPsUM4h/JV76BZhbqZHnJt36Gd1If7tz8um5/+8K185nLlrMGfka0FzKVcgMxsKxVmr5ol3iXNOLRDmCHPe/gJ/f2DlZ+L9xUK+WF4IKjBJxenUH8RpRc1gZnTuV9rJg/AROjAdBmGI8XO9XMITDnYMtO4BHly0B9D37uV3FOfDhPDeRI5Q+3nuxczsQqjx2DpAOswMsykfEudPB/EWaKQpykE6HJTFWUWVA6oBaFaDM1K8D0bZM3AG9lD7AEWAS6YBaorLoYq1cA7GwVM8zdAHQbgLCeumOziKswEJNG0l5fpacwWpcujoehop8vLhgnB+ouCNvwpbL5eMyS6/IXxR2JjUdHQk4h1FECNiBg/JArBsItET6IfP4a0yWAHVLfWVddsqxK3izZQNURTYwJq9WIqzG0DYBEh4IY9leRY4JPsby3YKNwPr8DKMFloAgFTamymbzYyIPJLeAK/QC0ALwAD740kv7+Li3qj3VPeRdOQ4kl1m3eCHAPjAR7s1ny0cFiWAHnqg4rHifLF2TDg8KLhGCiaFacLvv3tUyJX98L2tsLS5uawYmr1NYdXglmO1n0EYwoyX+Sp65kTsAuvFfyx7+Skv0r/z2sQzbXbWztAM8ruk+1P9vak9SJYJtLrboQ1GlcO7Osrby/wvgxGstJl63rBpp2kthX8EK6rsUPf0tbX1FsFgc6jB25EeTE3ASeiqhJWwvPG1XWrSaXM6wEG/ZLMDIinagf+KgWFdJBrO68FDcFM9ZIcqWodkP/hV7hoog+d0O8sVOouOVEEV1HnlQaNbEcNFAzzDAGrzJNugC/UquqqK8sX1E8Kcicyj6hzhwKe5wjrx/kKoctsDII2x70Iv7IcjdDeNAuDxQJ+Td3AtIFWCgiVYK+NkKQ/NQjvsRX/8YrrHDf029wKAzHy7WwPSFqDBSVHUlpXzxQIkPio2g0YKBiCzu0uAUIx3t0D8TZ7TISUtGqaKRvV5l4T1hWIjCI3CMWl2Y84LOcLCYeHarwoOCTkvTAiVX8v+JTy8vXCgubW2Ut1cWuRaeGz1+6qwM0pF4DOYPND/RnJ3sBcOwkntvtrh2tHNvSsANYHc3mxGsp/0Nq3RTKCL0z8EP1MUtHdTrfA3mBweP4pC00O0y1rkBCdtczZb5LYmh4I0QwO8CiWBnTEnQ0H2ooGiEUlry4uhgdkFr4F4HxhYB0tydBgiwDBub9ueoY7jeOWC1rgWdTT4KuBJWGBc92q9ztbiaIHVsLOneRiRPg9IO9l0HPpQvnIsc92wsHakYO9l4aXvF0/JMsKdQqYwOZ37yDueHE2O9vcMBcN8mAtDHGKOkM3j8NvwaPBgnIBslMlut1ssDgMYUUNK0duXbBsosp/b3L8IdkK5vkb54CvrxGtA/D3clXhk9MWukrH6/YSfCtJBQNmiDnJD3u5YT2//QHLAi+v2Bz7K+CCO4tPhsD2lH2gZrB2sTzbG5N5SQKugqrphGxJ+N1I4TLTXerezOm4zbId7bHUNDS1aFVEHW6FswDxiS5GH4RCCv+z++JQf+fP8EAI3jfKFS1/24Wp76vvcDwW6MAAsVgWeA4ZPuvt9vTzu9iFGQMx3kMBCA+Rjc9fNR2vn1s12zgYNkAzpbk7oOnFXJSLuNpYHL3TBIHOAbUOefyYmB45xroH9w4fRe3+H3Ta3mA9S8SbYyTSxTZzZhSXA5eCcHDLlWYGkKUAOh5RyVouvAclbaToGKF+1N/PtaMHYqfLjgvN4xSnZpJCf+bmwsqZlO56k3C0PNntbAsaIPmD2kK0GFLEQpLS6pU6hkiPZn5vqDDWwGcxgZq3xhedf+hEECZz/Y/ICH2Y8EETB6TBkj5rb5fu14Q27UVNM2p/a3RHvQLLz0XZvHIZ/EaiWc88dvQ/QBtiqbGhAgsxfeBImykMbWSs4QQ8a2mLTm+vlDdUqZLGtGZS+uIfkCL8uZk1BEk6+s/tNQMzP3xbK/vz0c8f/RzEE2SAX8g93Dg12+DzxAIOlU7j18YQmqQwooR69uGrNoqKrMrhiKHPNKC7CxacF5WXZ18J1mwrrm1VVz5wq/aj4AOyO7E59fuyIkAvCTOildjs6DcL0dd/PDDuAYK7qNpYm1AhNhNJUrindqS7DpaSrtjfCNnglsnWgpG/XgHKv1UMH6QC8DsPtnWPI7QObFBYZlsvL5OU1DesAyb4uqY66sE6xxTyEvS6X38+HIYQ6Ve21RcKLmdWFISKs8+j8Gu8mbCEvaNfX1WnUamsjVIA83NJlSpAJaj9+Z1zdCbwcnzJjA0OxaMrfC50QdEZNKP/zjT/9OPn8iQyjLug5ltFdlh3sGStcO162r2gEJva8/VkomuyOtaNQQir7RLiVFm4FcEoZiiEYC1/lqfRVeBpZG2/3GhPmFNbfCBvkw3yATwdRbyzo9Yc5N8MyPPhJ3gwm0NlVFmS2S828jSWDlNva74gSe8l+xylCyHF8Dz8i4Y7pTIB0maEaShssatqBu5pEBABRZAVtlXSJOO8hcc7d4p3rn64qbzI7KAc24SaoTDq7qQDlJQDpGkp2FWcOCzsLWa24DiwOqeygncJeAYgGlh99W3r08zen9n6OAilYJeVms4+7HkT5a5STmX2HrGcKhDVfLPhe0F1eeVnWLhwX/lEYhFYuACMwSnRre1tSDYEa3sTYwIRM02Gjvl7eVN+0Vb0ON3plTN5uCjpZO9TB5rqsHTNUyIj6akZbXsd6mGBCrHBLTLjxYt8lT4pP4/34eP2by9LI6Aq5pYe79vT0j8bSvqS7HclGGBfjBQ/4aT/l0R8u6VyJFy/rl4tMT+1Y9YLNivkAY8ApLhD+Bne9x+6ygAPLNYmrjqSctMV5/xar3UBoDaBHVo8jUNTFtSfckC13rNs0ZaR0LeKv5GJBjXizdpl6bfUKu9GBdQBZ3Q5fURKG4rGkP9B2OL43PBzoCx7o+LbjXP87wXZPKJIaONrbNehHsnSIj7NBGHF26cMNLgtrAzOyTYcao0qrb9FWaDZqbJTSqrGVGm1Ok5WwK1vAgOw86cMNtko+mfnzmZzglHBuKjejFBYX1kBlk05RtWFH02bAAr3hSxCmw+noud73+j/af/xge0ewxzcIqD9uqSkGC2V2WqzN2jKjgmihnNhy7BzlwwvmZb1sfyASju1G6b2J/Xw7phQ3uGG8Lr6VxVKEXSJLVnb6AWLe5mXPopdWbn+s6ffmHfYSKIVHOp8/WNGlHNbvh3+AID3+7l/CCTd2e+Sx80RR/nGYzOydzLly3+XcoUxDYSfXn4ikGI5zs67Eidej511u3KjOep34xE5xyYviw8iqNjukWlJnMZlsdgLzDThYp8vJY7M6Dx/jDe5zCbkRQTL+5Tvoq8njF1J/dXdy7ZCGP5e9uWr4mbEVHvEGKIcK2grinYR425P1DyDahiveAdk9BXQFPV+onw462uLQaO5Z+cS9G1fUvKybT6FyCPdLjwq3DQm/Tgu/cQ/7TmExZRkIwlk4YRhXn6retxkeQPniS8pJYf+koJrM6ZkKXxbqL+cKCuF/Fhqs0md3vLqqYaVJTjThcl58fsNf4Du8IyfP/DUQcfnwinpsPG62BiiVG1WVG7Y0rodFsGYMw1qMj/nbWl/fN34okfQl+Q4G9bOpYCLh9129L0AwetjFlgXkUUVUk8Yyn2IDgSRK7t3TcRK32T4SdoGJdtiMpI2y46na3A4/XpPhZCSBArFQGtsdBk3SZ+jd7t8MFrDQNphL3P3qpmda5NhxyhFs7qk8KEf57ppJgfnTc5NCzXfPTRbIuoXWzL8Kz+YN9wFdDJRpg72hVrxph3jjGvEm1ZbaVXaLww6QXVwzS3DNnpaYuRXZQ8DqoZlq0LdorFanHfCIGFxtibLBpjevUrSbQfv9B/t6RkffGheu6TqLOLewHKSyo5yVc/qhA0Zaw62cyxWnccN20+7s7Ui8MU+81o5lHUNSzJNKnowcDr/FR/kIsIjh/wnS72gGYqSPYiiaQDKXxUUGut/sHi6i4vpAgwvJnASjBHEtI86Au2k7LCdfblCWOG0UCQ788uySFXVBOpqK4z2eIV53tuyDTyczjjMF+6YEYUp2ULhLeK/QN90tXPeWcM3Zib7WkeBR6IfdjoTebcNKbYEs/DmdhuZdGgWy41yBi9fO45rrgrZINJJKvXEestGLp3lbX3NkvQ/ZGAUOIuVQRzbZxEd2ideKN5eJDxCVDizO8Hzq1cHKroYB3REMunkXz0Ex0OYam1a5pnmnoslosDnUgKx522CrvzSJZHqzy4rRmmoyaloIC9YlOxA8HbIj2cEx1ShxhOqEKNPqPpc4dWj83O43Oia7fwiMRk5mo6DdbQVUBduq7SpSR2pJs2pj1fZyhVKvsDYBmrP9T5eL84Vfbz4juN96ZVJoO1sgHJ0S8r+RHcy2dJptDyXiXh/DuoORrmgqEYyHdnv78aTjFpDDa0pRaliHHDoFjd2wAXuT1tpoVKmwMuONYig8PJedxsDdjxstK7NOs8PY/FTz0oZndNsdWV6xeh1eHDpgMBFr5V2uQGwi9WbH+ejrSPaJpw37lHANCLmMlGfCPMsiW61Utcj4tH0ZskyH2pC20+ymGGzkf4VPR3rfcPncUTxjv5Uz0kqn3KTVIovFaXMYDVSL0wwKMAZxq3jZENvmfT/8btflzn8OCrmD/0DuKOfBN/oIFk+KqlQb1GbdGvHh+tnIphCvB+ndWmCKY4fjF70n+G7XPqwcXmfA4SValcEaEG+Gu1eufcLYYsDBHFl9uNDyxSd/UUbhwmThbPD6pN296bHksdCAfyh1oe1ScCQ6FuwKdwcj6FTe25hmPGy7tzvpjbI8wwEHbpLLtsS9eY/BUzQBK52biF26FfItO/RbnDaazKqd2xmCJNsZjMeQz8e5+KA75vJ6uIinxzXEeZgBGGDQacDpSdEk36RZbSy1VGueapxpLGkpMdQY1TodEqWUVEGqjXoDQTgIXFBkVoo5OgXCEhCqGD3d6Xk3enJfZByxLsaFh+WzcWZQUo3GFq1a6SYcAPYm9hEM7ZXidZNX5k3m7L+ce+W9K4sLxWvzFkA1baHFa81i/tNr7jMoLU2OFqfFbQ9i32/3JSKRgMfHhxHj4rysK31sfPREJO0GOMegM2AhpPPu3yQu3iausDXZmii7dl3lxtImtUFja4An4NX98Ek2XbNefDuTtXAvwZtpNaW0aHRqrUODY22jR+nVtG86WvlBNsSEMGh8HPz80PGzPQPpPaFR1u3tdHd2fBc9mniz7x9D7/X3ooAfLx50w1h7oI3N7gELLpJz8Cj/oPJ45o1D3PGcvkvCzR8KH3+YKySvrCn8f7HiFwsKMgEeg4LLy+MwzVDkOrKGWG58qXFe472191bcb9c5LJjP7G67DxMnfrdWxLkie0L9A1/3fNNxKXk+cNI7yXVx4xAGv53/3xCDMveL1xb2cekkDMCIPFnOVoPO1mSZvUucO2v1suYGQo2Zz8HgUSHP4j+KC48ubisd3Dli4mhsTIC76K8n29/HheECF/hItzGbe5tbrErTjh2KtVkpYwh+U9szwk07hNsMY8QYpCDm9Xd0oNOnhV9//laEu1qYKBo0a4v10ymTxx7BcahZeS7z4Yc5GV7Izc1AJlpo5alAFpai6XQ8hlGoPxtqQrSbDBr7m2PbMGjYMJC9YF9WsW59XW1zdfPW6hXNy6vEW5Fivvbl9esNBjOmLtqJmcSZLXJf1i7SiQTy+yK0tJvqIUfNF5UBqtMRdyZwIovgvfWzn8T/9E7qFOvNjhF5bJy1SA8KolmvMmDIarFr7QRBIENeGdvoWpJYnJTz2/D0GbdP6glE+jyRUJ+3I3Sk9WLkYPxgx9m+N3s6A/4gl8BGHKuHnQh0DiOG2/yMfuNPV27H4VT4Z0Y/lfuvJZcKQc0oGT1XyVn9Fr8lRMYhu74uJslHXL3RdJBl/V4UCnivHi3ZOSvoQG62kXanA6+CDRy804evg9CL4IOEsLhDmOc95D/I+vkgE8S3BKkAgdeBxL7jpA1anQaJvxYfFOeKSx5/pKlh6bLsmYN22JawtFvT5pFK4foG4bpmocC2B8DGI6y/+OYmUJkMOouFdpANWvG6OnHGDnFG84pN4m01KhuZDWdIzqv8phCJ24/El4OykwaDrh5qcVGQjMOrHlNgzMTOBhy2mLbWtsHOvZ3HRr7bK+S0f9KBAx/sFyuGRElsQ+vmrq3I38JR/qsv5lif66Nz4weEa4WbhCeErTjGwzbRBeIdKP8nvJZ5Py5UF8hSwqUr6woboU5l0TrttNNRqxXvqRTnrhMfUCzV1+ot2VFaGAWv8hnCiHTRuMjtmFptdq3WWAnNUH1APgpxiHhj0f6+rjcGvkUjgrRHmNYqTONiXIRhgWcojzL1/OCdncuOiHfEyk7NjioYCAHqgy4crJnswRfF0JA9HnQNCw9E3+4T8keE4rbz3vZgP+fCAhgJhD1IdrQt2OsZYGOYHL3eWDzQhzEsRnk0eEAWrMuv2rcoq6tRXY38+VViY9P92hflc5D6SdIn3XxBc6D0xxIhd4dwc7WAnEFHgGaQi2DtRfkXlGczn0/mHJ/KRDH5ZxfDBGYsnsvNy3ZteKW6vGG7aqNVQ2NP4B087Yck0xmORbOyz3vjqUPtI11dqVTA2wM/wd4FIObCdutGY0ntnGcffLIUVWobiC2wHirCtel1e2omMcdHMSr4osKdnwrSH99OBoMBdwD923j+T2xygNFpJJWG+WufXbr50erVLa9alyFsRTp8iTceXvhpWa++B9fZOEx4J2LC3DcEmXDLhPD7yITvGEwgoWDtJfHGonytUDIp/A0nhBum/kNC4Bg2u+5O+2uUpllcsUV87mlxFc4JpA7XNum2eaAXhlpDrW5f52Ti6JvCQ3uEZ2LCfYgNdIP0S3hPPVLRpgw24GJV2FVGefmTj28Vc63NtJ3S2RqMGkwi6BcU4e0cBoUfsFKNXTgbCnR0+oMDY6lx9z7Gw3hwooEQFSaD9iQR1sVKh19s+wMGrh3MDsDXf0wb+d+Lt052nTlzNlOKvT5vKlPyTe6VhZkFhbDSsKFxbfnSVS89V1WvbyCqbLuIGudyGpVjx5Bq7DqL0WghyKzrYmDwYWxOUjFqhBw2n1ZerO2wDllRJ9ntbL+qbwH2/dAXr6cnWQ/DX6UUzkw3OxsNGG9w7HU4zESjxVQDr8KuwMrWFveaJM3QzEdt7x0Qrjn3jXBDQpiHGH921+HbyndX7alMVwU34LZpcpooUdIi5i1dcu/apTWPwjMIHhtafaKhzZRy9MJp+KlzZK/Xy7vx8gRsrBHXpI3SEKhK32ivwctSG2jsqOvRj2O6S7Epd2vkrd3Hx8cPHTrceSZ7dvvHe8WbMFj+VpnNUkL7mRzh2kuZR/5TUEQuBqxSrfjaJnHDE+J6u4HEBEnZPDb/v12Sc0eGfOnTwqK9wsKksAjx3VI8qVDRJ3DRPKhoNQTV2PU3NJfWNdTLd7Zss5M0ZnZajYest6Emk1pDGcDiwpsWpgL2oCmujjSkV3ct96uCqmR1WtVhRzztwmEsCq1snD8efnto73goHItjlfBasQ3jhnSaSKSxGC0mvUahUZaCCnR+bbsuRSSrP24ZM3YaE04XxQOgqdHv/5QUclg/g1UfhvTddYl1g0v42YAW5q0COb3VKOY0PvxC8zP/dzHNxDrw2WRBfOqDb4SVl2umZJmM4craQmyZTFaXnTQNc6yPbtzyikZhktubKCsQVy8La0ee2mRjnyKl85F/rD1XMVwR3M5iewEDDmoms0qx8dWaRwA9A1vaqvYaY/YQncge7LpCiAu4OGnUE496/BzH/huCjVBDVbQ0NcnlmkrYBgqPKtyCRjacqP0Ug9fFjsn9reFQIB775UCY9V2d5R7NUFkvamqtj61v35HUBNUJRdrYgXOCn/Vz/ujEQOdpmIDX9XEdkv3gs7gMWEgImnBaHHqGcpM8xngvrqOuUDx+lWejiAthfvCj9xe1Ls0CdebHc/3qnCvaLF6a8sQSnMHN1BLi0Y07X9UqLI24oM1u8moMZ71cp3egzR/PcivGOEiH+1OeEO+BbwF9A0at1Kq54+elNrlhk3qdcgNJOAkcTa7Chgd8jJfr9vckQx0ovb/9TOQo5+/4vluY0SNc2/Z19tzRg8PGdwxA2jXk3dfe2oF8AU8ke+Jkw+GhHhQalR7lL8Bb+fbZHO3UqSnh2anc9sz5wjAkPYlQ2Bfko5DEhA9KLLFau9pSY6goX7hJzNVsMmxEtkaHHE9lVef2Awas9fTVj5EYLzPi2Rsf7zo7/uEHH36NXG7eBbR2VZ14DTwH9XFtN35VmA3x3cHTXa7uX44WkRn0JG5XCyk1Y8+EJDfh2Zc1tpuPCIu73vW3+TpcSRbDN5Z9r5WzYCKiKtQGlYM017ZsIOR2vbpsofik+FtxybyVzXqjTQUbQL0XjiJIcWlPOjiRODD+bfc7gU5/Z3y/rx8nq4GWWCVshSpzmQqVKOVKjMSEF68qyp+dOffji6cKhO1fCm8flzW2X7mhkPA4fEVe3I5+Z48tpU3VDq9OzgbxNnjcJM40raZttA2ro5Ez+wGx2Y8BmJD7rf1jQyeOnj07cfS9z8//mBDyWDxrCCLZEJwpO/ySy4z30UGpTdqd0Ah6lojCXudALewEK21zWlHjo3eLMnGWWKDRNiqz535BzMV/B+HJOiHvlTeQrLGxvT6yFVB5WZ0aS1fXFcmpHOGFL6+8djw3O2Krh/QK07rFO8XiIlhpf8b8B9tGy2qH0WGiTLgNTZw5AF6G5xNpYY7wrHCbsHFKWIt4N+fOckVom6d+SCxOi/Nd4lxuKdAMyRNe2ucOed/74tC7CBvoU+eEu6M/4d0OYdV5UzNUHbHyZpbIMhkmYrVJVw1VSMcQgaFUfXkRbh+L06JdtXH+07OUtVtXaTUIY2VcahEW1AsLtgmzrZ3aIxSHjQ9LQSOUY3/EiAKslc3GBBrb4s7Fip0vz1o5d8k9qjpDS/YoFL+3P/CB6z14Gz4gJrVHENFmbDNEFb3lyR2ASksbm4vz4Zdoe2Qqc2QqVzif+VehL4+nPTRPDxi49a61KCD+Tgqk2CRe//DDtbUWDe6KyoS8H3bDQDqc4rHmUy7E21wOtTXcWoRLl2V5d2Rs9+TEcPtXx7MY4nqcq/M8xC4/KA+QXioG6BCMBAY6UqFoypNmgySvByXdZNRorNYss9aCsdXaj8wjhLDC6Ufgao9IL799enzfYCycTvtCkQQfglY00NJetXNLuRrLrbco7vRYspqBXcahrxZfEqfjOAtmYQExZOu0xPVBQ9DCy7Oa+WSVbjXtvPr5HpFN3W1MXyKeQvnbMhe+zul9XeC/FCxHcy9kLhTGIeWPRTCY+WlpuzNtjRlObB26Myg+wFUzu6AMyp2LnBr8hk6DZePOTfVyEmGyxwC+ma9rt4xTYafXgltGUQU1sGZ065g+6IhQoV/Im2de9/7w0eXvhDuFu6eER4eEuzxdWHfb4Yi+pz5tCKh8SkBkNinQequuAS+5gcedk4I2c8ASMviwEYDJabTKUd39y0XJQ7N1LfJGDF4J9jBuXOGRZmHuixcbRrb2vAybYaeyrhYZDHYC50KL14kbMD/IfPDaOUF1fs0x4eUP158rkD19+JYIRF1BT9wT4trhAMSpzwkkM39FJOgJzGwcFv5jweNDIwdTHfGBwAAXBN7JO1masQKyYmuyUzVEWTPRSFTo5C0KpMorZZvYZZ77fQoGt6DslUrGxUsvnvvTuQ/fR23pGC3tosJUlk3ddp5CspkszWOxTzF9SczgHI0vIqZx1zJIdrPdCkwxMIFAJPr+ubfeOfF+NMlyrBt7AZM9LLCyZtDRWkJuQjKkYqRNjJl9DcP9tBf9FLMJsvDtgMds967f9qJJZ6jNeqyLCmNoTnmTYZQK43AfCe1JhA5BK/Q7DtqQbMMb1gTVT6N2MOikeo3dLm9AYq44Q7wBrA6pkjDowAi44N1OtJ8+AAqFdM68x54W8+/U6gkTWJHN5fQVZf8r5OcHYSoHpqamcmHa1NTsPGHL7MLs43/zxJWrT/z71/kZ581Xthaqk1fuY6IDeUUzcgOLr78Wrp9xaMah64pm5P2v6wv+Cyb7dp8AAAAAAAABAAAAAMw9os8AAAAAxvkyTwAAAADJ9CXHeJxjYGRgYOADYgkGEGBiYARCTSBmAfMYAAYNAFwAAAB4nGNgYUpknMDAysDA1MW0h4GBoQdCMz5gMGRkYkACDQwM7wUY3ryF8QPSXFMYDjAovP/PIPf/EVBAjkFOgYGhP44ZJMu0ikEBCBkBG0IQ8HicY2BgYGaAYBkGRgYQiAHyGMF8FgYHIM3DwMHABGQrMFgyRDEseP///3+gqAKDAYMjkPcXyH34/9L/0//bBLSgJsABIxsDuhAGQJdnYmZhZWPn4OTihgrw8PLxCwgKCYuIiolLSEpJy8jKySsoKimrqBIwmdpAjSxdAD02FYAAeJxjYGRgYADiL8KHN8bz23xl4GZ+ARRhuBq7aj2M/v/ovwZLIbMokMvBwAQSBQCIvg3IAHicY2BkYGCQ+/+IgYFl4/9H/x6wFDKARJCBFgCqbgcVeJxj+MVgxPCLgYHxC4M6EIcBsQ4QawGxDBAbQdnmQKwNYjPLMcgxTWRQYOJn4GFmZhBmEgDyzzMIMQUz6DD7AmnF/4+YljHoM/0CqtnEoMCykUGG2eT/U2YZBiumHQzCzIYMRcwBQH1xILUMSkxF/98zpTJIMt9hkGQ6yWDCNIdBnukqgyrYTToQzJDCwAAArGwjmAAAUAAAKgAAeJy1VN1KG0EYPRuzSlNMFaEX9WauJMHN5qelYBBBlEAkKhqR0ovKmIzZkc1m2dlk9Qn6CL3uE/Si9AlKr3rZi170VUrpt5OxNiUVFcyyO2e//eacM983EwBPrTwsjH8OXhtsYQkfDM5gDt8MnsGq9dzgLJatdwbbeGx9NXgWy5knBs/jV7ZocB7P7DcGL2DJfm/wIubsL8RsZR/R2yutkmILK3hrcIZmfzZ4Bsf4YXAWL60Tg21ay0eDZyn+3eB562dm1eA8XtgFgxewYl8avIi8/QlbGCDEJSJI9OAhBkMBHRRprKFC1xpKGlXpZtiGgNK5Ab21KVNSJKBRUC0Zmhq7wNYgvIxkz4tZoVNktUplrVSrVCtsWyjZC1i7I0XQEQ5rBh3K3gUnaQ87NF7ghGxx+FomIhTSF0m02OWxt8MvTra4L3sRDz1JwUOS7mFI+ZyycSh6Q58TaNDSAmJNx4gyhF6Sq5dRp/t2mqV/+RuDIG4Mop5gNbfC6myKp9IfD/fUuJHzmHIj3YSBbkKV1lSlsIiUHASs6lYfRvduW8W5w2ZJedaR6MtF33g/195d070N0nGQowypvzLtXelajOjZpchVxxn2aG5fd/x2lXCJOYcj/aYmmNqEzgglukIp4zjD1/PS1SijPiTc1X6YVhR6dhMtGvdJSegqXDO3JhjSekzvrDvhbFKXkasR3VJ38JSeaey6RlwrbuJA45j2fU53LiY/dZTpUsSWdjSkmCItpbmuql4m5w1y+r/j7Ew9z6ywniSJ26fddM4vXDosG0Unl8jYY4dCiWgkuiw9RmyP98W0A+TmckeeVOOk9uAsTngkGAV82RGBounDoCsiFnuCtZstth+KYJzcGic47K/j4I7JzFzGR1z6/NQXTDvirLF5wHhcz3lxHNbLZdWJZBgrV0k/tV7eb9D671W0mwgf4B/vN8NCYPYAAAB4nGNgZgCD/80MRgxYAAAoRAG4AA==) format("woff")}@font-face{font-family:MJXTEX-C-B;src:url(data:font/woff;base64,d09GRk9UVE8AACa0AAsAAAAAMDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAABCAAAIMsAACWhxti3MEZGVE0AACHUAAAAHAAAABxdKvrlR0RFRgAAIfAAAAAdAAAAIABXAARPUy8yAAAiEAAAAFQAAABgQqJfMWNtYXAAACJkAAAAfwAAAWLiwp1NaGVhZAAAIuQAAAAzAAAANg8JmLhoaGVhAAAjGAAAACAAAAAkBU8EQGhtdHgAACM4AAAAmgAAAKhxhgV4bWF4cAAAI9QAAAAGAAAABgAqUABuYW1lAAAj3AAAAsEAAAauadlq8nBvc3QAACagAAAAEwAAACD/hgAyeJydeml4FGXabgfs8I5o1LStjqMJO4gb7g6KG4sKIygMOwSyEbKnk05635danqre9yWdpNPZ9xAghLCJICiKuAwu44iD5/OMDmG+Qd/mlNd1zts48+O7ru+cHyf1o3N1dXXV+zz3cy9VnSW66SZRVlbWb98olO9dXajctbywqrysvrBub3nxw6/UVpWIsqaJskQPpW8XpfOz0rOmpWdPT8+5qU4ou0/8+vWvxPeJ/nrbfSLR7fdlPX3HfaI598035IpQ5ggkuk10l+h+0euiQpFcpG6sKV+y5OUl5GXlqlUrfn1Z+evLquW1dar68rK98lmLih+Y9fiSJb9/+PEljy2ZtaK0obysZtaG4vLSmuLSh2a9XlP8yP/tMv+b99fW1lcXVonIX5boDlGuSCK6UyQl13S36B7Rb0X3iuaI5ormieaLFogWihaJHhAtFj0oekj0sOgR0aOiJaLHRI+LnhA9KXpK9LToGdGzot+Lloqey6Ky6CwmixUtzixxDjn4YNaKaXnT757+P276VvxOtmGGDFX+Rn5z68yaW7bfWp1Tf5vu9k/uSOXaJe/e2SW9eNfluz+95/S94t/tvE9z/5N5K/P+OWvO7Io5e+f2zR2ce2but3P/8UshTKZXTmZNkr/pk3fhxeluYXH25C8KKXn3l5Uzcn4pzFEfTd98JGsc5+PdOH86HlVL8dLPPsJL8+GCcUI2Wn5oZ/Jlv5mrhSZAimwdyGkDLWQ3bn0JhDwkLP1sJV6a90V6gTSqder4N8HA1UENFLMFrJ5V0AraYq4s1eyEnVAaNfci2ksn2AQbYg/CKHRxHRDkTznD0Ugk0ubrhzFI2hIqlMOfxuNnsrAK3z39y/RdUmgANmRDQ9ktXCt4uTDX7XRwiAOFcFe+8OCbMzYABTRjolg7aJBthoIzJ/KOwiH+C/gCJpgjgBKcL5HvngFR1ml2UTwFGwCtw3/MBvwGeBkn7bE5jGADFgy2rbI1hqcANWTrLKwDZCgH8F249d3c937C2/CiN85KruLb8GHpQLK9Px+CdNDmY3iWBwBXP++HJHTRLbajus5aKIY6k1IuRwqF1S787tk1JZsrWJaiWQqU0MhRfsrB+ABvBrwJfODkkZMnfy4k+d7h6cYPgo91U067g+IZ0IIMGIZqtCspk82EjNk6VniSBeC4y2N+l5uPeSLuA9GIpzmEJFd7WiJxOAAHNCl5S2XP1uaVXgNXTr7gKVijqN9jNtg1oER7k/UDeTlC2SncewSrjudO4CeFO/ECPBM/INyFn5JcxivTt0o7Yj2hAXgHYjJYC1Wswaow7mmql5lMZBUVTCHNcWwDAhVHkytlOBiCfeSqQ1TUGjL7DEjynzG5WwbroZSR29SGPTL5VtgL1e66kNoL4HU6eLfD4UDNYX87JNHByv7tm2vLduaRNtg5W2TJP7ZiEXwLn3ePHeroiQ3AMRi2NquT9cM7uzeGkNYZdIoHo/3tzSkk+bG5PdQJw9BMxS2xmlMvD8yDhfDyFtUq2sgawYQKOmrGxzu6xvNgsClRG0A5wqYz+J4zufgDfL+Qi3Ml3+BqYZN0hBO3c4dhAs7BIDMGceC90AYtjNPspHkrVAIqxfcMZw+Ak7TL6+Sd0JLZa3FmALUXkOR8Kd5CIPVWBlJk4+08zdtAATrQsywwBKIsa6eFy7/kMXbEEMgSJCiAJp+y84yLHBEF/BvyPd/ge4V7tmXvIHi0MxY7y4AemWeQIWDCdnIWLMI+qTANhGkcrsN+8Y0+XjjyF3xn7kk8a/GHeDN+RPJjuiBdKGXByliZrapNpo2wCdYFCqNaF8XZaRvF+uFh9OgMEJ4FC0+TJTIJSBBEBSLJgQOtb0MXpDT+Jp/KUQGrELxO1xvkhvo6XY3VxhrABHtA5pdHzG6Tn+MAHBzPoWZ3NOZpRpJrpGw8ROBgfaLItQPqqmE3FMTLO2sG9040fAh4HuCb/wR4FoLvdry3pq8qXBQoJOxQbKhWkVZSNKkSIDzTMcPHJJlWCEOI83If+d7rPnw4EAyFeRfPgwe8KMIEDHk56nfwfxzBK44RCC/Cy/A9ws14oSSdfiD9nbRRr1JBJcF6zdi+9o6RPPhsx9DrESvXBGpA6uwnLC8V7VxdsFaxEhaBMKd3wVcb+xtHdcfhIIx5u8K90YGeRBdZTlt/YASOw6eKidLhwoM746/BOqhpqNuLGIaLiPnPPPuivS2jh/rfhQD4GT+D3BC0umm0XdBLmxW8iVsEz7EltibaZLeYTQajzqag7WBjbaSIDRFtEtk8tjDjo+P0BAzC+5GjXV3RqN/dB91MgIppUQ4+jWd3KrLwW/ie6fjpdIEUnIyb5inSSRXBjx0oI23bK6iB4mxOykUT5JHyoxg4OaeTEKXTmXD1eVMEsPx+bopDP2fzQNtrKndsVMiayt98pOpBejGoyNRZPbXt8j7ohVSbO4VIG91wgDvMJRy9nsut54Ym0aUr4rGJgTGOEBXhLB/E2ICBZ7it8Cws49aCkTNCE68FVM03kQlHOepT6TOEXKZe/Ss2/3XVVcnJdBt+SwoXdn+wahhJLmbmAzjkdYuP9XYcIDX+27LTQi5Bl4kUhwEza2VL7JX6WoXRrFRajUhRaaqAEtjrr05U+3UJgj8n5aQBdtZX1Cj3IMllY6NNRqjuyWNr/ybvsLVT/QRI+dc+wb/Nl1wUbsEfSaHSUCNrMJvttMWGVoyKS1rKEzSvCWgjhLm9vNfhDXaPRE9x6JPJ8tfyhRm/lEgll59aP/LnfDgY70+lQqFYyAEcO6DcJx+TDzY56RZ9oglqkHXG6vV1LxBK3fMOXnYUf3cig0dhJr4Hv0DweA1bhT3SIzDsH4z9dPzET4CfgH+qPi09VTda1Lk11OQycTKwgo2zASqCclODaYt82w7VRmstpYFSeCleNFY4VnhQ9QFhHB8XdaE2b6o52uJw8g4OkGYGNctYWllR31Br2A11oHRqvWSSEqFwAlJoWNZZXCyrLcl77KPS7/M+TgvSblNHjbPSoSCKXghlYGFN1p26iqYmo9FEaW1E4veA3qNpNgVpH9NLBoBQxTAhd7Jxfj7BR5w+3usLeD3BQIs3RUAfAhdLULpnG35EuPsf30yl9Yrc61I8V3IQz9kmbYWYtz26r3P/gfOXUSIlhnPsF3l4franIPFMUI4kSl9jh34Aklzc2e6Pez/sD3rbIq0t0AwBi8PiJGqnYA3UHqXCZGfoTJE8tNsa0h2xDCv+rsEBwM9CB3CMAzE87aA5oqrkQ3awEp0tsWyv1NXSVkK+RmSomWG3iJ8RFr8kiGcL9y5/tKi4yoIkBxmWJlirhOoWe4oOUn49OdRqt1jlcuV22IveOFY4mYdP4RPS3gOHLnQfQn/Bs0Er5sxEw1X8q14BuQqR/bEZL2XXAcNqrChnSD11XaTITX+I5wm34vmSb8h/m6VLN1W9kLcFqiJ7WsiSKpkSpUym01kzXGrw0knjSFOH7SQpZoD4m0u+v/SfP4FC/lTKFxzYHx1nD1Ofb554vQ2ZnQG3WHL+7MDFt50Xuf3KnuKELGTkKzgNGFkLu9T0XNmKdRYrbbczyNHh/QC8EDB59GAEI6O3Gyjh7tVac41K2QAaMARsQUDNEHP1REOegIvwOLDkY1pB3CRk1wnZquWKzeXrzVqaFB3pCBfltXGdgfZ4Iuz1h9sG3k2eSvxpGD/wEZaePxwLdXpbYBIG5bATgZIymq1y9bamx6obLFqbhSpV1tUSqjL6rUFCTSl3FNDfvy1anJ/zgGIqnZjKSuB5eD+ePz09iddJC+gqeV1tbXWVfAvsgD2xuraiwYaj8CcIcxHO77/Y9/nB42jfofHkp9AOYQvUkoZbGBul09doasxqYAl7GHliNBHRbcJhA3AklewOx3vOelLOEB+CIPQYWhqCWg9NpgVZwUrmzgY0gYnwola448mlwrSCNRVLTS8wxMESsRBmf7kYzwWUoTwP9577g+TZ0cG2oZ5UVzjm8oAfCBGpgIzA6zCVVl3NwmfwLHwQz5v+811fZh8geuLn8Cwvvn8/nnbh04mTJwfPpA41H4EzgJcKs04Jz/kNsJvbDWg3FLImWGpfrnqzukxd3lAnq6tV1ZqrWDsxtjToffYwIBe4ODc34D7QEe8gJ+cdfoffE3a5gsFz0aOkg2SejcgsLNorLH5LWIjMCooRFxp31+prGTuZCQrMbruPQtdz0r+Tgtxea5Vp1pdt21bx8o45tcIdgOzZwDn9rsA5/PAIfjCKH0bg8bJiF/hZYldnm/DMbSDci3Lmaq6kV+J1C6/kDuF5VXg+Xkewvg9X4bTUbDPZDOYXN255Tb2SNpAlGeHVE2WnNe22EDtIeuaDAIdwVvTKO+fOtbZ6AqQhIZNTDUpWYWvSay0mi05XVl6teAvQqy91vp9PDJeLc7o6o72Jtq6+0fhRRzvv4ULOvsBwKtTucHPEkCGCc0Me8TgRWSeS9OlDliCh9FSwPRgMB/tJtGiDHipA+yk3GTgwG5uIL5S8bwpSwTwXwYibP+afGAuOE9FzkJWGGK+VYNXo1bh17kpHKTFlfQZyHEu8GMEKu8S8aMe6P5QUNxVAEYJNvbL+JpTzn9X/mI8fIBtaOIX/gMUPXcmVvBkblIKdpzzW1oZedZ/Vw0bYMJlKL1nRee+XR/edjaUOXmo/gfxtJIqIJbMcJrctDCPwdm9Lv9PjSoAHSe5kfXaH2YmEbvC2ieOTLRf8Y5yTdwOPOOdfYT+IT+xjbfnAuOwuBkmQm/awYX6f59hgoJtzcA6ypGalX8MrnTwIHg5JrMJ9IGQTxG9gigwlcrmuUWlU28w2HVmcyW8JEQswFI/FEH4IKI24Xri1WLj5j8JMVXHR80Y1Ma6EX2VOlV8VR5I3jQE2A/6d9PICQpc5NYL4yiI849xUetXV3Eky1pfwPMnhdDJ9SkogTLM0bdLI1Eq9zm4CMxh91jA52YGWzu5ke/d+fytyhRyZAW2xxDUhRazEuwH0xD3TsJx6Xr66TLhrxTOCWCHcjRgDqyYkJtz++ZP4DjgLX6ZO9CG7Tty0uXarQmGnLKwMCvkSZ6kbSbQKJxEEqKSLFPUyg95GMgFYHZSHIp6bbaYnLMM0yYi9xFUGuEnvkdaDfRffmfya8FFoNPk9AUfI4NRCEb22QluE1OurthXWq00N1kZYAOu/gB+hxdHmboudHzp1sLunZTI4CWj0OBTn5+Cu7Vdx0dRj32HFVC7+ntQiK1OLsfQG6Si809cyNHg8FfmEqFdMSziMIqxlpXZat5oKKD1jAEDEaOvy6gnizMx23Y4SkkUlX4HJQ3vt6GR2TwrYfGB1BeZa5XrllsaNmiLC3zbe5CXwaYfeUGfC7w2G3F7EOz1RX1v76dBQy7soOPQDiH/iLGwzwdVhF+/M2HcoEubDQ6B2GDwmr85rjZkjFhd0wp8d7yeOj6BkS3+vow/CZreexJzNdfJqq5lkbxaZsmXacCofkp6T3gOJn47jl0/ifF8b7yIDGzS5dcRcvFmurlXWrBeWKt9EtFEs+UqYlr16F3D5JDSEnJHou/5J1zFnD9dGhi5ujRhCqqjGW0oIw0DUFAkPGAX0wqsLjGraBhaUkY+8nFWEZNVTWW+nKakfgnzItS/U1x3oGHNNuP4MaD+YDeLKXQ3r6hbUC9NqH96+Gm3I/gNReJVVbm3QajRanUWf6b/T5iVO2Q1YBhg4NdvtRhcjHx+NHeGIbSYTEzS71VDNlKrr6pHZPB/mcT6/ePztvos9+PaWv4TGwoOellDSE0Dn4SNOPOIbTcVSLq+DUAn4rE6rCwmvZi+CpwnlPsWsNW6SFyiLquXVRq3NYNey1A1CN/gzhJ7zoZB9Nf3DVNYxvHA63oEl0pDFo82rhiJlnaxJYc+UsYmzuNXh0r6aI8qUMUmPwPuwP/xOJ/ps6MNT+y5EUp5EaKIX3932cepM84HOE53tbreTa+YCnIdsqM8/3B5N/teLuyt7BckxDFtC19j3mlYpXivbWLC7vHSLagttZDIGyhCwE3tAtLOjrdvt5Z2uSHisvXsofqilm/sE0BEwmcRrXtuxuEB4mlDIXE25oqimpsJE5poM5jJYMQrnwecMgp/o4pOaS2kOS3PxJjy/Gmfjo/gmyfd/T49IM+6jP45SIdCJ6bXGVapXawRULMzcKUyzmxgbuQx9kIrCQcfx4XCXy5c8HexDI9eG8e3xb8PveT8hEtoGvNlld7CETLRgoPU2YnKkq41W9KvLQRmXk3d96y+3SS2ZWMHUm2tVlnqbmqYMdr1NZmskSDM4DT6zW9FiCqIdp7b/R80lkk30Q/Z2aEb+Ge5QIh6PvH3ou+OHoijoFMeZGEtrQeexB2wokD3gONIJ+yBhDikDmoCeryPYMmeynW1T01sVT2x75g+7tyNlo0FhV5P1mDPhhpgTS2TpCeH2d55treqsatYHLVEzcStuktuSQNjs2tn2L3g35yZjFDJ5SVjNuaj5aflPaYSLciW7z6qJp+70dcVRyBsF8RjTRf2gRZKW903d9DhhEy+JCN9GMHq/7at/QTlgchlI/F++xVKB9Jy4git17SDjv3t2rN6xjUPV4A6K44PBoeaPO/GMgW/GzgZj3kAoGAhwXAiQJ3swVl+RDxbaQOTB4KNCcATOTwR6SA6IkHh+vHxg/Y2bNnZiHm64qIct89avfGbrusLnKh8w11jqDDvUrxkrtHVmjd1mNKNGjdFo1dMZU0ORmSb9ybn+6PUNiqz/dZhYwOGEFMyc1WELyPc1DjFh8PNh94HWQ+fGfzp0beCH5HfI3epSi5PLDgi3tG1q2dGxs7cw2sQxGTbnCIUHORaO7kOXPxEfOYhvuoZn4OkolRQTY0SzlHmVXlgIL8JuR5Wn3NUQ1LWb3OSoOPF22RFypqgr5gq6hpsnkgFPLOYP+jzErgaNbg1kQki5CqktVooiLaQiTNg2yLYQpf6+FUPL5RvG0g8xqpn0iyIDTjM029BQUYmEy8In4i07l7xIAgonHze27Zp6E6+uxLfb46ynCbbDpiJTLfm4ntEhnTC9bt4uIatwjmyLUmex21kT1+BQ+LRhiyejutVQthK2kYlqImEr/TeFGz+YK2k5hPOltmwLkQ+LpaFBtZMQhtxjbNU2G5rNXZmgznn48dD46eEf0eDfRnBuG74JOaJOk3hMyPpYWNq/pnNT77bBgqCGp920k+bIOg7D8TFfj8PDUiRgAjgD3r5BPGcY/24/zm+9EDnoSzg8POf19naMRQ84AkB8tgO1BXqOkyNbqYiCGOsqq9y8RbFzT21hY7n8j3VPFwu3bxZeLRPmICLnLMtRroYhQ4uiX9NbfW4jvmU9nlOKxUhyzJLg/XIogMIqVb2VkADbZBBulQl3lAgzG1eqdpl0NqvFbgS0FxrimiipxWb11XR0KussnpfuIAC63ph+QGqfAcITgkjIFe6VNVFGthGEW+G5jxuu2FroJJkyD+cFj/tc66nRY6h7X3/nWKI72t0caHeS6aFcJGHyRlJuC0uzOkZjkxuQMHvlLOGWMiHXuMdeRmSwiW9yKtqE7EvL8G9UPjbBNsNluNBycQRhdOp/Xp682nE8chZOAc55668LWgwONacmBKVlDcw89dzlry9AGrmilNLfCJ808UGWKPTyQ/GOdr/f5fWEgql4d7QZ+YLRqNfl8/gdRChw1tHHhaz8nCu46FP8ztWs62+R1eIXXpMOw7G+lg5/ZOwfyQvI2x4EcT8cdO/z4fl9+PErQ1jqijniEIWJht7S5IuHXuKFPNgKW4kxR//vsPFr1kD/Xdh4n4QNDkjmNGmEkvXCzhXCM0hTQt6yZVIeoY303utZ0j5tc5OvlrdmxI6Iuo21WcpVlXJFccVq7Qv2csZol+uRjbbTLCB3i7j16/hl39d8kAiXAzlDM87Dh4ZRBWmxUlgwRU0dm1qIZ6Zvv5qLbyG93kPMVF76fVwvldQUmF837SFRLvsJ99pj8D3xcQHOG/ryxGcXBvuiA/5DgHPhL4+DkJu5gcBake2VmnWbNj79jHBbifC8VUa6YGZKjEU1BhltuxGS9CEqAaiTbad7rQPWbsuFxquVo+aTNiRxEKMCsRublxt0Dwf74uf6JyZDh2/4bAeSrM1IrMWJDNk76TdLjHtZirEzxJY3U1bCCATYG/yvNdd5t0dIsTicNfLzN6cnD5/qOtk2Hj4MpxHgu5+/JIhSCpeeqwILWEg4bQQVraeXG1+uWVnw9MaVyyqXIXWxZQ+B4dzzq7/TeNkQG808euCT/Nfeo4H9o7Gom3gjFDK6tHk5uJcMCDv1ayx14LnT8Tq1dJA71pvocvs7z8YPTeK7+/HvwvhOzk82UvnWGV/B27ZhQ58x0QQVoLDWGpUNu9dqV1BqAg5LplTVBhmiM09MbBkbE8ikQ9pt99rDOp8hrPBpBl7tWu/TxhpRsyyhbTe7GT/JPV/D1dHP34tHAiFngGhTpmABI3GVqA72amvlDUq5oSyTrziKa/I0dNYdodyGpLFVfsAcM8aQ1R9yi99NvT0yuL+rP9bnG+UDRCFj0Mr6rBFjQhuWhbakXuWfALQyewNs/P+P0oHAWGDS5SOx3UE+ZMrWC+t2Ca/8XlhjUdGWf3sSlKMlCTg2ldWO5/cTb/8Cyft4F94v1bBmRmXbpC4olReYmigNqKA00pBUjVSMq06Z/IQoCLJ+hA/jHw5cO/bBRfgz9JiTilRd3+aupZ17Qjq3KqD2a0PmIDKHiJdvgYQ74fd7/SP+PuLJh+zdlhjlYF02n9mpBx0CM2UmvkIXoGMw7jg+Eup0BhwxIltDqtaaYF14g3szoJdgq2Z9zUt7Nm1S/dGuIf5Ol3mgoAGat3hkUXlSmVJ0a4+oP5Ptk7dVhdRuJShBS+msWmSUm8x15hpjua2YcMbGcFmyLm4M2JqJcybNI6TC+90o5o+EfEGvn/eAjwlZHJmbIa+lL14bUGS9my6SEnTwIedoaKwn1M45Ms7GGSbZ1oOwKttqtRhpC8vUP1grILReaBTrdqh2Nu6waJnMJBpIa2HCOdHd1uVyOz3eWHIicTQyiXhf8m8dP6PDePMVkn5hnMQYjhgmF7ffdbh1sLu9JZbkYhAyu7T/onGkpBpMKiMy237pZrSMeJe5UFPcsLp411b9VnIme2bmvVSEXLhTPZWeUmSZ8Hwnaesa0tZI+rA0ARHXcMLrjJHB8oPbBjowMTq7lpSmuuy5ksf0FboipNttq4RKWNe6e5+i2eRi2gEvBLwY33sVizRrjVupYkbLasCIStrV+/J6uKj7eMexVMZqBILeG1bD5M7cBtFTFWrUYBDbvcQSxhxjroHgodZve651fxMd592eaHwkcoCEZH/m1h7aA+srFdUsUzzf1PSC8IAwV3hl7sp6rdpiAAVZk5HEdEsn9CNIOFrdbYF9kZH9V9pPEpB3Jg77BiAFw42xEshgiCSuNbZnKwqK9DprJiMbfLYMzlPXlzdlYRshj3e/mT6ZviRtZ5LWqPGDnWNCdkh4xbkLmmAt2Wqp3SCD2jgJGU4+4kOHOj87ceowGYy5V/H9ffi37qSjFRLo8x1nluVZsk2ZJ7ZmuVxZACXQ6NI3wxi1X+4sJf1iaJu5oamivgptXLX0xcWvIJWOnRSz55hR22EdvrP6+x3vlI+Vtq5zqknXLEyBaVsJ8RsGvzXTvnRB+tKPWbgU34e78RL8wzfT29P/lBJN8ue1QIclYjq3a0C4A4Q3YLVdmGnYlIndZFM5lNHMfSbeySO3s7m5dwDPxg/iO/DSf+JXvGF3gCN47/x9eOewcGe7cLdfmOXYy5t9dsSzPOu48UjQxXuc44c6uvB0fMslPHPySu/ZltOeI5yXCxIuhk+qTr3uIKogN6nlhj1WJWPKPAh26eLQT6ca+QrC9QxtsWttOpMC7X1t3bMvPIG0KjHjYT10vBE/sgs/vA7PMrca21gHw1ucNE++bBu1toC4QsajIT6Cke3WyNbMW75o2SNatc1itaLwDK6NayfSMMQMMh1GvKD0hzf21TYrfIWANqzdVp2f8xN35UaaJlC34bl4VYbF4umT0k5I+Jv9yOf2gTgGQdprCRp9ane9tyYg3AvAEZ+vNAnzlz75x40Fal1Dg0mPdAqrBtSosqNuKC9jp53g4Ts9XbFEIkzqR6YmUUWTGXNSXmIsnBzncqNE/NjA5wdHkgeSHADr3OvcFZjDayO1IVmzJmXxEPT3ExW+ccNwwjPe2tsTjfqiJJSEM4PdADKj2milgEAXbQPDgHWCdWjw84wDgas7Jr52+vzB8eFYOJn0h8PNnowDGtzbtockoTd3mWoICVK8DTnsbsrHxombJ3RIsazdVrpXmP0ccMj6npgeoPpZt3VU162MGf0Kv56nQcfpoBBkdI1pvXJrAVQik8caycuZEJ7F917frchKT8P348ovpn+SPkpyWsrXHkN+j3jI3mbskDUrIk2R6v1PEQC5hWWcJsPACOw2+4Y94mp1pVZz4+cBmR8I1HtUgaagIW5N0WGLz0LmqmIb7CBkz1t4U/itia2fQkafvHy/7+3uU/sun7381cdfX/7nmZ+7/xMFhhzN0EWE0c34jKcKJ1eQkcoEsxpd4w4oRxp3Y2T/IVlRHjlxk11X8cz659euUTVVVjJEzTNAhrj9DDVkuNp4ufoM0vYquxWJ+o6y1kqvwaHhNbAC1pcVl2o11oyjIxSRGbqfuWsLf8ZVl/ATeHqupO76tPQF6RiolcJsYdZqEG/I3HBh6uw1TaYm2sZkLsfksfkpdIg9BPWN4ideevTlxS9XNBAxMFuMRM+s5IvtUXBn7mBAi6OFGwUkGXoX8DL7RRL6OQjxk77jqfGR/X2jJyPHeQ+XuecUMJKci0rg+V26Elu9UWFQouLstQ5hHreGR5K6t7iuNvH54xj9sH8EuZxJEHeTxjuZX+d3Pwz1eJP/ciVeym12WVw2rpZDBjCRSIlaW8Xvnjz/0Ykzre0uLwFzwOQ2QOY5roXV0FpWBptBuN+1HlB99nLri5Vrt1XUVZbpC5kbMReMXrKcEOfjQ66R0MHO8Ahyd3j5XkBt2Udgij7CoMwvcYQymMqCKXxsajrcNDW1MDs9b6E085rzy6M39kz9ewfe8e8d+MaOf72dk/74zuvbpYrE9UVce3923s3TAy/e8hu45ebJmydn5t2c/b9vyf0/62YiOAAAAAABAAAAAMw9os8AAAAAxvkyTwAAAADJ9CXGeJxjYGRgYOADYgkGEGBiYARCTSBmAfMYAAYNAFwAAAB4nGNgYdrHtIeBlYGBqQtIMzD0QGjGBwyGjExAPgMHAwQ0MDC8F2B48xbKZQhIc01hWMCg8P4/g9z/R0ABOQY5BQaG/jhmkCzTOgYFIGQEAEr3EWZ4nGNgYGBmgGAZBkYGEIgB8hjBfBYGByDNw8DBwARkKzBYMkQxLHj///9/oKgCgwGDI5D3F8h9+P/S/9P/2wS0oCbAASMbA7oQBkCXZ2JmYWVj5+Dk4oYK8PDy8QsICgmLiIqJS0hKScvIyskrKCopq6gSMJnaQI0sXQA9NhWAAHicY2BkYGAA4mf/4lzj+W2+MnAzvwCKMFyNXbUeRv9/+l+X1ZPZA6iOg4EJJAoAjMcN6QB4nGNgZGBgkPv/iIGBNen/038XWT0ZQCLIQAsAnvcGlHicY/jFYMTwi4GByZ5BD4gDgNgYiA2AWAGILaFsByhtwDyTQZ3pDYMGUyqDCHMNgwhTPIMqsx6DINMqBiPm20B+0/+nzNwMpszpDBrMIgyarEkMaswr/79g7mKwZ9YC6lnNUMF8D6huB4MkUwuDGtPp/9+YHjJIskxkkGQ2ZLBg+s6gwmzEoAdyE+MXINZhYGBIYWAAAPNOIFYAAAAAUAAAKgAAeJytlE9LG0EYxp/VrLUpSkUopac5FIkQN3/oxSCCVQKRqNXYUnqRMRmzI5vdsLsmeig99txboR+i/QC99dxLP0g/QSl9djJiA7FoMcvO/Obdd573nXdmAuCRMw8Ho18Rbyw7WMRny1PI4bvlaRScp5ZzeOy8s+zigfPF8gztPy3P4XfOtTyPJ27N8kMsum8tLyDnfqKyk7vP0WsTJWMHS3hveQqz+GZ5Gi/ww3IOZWfHssu1fLQ8Q/tXy3POr6l7lufxzM1Zfogl96XlBcy6H7CJCH1cIIZGFz5SCBTQxjL7Ksp8VrFiqMJXYAsKifENOWrRU9MSslespUDDsAdsRv2LWHf9VBTay6JaLq+uVMuVsthSie6GotXWKmyromiEbXrvQDK0j2325zhiWhKBCROT+vyiKYsdmfrb8vxoUwa6G8u+r2l8ziUE6BCigG2dw5BiWR9TQJmVeCb7Gt+bhVq5kq1HYVqP4q4SVa8samJCEiuj0LeWvl7qFfOOTaUjU+kKV1ChWcWJjkJR8Sp3Gu52x6B4i4OQ6axhaB4PPZvyqUnZs1u0zjhF5OmhzVeBA6OelWDAtkPL5bYK7HJuz2zrzQrgUTmPQzNKxpRapBPSkN6xURx5BGZetprERj8jd0w+wkRUZnYDTfZ7jKRMFa6Um2MKWT0mb6g3ltl4XMGsBnw17RLHbDPbVY2kibiBfcMpD3fe7FzKfGoo8Umolu1on7aEsRKjdVn1EjOvM9Prrmpx4l0VhbXhcOj1eJRO5bnHe7G+XMwPdeqLA5WoeKA6IrsxYlf21KS74uXzh75ORk6t6CQdylgJGgLdVmHC6WdhR8Ui9ZVoNZpir6/CkXNz5FAUf90CbyRm5wo5kDqQx4ESJiMp6hv7Qqa1vJ+m/VqplLRj3U8TL9FBlnppr871/1fR/iV4d/9mfwDrbFK+AAAAeJxjYGYAg//NDEYMWAAAKEQBuAA=) format("woff")}@font-face{font-family:MJXTEX-FR;src:url(/Blog/assets/fonts/MathJax_Fraktur-Regular.b80e08d5.woff) format("woff")}@font-face{font-family:MJXTEX-FR-B;src:url(/Blog/assets/fonts/MathJax_Fraktur-Bold.bc421258.woff) format("woff")}@font-face{font-family:MJXTEX-SS;src:url(/Blog/assets/fonts/MathJax_SansSerif-Regular.bc3af04f.woff) format("woff")}@font-face{font-family:MJXTEX-SS-B;src:url(/Blog/assets/fonts/MathJax_SansSerif-Bold.07281897.woff) format("woff")}@font-face{font-family:MJXTEX-SS-I;src:url(/Blog/assets/fonts/MathJax_SansSerif-Italic.3d580bd5.woff) format("woff")}@font-face{font-family:MJXTEX-SC;src:url(/Blog/assets/fonts/MathJax_Script-Regular.4c74e33b.woff) format("woff")}@font-face{font-family:MJXTEX-T;src:url(/Blog/assets/fonts/MathJax_Typewriter-Regular.72815766.woff) format("woff")}@font-face{font-family:MJXTEX-V;src:url(data:font/woff;base64,d09GRk9UVE8AAARwAAsAAAAABoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAADKAAAAQkAAAElso6A7EZGVE0AAAQ0AAAAHAAAABx3J0njR0RFRgAABFAAAAAYAAAAHAAoAAJPUy8yAAABaAAAAEkAAABgd6mCHGNtYXAAAALcAAAANAAAAUIADSQ4aGVhZAAAAQgAAAA1AAAANgw5vZloaGVhAAABQAAAAB4AAAAkBKMBLmhtdHgAAARoAAAABgAAAAYCEQAAbWF4cAAAAWAAAAAGAAAABgACUABuYW1lAAABtAAAASYAAAIx/gQR3nBvc3QAAAMQAAAAFgAAACD/hgAzeNpjYGRgYADir0asH+L5bb4ycDO/AIowXJ28TRJCHzzLIMvEwnid6RSQy8HABBIFAFQsC7IAAAB42mNgZGBgOvXfgoGB8QsDEDBeZ2BkQAWMAGVAA9QAAAAAUAAAAgAAeNpjYGH8wviFgZWBgamLaQ8DA0MPhGZ8wGDIyAQUZWBjZoABRiBWgHEC0lxTGA4oTlKcxHTqvwVQ5SmGE1A1EKAAhIwAzIwNswAAAHjalZCxasMwEIZ/xU5KKXTM1EF0iqEJcZZAhkJxyRDIYoLX1BhhC2IryHJJxr5QX6YP0ico9OzckqRLDfJ9+u+/O0kA7vEJgdMX0DqxID1g7uEGc2YPj3hm9jHEG3Mfd3hnHnS6B+Hf0i7GB7PAA76Ye9T/m9nDK36YfTyJF+Y+hqJkHrR6ZPZHq/PCyVEWyNk0nMtNoeQ6dcUqPcjIVLWxTjclK9tEZc7YWOXNLrVLU7mlsbmSC3luGLPjbzVRttamkuEkRASDPY6w0MhRwEFihIyeSmKGKUJ6KIkNZRTFNVJyFFhRPNC+ra5Q09+SrtGgvPBskVBlRkrriYlzcu0oZ7Hsql0XLenthMXVlPMO44se//G2OUun1d1cSXebIPwFZj5mrgAAeNpjYGBgZoBgGQZGBhCwAfIYwXwWBgUgzQKEQL7ipP//IeS9fKhKBkY2BhhzxAIA+yMHZXjaY2BmAIP/zQxGQIqRAQ0AAChVAbkAAHjaY2RgYWJgZGQU900syfBKrIgPS00uyS/SDUpNL81JLAJJqf7gZ/ghw/hDlumHHPMPcZYeHsYVP2b8yP4Zx/rdln/295VC3x0EGVgYGblNvCISi4ryy4sy0zNKnPMLKsEMBY1kTQUjA0NzhZCMVAWoPQrO+XnF+UUlmaW52G1GFWVgYGBsZ2BiZGRK4fvB+9NLtLtuZu7Uao7fv9laW1vaupu6mya2TWrj+G7f9d2+m7WuITO3u7K7flrzlO7p3d39U6ctXL5w3qrZMyb193TP6J7cMaF5Akf5jJoFrYvap3f2t/d19LX3tnXXdzc3djdy8HXzcG3m2sq9mYdnKw/vjw4RAKc+clgAAAAAAAABAAAAAMw9os8AAAAA1VXxAgAAAADVk7YReNpjYGRgYOABYhEgZoRCFjCbAQADFgArAfQAAAAdAAA=) format("woff")}@font-face{font-family:MJXTEX-VB;src:url(data:font/woff;base64,d09GRk9UVE8AAARcAAsAAAAABjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAADGAAAAQcAAAEfGT6+mEZGVE0AAAQgAAAAHAAAABx3J0n8R0RFRgAABDwAAAAYAAAAHAAoAAJPUy8yAAABaAAAAEkAAABgd7yCRmNtYXAAAALMAAAANAAAAUIADSQ4aGVhZAAAAQgAAAA1AAAANgyFt9poaGVhAAABQAAAAB0AAAAkBPMBb2htdHgAAARUAAAABgAAAAYCYAAAbWF4cAAAAWAAAAAGAAAABgACUABuYW1lAAABtAAAARYAAAHs9k2y63Bvc3QAAAMAAAAAFgAAACD/hgAzeNpjYGRgYABiU6dQ9nh+m68M3MwvgCIMVydvM4bQu98xKDIxMskxXQaq42BgAokCABb+CfEAAAB42mNgZGBguvxfD0jaMwABkxwDIwMqYAQARfsCZwAAAAAAUAAAAgAAeNpjYGGyZ/zCwMrAwNTFtIeBgaEHQjM+YDBkZAKKMrAxM8AAIxArwDgBaa4pDAsUJylOYrr8Xw+o8jLDJagaCFAAQkYAiH0M8QAAAHjadY/NasJAFIW/mCgthW4K3XZWRReKcSNIKUXBheCmiFuRGJIUzchkBH2pPkGfpss+RW+SQaQ/AzPnuydn7p0At7zjUa+O7Jo97qSquUHAk2OfB14cBxeZJjesHLcq38cLrqV65c2xxyMfjhtc8enY55kvx8FFpsm913bcKv2J3p9MlqRWtaOOGvTDoVqksZqvbTpbH9VE54U2NjvsnLNaxpHVpjvW2025pzq3U22SWI3UH5FlbIpM5yrshUzQ7DlhyEhIsSjaRPJfigF9QoZCC/kSi85ZSyJlJnqUurydU8hpxM84sPuRWbGUm5E4ZabLWHTL5qzTqoOt1MgLyimjX5P+61K6RuZnVRclr+0RfgNnQFOYAAB42mNgYGBmgGAZBkYGELAB8hjBfBYGBSDNAoRAvuKk//8h5L18qEoGRjYGGHPEAgD7IwdleNpjYGYAg//NDEZAipEBDQAAKFUBuQAAeNpjZGBhYmBkZBTxTSzJ8EqsiA9LTS7JL9J1ys9JAYmr/uBn+CHD+EOW6Ycc8w9xlh4exjU/pv7Y9DOd9bs5/7zvC4S+WwkysDAycpu4hyYWFeWXF2WmZ5Q45xdUghkKGsmaCkYGhuYKIRmpClBLFJzz84rzi0oyS3OxWIsqxMDAwNjOwMTIyJTI9+2H1k8v0e666WWTGzj+sLHVtzS0dld210xtmtHG8d2h67tDd10ta21te1d3dXf1jNo53dO7+/rmzF6yZOmc1dPnTZ4yoXt+94zWybWTOfKnV89uWNI8p3VCeXdVd2NVdz0HXzcP12aurdybeXi28vD+6BD5kSEKAO9nb1wAAAAAAQAAAADMPaLPAAAAANVV8QIAAAAA1ZO2KnjaY2BkYGDgAWIRIGaEQhYwmwEAAxYAKwI/AAAAIQAA) format("woff")}.MJX-TEX mjx-stretchy-v[c="("] mjx-beg mjx-c:before{content:"\239B";width:.875em;padding:1.154em 0 .655em}.MJX-TEX mjx-stretchy-v[c="("] mjx-ext mjx-c:before{content:"\239C";width:.875em}.MJX-TEX mjx-stretchy-v[c="("] mjx-end mjx-c:before{content:"\239D";width:.875em;padding:1.165em 0 .644em}.MJX-TEX mjx-stretchy-v[c="("]>mjx-end{margin-top:-1.809em}.MJX-TEX mjx-stretchy-v[c="("]>mjx-ext{border-top-width:1.779em;border-bottom-width:1.779em}.MJX-TEX mjx-stretchy-v[c=")"] mjx-beg mjx-c:before{content:"\239E";width:.875em;padding:1.154em 0 .655em}.MJX-TEX mjx-stretchy-v[c=")"] mjx-ext mjx-c:before{content:"\239F";width:.875em}.MJX-TEX mjx-stretchy-v[c=")"] mjx-end mjx-c:before{content:"\23A0";width:.875em;padding:1.165em 0 .644em}.MJX-TEX mjx-stretchy-v[c=")"]>mjx-end{margin-top:-1.809em}.MJX-TEX mjx-stretchy-v[c=")"]>mjx-ext{border-top-width:1.779em;border-bottom-width:1.779em}.MJX-TEX .mjx-stretched mjx-c[c="-"]:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="-"] mjx-ext mjx-c:before{content:"\2212";padding:.583em 0 .082em}.MJX-TEX mjx-stretchy-h[c="="] mjx-ext mjx-c:before{content:"=";padding:.583em 0 .082em}.MJX-TEX mjx-stretchy-v[c="["] mjx-beg mjx-c:before{content:"\23A1";width:.771em;padding:1.154em 0 .645em .104em}.MJX-TEX mjx-stretchy-v[c="["] mjx-ext mjx-c:before{content:"\23A2";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="["] mjx-end mjx-c:before{content:"\23A3";width:.771em;padding:1.155em 0 .644em .104em}.MJX-TEX mjx-stretchy-v[c="["]>mjx-end{margin-top:-1.799em}.MJX-TEX mjx-stretchy-v[c="["]>mjx-ext{border-top-width:1.769em;border-bottom-width:1.769em}.MJX-TEX mjx-stretchy-v[c="]"] mjx-beg mjx-c:before{content:"\23A4";width:.771em;padding:1.154em 0 .645em .104em}.MJX-TEX mjx-stretchy-v[c="]"] mjx-ext mjx-c:before{content:"\23A5";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="]"] mjx-end mjx-c:before{content:"\23A6";width:.771em;padding:1.155em 0 .644em .104em}.MJX-TEX mjx-stretchy-v[c="]"]>mjx-end{margin-top:-1.799em}.MJX-TEX mjx-stretchy-v[c="]"]>mjx-ext{border-top-width:1.769em;border-bottom-width:1.769em}.MJX-TEX .mjx-stretched mjx-c[c="^"]:before{content:"\2C6"}.MJX-TEX .mjx-stretched mjx-c[c=_]:before{content:"\2013"}.MJX-TEX mjx-stretchy-h[c=_] mjx-ext mjx-c:before{content:"\2013";padding:.285em 0 0}.MJX-TEX mjx-stretchy-v[c="{"] mjx-beg mjx-c:before{content:"\23A7";width:.889em;padding:.899em 0 .01em}.MJX-TEX mjx-stretchy-v[c="{"] mjx-ext mjx-c:before{content:"\23AA";width:.889em}.MJX-TEX mjx-stretchy-v[c="{"] mjx-end mjx-c:before{content:"\23A9";width:.889em;padding:.01em 0 .899em}.MJX-TEX mjx-stretchy-v[c="{"] mjx-mid mjx-c:before{content:"\23A8";width:.889em;padding:1.16em 0 .66em}.MJX-TEX mjx-stretchy-v[c="{"]>mjx-mid{margin-top:-.91em;margin-bottom:-.91em}.MJX-TEX mjx-stretchy-v[c="{"]>mjx-end{margin-top:-.909em}.MJX-TEX mjx-stretchy-v[c="{"]>mjx-ext{height:50%;border-top-width:.879em;border-bottom-width:.879em}.MJX-TEX mjx-stretchy-v[c="|"] mjx-ext mjx-c:before{content:"\2223";width:.305em;padding-left:0}.MJX-TEX mjx-stretchy-v[c="}"] mjx-beg mjx-c:before{content:"\23AB";width:.889em;padding:.899em 0 .01em}.MJX-TEX mjx-stretchy-v[c="}"] mjx-ext mjx-c:before{content:"\23AA";width:.889em}.MJX-TEX mjx-stretchy-v[c="}"] mjx-end mjx-c:before{content:"\23AD";width:.889em;padding:.01em 0 .899em}.MJX-TEX mjx-stretchy-v[c="}"] mjx-mid mjx-c:before{content:"\23AC";width:.889em;padding:1.16em 0 .66em}.MJX-TEX mjx-stretchy-v[c="}"]>mjx-mid{margin-top:-.91em;margin-bottom:-.91em}.MJX-TEX mjx-stretchy-v[c="}"]>mjx-end{margin-top:-.909em}.MJX-TEX mjx-stretchy-v[c="}"]>mjx-ext{height:50%;border-top-width:.879em;border-bottom-width:.879em}.MJX-TEX .mjx-stretched mjx-c[c="~"]:before{content:"\2DC"}.MJX-TEX mjx-stretchy-h[c=AF] mjx-ext mjx-c:before{content:"\AF";padding:.59em 0 0}.MJX-TEX .mjx-stretched mjx-c[c="2C9"]:before{content:"\AF"}.MJX-TEX mjx-stretchy-h[c="2C9"] mjx-ext mjx-c:before{content:"\AF";padding:.59em 0 0}.MJX-TEX .mjx-stretched mjx-c[c="302"]:before{content:"\2C6"}.MJX-TEX .mjx-stretched mjx-c[c="303"]:before{content:"\2DC"}.MJX-TEX .mjx-stretched mjx-c[c="332"]:before{content:"\2013"}.MJX-TEX mjx-stretchy-h[c="332"] mjx-ext mjx-c:before,.MJX-TEX mjx-stretchy-h[c="2013"] mjx-ext mjx-c:before{content:"\2013";padding:.285em 0 0}.MJX-TEX .mjx-stretched mjx-c[c="2014"]:before{content:"\2013"}.MJX-TEX mjx-stretchy-h[c="2014"] mjx-ext mjx-c:before{content:"\2013";padding:.285em 0 0}.MJX-TEX .mjx-stretched mjx-c[c="2015"]:before{content:"\2013"}.MJX-TEX mjx-stretchy-h[c="2015"] mjx-ext mjx-c:before{content:"\2013";padding:.285em 0 0}.MJX-TEX mjx-stretchy-v[c="2016"] mjx-ext mjx-c:before{content:"\2225";width:.528em;padding-left:0}.MJX-TEX .mjx-stretched mjx-c[c="2017"]:before{content:"\2013"}.MJX-TEX mjx-stretchy-h[c="2017"] mjx-ext mjx-c:before{content:"\2013";padding:.285em 0 0}.MJX-TEX .mjx-stretched mjx-c[c="203E"]:before{content:"\AF"}.MJX-TEX mjx-stretchy-h[c="203E"] mjx-ext mjx-c:before{content:"\AF";padding:.59em 0 0}.MJX-TEX .mjx-stretched mjx-c[c="20D7"]:before{content:"\2192"}.MJX-TEX mjx-stretchy-h[c="20D7"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="20D7"] mjx-end mjx-c:before{content:"\2192";padding:.511em 0 .011em}.MJX-TEX mjx-stretchy-h[c="2190"] mjx-beg mjx-c:before{content:"\2190";padding:.511em 0 .011em}.MJX-TEX mjx-stretchy-h[c="2190"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-v[c="2191"] mjx-beg mjx-c:before{content:"\2191";width:.667em;padding:.6em 0 0}.MJX-TEX mjx-stretchy-v[c="2191"] mjx-ext mjx-c:before{content:"\23D0";width:.667em}.MJX-TEX mjx-stretchy-v[c="2191"]>mjx-ext{border-top-width:.57em}.MJX-TEX mjx-stretchy-h[c="2192"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="2192"] mjx-end mjx-c:before{content:"\2192";padding:.511em 0 .011em}.MJX-TEX mjx-stretchy-v[c="2193"] mjx-ext mjx-c:before{content:"\23D0";width:.667em}.MJX-TEX mjx-stretchy-v[c="2193"] mjx-end mjx-c:before{content:"\2193";width:.667em;padding:.6em 0 0}.MJX-TEX mjx-stretchy-v[c="2193"]>mjx-end{margin-top:-.6em}.MJX-TEX mjx-stretchy-v[c="2193"]>mjx-ext{border-bottom-width:.57em}.MJX-TEX mjx-stretchy-h[c="2194"] mjx-beg mjx-c:before{content:"\2190";padding:.511em 0 .011em}.MJX-TEX mjx-stretchy-h[c="2194"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="2194"] mjx-end mjx-c:before{content:"\2192";padding:.511em 0 .011em}.MJX-TEX mjx-stretchy-v[c="2195"] mjx-beg mjx-c:before{content:"\2191";width:.667em;padding:.6em 0 0}.MJX-TEX mjx-stretchy-v[c="2195"] mjx-ext mjx-c:before{content:"\23D0";width:.667em}.MJX-TEX mjx-stretchy-v[c="2195"] mjx-end mjx-c:before{content:"\2193";width:.667em;padding:.6em 0 0}.MJX-TEX mjx-stretchy-v[c="2195"]>mjx-end{margin-top:-.6em}.MJX-TEX mjx-stretchy-v[c="2195"]>mjx-ext{border-top-width:.57em;border-bottom-width:.57em}.MJX-TEX mjx-stretchy-h[c="219E"] mjx-beg mjx-c:before{content:"\219E";padding:.417em 0 0}.MJX-TEX mjx-stretchy-h[c="21A0"] mjx-ext mjx-c:before,.MJX-TEX mjx-stretchy-h[c="219E"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="21A0"] mjx-end mjx-c:before{content:"\21A0";padding:.417em 0 0}.MJX-TEX mjx-stretchy-h[c="21A4"] mjx-beg mjx-c:before{content:"\2190";padding:.511em 0 .011em}.MJX-TEX mjx-stretchy-h[c="21A4"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="21A4"] mjx-end mjx-c:before{content:"\2223";padding:.627em 0 .015em}.MJX-TEX mjx-stretchy-v[c="21A5"] mjx-beg mjx-c:before{content:"\2191";width:.771em;padding:.6em 0 0 .104em}.MJX-TEX mjx-stretchy-v[c="21A5"] mjx-ext mjx-c:before{content:"\23D0";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="21A5"] mjx-end mjx-c:before{content:"\22A5";width:.827em;padding:.668em 0 0 .048em}.MJX-TEX mjx-stretchy-v[c="21A5"]>mjx-end{margin-top:-.668em}.MJX-TEX mjx-stretchy-v[c="21A5"]>mjx-ext{border-top-width:.57em;border-bottom-width:.638em}.MJX-TEX mjx-stretchy-h[c="21A6"] mjx-beg mjx-c:before{content:"\2223";padding:.627em 0 .015em}.MJX-TEX mjx-stretchy-h[c="21A6"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="21A6"] mjx-end mjx-c:before{content:"\2192";padding:.511em 0 .011em}.MJX-TEX mjx-stretchy-v[c="21A7"] mjx-beg mjx-c:before{content:"\22A4";width:.827em;padding:.668em 0 0 .048em}.MJX-TEX mjx-stretchy-v[c="21A7"] mjx-ext mjx-c:before{content:"\23D0";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="21A7"] mjx-end mjx-c:before{content:"\2193";width:.771em;padding:.6em 0 0 .104em}.MJX-TEX mjx-stretchy-v[c="21A7"]>mjx-end{margin-top:-.6em}.MJX-TEX mjx-stretchy-v[c="21A7"]>mjx-ext{border-top-width:.638em;border-bottom-width:.57em}.MJX-TEX mjx-stretchy-v[c="21B0"] mjx-beg mjx-c:before{content:"\21B0";width:.584em;padding:.722em 0 0 .084em}.MJX-TEX mjx-stretchy-v[c="21B0"] mjx-ext mjx-c:before{content:"\23D0";width:.667em}.MJX-TEX mjx-stretchy-v[c="21B0"]>mjx-ext{border-top-width:.692em}.MJX-TEX mjx-stretchy-v[c="21B1"] mjx-beg mjx-c:before{content:"\21B1";width:.584em;padding:.722em 0 0 .084em}.MJX-TEX mjx-stretchy-v[c="21B1"] mjx-ext mjx-c:before{content:"\23D0";width:.667em}.MJX-TEX mjx-stretchy-v[c="21B1"]>mjx-ext{border-top-width:.692em}.MJX-TEX mjx-stretchy-h[c="21BC"] mjx-beg mjx-c:before{content:"\21BC";padding:.511em 0 0}.MJX-TEX mjx-stretchy-h[c="21BC"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="21BD"] mjx-beg mjx-c:before{content:"\21BD";padding:.27em 0 .011em}.MJX-TEX mjx-stretchy-h[c="21BD"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-v[c="21BE"] mjx-beg mjx-c:before{content:"\21BE";width:.542em;padding:.694em 0 .194em .125em}.MJX-TEX mjx-stretchy-v[c="21BE"] mjx-ext mjx-c:before{content:"\23D0";width:.667em}.MJX-TEX mjx-stretchy-v[c="21BE"]>mjx-ext{border-top-width:.858em}.MJX-TEX mjx-stretchy-v[c="21BF"] mjx-beg mjx-c:before{content:"\21BF";width:.542em;padding:.694em 0 .194em .125em}.MJX-TEX mjx-stretchy-v[c="21BF"] mjx-ext mjx-c:before{content:"\23D0";width:.667em}.MJX-TEX mjx-stretchy-v[c="21BF"]>mjx-ext{border-top-width:.858em}.MJX-TEX mjx-stretchy-h[c="21C0"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="21C0"] mjx-end mjx-c:before{content:"\21C0";padding:.511em 0 0}.MJX-TEX mjx-stretchy-h[c="21C1"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="21C1"] mjx-end mjx-c:before{content:"\21C1";padding:.27em 0 .011em}.MJX-TEX mjx-stretchy-v[c="21C2"] mjx-ext mjx-c:before{content:"\23D0";width:.667em}.MJX-TEX mjx-stretchy-v[c="21C2"] mjx-end mjx-c:before{content:"\21C2";width:.542em;padding:.694em 0 .194em .125em}.MJX-TEX mjx-stretchy-v[c="21C2"]>mjx-end{margin-top:-.888em}.MJX-TEX mjx-stretchy-v[c="21C2"]>mjx-ext{border-bottom-width:.858em}.MJX-TEX mjx-stretchy-v[c="21C3"] mjx-ext mjx-c:before{content:"\23D0";width:.667em}.MJX-TEX mjx-stretchy-v[c="21C3"] mjx-end mjx-c:before{content:"\21C3";width:.542em;padding:.694em 0 .194em .125em}.MJX-TEX mjx-stretchy-v[c="21C3"]>mjx-end{margin-top:-.888em}.MJX-TEX mjx-stretchy-v[c="21C3"]>mjx-ext{border-bottom-width:.858em}.MJX-TEX mjx-stretchy-h[c="21D0"] mjx-beg mjx-c:before{content:"\21D0";padding:.525em 0 .024em}.MJX-TEX mjx-stretchy-h[c="21D0"] mjx-ext mjx-c:before{content:"="}.MJX-TEX mjx-stretchy-v[c="21D1"] mjx-beg mjx-c:before{content:"\21D1";width:.778em;padding:.599em 0 0}.MJX-TEX mjx-stretchy-v[c="21D1"] mjx-ext mjx-c:before{content:"\2016";width:.778em}.MJX-TEX mjx-stretchy-v[c="21D1"]>mjx-ext{border-top-width:.569em}.MJX-TEX mjx-stretchy-h[c="21D2"] mjx-ext mjx-c:before{content:"="}.MJX-TEX mjx-stretchy-h[c="21D2"] mjx-end mjx-c:before{content:"\21D2";padding:.525em 0 .024em}.MJX-TEX mjx-stretchy-v[c="21D3"] mjx-ext mjx-c:before{content:"\2016";width:.778em}.MJX-TEX mjx-stretchy-v[c="21D3"] mjx-end mjx-c:before{content:"\21D3";width:.778em;padding:.6em 0 0}.MJX-TEX mjx-stretchy-v[c="21D3"]>mjx-end{margin-top:-.6em}.MJX-TEX mjx-stretchy-v[c="21D3"]>mjx-ext{border-bottom-width:.57em}.MJX-TEX mjx-stretchy-h[c="21D4"] mjx-beg mjx-c:before{content:"\21D0";padding:.525em 0 .024em}.MJX-TEX mjx-stretchy-h[c="21D4"] mjx-ext mjx-c:before{content:"="}.MJX-TEX mjx-stretchy-h[c="21D4"] mjx-end mjx-c:before{content:"\21D2";padding:.525em 0 .024em}.MJX-TEX mjx-stretchy-v[c="21D5"] mjx-beg mjx-c:before{content:"\21D1";width:.778em;padding:.599em 0 0}.MJX-TEX mjx-stretchy-v[c="21D5"] mjx-ext mjx-c:before{content:"\2016";width:.778em}.MJX-TEX mjx-stretchy-v[c="21D5"] mjx-end mjx-c:before{content:"\21D3";width:.778em;padding:.6em 0 0}.MJX-TEX mjx-stretchy-v[c="21D5"]>mjx-end{margin-top:-.6em}.MJX-TEX mjx-stretchy-v[c="21D5"]>mjx-ext{border-top-width:.569em;border-bottom-width:.57em}.MJX-TEX mjx-stretchy-h[c="21DA"] mjx-beg mjx-c:before{content:"\21DA";padding:.611em 0 .111em}.MJX-TEX mjx-stretchy-h[c="21DA"] mjx-ext mjx-c:before,.MJX-TEX mjx-stretchy-h[c="21DB"] mjx-ext mjx-c:before{content:"\2261"}.MJX-TEX mjx-stretchy-h[c="21DB"] mjx-end mjx-c:before{content:"\21DB";padding:.611em 0 .111em}.MJX-TEX mjx-stretchy-h[c="2212"] mjx-ext mjx-c:before{content:"\2212";padding:.583em 0 .082em}.MJX-TEX .mjx-stretched mjx-c[c="2215"]:before{content:"/"}.MJX-TEX mjx-stretchy-v[c="221A"] mjx-beg mjx-c:before{content:"\E001";width:1.056em;padding:.605em 0 .014em}.MJX-TEX mjx-stretchy-v[c="221A"] mjx-ext mjx-c:before{content:"\E000";width:1.056em}.MJX-TEX mjx-stretchy-v[c="221A"] mjx-end mjx-c:before{content:"\23B7";width:1.056em;padding:.935em 0 .885em}.MJX-TEX mjx-stretchy-v[c="221A"]>mjx-end{margin-top:-1.82em}.MJX-TEX mjx-stretchy-v[c="221A"]>mjx-ext{border-top-width:.589em;border-bottom-width:1.79em}.MJX-TEX mjx-stretchy-v[c="2223"] mjx-ext mjx-c:before{content:"\2223";width:.305em;padding-left:0}.MJX-TEX mjx-stretchy-v[c="2225"] mjx-ext mjx-c:before{content:"\2225";width:.528em;padding-left:0}.MJX-TEX mjx-stretchy-v[c="2308"] mjx-beg mjx-c:before{content:"\23A1";width:.771em;padding:1.154em 0 .645em .104em}.MJX-TEX mjx-stretchy-v[c="2308"] mjx-ext mjx-c:before{content:"\23A2";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="2308"]>mjx-ext{border-top-width:1.769em}.MJX-TEX mjx-stretchy-v[c="2309"] mjx-beg mjx-c:before{content:"\23A4";width:.771em;padding:1.154em 0 .645em .104em}.MJX-TEX mjx-stretchy-v[c="2309"] mjx-ext mjx-c:before{content:"\23A5";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="2309"]>mjx-ext{border-top-width:1.769em}.MJX-TEX mjx-stretchy-v[c="230A"] mjx-ext mjx-c:before{content:"\23A2";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="230A"] mjx-end mjx-c:before{content:"\23A3";width:.771em;padding:1.155em 0 .644em .104em}.MJX-TEX mjx-stretchy-v[c="230A"]>mjx-end{margin-top:-1.799em}.MJX-TEX mjx-stretchy-v[c="230A"]>mjx-ext{border-bottom-width:1.769em}.MJX-TEX mjx-stretchy-v[c="230B"] mjx-ext mjx-c:before{content:"\23A5";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="230B"] mjx-end mjx-c:before{content:"\23A6";width:.771em;padding:1.155em 0 .644em .104em}.MJX-TEX mjx-stretchy-v[c="230B"]>mjx-end{margin-top:-1.799em}.MJX-TEX mjx-stretchy-v[c="230B"]>mjx-ext{border-bottom-width:1.769em}.MJX-TEX .mjx-stretched mjx-c[c="2312"]:before{content:"\23DC"}.MJX-TEX mjx-stretchy-h[c="2312"] mjx-beg mjx-c:before{content:"\E150";padding:.12em 0 .213em}.MJX-TEX mjx-stretchy-h[c="2312"] mjx-ext mjx-c:before{content:"\E154"}.MJX-TEX mjx-stretchy-h[c="2312"] mjx-end mjx-c:before{content:"\E151";padding:.12em 0 .213em}.MJX-TEX .mjx-stretched mjx-c[c="2322"]:before{content:"\23DC"}.MJX-TEX mjx-stretchy-h[c="2322"] mjx-beg mjx-c:before{content:"\E150";padding:.12em 0 .213em}.MJX-TEX mjx-stretchy-h[c="2322"] mjx-ext mjx-c:before{content:"\E154"}.MJX-TEX mjx-stretchy-h[c="2322"] mjx-end mjx-c:before{content:"\E151";padding:.12em 0 .213em}.MJX-TEX .mjx-stretched mjx-c[c="2323"]:before{content:"\23DD"}.MJX-TEX mjx-stretchy-h[c="2323"] mjx-beg mjx-c:before{content:"\E152";padding:.333em 0 0}.MJX-TEX mjx-stretchy-h[c="2323"] mjx-ext mjx-c:before{content:"\E154"}.MJX-TEX mjx-stretchy-h[c="2323"] mjx-end mjx-c:before{content:"\E153";padding:.333em 0 0}.MJX-TEX .mjx-stretched mjx-c[c="2329"]:before{content:"\27E8"}.MJX-TEX .mjx-stretched mjx-c[c="232A"]:before{content:"\27E9"}.MJX-TEX mjx-stretchy-v[c="23AA"] mjx-beg mjx-c:before{content:"\23AA";width:.889em;padding:.29em 0 .015em}.MJX-TEX mjx-stretchy-v[c="23AA"] mjx-ext mjx-c:before{content:"\23AA";width:.889em}.MJX-TEX mjx-stretchy-v[c="23AA"] mjx-end mjx-c:before{content:"\23AA";width:.889em;padding:.29em 0 .015em}.MJX-TEX mjx-stretchy-v[c="23AA"]>mjx-end{margin-top:-.305em}.MJX-TEX mjx-stretchy-v[c="23AA"]>mjx-ext{border-top-width:.275em;border-bottom-width:.275em}.MJX-TEX .mjx-stretched mjx-c[c="23AF"]:before{content:"\2013"}.MJX-TEX mjx-stretchy-h[c="23AF"] mjx-ext mjx-c:before{content:"\2013";padding:.285em 0 0}.MJX-TEX mjx-stretchy-v[c="23B0"] mjx-beg mjx-c:before{content:"\23A7";width:.889em;padding:.899em 0 .01em}.MJX-TEX mjx-stretchy-v[c="23B0"] mjx-ext mjx-c:before{content:"\23AA";width:.889em}.MJX-TEX mjx-stretchy-v[c="23B0"] mjx-end mjx-c:before{content:"\23AD";width:.889em;padding:.01em 0 .899em}.MJX-TEX mjx-stretchy-v[c="23B0"]>mjx-end{margin-top:-.909em}.MJX-TEX mjx-stretchy-v[c="23B0"]>mjx-ext{border-top-width:.879em;border-bottom-width:.879em}.MJX-TEX mjx-stretchy-v[c="23B1"] mjx-beg mjx-c:before{content:"\23AB";width:.889em;padding:.899em 0 .01em}.MJX-TEX mjx-stretchy-v[c="23B1"] mjx-ext mjx-c:before{content:"\23AA";width:.889em}.MJX-TEX mjx-stretchy-v[c="23B1"] mjx-end mjx-c:before{content:"\23A9";width:.889em;padding:.01em 0 .899em}.MJX-TEX mjx-stretchy-v[c="23B1"]>mjx-end{margin-top:-.909em}.MJX-TEX mjx-stretchy-v[c="23B1"]>mjx-ext{border-top-width:.879em;border-bottom-width:.879em}.MJX-TEX mjx-stretchy-h[c="23B4"] mjx-beg mjx-c:before{content:"\250C";padding:.694em 0 0}.MJX-TEX mjx-stretchy-h[c="23B4"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="23B4"] mjx-end mjx-c:before{content:"\2510";padding:.694em 0 0}.MJX-TEX mjx-stretchy-h[c="23B5"] mjx-beg mjx-c:before{content:"\2514";padding:.366em 0 .022em}.MJX-TEX mjx-stretchy-h[c="23B5"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="23B5"] mjx-end mjx-c:before{content:"\2518";padding:.366em 0 .022em}.MJX-TEX mjx-stretchy-v[c="23D0"] mjx-ext mjx-c:before{content:"\2223";width:.305em;padding-left:0}.MJX-TEX mjx-stretchy-h[c="23DC"] mjx-beg mjx-c:before{content:"\E150";padding:.12em 0 .213em}.MJX-TEX mjx-stretchy-h[c="23DC"] mjx-ext mjx-c:before{content:"\E154"}.MJX-TEX mjx-stretchy-h[c="23DC"] mjx-end mjx-c:before{content:"\E151";padding:.12em 0 .213em}.MJX-TEX mjx-stretchy-h[c="23DD"] mjx-beg mjx-c:before{content:"\E152";padding:.333em 0 0}.MJX-TEX mjx-stretchy-h[c="23DD"] mjx-ext mjx-c:before{content:"\E154"}.MJX-TEX mjx-stretchy-h[c="23DD"] mjx-end mjx-c:before{content:"\E153";padding:.333em 0 0}.MJX-TEX mjx-stretchy-h[c="23DE"] mjx-beg mjx-c:before{content:"\E150";padding:.12em 0 .213em}.MJX-TEX mjx-stretchy-h[c="23DE"] mjx-ext mjx-c:before{content:"\E154"}.MJX-TEX mjx-stretchy-h[c="23DE"] mjx-end mjx-c:before{content:"\E151";padding:.12em 0 .213em}.MJX-TEX mjx-stretchy-h[c="23DE"] mjx-mid mjx-c:before{content:"\E153\E152";padding:.333em 0 0}.MJX-TEX mjx-stretchy-h[c="23DE"]>mjx-ext{width:50%}.MJX-TEX mjx-stretchy-h[c="23DF"] mjx-beg mjx-c:before{content:"\E152";padding:.333em 0 0}.MJX-TEX mjx-stretchy-h[c="23DF"] mjx-ext mjx-c:before{content:"\E154"}.MJX-TEX mjx-stretchy-h[c="23DF"] mjx-end mjx-c:before{content:"\E153";padding:.333em 0 0}.MJX-TEX mjx-stretchy-h[c="23DF"] mjx-mid mjx-c:before{content:"\E151\E150";padding:.12em 0 .213em}.MJX-TEX mjx-stretchy-h[c="23DF"]>mjx-ext{width:50%}.MJX-TEX mjx-stretchy-h[c="23E0"] mjx-beg mjx-c:before{content:"\2CA";padding:.699em 0 0}.MJX-TEX mjx-stretchy-h[c="23E0"] mjx-ext mjx-c:before{content:"\2C9"}.MJX-TEX mjx-stretchy-h[c="23E0"] mjx-end mjx-c:before,.MJX-TEX mjx-stretchy-h[c="23E1"] mjx-beg mjx-c:before{content:"\2CB";padding:.699em 0 0}.MJX-TEX mjx-stretchy-h[c="23E1"] mjx-ext mjx-c:before{content:"\2C9"}.MJX-TEX mjx-stretchy-h[c="23E1"] mjx-end mjx-c:before{content:"\2CA";padding:.699em 0 0}.MJX-TEX .mjx-stretched mjx-c[c="2500"]:before{content:"\2013"}.MJX-TEX mjx-stretchy-h[c="2500"] mjx-ext mjx-c:before{content:"\2013";padding:.285em 0 0}.MJX-TEX .mjx-stretched mjx-c[c="2758"]:before{content:"\2223"}.MJX-TEX mjx-stretchy-v[c="2758"] mjx-ext mjx-c:before{content:"\2223";width:.305em;padding-left:0}.MJX-TEX mjx-stretchy-v[c="27EE"] mjx-beg mjx-c:before{content:"\23A7";width:.889em;padding:.899em 0 .01em}.MJX-TEX mjx-stretchy-v[c="27EE"] mjx-ext mjx-c:before{content:"\23AA";width:.889em}.MJX-TEX mjx-stretchy-v[c="27EE"] mjx-end mjx-c:before{content:"\23A9";width:.889em;padding:.01em 0 .899em}.MJX-TEX mjx-stretchy-v[c="27EE"]>mjx-end{margin-top:-.909em}.MJX-TEX mjx-stretchy-v[c="27EE"]>mjx-ext{border-top-width:.879em;border-bottom-width:.879em}.MJX-TEX mjx-stretchy-v[c="27EF"] mjx-beg mjx-c:before{content:"\23AB";width:.889em;padding:.899em 0 .01em}.MJX-TEX mjx-stretchy-v[c="27EF"] mjx-ext mjx-c:before{content:"\23AA";width:.889em}.MJX-TEX mjx-stretchy-v[c="27EF"] mjx-end mjx-c:before{content:"\23AD";width:.889em;padding:.01em 0 .899em}.MJX-TEX mjx-stretchy-v[c="27EF"]>mjx-end{margin-top:-.909em}.MJX-TEX mjx-stretchy-v[c="27EF"]>mjx-ext{border-top-width:.879em;border-bottom-width:.879em}.MJX-TEX .mjx-stretched mjx-c[c="27F5"]:before{content:"\2190"}.MJX-TEX mjx-stretchy-h[c="27F5"] mjx-beg mjx-c:before{content:"\2190";padding:.511em 0 .011em}.MJX-TEX mjx-stretchy-h[c="27F5"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX .mjx-stretched mjx-c[c="27F6"]:before{content:"\2192"}.MJX-TEX mjx-stretchy-h[c="27F6"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="27F6"] mjx-end mjx-c:before{content:"\2192";padding:.511em 0 .011em}.MJX-TEX .mjx-stretched mjx-c[c="27F7"]:before{content:"\2194"}.MJX-TEX mjx-stretchy-h[c="27F7"] mjx-beg mjx-c:before{content:"\2190";padding:.511em 0 .011em}.MJX-TEX mjx-stretchy-h[c="27F7"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="27F7"] mjx-end mjx-c:before{content:"\2192";padding:.511em 0 .011em}.MJX-TEX .mjx-stretched mjx-c[c="27F8"]:before{content:"\21D0"}.MJX-TEX mjx-stretchy-h[c="27F8"] mjx-beg mjx-c:before{content:"\21D0";padding:.525em 0 .024em}.MJX-TEX mjx-stretchy-h[c="27F8"] mjx-ext mjx-c:before{content:"="}.MJX-TEX .mjx-stretched mjx-c[c="27F9"]:before{content:"\21D2"}.MJX-TEX mjx-stretchy-h[c="27F9"] mjx-ext mjx-c:before{content:"="}.MJX-TEX mjx-stretchy-h[c="27F9"] mjx-end mjx-c:before{content:"\21D2";padding:.525em 0 .024em}.MJX-TEX .mjx-stretched mjx-c[c="27FA"]:before{content:"\21D4"}.MJX-TEX mjx-stretchy-h[c="27FA"] mjx-beg mjx-c:before{content:"\21D0";padding:.525em 0 .024em}.MJX-TEX mjx-stretchy-h[c="27FA"] mjx-ext mjx-c:before{content:"="}.MJX-TEX mjx-stretchy-h[c="27FA"] mjx-end mjx-c:before{content:"\21D2";padding:.525em 0 .024em}.MJX-TEX .mjx-stretched mjx-c[c="27FB"]:before{content:"\21A4"}.MJX-TEX mjx-stretchy-h[c="27FB"] mjx-beg mjx-c:before{content:"\2190";padding:.511em 0 .011em}.MJX-TEX mjx-stretchy-h[c="27FB"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="27FB"] mjx-end mjx-c:before{content:"\2223";padding:.627em 0 .015em}.MJX-TEX .mjx-stretched mjx-c[c="27FC"]:before{content:"\21A6"}.MJX-TEX mjx-stretchy-h[c="27FC"] mjx-beg mjx-c:before{content:"\2223";padding:.627em 0 .015em}.MJX-TEX mjx-stretchy-h[c="27FC"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="27FC"] mjx-end mjx-c:before{content:"\2192";padding:.511em 0 .011em}.MJX-TEX .mjx-stretched mjx-c[c="27FD"]:before{content:"\2906"}.MJX-TEX mjx-stretchy-h[c="27FD"] mjx-beg mjx-c:before{content:"\21D0";padding:.525em 0 .024em}.MJX-TEX mjx-stretchy-h[c="27FD"] mjx-ext mjx-c:before{content:"="}.MJX-TEX mjx-stretchy-h[c="27FD"] mjx-end mjx-c:before{content:"\2223";padding:.627em 0 .015em}.MJX-TEX .mjx-stretched mjx-c[c="27FE"]:before{content:"\2907"}.MJX-TEX mjx-stretchy-h[c="27FE"] mjx-beg mjx-c:before{content:"\22A8";padding:.75em 0 .249em}.MJX-TEX mjx-stretchy-h[c="27FE"] mjx-ext mjx-c:before{content:"="}.MJX-TEX mjx-stretchy-h[c="27FE"] mjx-end mjx-c:before{content:"\21D2";padding:.525em 0 .024em}.MJX-TEX mjx-stretchy-h[c="2906"] mjx-beg mjx-c:before{content:"\21D0";padding:.525em 0 .024em}.MJX-TEX mjx-stretchy-h[c="2906"] mjx-ext mjx-c:before{content:"="}.MJX-TEX mjx-stretchy-h[c="2906"] mjx-end mjx-c:before{content:"\2223";padding:.627em 0 .015em}.MJX-TEX mjx-stretchy-h[c="2907"] mjx-beg mjx-c:before{content:"\22A8";padding:.75em 0 .249em}.MJX-TEX mjx-stretchy-h[c="2907"] mjx-ext mjx-c:before{content:"="}.MJX-TEX mjx-stretchy-h[c="2907"] mjx-end mjx-c:before{content:"\21D2";padding:.525em 0 .024em}.MJX-TEX mjx-stretchy-h[c="294E"] mjx-beg mjx-c:before{content:"\21BC";padding:.511em 0 0}.MJX-TEX mjx-stretchy-h[c="294E"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="294E"] mjx-end mjx-c:before{content:"\21C0";padding:.511em 0 0}.MJX-TEX mjx-stretchy-v[c="294F"] mjx-beg mjx-c:before{content:"\21BE";width:.646em;padding:.694em 0 .194em .229em}.MJX-TEX mjx-stretchy-v[c="294F"] mjx-ext mjx-c:before{content:"\23D0";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="294F"] mjx-end mjx-c:before{content:"\21C2";width:.646em;padding:.694em 0 .194em .229em}.MJX-TEX mjx-stretchy-v[c="294F"]>mjx-end{margin-top:-.888em}.MJX-TEX mjx-stretchy-v[c="294F"]>mjx-ext{border-top-width:.858em;border-bottom-width:.858em}.MJX-TEX mjx-stretchy-h[c="2950"] mjx-beg mjx-c:before{content:"\21BD";padding:.27em 0 .011em}.MJX-TEX mjx-stretchy-h[c="2950"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="2950"] mjx-end mjx-c:before{content:"\21C1";padding:.27em 0 .011em}.MJX-TEX mjx-stretchy-v[c="2951"] mjx-beg mjx-c:before{content:"\21BF";width:.646em;padding:.694em 0 .194em .229em}.MJX-TEX mjx-stretchy-v[c="2951"] mjx-ext mjx-c:before{content:"\23D0";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="2951"] mjx-end mjx-c:before{content:"\21C3";width:.646em;padding:.694em 0 .194em .229em}.MJX-TEX mjx-stretchy-v[c="2951"]>mjx-end{margin-top:-.888em}.MJX-TEX mjx-stretchy-v[c="2951"]>mjx-ext{border-top-width:.858em;border-bottom-width:.858em}.MJX-TEX mjx-stretchy-h[c="295A"] mjx-beg mjx-c:before{content:"\21BC";padding:.511em 0 0}.MJX-TEX mjx-stretchy-h[c="295A"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="295A"] mjx-end mjx-c:before,.MJX-TEX mjx-stretchy-h[c="295B"] mjx-beg mjx-c:before{content:"\2223";padding:.627em 0 .015em}.MJX-TEX mjx-stretchy-h[c="295B"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="295B"] mjx-end mjx-c:before{content:"\21C0";padding:.511em 0 0}.MJX-TEX mjx-stretchy-v[c="295C"] mjx-beg mjx-c:before{content:"\21BE";width:.646em;padding:.694em 0 .194em .229em}.MJX-TEX mjx-stretchy-v[c="295C"] mjx-ext mjx-c:before{content:"\23D0";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="295C"] mjx-end mjx-c:before{content:"\22A5";width:.827em;padding:.668em 0 0 .048em}.MJX-TEX mjx-stretchy-v[c="295C"]>mjx-end{margin-top:-.668em}.MJX-TEX mjx-stretchy-v[c="295C"]>mjx-ext{border-top-width:.858em;border-bottom-width:.638em}.MJX-TEX mjx-stretchy-v[c="295D"] mjx-beg mjx-c:before{content:"\22A4";width:.827em;padding:.668em 0 0 .048em}.MJX-TEX mjx-stretchy-v[c="295D"] mjx-ext mjx-c:before{content:"\23D0";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="295D"] mjx-end mjx-c:before{content:"\21C2";width:.646em;padding:.694em 0 .194em .229em}.MJX-TEX mjx-stretchy-v[c="295D"]>mjx-end{margin-top:-.888em}.MJX-TEX mjx-stretchy-v[c="295D"]>mjx-ext{border-top-width:.638em;border-bottom-width:.858em}.MJX-TEX mjx-stretchy-h[c="295E"] mjx-beg mjx-c:before{content:"\21BD";padding:.27em 0 .011em}.MJX-TEX mjx-stretchy-h[c="295E"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="295E"] mjx-end mjx-c:before,.MJX-TEX mjx-stretchy-h[c="295F"] mjx-beg mjx-c:before{content:"\2223";padding:.627em 0 .015em}.MJX-TEX mjx-stretchy-h[c="295F"] mjx-ext mjx-c:before{content:"\2212"}.MJX-TEX mjx-stretchy-h[c="295F"] mjx-end mjx-c:before{content:"\21C1";padding:.27em 0 .011em}.MJX-TEX mjx-stretchy-v[c="2960"] mjx-beg mjx-c:before{content:"\21BF";width:.646em;padding:.694em 0 .194em .229em}.MJX-TEX mjx-stretchy-v[c="2960"] mjx-ext mjx-c:before{content:"\23D0";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="2960"] mjx-end mjx-c:before{content:"\22A5";width:.827em;padding:.668em 0 0 .048em}.MJX-TEX mjx-stretchy-v[c="2960"]>mjx-end{margin-top:-.668em}.MJX-TEX mjx-stretchy-v[c="2960"]>mjx-ext{border-top-width:.858em;border-bottom-width:.638em}.MJX-TEX mjx-stretchy-v[c="2961"] mjx-beg mjx-c:before{content:"\22A4";width:.827em;padding:.668em 0 0 .048em}.MJX-TEX mjx-stretchy-v[c="2961"] mjx-ext mjx-c:before{content:"\23D0";width:.771em;padding-left:.104em}.MJX-TEX mjx-stretchy-v[c="2961"] mjx-end mjx-c:before{content:"\21C3";width:.646em;padding:.694em 0 .194em .229em}.MJX-TEX mjx-stretchy-v[c="2961"]>mjx-end{margin-top:-.888em}.MJX-TEX mjx-stretchy-v[c="2961"]>mjx-ext{border-top-width:.638em;border-bottom-width:.858em}.MJX-TEX .mjx-stretched mjx-c[c="3008"]:before{content:"\27E8"}.MJX-TEX .mjx-stretched mjx-c[c="3009"]:before{content:"\27E9"}.MJX-TEX .mjx-stretched mjx-c[c=FE37]:before{content:"\23DE"}.MJX-TEX mjx-stretchy-h[c=FE37] mjx-beg mjx-c:before{content:"\E150";padding:.12em 0 .213em}.MJX-TEX mjx-stretchy-h[c=FE37] mjx-ext mjx-c:before{content:"\E154"}.MJX-TEX mjx-stretchy-h[c=FE37] mjx-end mjx-c:before{content:"\E151";padding:.12em 0 .213em}.MJX-TEX mjx-stretchy-h[c=FE37] mjx-mid mjx-c:before{content:"\E153\E152";padding:.333em 0 0}.MJX-TEX mjx-stretchy-h[c=FE37]>mjx-ext{width:50%}.MJX-TEX .mjx-stretched mjx-c[c=FE38]:before{content:"\23DF"}.MJX-TEX mjx-stretchy-h[c=FE38] mjx-beg mjx-c:before{content:"\E152";padding:.333em 0 0}.MJX-TEX mjx-stretchy-h[c=FE38] mjx-ext mjx-c:before{content:"\E154"}.MJX-TEX mjx-stretchy-h[c=FE38] mjx-end mjx-c:before{content:"\E153";padding:.333em 0 0}.MJX-TEX mjx-stretchy-h[c=FE38] mjx-mid mjx-c:before{content:"\E151\E150";padding:.12em 0 .213em}.MJX-TEX mjx-stretchy-h[c=FE38]>mjx-ext{width:50%}.MJX-TEX mjx-c[c=" "]:before{width:.25em;content:" "}.MJX-TEX mjx-c[c="!"]:before{width:.278em;padding:.716em 0 0;content:"!"}.MJX-TEX mjx-c[c="22"]:before{width:.5em;padding:.694em 0 0;content:"\22"}.MJX-TEX mjx-c[c="#"]:before{width:.833em;padding:.694em 0 .194em;content:"#"}.MJX-TEX mjx-c[c="$"]:before{width:.5em;padding:.75em 0 .056em;content:"$"}.MJX-TEX mjx-c[c="%"]:before{width:.833em;padding:.75em 0 .056em;content:"%"}.MJX-TEX mjx-c[c="&"]:before{width:.778em;padding:.716em 0 .022em;content:"&"}.MJX-TEX mjx-c[c="27"]:before{width:.278em;padding:.694em 0 0;content:"\27"}.MJX-TEX mjx-c[c="("]:before{width:.389em;padding:.75em 0 .25em;content:"("}.MJX-TEX mjx-c[c=")"]:before{width:.389em;padding:.75em 0 .25em;content:")"}.MJX-TEX mjx-c[c="*"]:before{width:.5em;padding:.75em 0 0;content:"*"}.MJX-TEX mjx-c[c="+"]:before{width:.778em;padding:.583em 0 .082em;content:"+"}.MJX-TEX mjx-c[c=","]:before{width:.278em;padding:.121em 0 .194em;content:","}.MJX-TEX mjx-c[c="-"]:before{width:.333em;padding:.252em 0 0;content:"-"}.MJX-TEX mjx-c[c="."]:before{width:.278em;padding:.12em 0 0;content:"."}.MJX-TEX mjx-c[c="/"]:before{width:.5em;padding:.75em 0 .25em;content:"/"}.MJX-TEX mjx-c[c="0"]:before{width:.5em;padding:.666em 0 .022em;content:"0"}.MJX-TEX mjx-c[c="1"]:before{width:.5em;padding:.666em 0 0;content:"1"}.MJX-TEX mjx-c[c="2"]:before{width:.5em;padding:.666em 0 0;content:"2"}.MJX-TEX mjx-c[c="3"]:before{width:.5em;padding:.665em 0 .022em;content:"3"}.MJX-TEX mjx-c[c="4"]:before{width:.5em;padding:.677em 0 0;content:"4"}.MJX-TEX mjx-c[c="5"]:before{width:.5em;padding:.666em 0 .022em;content:"5"}.MJX-TEX mjx-c[c="6"]:before{width:.5em;padding:.666em 0 .022em;content:"6"}.MJX-TEX mjx-c[c="7"]:before{width:.5em;padding:.676em 0 .022em;content:"7"}.MJX-TEX mjx-c[c="8"]:before{width:.5em;padding:.666em 0 .022em;content:"8"}.MJX-TEX mjx-c[c="9"]:before{width:.5em;padding:.666em 0 .022em;content:"9"}.MJX-TEX mjx-c[c=":"]:before{width:.278em;padding:.43em 0 0;content:":"}.MJX-TEX mjx-c[c=";"]:before{width:.278em;padding:.43em 0 .194em;content:";"}.MJX-TEX mjx-c[c="<"]:before{width:.778em;padding:.54em 0 .04em;content:"<"}.MJX-TEX mjx-c[c="="]:before{width:.778em;padding:.583em 0 .082em;content:"="}.MJX-TEX mjx-c[c=">"]:before{width:.778em;padding:.54em 0 .04em;content:">"}.MJX-TEX mjx-c[c="?"]:before{width:.472em;padding:.705em 0 0;content:"?"}.MJX-TEX mjx-c[c="@"]:before{width:.778em;padding:.705em 0 .011em;content:"@"}.MJX-TEX mjx-c[c=A]:before{width:.75em;padding:.716em 0 0;content:"A"}.MJX-TEX mjx-c[c=B]:before{width:.708em;padding:.683em 0 0;content:"B"}.MJX-TEX mjx-c[c=C]:before{width:.722em;padding:.705em 0 .021em;content:"C"}.MJX-TEX mjx-c[c=D]:before{width:.764em;padding:.683em 0 0;content:"D"}.MJX-TEX mjx-c[c=E]:before{width:.681em;padding:.68em 0 0;content:"E"}.MJX-TEX mjx-c[c=F]:before{width:.653em;padding:.68em 0 0;content:"F"}.MJX-TEX mjx-c[c=G]:before{width:.785em;padding:.705em 0 .022em;content:"G"}.MJX-TEX mjx-c[c=H]:before{width:.75em;padding:.683em 0 0;content:"H"}.MJX-TEX mjx-c[c=I]:before{width:.361em;padding:.683em 0 0;content:"I"}.MJX-TEX mjx-c[c=J]:before{width:.514em;padding:.683em 0 .022em;content:"J"}.MJX-TEX mjx-c[c=K]:before{width:.778em;padding:.683em 0 0;content:"K"}.MJX-TEX mjx-c[c=L]:before{width:.625em;padding:.683em 0 0;content:"L"}.MJX-TEX mjx-c[c=M]:before{width:.917em;padding:.683em 0 0;content:"M"}.MJX-TEX mjx-c[c=N]:before{width:.75em;padding:.683em 0 0;content:"N"}.MJX-TEX mjx-c[c=O]:before{width:.778em;padding:.705em 0 .022em;content:"O"}.MJX-TEX mjx-c[c=P]:before{width:.681em;padding:.683em 0 0;content:"P"}.MJX-TEX mjx-c[c=Q]:before{width:.778em;padding:.705em 0 .193em;content:"Q"}.MJX-TEX mjx-c[c=R]:before{width:.736em;padding:.683em 0 .022em;content:"R"}.MJX-TEX mjx-c[c=S]:before{width:.556em;padding:.705em 0 .022em;content:"S"}.MJX-TEX mjx-c[c=T]:before{width:.722em;padding:.677em 0 0;content:"T"}.MJX-TEX mjx-c[c=U]:before{width:.75em;padding:.683em 0 .022em;content:"U"}.MJX-TEX mjx-c[c=V]:before{width:.75em;padding:.683em 0 .022em;content:"V"}.MJX-TEX mjx-c[c=W]:before{width:1.028em;padding:.683em 0 .022em;content:"W"}.MJX-TEX mjx-c[c=X]:before{width:.75em;padding:.683em 0 0;content:"X"}.MJX-TEX mjx-c[c=Y]:before{width:.75em;padding:.683em 0 0;content:"Y"}.MJX-TEX mjx-c[c=Z]:before{width:.611em;padding:.683em 0 0;content:"Z"}.MJX-TEX mjx-c[c="["]:before{width:.278em;padding:.75em 0 .25em;content:"["}.MJX-TEX mjx-c[c="5C"]:before{width:.5em;padding:.75em 0 .25em;content:"\5C"}.MJX-TEX mjx-c[c="]"]:before{width:.278em;padding:.75em 0 .25em;content:"]"}.MJX-TEX mjx-c[c="^"]:before{width:.5em;padding:.694em 0 0;content:"^"}.MJX-TEX mjx-c[c=_]:before{width:.5em;padding:0 0 .062em;content:"_"}.MJX-TEX mjx-c[c="`"]:before{width:.5em;padding:.699em 0 0;content:"`"}.MJX-TEX mjx-c[c=a]:before{width:.5em;padding:.448em 0 .011em;content:"a"}.MJX-TEX mjx-c[c=b]:before{width:.556em;padding:.694em 0 .011em;content:"b"}.MJX-TEX mjx-c[c=c]:before{width:.444em;padding:.448em 0 .011em;content:"c"}.MJX-TEX mjx-c[c=d]:before{width:.556em;padding:.694em 0 .011em;content:"d"}.MJX-TEX mjx-c[c=e]:before{width:.444em;padding:.448em 0 .011em;content:"e"}.MJX-TEX mjx-c[c=f]:before{width:.306em;padding:.705em 0 0;content:"f"}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c=f]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c=f]:last-child:before{width:.372em}.MJX-TEX mjx-c[c=g]:before{width:.5em;padding:.453em 0 .206em;content:"g"}.MJX-TEX mjx-c[c=h]:before{width:.556em;padding:.694em 0 0;content:"h"}.MJX-TEX mjx-c[c=i]:before{width:.278em;padding:.669em 0 0;content:"i"}.MJX-TEX mjx-c[c=j]:before{width:.306em;padding:.669em 0 .205em;content:"j"}.MJX-TEX mjx-c[c=k]:before{width:.528em;padding:.694em 0 0;content:"k"}.MJX-TEX mjx-c[c=l]:before{width:.278em;padding:.694em 0 0;content:"l"}.MJX-TEX mjx-c[c=m]:before{width:.833em;padding:.442em 0 0;content:"m"}.MJX-TEX mjx-c[c=n]:before{width:.556em;padding:.442em 0 0;content:"n"}.MJX-TEX mjx-c[c=o]:before{width:.5em;padding:.448em 0 .01em;content:"o"}.MJX-TEX mjx-c[c=p]:before{width:.556em;padding:.442em 0 .194em;content:"p"}.MJX-TEX mjx-c[c=q]:before{width:.528em;padding:.442em 0 .194em;content:"q"}.MJX-TEX mjx-c[c=r]:before{width:.392em;padding:.442em 0 0;content:"r"}.MJX-TEX mjx-c[c=s]:before{width:.394em;padding:.448em 0 .011em;content:"s"}.MJX-TEX mjx-c[c=t]:before{width:.389em;padding:.615em 0 .01em;content:"t"}.MJX-TEX mjx-c[c=u]:before{width:.556em;padding:.442em 0 .011em;content:"u"}.MJX-TEX mjx-c[c=v]:before{width:.528em;padding:.431em 0 .011em;content:"v"}.MJX-TEX mjx-c[c=w]:before{width:.722em;padding:.431em 0 .011em;content:"w"}.MJX-TEX mjx-c[c=x]:before{width:.528em;padding:.431em 0 0;content:"x"}.MJX-TEX mjx-c[c=y]:before{width:.528em;padding:.431em 0 .204em;content:"y"}.MJX-TEX mjx-c[c=z]:before{width:.444em;padding:.431em 0 0;content:"z"}.MJX-TEX mjx-c[c="{"]:before{width:.5em;padding:.75em 0 .25em;content:"{"}.MJX-TEX mjx-c[c="|"]:before{width:.278em;padding:.75em 0 .249em;content:"|"}.MJX-TEX mjx-c[c="}"]:before{width:.5em;padding:.75em 0 .25em;content:"}"}.MJX-TEX mjx-c[c="~"]:before{width:.5em;padding:.318em 0 0;content:"~"}.MJX-TEX mjx-c[c=A0]:before{width:.25em;content:"\A0"}.MJX-TEX mjx-c[c=A3]:before{width:.769em;padding:.714em 0 .011em;content:"\A3";font-family:MJXZERO,MJXTEX-MI}.MJX-TEX mjx-c[c=A5]:before{width:.75em;padding:.683em 0 0;content:"\A5"}.MJX-TEX mjx-c[c=A8]:before{width:.5em;padding:.669em 0 0;content:"\A8"}.MJX-TEX mjx-c[c=AC]:before{width:.667em;padding:.356em 0 0;content:"\AC"}.MJX-TEX mjx-c[c=AE]:before{width:.947em;padding:.709em 0 .175em;content:"\AE"}.MJX-TEX mjx-c[c=AF]:before{width:.5em;padding:.59em 0 0;content:"\AF"}.MJX-TEX mjx-c[c=B0]:before{width:.5em;padding:.715em 0 0;content:"\B0"}.MJX-TEX mjx-c[c=B1]:before{width:.778em;padding:.666em 0 0;content:"\B1"}.MJX-TEX mjx-c[c=B4]:before{width:.5em;padding:.699em 0 0;content:"\B4"}.MJX-TEX mjx-c[c=B7]:before{width:.278em;padding:.31em 0 0;content:"\22C5"}.MJX-TEX mjx-c[c=D7]:before{width:.778em;padding:.491em 0 0;content:"\D7"}.MJX-TEX mjx-c[c=F0]:before{width:.556em;padding:.749em 0 .021em;content:"\F0"}.MJX-TEX mjx-c[c=F7]:before{width:.778em;padding:.537em 0 .036em;content:"\F7"}.MJX-TEX mjx-c[c="127"]:before{width:.54em;padding:.695em 0 .013em;content:"\127"}.MJX-TEX mjx-c[c="131"]:before{width:.278em;padding:.442em 0 0;content:"\131"}.MJX-TEX mjx-c[c="237"]:before{width:.306em;padding:.442em 0 .205em;content:"\237"}.MJX-TEX mjx-c[c="2B9"]:before{width:.275em;padding:.56em 0 0;content:"\2032"}.MJX-TEX mjx-c[c="2C6"]:before{width:.5em;padding:.694em 0 0;content:"\2C6"}.MJX-TEX mjx-c[c="2C7"]:before{width:.5em;padding:.644em 0 0;content:"\2C7"}.MJX-TEX mjx-c[c="2C9"]:before{width:.5em;padding:.59em 0 0;content:"\2C9"}.MJX-TEX mjx-c[c="2CA"]:before{width:.5em;padding:.699em 0 0;content:"\2CA"}.MJX-TEX mjx-c[c="2CB"]:before{width:.5em;padding:.699em 0 0;content:"\2CB"}.MJX-TEX mjx-c[c="2D8"]:before{width:.5em;padding:.694em 0 0;content:"\2D8"}.MJX-TEX mjx-c[c="2D9"]:before{width:.5em;padding:.669em 0 0;content:"\2D9"}.MJX-TEX mjx-c[c="2DA"]:before{width:.5em;padding:.715em 0 0;content:"\2DA"}.MJX-TEX mjx-c[c="2DC"]:before{width:.5em;padding:.668em 0 0;content:"\2DC"}.MJX-TEX mjx-c[c="300"]:before{width:0;padding:.699em 0 0;content:"\300"}.MJX-TEX mjx-c[c="301"]:before{width:0;padding:.699em 0 0;content:"\301"}.MJX-TEX mjx-c[c="302"]:before{width:0;padding:.694em 0 0;content:"\302"}.MJX-TEX mjx-c[c="303"]:before{width:0;padding:.668em 0 0;content:"\303"}.MJX-TEX mjx-c[c="304"]:before{width:0;padding:.59em 0 0;content:"\304"}.MJX-TEX mjx-c[c="306"]:before{width:0;padding:.694em 0 0;content:"\306"}.MJX-TEX mjx-c[c="307"]:before{width:0;padding:.669em 0 0;content:"\307"}.MJX-TEX mjx-c[c="308"]:before{width:0;padding:.669em 0 0;content:"\308"}.MJX-TEX mjx-c[c="30A"]:before{width:0;padding:.715em 0 0;content:"\30A"}.MJX-TEX mjx-c[c="30B"]:before{width:0;padding:.701em 0 0;content:"\30B"}.MJX-TEX mjx-c[c="30C"]:before{width:0;padding:.644em 0 0;content:"\30C"}.MJX-TEX mjx-c[c="338"]:before{width:0;padding:.716em 0 .215em;content:"\338"}.MJX-TEX mjx-c[c="391"]:before{width:.75em;padding:.716em 0 0;content:"A"}.MJX-TEX mjx-c[c="392"]:before{width:.708em;padding:.683em 0 0;content:"B"}.MJX-TEX mjx-c[c="393"]:before{width:.625em;padding:.68em 0 0;content:"\393"}.MJX-TEX mjx-c[c="394"]:before{width:.833em;padding:.716em 0 0;content:"\394"}.MJX-TEX mjx-c[c="395"]:before{width:.681em;padding:.68em 0 0;content:"E"}.MJX-TEX mjx-c[c="396"]:before{width:.611em;padding:.683em 0 0;content:"Z"}.MJX-TEX mjx-c[c="397"]:before{width:.75em;padding:.683em 0 0;content:"H"}.MJX-TEX mjx-c[c="398"]:before{width:.778em;padding:.705em 0 .022em;content:"\398"}.MJX-TEX mjx-c[c="399"]:before{width:.361em;padding:.683em 0 0;content:"I"}.MJX-TEX mjx-c[c="39A"]:before{width:.778em;padding:.683em 0 0;content:"K"}.MJX-TEX mjx-c[c="39B"]:before{width:.694em;padding:.716em 0 0;content:"\39B"}.MJX-TEX mjx-c[c="39C"]:before{width:.917em;padding:.683em 0 0;content:"M"}.MJX-TEX mjx-c[c="39D"]:before{width:.75em;padding:.683em 0 0;content:"N"}.MJX-TEX mjx-c[c="39E"]:before{width:.667em;padding:.677em 0 0;content:"\39E"}.MJX-TEX mjx-c[c="39F"]:before{width:.778em;padding:.705em 0 .022em;content:"O"}.MJX-TEX mjx-c[c="3A0"]:before{width:.75em;padding:.68em 0 0;content:"\3A0"}.MJX-TEX mjx-c[c="3A1"]:before{width:.681em;padding:.683em 0 0;content:"P"}.MJX-TEX mjx-c[c="3A2"]:before{width:.778em;padding:.705em 0 .022em;content:"\398"}.MJX-TEX mjx-c[c="3A3"]:before{width:.722em;padding:.683em 0 0;content:"\3A3"}.MJX-TEX mjx-c[c="3A4"]:before{width:.722em;padding:.677em 0 0;content:"T"}.MJX-TEX mjx-c[c="3A5"]:before{width:.778em;padding:.705em 0 0;content:"\3A5"}.MJX-TEX mjx-c[c="3A6"]:before{width:.722em;padding:.683em 0 0;content:"\3A6"}.MJX-TEX mjx-c[c="3A7"]:before{width:.75em;padding:.683em 0 0;content:"X"}.MJX-TEX mjx-c[c="3A8"]:before{width:.778em;padding:.683em 0 0;content:"\3A8"}.MJX-TEX mjx-c[c="3A9"]:before{width:.722em;padding:.704em 0 0;content:"\3A9"}.MJX-TEX mjx-c[c="3D2"]:before{width:.778em;padding:.705em 0 0;content:"\3A5"}.MJX-TEX mjx-c[c="3DC"]:before{width:.653em;padding:.68em 0 0;content:"F"}.MJX-TEX mjx-c[c="3DD"]:before{width:.778em;padding:.605em 0 .085em;content:"\3DD"}.MJX-TEX mjx-c[c="3F0"]:before{width:.667em;padding:.434em 0 .006em;content:"\3F0"}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="3F0"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="3F0"]:last-child:before{width:.734em}.MJX-TEX mjx-c[c="3F6"]:before{width:.429em;padding:.44em 0 0;content:"\220D"}.MJX-TEX mjx-c[c="2000"]:before{width:.5em;content:"\2000"}.MJX-TEX mjx-c[c="2001"]:before{width:1em;content:"\2001"}.MJX-TEX mjx-c[c="2002"]:before{width:.5em;content:"\2002"}.MJX-TEX mjx-c[c="2003"]:before{width:1em;content:"\2003"}.MJX-TEX mjx-c[c="2004"]:before{width:.333em;content:"\2004"}.MJX-TEX mjx-c[c="2005"]:before{width:.25em;content:"\2005"}.MJX-TEX mjx-c[c="2006"]:before{width:.167em;content:"\2006"}.MJX-TEX mjx-c[c="2009"]:before{width:.167em;content:"\2009"}.MJX-TEX mjx-c[c="200A"]:before{width:.1em;content:"\200A"}.MJX-TEX mjx-c[c="200B"]:before{width:0;content:"\200B"}.MJX-TEX mjx-c[c="200C"]:before{width:0;content:"\200C"}.MJX-TEX mjx-c[c="2013"]:before{width:.5em;padding:.285em 0 0;content:"\2013"}.MJX-TEX mjx-c[c="2014"]:before,.MJX-TEX mjx-c[c="2015"]:before{width:1em;padding:.285em 0 0;content:"\2014"}.MJX-TEX mjx-c[c="2016"]:before{width:.5em;padding:.75em 0 .25em;content:"\2225"}.MJX-TEX mjx-c[c="2017"]:before{width:.5em;padding:0 0 .062em;content:"_"}.MJX-TEX mjx-c[c="2018"]:before{width:.278em;padding:.694em 0 0;content:"\2018"}.MJX-TEX mjx-c[c="2019"]:before{width:.278em;padding:.694em 0 0;content:"\2019"}.MJX-TEX mjx-c[c="201C"]:before{width:.5em;padding:.694em 0 0;content:"\201C"}.MJX-TEX mjx-c[c="201D"]:before{width:.5em;padding:.694em 0 0;content:"\201D"}.MJX-TEX mjx-c[c="2020"]:before{width:.444em;padding:.705em 0 .216em;content:"\2020"}.MJX-TEX mjx-c[c="2021"]:before{width:.444em;padding:.705em 0 .205em;content:"\2021"}.MJX-TEX mjx-c[c="2022"]:before{width:.5em;padding:.444em 0 0;content:"\2219"}.MJX-TEX mjx-c[c="2026"]:before{width:1.172em;padding:.12em 0 0;content:"\2026"}.MJX-TEX mjx-c[c="2032"]:before{width:.275em;padding:.56em 0 0;content:"\2032"}.MJX-TEX mjx-c[c="2033"]:before{width:.55em;padding:.56em 0 0;content:"\2032\2032"}.MJX-TEX mjx-c[c="2034"]:before{width:.825em;padding:.56em 0 0;content:"\2032\2032\2032"}.MJX-TEX mjx-c[c="2035"]:before{width:.275em;padding:.56em 0 0;content:"\2035"}.MJX-TEX mjx-c[c="2036"]:before{width:.55em;padding:.56em 0 0;content:"\2035\2035"}.MJX-TEX mjx-c[c="2037"]:before{width:.825em;padding:.56em 0 0;content:"\2035\2035\2035"}.MJX-TEX mjx-c[c="203E"]:before{width:.5em;padding:.59em 0 0;content:"\2C9"}.MJX-TEX mjx-c[c="2044"]:before{width:.5em;padding:.75em 0 .25em;content:"/"}.MJX-TEX mjx-c[c="2057"]:before{width:1.1em;padding:.56em 0 0;content:"\2032\2032\2032\2032"}.MJX-TEX mjx-c[c="2061"]:before{width:0;content:"\2061"}.MJX-TEX mjx-c[c="2062"]:before{width:0;content:"\2062"}.MJX-TEX mjx-c[c="2063"]:before{width:0;content:"\2063"}.MJX-TEX mjx-c[c="2064"]:before{width:0;content:"\2064"}.MJX-TEX mjx-c[c="20D7"]:before{width:.5em;padding:.714em 0 0;content:"\2192";font-family:MJXZERO,MJXTEX-V}.MJX-TEX mjx-c[c="2102"]:before{width:.722em;padding:.702em 0 .019em;content:"C";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="210B"]:before{width:.969em;padding:.717em 0 .036em;content:"H";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="210B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="210B"]:last-child:before{width:1.241em}.MJX-TEX mjx-c[c="210C"]:before{width:.72em;padding:.666em 0 .133em;content:"H";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="210D"]:before{width:.778em;padding:.683em 0 0;content:"H";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="210E"]:before{width:.576em;padding:.694em 0 .011em;content:"h";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="210F"]:before{width:.54em;padding:.695em 0 .013em;content:"\210F";font-family:MJXZERO,MJXTEX}.MJX-TEX mjx-c[c="2110"]:before{width:1.052em;padding:.717em 0 .314em;content:"J";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="2110"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="2110"]:last-child:before{width:1.133em}.MJX-TEX mjx-c[c="2111"]:before{width:.554em;padding:.686em 0 .026em;content:"I";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="2112"]:before{width:.874em;padding:.717em 0 .017em;content:"L";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="2112"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="2112"]:last-child:before{width:1.035em}.MJX-TEX mjx-c[c="2113"]:before{width:.417em;padding:.705em 0 .02em;content:"\2113"}.MJX-TEX mjx-c[c="2115"]:before{width:.722em;padding:.683em 0 .02em;content:"N";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="2118"]:before{width:.636em;padding:.453em 0 .216em;content:"\2118"}.MJX-TEX mjx-c[c="2119"]:before{width:.611em;padding:.683em 0 0;content:"P";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="211A"]:before{width:.778em;padding:.701em 0 .181em;content:"Q";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="211B"]:before{width:.85em;padding:.717em 0 .017em;content:"R";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-c[c="211C"]:before{width:.828em;padding:.686em 0 .026em;content:"R";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="211D"]:before{width:.722em;padding:.683em 0 0;content:"R";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="2124"]:before{width:.667em;padding:.683em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="2126"]:before{width:.722em;padding:.704em 0 0;content:"\3A9";font-family:MJXZERO,MJXTEX}.MJX-TEX mjx-c[c="2127"]:before{width:.722em;padding:.684em 0 .022em;content:"\2127"}.MJX-TEX mjx-c[c="2128"]:before{width:.602em;padding:.729em 0 .139em;content:"Z";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="212C"]:before{width:.908em;padding:.708em 0 .028em;content:"B";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-c[c="212D"]:before{width:.613em;padding:.685em 0 .024em;content:"C";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="2130"]:before{width:.562em;padding:.707em 0 .008em;content:"E";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="2130"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="2130"]:last-child:before{width:.718em}.MJX-TEX mjx-c[c="2131"]:before{width:.895em;padding:.735em 0 .036em;content:"F";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="2131"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="2131"]:last-child:before{width:.99em}.MJX-TEX mjx-c[c="2132"]:before{width:.556em;padding:.695em 0 0;content:"\2132"}.MJX-TEX mjx-c[c="2133"]:before{width:1.08em;padding:.721em 0 .05em;content:"M";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="2133"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="2133"]:last-child:before{width:1.216em}.MJX-TEX mjx-c[c="2135"]:before{width:.611em;padding:.694em 0 0;content:"\2135"}.MJX-TEX mjx-c[c="2136"]:before{width:.667em;padding:.763em 0 .021em;content:"\2136"}.MJX-TEX mjx-c[c="2137"]:before{width:.444em;padding:.764em 0 .043em;content:"\2137"}.MJX-TEX mjx-c[c="2138"]:before{width:.667em;padding:.764em 0 .043em;content:"\2138"}.MJX-TEX mjx-c[c="2141"]:before{width:.639em;padding:.705em 0 .023em;content:"\2141"}.MJX-TEX mjx-c[c="2190"]:before{width:1em;padding:.511em 0 .011em;content:"\2190"}.MJX-TEX mjx-c[c="2191"]:before{width:.5em;padding:.694em 0 .193em;content:"\2191"}.MJX-TEX mjx-c[c="2192"]:before{width:1em;padding:.511em 0 .011em;content:"\2192"}.MJX-TEX mjx-c[c="2193"]:before{width:.5em;padding:.694em 0 .194em;content:"\2193"}.MJX-TEX mjx-c[c="2194"]:before{width:1em;padding:.511em 0 .011em;content:"\2194"}.MJX-TEX mjx-c[c="2195"]:before{width:.5em;padding:.772em 0 .272em;content:"\2195"}.MJX-TEX mjx-c[c="2196"]:before{width:1em;padding:.72em 0 .195em;content:"\2196"}.MJX-TEX mjx-c[c="2197"]:before{width:1em;padding:.72em 0 .195em;content:"\2197"}.MJX-TEX mjx-c[c="2198"]:before{width:1em;padding:.695em 0 .22em;content:"\2198"}.MJX-TEX mjx-c[c="2199"]:before{width:1em;padding:.695em 0 .22em;content:"\2199"}.MJX-TEX mjx-c[c="219A"]:before{width:1em;padding:.437em 0 0;content:"\219A"}.MJX-TEX mjx-c[c="219B"]:before{width:1em;padding:.437em 0 0;content:"\219B"}.MJX-TEX mjx-c[c="219E"]:before{width:1em;padding:.417em 0 0;content:"\219E"}.MJX-TEX mjx-c[c="21A0"]:before{width:1em;padding:.417em 0 0;content:"\21A0"}.MJX-TEX mjx-c[c="21A2"]:before{width:1.111em;padding:.417em 0 0;content:"\21A2"}.MJX-TEX mjx-c[c="21A3"]:before{width:1.111em;padding:.417em 0 0;content:"\21A3"}.MJX-TEX mjx-c[c="21A6"]:before{width:1em;padding:.511em 0 .011em;content:"\21A6"}.MJX-TEX mjx-c[c="21A9"]:before{width:1.126em;padding:.511em 0 .011em;content:"\21A9"}.MJX-TEX mjx-c[c="21AA"]:before{width:1.126em;padding:.511em 0 .011em;content:"\21AA"}.MJX-TEX mjx-c[c="21AB"]:before{width:1em;padding:.575em 0 .041em;content:"\21AB"}.MJX-TEX mjx-c[c="21AC"]:before{width:1em;padding:.575em 0 .041em;content:"\21AC"}.MJX-TEX mjx-c[c="21AD"]:before{width:1.389em;padding:.417em 0 0;content:"\21AD"}.MJX-TEX mjx-c[c="21AE"]:before{width:1em;padding:.437em 0 0;content:"\21AE"}.MJX-TEX mjx-c[c="21B0"]:before{width:.5em;padding:.722em 0 0;content:"\21B0"}.MJX-TEX mjx-c[c="21B1"]:before{width:.5em;padding:.722em 0 0;content:"\21B1"}.MJX-TEX mjx-c[c="21B6"]:before{width:1em;padding:.461em 0 0;content:"\21B6"}.MJX-TEX mjx-c[c="21B7"]:before{width:1em;padding:.46em 0 0;content:"\21B7"}.MJX-TEX mjx-c[c="21BA"]:before{width:.778em;padding:.65em 0 .083em;content:"\21BA"}.MJX-TEX mjx-c[c="21BB"]:before{width:.778em;padding:.65em 0 .083em;content:"\21BB"}.MJX-TEX mjx-c[c="21BC"]:before{width:1em;padding:.511em 0 0;content:"\21BC"}.MJX-TEX mjx-c[c="21BD"]:before{width:1em;padding:.27em 0 .011em;content:"\21BD"}.MJX-TEX mjx-c[c="21BE"]:before{width:.417em;padding:.694em 0 .194em;content:"\21BE"}.MJX-TEX mjx-c[c="21BF"]:before{width:.417em;padding:.694em 0 .194em;content:"\21BF"}.MJX-TEX mjx-c[c="21C0"]:before{width:1em;padding:.511em 0 0;content:"\21C0"}.MJX-TEX mjx-c[c="21C1"]:before{width:1em;padding:.27em 0 .011em;content:"\21C1"}.MJX-TEX mjx-c[c="21C2"]:before{width:.417em;padding:.694em 0 .194em;content:"\21C2"}.MJX-TEX mjx-c[c="21C3"]:before{width:.417em;padding:.694em 0 .194em;content:"\21C3"}.MJX-TEX mjx-c[c="21C4"]:before{width:1em;padding:.667em 0 0;content:"\21C4"}.MJX-TEX mjx-c[c="21C6"]:before{width:1em;padding:.667em 0 0;content:"\21C6"}.MJX-TEX mjx-c[c="21C7"]:before{width:1em;padding:.583em 0 .083em;content:"\21C7"}.MJX-TEX mjx-c[c="21C8"]:before{width:.833em;padding:.694em 0 .193em;content:"\21C8"}.MJX-TEX mjx-c[c="21C9"]:before{width:1em;padding:.583em 0 .083em;content:"\21C9"}.MJX-TEX mjx-c[c="21CA"]:before{width:.833em;padding:.694em 0 .194em;content:"\21CA"}.MJX-TEX mjx-c[c="21CB"]:before{width:1em;padding:.514em 0 .014em;content:"\21CB"}.MJX-TEX mjx-c[c="21CC"]:before{width:1em;padding:.671em 0 .011em;content:"\21CC"}.MJX-TEX mjx-c[c="21CD"]:before{width:1em;padding:.534em 0 .035em;content:"\21CD"}.MJX-TEX mjx-c[c="21CE"]:before{width:1em;padding:.534em 0 .037em;content:"\21CE"}.MJX-TEX mjx-c[c="21CF"]:before{width:1em;padding:.534em 0 .035em;content:"\21CF"}.MJX-TEX mjx-c[c="21D0"]:before{width:1em;padding:.525em 0 .024em;content:"\21D0"}.MJX-TEX mjx-c[c="21D1"]:before{width:.611em;padding:.694em 0 .194em;content:"\21D1"}.MJX-TEX mjx-c[c="21D2"]:before{width:1em;padding:.525em 0 .024em;content:"\21D2"}.MJX-TEX mjx-c[c="21D3"]:before{width:.611em;padding:.694em 0 .194em;content:"\21D3"}.MJX-TEX mjx-c[c="21D4"]:before{width:1em;padding:.526em 0 .025em;content:"\21D4"}.MJX-TEX mjx-c[c="21D5"]:before{width:.611em;padding:.772em 0 .272em;content:"\21D5"}.MJX-TEX mjx-c[c="21DA"]:before{width:1em;padding:.611em 0 .111em;content:"\21DA"}.MJX-TEX mjx-c[c="21DB"]:before{width:1em;padding:.611em 0 .111em;content:"\21DB"}.MJX-TEX mjx-c[c="21DD"]:before{width:1em;padding:.417em 0 0;content:"\21DD"}.MJX-TEX mjx-c[c="21E0"]:before{width:1.334em;padding:.437em 0 0;content:"\21E0"}.MJX-TEX mjx-c[c="21E2"]:before{width:1.334em;padding:.437em 0 0;content:"\21E2"}.MJX-TEX mjx-c[c="2200"]:before{width:.556em;padding:.694em 0 .022em;content:"\2200"}.MJX-TEX mjx-c[c="2201"]:before{width:.5em;padding:.846em 0 .021em;content:"\2201"}.MJX-TEX mjx-c[c="2202"]:before{width:.531em;padding:.715em 0 .022em;content:"\2202"}.MJX-TEX mjx-c[c="2203"]:before{width:.556em;padding:.694em 0 0;content:"\2203"}.MJX-TEX mjx-c[c="2204"]:before{width:.556em;padding:.716em 0 .215em;content:"\2203\338"}.MJX-TEX mjx-c[c="2205"]:before{width:.5em;padding:.772em 0 .078em;content:"\2205"}.MJX-TEX mjx-c[c="2206"]:before{width:.833em;padding:.716em 0 0;content:"\394"}.MJX-TEX mjx-c[c="2207"]:before{width:.833em;padding:.683em 0 .033em;content:"\2207"}.MJX-TEX mjx-c[c="2208"]:before{width:.667em;padding:.54em 0 .04em;content:"\2208"}.MJX-TEX mjx-c[c="2209"]:before{width:.667em;padding:.716em 0 .215em;content:"\2209"}.MJX-TEX mjx-c[c="220B"]:before{width:.667em;padding:.54em 0 .04em;content:"\220B"}.MJX-TEX mjx-c[c="220C"]:before{width:.667em;padding:.716em 0 .215em;content:"\220B\338"}.MJX-TEX mjx-c[c="220D"]:before{width:.429em;padding:.44em 0 0;content:"\220D"}.MJX-TEX mjx-c[c="220F"]:before{width:.944em;padding:.75em 0 .25em;content:"\220F"}.MJX-TEX mjx-c[c="2210"]:before{width:.944em;padding:.75em 0 .25em;content:"\2210"}.MJX-TEX mjx-c[c="2211"]:before{width:1.056em;padding:.75em 0 .25em;content:"\2211"}.MJX-TEX mjx-c[c="2212"]:before{width:.778em;padding:.583em 0 .082em;content:"\2212"}.MJX-TEX mjx-c[c="2213"]:before{width:.778em;padding:.5em 0 .166em;content:"\2213"}.MJX-TEX mjx-c[c="2214"]:before{width:.778em;padding:.766em 0 .093em;content:"\2214"}.MJX-TEX mjx-c[c="2215"]:before{width:.5em;padding:.75em 0 .25em;content:"\2215"}.MJX-TEX mjx-c[c="2216"]:before{width:.778em;padding:.43em 0 .023em;content:"\2216";font-family:MJXZERO,MJXTEX}.MJX-TEX mjx-c[c="2217"]:before{width:.5em;padding:.465em 0 0;content:"\2217"}.MJX-TEX mjx-c[c="2218"]:before{width:.5em;padding:.444em 0 0;content:"\2218"}.MJX-TEX mjx-c[c="2219"]:before{width:.5em;padding:.444em 0 0;content:"\2219"}.MJX-TEX mjx-c[c="221A"]:before{width:.833em;padding:.8em 0 .2em;content:"\221A"}.MJX-TEX mjx-c[c="221D"]:before{width:.778em;padding:.442em 0 .011em;content:"\221D"}.MJX-TEX mjx-c[c="221E"]:before{width:1em;padding:.442em 0 .011em;content:"\221E"}.MJX-TEX mjx-c[c="2220"]:before{width:.722em;padding:.694em 0 0;content:"\2220"}.MJX-TEX mjx-c[c="2221"]:before{width:.722em;padding:.714em 0 .02em;content:"\2221"}.MJX-TEX mjx-c[c="2222"]:before{width:.722em;padding:.551em 0 .051em;content:"\2222"}.MJX-TEX mjx-c[c="2223"]:before{width:.278em;padding:.75em 0 .249em;content:"\2223"}.MJX-TEX mjx-c[c="2224"]:before{width:.278em;padding:.75em 0 .252em;content:"\2224"}.MJX-TEX mjx-c[c="2225"]:before{width:.5em;padding:.75em 0 .25em;content:"\2225"}.MJX-TEX mjx-c[c="2226"]:before{width:.5em;padding:.75em 0 .25em;content:"\2226"}.MJX-TEX mjx-c[c="2227"]:before{width:.667em;padding:.598em 0 .022em;content:"\2227"}.MJX-TEX mjx-c[c="2228"]:before{width:.667em;padding:.598em 0 .022em;content:"\2228"}.MJX-TEX mjx-c[c="2229"]:before{width:.667em;padding:.598em 0 .022em;content:"\2229"}.MJX-TEX mjx-c[c="222A"]:before{width:.667em;padding:.598em 0 .022em;content:"\222A"}.MJX-TEX mjx-c[c="222B"]:before{width:.417em;padding:.716em 0 .216em;content:"\222B"}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="222B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="222B"]:last-child:before{width:.472em}.MJX-TEX mjx-c[c="222C"]:before{width:.819em;padding:.805em 0 .306em;content:"\222C"}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="222C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="222C"]:last-child:before{width:.957em}.MJX-TEX mjx-c[c="222D"]:before{width:1.166em;padding:.805em 0 .306em;content:"\222D"}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="222D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="222D"]:last-child:before{width:1.304em}.MJX-TEX mjx-c[c="222E"]:before{width:.472em;padding:.805em 0 .306em;content:"\222E"}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="222E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="222E"]:last-child:before{width:.61em}.MJX-TEX mjx-c[c="2234"]:before{width:.667em;padding:.471em 0 .082em;content:"\2234"}.MJX-TEX mjx-c[c="2235"]:before{width:.667em;padding:.471em 0 .082em;content:"\2235"}.MJX-TEX mjx-c[c="223C"]:before{width:.778em;padding:.367em 0 0;content:"\223C"}.MJX-TEX mjx-c[c="223D"]:before{width:.778em;padding:.367em 0 0;content:"\223D"}.MJX-TEX mjx-c[c="2240"]:before{width:.278em;padding:.583em 0 .083em;content:"\2240"}.MJX-TEX mjx-c[c="2241"]:before{width:.778em;padding:.467em 0 0;content:"\2241"}.MJX-TEX mjx-c[c="2242"]:before{width:.778em;padding:.463em 0 0;content:"\2242"}.MJX-TEX mjx-c[c="2243"]:before{width:.778em;padding:.464em 0 0;content:"\2243"}.MJX-TEX mjx-c[c="2244"]:before{width:.778em;padding:.716em 0 .215em;content:"\2243\338"}.MJX-TEX mjx-c[c="2245"]:before{width:.778em;padding:.589em 0 0;content:"\2245"}.MJX-TEX mjx-c[c="2246"]:before,.MJX-TEX mjx-c[c="2247"]:before{width:.778em;padding:.652em 0 .155em;content:"\2246"}.MJX-TEX mjx-c[c="2248"]:before{width:.778em;padding:.483em 0 0;content:"\2248"}.MJX-TEX mjx-c[c="2249"]:before{width:.778em;padding:.716em 0 .215em;content:"\2248\338"}.MJX-TEX mjx-c[c="224A"]:before{width:.778em;padding:.579em 0 .039em;content:"\224A"}.MJX-TEX mjx-c[c="224D"]:before{width:.778em;padding:.484em 0 0;content:"\224D"}.MJX-TEX mjx-c[c="224E"]:before{width:.778em;padding:.492em 0 0;content:"\224E"}.MJX-TEX mjx-c[c="224F"]:before{width:.778em;padding:.492em 0 0;content:"\224F"}.MJX-TEX mjx-c[c="2250"]:before{width:.778em;padding:.67em 0 0;content:"\2250"}.MJX-TEX mjx-c[c="2251"]:before{width:.778em;padding:.609em 0 .108em;content:"\2251"}.MJX-TEX mjx-c[c="2252"]:before{width:.778em;padding:.601em 0 .101em;content:"\2252"}.MJX-TEX mjx-c[c="2253"]:before{width:.778em;padding:.601em 0 .102em;content:"\2253"}.MJX-TEX mjx-c[c="2256"]:before{width:.778em;padding:.367em 0 0;content:"\2256"}.MJX-TEX mjx-c[c="2257"]:before{width:.778em;padding:.721em 0 0;content:"\2257"}.MJX-TEX mjx-c[c="225C"]:before{width:.778em;padding:.859em 0 0;content:"\225C"}.MJX-TEX mjx-c[c="2260"]:before{width:.778em;padding:.716em 0 .215em;content:"\2260"}.MJX-TEX mjx-c[c="2261"]:before{width:.778em;padding:.464em 0 0;content:"\2261"}.MJX-TEX mjx-c[c="2262"]:before{width:.778em;padding:.716em 0 .215em;content:"\2261\338"}.MJX-TEX mjx-c[c="2264"]:before{width:.778em;padding:.636em 0 .138em;content:"\2264"}.MJX-TEX mjx-c[c="2265"]:before{width:.778em;padding:.636em 0 .138em;content:"\2265"}.MJX-TEX mjx-c[c="2266"]:before{width:.778em;padding:.753em 0 .175em;content:"\2266"}.MJX-TEX mjx-c[c="2267"]:before{width:.778em;padding:.753em 0 .175em;content:"\2267"}.MJX-TEX mjx-c[c="2268"]:before{width:.778em;padding:.752em 0 .286em;content:"\2268"}.MJX-TEX mjx-c[c="2269"]:before{width:.778em;padding:.752em 0 .286em;content:"\2269"}.MJX-TEX mjx-c[c="226A"]:before{width:1em;padding:.568em 0 .067em;content:"\226A"}.MJX-TEX mjx-c[c="226B"]:before{width:1em;padding:.567em 0 .067em;content:"\226B"}.MJX-TEX mjx-c[c="226C"]:before{width:.5em;padding:.75em 0 .25em;content:"\226C"}.MJX-TEX mjx-c[c="226D"]:before{width:.778em;padding:.716em 0 .215em;content:"\224D\338"}.MJX-TEX mjx-c[c="226E"]:before{width:.778em;padding:.708em 0 .209em;content:"\226E"}.MJX-TEX mjx-c[c="226F"]:before{width:.778em;padding:.708em 0 .209em;content:"\226F"}.MJX-TEX mjx-c[c="2270"]:before{width:.778em;padding:.801em 0 .303em;content:"\2270"}.MJX-TEX mjx-c[c="2271"]:before{width:.778em;padding:.801em 0 .303em;content:"\2271"}.MJX-TEX mjx-c[c="2272"]:before{width:.778em;padding:.732em 0 .228em;content:"\2272"}.MJX-TEX mjx-c[c="2273"]:before{width:.778em;padding:.732em 0 .228em;content:"\2273"}.MJX-TEX mjx-c[c="2274"]:before{width:.778em;padding:.732em 0 .228em;content:"\2272\338"}.MJX-TEX mjx-c[c="2275"]:before{width:.778em;padding:.732em 0 .228em;content:"\2273\338"}.MJX-TEX mjx-c[c="2276"]:before{width:.778em;padding:.681em 0 .253em;content:"\2276"}.MJX-TEX mjx-c[c="2277"]:before{width:.778em;padding:.681em 0 .253em;content:"\2277"}.MJX-TEX mjx-c[c="2278"]:before{width:.778em;padding:.716em 0 .253em;content:"\2276\338"}.MJX-TEX mjx-c[c="2279"]:before{width:.778em;padding:.716em 0 .253em;content:"\2277\338"}.MJX-TEX mjx-c[c="227A"]:before{width:.778em;padding:.539em 0 .041em;content:"\227A"}.MJX-TEX mjx-c[c="227B"]:before{width:.778em;padding:.539em 0 .041em;content:"\227B"}.MJX-TEX mjx-c[c="227C"]:before{width:.778em;padding:.58em 0 .153em;content:"\227C"}.MJX-TEX mjx-c[c="227D"]:before{width:.778em;padding:.58em 0 .154em;content:"\227D"}.MJX-TEX mjx-c[c="227E"]:before{width:.778em;padding:.732em 0 .228em;content:"\227E"}.MJX-TEX mjx-c[c="227F"]:before{width:.778em;padding:.732em 0 .228em;content:"\227F"}.MJX-TEX mjx-c[c="2280"]:before{width:.778em;padding:.705em 0 .208em;content:"\2280"}.MJX-TEX mjx-c[c="2281"]:before{width:.778em;padding:.705em 0 .208em;content:"\2281"}.MJX-TEX mjx-c[c="2282"]:before{width:.778em;padding:.54em 0 .04em;content:"\2282"}.MJX-TEX mjx-c[c="2283"]:before{width:.778em;padding:.54em 0 .04em;content:"\2283"}.MJX-TEX mjx-c[c="2284"]:before{width:.778em;padding:.716em 0 .215em;content:"\2282\338"}.MJX-TEX mjx-c[c="2285"]:before{width:.778em;padding:.716em 0 .215em;content:"\2283\338"}.MJX-TEX mjx-c[c="2286"]:before{width:.778em;padding:.636em 0 .138em;content:"\2286"}.MJX-TEX mjx-c[c="2287"]:before{width:.778em;padding:.636em 0 .138em;content:"\2287"}.MJX-TEX mjx-c[c="2288"]:before{width:.778em;padding:.801em 0 .303em;content:"\2288"}.MJX-TEX mjx-c[c="2289"]:before{width:.778em;padding:.801em 0 .303em;content:"\2289"}.MJX-TEX mjx-c[c="228A"]:before{width:.778em;padding:.635em 0 .241em;content:"\228A"}.MJX-TEX mjx-c[c="228B"]:before{width:.778em;padding:.635em 0 .241em;content:"\228B"}.MJX-TEX mjx-c[c="228E"]:before{width:.667em;padding:.598em 0 .022em;content:"\228E"}.MJX-TEX mjx-c[c="228F"]:before{width:.778em;padding:.539em 0 .041em;content:"\228F"}.MJX-TEX mjx-c[c="2290"]:before{width:.778em;padding:.539em 0 .041em;content:"\2290"}.MJX-TEX mjx-c[c="2291"]:before{width:.778em;padding:.636em 0 .138em;content:"\2291"}.MJX-TEX mjx-c[c="2292"]:before{width:.778em;padding:.636em 0 .138em;content:"\2292"}.MJX-TEX mjx-c[c="2293"]:before{width:.667em;padding:.598em 0 0;content:"\2293"}.MJX-TEX mjx-c[c="2294"]:before{width:.667em;padding:.598em 0 0;content:"\2294"}.MJX-TEX mjx-c[c="2295"]:before{width:.778em;padding:.583em 0 .083em;content:"\2295"}.MJX-TEX mjx-c[c="2296"]:before{width:.778em;padding:.583em 0 .083em;content:"\2296"}.MJX-TEX mjx-c[c="2297"]:before{width:.778em;padding:.583em 0 .083em;content:"\2297"}.MJX-TEX mjx-c[c="2298"]:before{width:.778em;padding:.583em 0 .083em;content:"\2298"}.MJX-TEX mjx-c[c="2299"]:before{width:.778em;padding:.583em 0 .083em;content:"\2299"}.MJX-TEX mjx-c[c="229A"]:before{width:.778em;padding:.582em 0 .082em;content:"\229A"}.MJX-TEX mjx-c[c="229B"]:before{width:.778em;padding:.582em 0 .082em;content:"\229B"}.MJX-TEX mjx-c[c="229D"]:before{width:.778em;padding:.582em 0 .082em;content:"\229D"}.MJX-TEX mjx-c[c="229E"]:before{width:.778em;padding:.689em 0 0;content:"\229E"}.MJX-TEX mjx-c[c="229F"]:before{width:.778em;padding:.689em 0 0;content:"\229F"}.MJX-TEX mjx-c[c="22A0"]:before{width:.778em;padding:.689em 0 0;content:"\22A0"}.MJX-TEX mjx-c[c="22A1"]:before{width:.778em;padding:.689em 0 0;content:"\22A1"}.MJX-TEX mjx-c[c="22A2"]:before{width:.611em;padding:.694em 0 0;content:"\22A2"}.MJX-TEX mjx-c[c="22A3"]:before{width:.611em;padding:.694em 0 0;content:"\22A3"}.MJX-TEX mjx-c[c="22A4"]:before{width:.778em;padding:.668em 0 0;content:"\22A4"}.MJX-TEX mjx-c[c="22A5"]:before{width:.778em;padding:.668em 0 0;content:"\22A5"}.MJX-TEX mjx-c[c="22A8"]:before{width:.867em;padding:.75em 0 .249em;content:"\22A8"}.MJX-TEX mjx-c[c="22A9"]:before{width:.722em;padding:.694em 0 0;content:"\22A9"}.MJX-TEX mjx-c[c="22AA"]:before{width:.889em;padding:.694em 0 0;content:"\22AA"}.MJX-TEX mjx-c[c="22AC"]:before{width:.611em;padding:.695em 0 0;content:"\22AC"}.MJX-TEX mjx-c[c="22AD"]:before{width:.611em;padding:.695em 0 0;content:"\22AD"}.MJX-TEX mjx-c[c="22AE"]:before{width:.722em;padding:.695em 0 0;content:"\22AE"}.MJX-TEX mjx-c[c="22AF"]:before{width:.722em;padding:.695em 0 0;content:"\22AF"}.MJX-TEX mjx-c[c="22B2"]:before{width:.778em;padding:.539em 0 .041em;content:"\22B2"}.MJX-TEX mjx-c[c="22B3"]:before{width:.778em;padding:.539em 0 .041em;content:"\22B3"}.MJX-TEX mjx-c[c="22B4"]:before{width:.778em;padding:.636em 0 .138em;content:"\22B4"}.MJX-TEX mjx-c[c="22B5"]:before{width:.778em;padding:.636em 0 .138em;content:"\22B5"}.MJX-TEX mjx-c[c="22B8"]:before{width:1.111em;padding:.408em 0 0;content:"\22B8"}.MJX-TEX mjx-c[c="22BA"]:before{width:.556em;padding:.431em 0 .212em;content:"\22BA"}.MJX-TEX mjx-c[c="22BB"]:before{width:.611em;padding:.716em 0 0;content:"\22BB"}.MJX-TEX mjx-c[c="22BC"]:before{width:.611em;padding:.716em 0 0;content:"\22BC"}.MJX-TEX mjx-c[c="22C0"]:before{width:.833em;padding:.75em 0 .249em;content:"\22C0"}.MJX-TEX mjx-c[c="22C1"]:before{width:.833em;padding:.75em 0 .249em;content:"\22C1"}.MJX-TEX mjx-c[c="22C2"]:before{width:.833em;padding:.75em 0 .249em;content:"\22C2"}.MJX-TEX mjx-c[c="22C3"]:before{width:.833em;padding:.75em 0 .249em;content:"\22C3"}.MJX-TEX mjx-c[c="22C4"]:before{width:.5em;padding:.488em 0 0;content:"\22C4"}.MJX-TEX mjx-c[c="22C5"]:before{width:.278em;padding:.31em 0 0;content:"\22C5"}.MJX-TEX mjx-c[c="22C6"]:before{width:.5em;padding:.486em 0 0;content:"\22C6"}.MJX-TEX mjx-c[c="22C7"]:before{width:.778em;padding:.545em 0 .044em;content:"\22C7"}.MJX-TEX mjx-c[c="22C8"]:before{width:.9em;padding:.505em 0 .005em;content:"\22C8"}.MJX-TEX mjx-c[c="22C9"]:before{width:.778em;padding:.492em 0 0;content:"\22C9"}.MJX-TEX mjx-c[c="22CA"]:before{width:.778em;padding:.492em 0 0;content:"\22CA"}.MJX-TEX mjx-c[c="22CB"]:before{width:.778em;padding:.694em 0 .022em;content:"\22CB"}.MJX-TEX mjx-c[c="22CC"]:before{width:.778em;padding:.694em 0 .022em;content:"\22CC"}.MJX-TEX mjx-c[c="22CD"]:before{width:.778em;padding:.464em 0 0;content:"\22CD"}.MJX-TEX mjx-c[c="22CE"]:before{width:.76em;padding:.578em 0 .021em;content:"\22CE"}.MJX-TEX mjx-c[c="22CF"]:before{width:.76em;padding:.578em 0 .022em;content:"\22CF"}.MJX-TEX mjx-c[c="22D0"]:before{width:.778em;padding:.54em 0 .04em;content:"\22D0"}.MJX-TEX mjx-c[c="22D1"]:before{width:.778em;padding:.54em 0 .04em;content:"\22D1"}.MJX-TEX mjx-c[c="22D2"]:before{width:.667em;padding:.598em 0 .022em;content:"\22D2"}.MJX-TEX mjx-c[c="22D3"]:before{width:.667em;padding:.598em 0 .022em;content:"\22D3"}.MJX-TEX mjx-c[c="22D4"]:before{width:.667em;padding:.736em 0 .022em;content:"\22D4"}.MJX-TEX mjx-c[c="22D6"]:before{width:.778em;padding:.541em 0 .041em;content:"\22D6"}.MJX-TEX mjx-c[c="22D7"]:before{width:.778em;padding:.541em 0 .041em;content:"\22D7"}.MJX-TEX mjx-c[c="22D8"]:before{width:1.333em;padding:.568em 0 .067em;content:"\22D8"}.MJX-TEX mjx-c[c="22D9"]:before{width:1.333em;padding:.568em 0 .067em;content:"\22D9"}.MJX-TEX mjx-c[c="22DA"]:before{width:.778em;padding:.886em 0 .386em;content:"\22DA"}.MJX-TEX mjx-c[c="22DB"]:before{width:.778em;padding:.886em 0 .386em;content:"\22DB"}.MJX-TEX mjx-c[c="22DE"]:before{width:.778em;padding:.734em 0 0;content:"\22DE"}.MJX-TEX mjx-c[c="22DF"]:before{width:.778em;padding:.734em 0 0;content:"\22DF"}.MJX-TEX mjx-c[c="22E0"]:before{width:.778em;padding:.801em 0 .303em;content:"\22E0"}.MJX-TEX mjx-c[c="22E1"]:before{width:.778em;padding:.801em 0 .303em;content:"\22E1"}.MJX-TEX mjx-c[c="22E2"]:before{width:.778em;padding:.716em 0 .215em;content:"\2291\338"}.MJX-TEX mjx-c[c="22E3"]:before{width:.778em;padding:.716em 0 .215em;content:"\2292\338"}.MJX-TEX mjx-c[c="22E6"]:before{width:.778em;padding:.73em 0 .359em;content:"\22E6"}.MJX-TEX mjx-c[c="22E7"]:before{width:.778em;padding:.73em 0 .359em;content:"\22E7"}.MJX-TEX mjx-c[c="22E8"]:before{width:.778em;padding:.73em 0 .359em;content:"\22E8"}.MJX-TEX mjx-c[c="22E9"]:before{width:.778em;padding:.73em 0 .359em;content:"\22E9"}.MJX-TEX mjx-c[c="22EA"]:before{width:.778em;padding:.706em 0 .208em;content:"\22EA"}.MJX-TEX mjx-c[c="22EB"]:before{width:.778em;padding:.706em 0 .208em;content:"\22EB"}.MJX-TEX mjx-c[c="22EC"]:before{width:.778em;padding:.802em 0 .303em;content:"\22EC"}.MJX-TEX mjx-c[c="22ED"]:before{width:.778em;padding:.801em 0 .303em;content:"\22ED"}.MJX-TEX mjx-c[c="22EE"]:before{width:.278em;padding:1.3em 0 .03em;content:"\22EE"}.MJX-TEX mjx-c[c="22EF"]:before{width:1.172em;padding:.31em 0 0;content:"\22EF"}.MJX-TEX mjx-c[c="22F1"]:before{width:1.282em;padding:1.52em 0 0;content:"\22F1"}.MJX-TEX mjx-c[c="2305"]:before{width:.611em;padding:.716em 0 0;content:"\22BC"}.MJX-TEX mjx-c[c="2306"]:before{width:.611em;padding:.813em 0 .097em;content:"\2A5E"}.MJX-TEX mjx-c[c="2308"]:before{width:.444em;padding:.75em 0 .25em;content:"\2308"}.MJX-TEX mjx-c[c="2309"]:before{width:.444em;padding:.75em 0 .25em;content:"\2309"}.MJX-TEX mjx-c[c="230A"]:before{width:.444em;padding:.75em 0 .25em;content:"\230A"}.MJX-TEX mjx-c[c="230B"]:before{width:.444em;padding:.75em 0 .25em;content:"\230B"}.MJX-TEX mjx-c[c="231C"]:before{width:.5em;padding:.694em 0 0;content:"\250C"}.MJX-TEX mjx-c[c="231D"]:before{width:.5em;padding:.694em 0 0;content:"\2510"}.MJX-TEX mjx-c[c="231E"]:before{width:.5em;padding:.366em 0 .022em;content:"\2514"}.MJX-TEX mjx-c[c="231F"]:before{width:.5em;padding:.366em 0 .022em;content:"\2518"}.MJX-TEX mjx-c[c="2322"]:before{width:1em;padding:.388em 0 0;content:"\2322"}.MJX-TEX mjx-c[c="2323"]:before{width:1em;padding:.378em 0 0;content:"\2323"}.MJX-TEX mjx-c[c="2329"]:before{width:.389em;padding:.75em 0 .25em;content:"\27E8"}.MJX-TEX mjx-c[c="232A"]:before{width:.389em;padding:.75em 0 .25em;content:"\27E9"}.MJX-TEX mjx-c[c="23B0"]:before{width:.412em;padding:.744em 0 .244em;content:"\23B0"}.MJX-TEX mjx-c[c="23B1"]:before{width:.412em;padding:.744em 0 .244em;content:"\23B1"}.MJX-TEX mjx-c[c="23D0"]:before{width:.667em;padding:.602em 0 0;content:"\23D0"}.MJX-TEX mjx-c[c="24C8"]:before{width:.902em;padding:.709em 0 .175em;content:"\24C8"}.MJX-TEX mjx-c[c="250C"]:before{width:.5em;padding:.694em 0 0;content:"\250C"}.MJX-TEX mjx-c[c="2510"]:before{width:.5em;padding:.694em 0 0;content:"\2510"}.MJX-TEX mjx-c[c="2514"]:before{width:.5em;padding:.366em 0 .022em;content:"\2514"}.MJX-TEX mjx-c[c="2518"]:before{width:.5em;padding:.366em 0 .022em;content:"\2518"}.MJX-TEX mjx-c[c="2571"]:before{width:.889em;padding:.694em 0 .195em;content:"\2571"}.MJX-TEX mjx-c[c="2572"]:before{width:.889em;padding:.694em 0 .195em;content:"\2572"}.MJX-TEX mjx-c[c="25A0"]:before{width:.778em;padding:.689em 0 0;content:"\25A0"}.MJX-TEX mjx-c[c="25A1"]:before{width:.778em;padding:.689em 0 0;content:"\25A1"}.MJX-TEX mjx-c[c="25AA"]:before{width:.778em;padding:.689em 0 0;content:"\25A0"}.MJX-TEX mjx-c[c="25B2"]:before{width:.722em;padding:.575em 0 .02em;content:"\25B2"}.MJX-TEX mjx-c[c="25B3"]:before{width:.889em;padding:.716em 0 0;content:"\25B3"}.MJX-TEX mjx-c[c="25B4"]:before{width:.722em;padding:.575em 0 .02em;content:"\25B2"}.MJX-TEX mjx-c[c="25B5"]:before{width:.889em;padding:.716em 0 0;content:"\25B3"}.MJX-TEX mjx-c[c="25B6"]:before,.MJX-TEX mjx-c[c="25B8"]:before{width:.778em;padding:.539em 0 .041em;content:"\25B6"}.MJX-TEX mjx-c[c="25B9"]:before{width:.5em;padding:.505em 0 .005em;content:"\25B9"}.MJX-TEX mjx-c[c="25BC"]:before{width:.722em;padding:.576em 0 .019em;content:"\25BC"}.MJX-TEX mjx-c[c="25BD"]:before{width:.889em;padding:.5em 0 .215em;content:"\25BD"}.MJX-TEX mjx-c[c="25BE"]:before{width:.722em;padding:.576em 0 .019em;content:"\25BC"}.MJX-TEX mjx-c[c="25BF"]:before{width:.889em;padding:.5em 0 .215em;content:"\25BD"}.MJX-TEX mjx-c[c="25C0"]:before,.MJX-TEX mjx-c[c="25C2"]:before{width:.778em;padding:.539em 0 .041em;content:"\25C0"}.MJX-TEX mjx-c[c="25C3"]:before{width:.5em;padding:.505em 0 .005em;content:"\25C3"}.MJX-TEX mjx-c[c="25CA"]:before{width:.667em;padding:.716em 0 .132em;content:"\25CA"}.MJX-TEX mjx-c[c="25EF"]:before{width:1em;padding:.715em 0 .215em;content:"\25EF"}.MJX-TEX mjx-c[c="25FB"]:before{width:.778em;padding:.689em 0 0;content:"\25A1"}.MJX-TEX mjx-c[c="25FC"]:before{width:.778em;padding:.689em 0 0;content:"\25A0"}.MJX-TEX mjx-c[c="2605"]:before{width:.944em;padding:.694em 0 .111em;content:"\2605"}.MJX-TEX mjx-c[c="2660"]:before{width:.778em;padding:.727em 0 .13em;content:"\2660"}.MJX-TEX mjx-c[c="2661"]:before{width:.778em;padding:.716em 0 .033em;content:"\2661"}.MJX-TEX mjx-c[c="2662"]:before{width:.778em;padding:.727em 0 .162em;content:"\2662"}.MJX-TEX mjx-c[c="2663"]:before{width:.778em;padding:.726em 0 .13em;content:"\2663"}.MJX-TEX mjx-c[c="266D"]:before{width:.389em;padding:.75em 0 .022em;content:"\266D"}.MJX-TEX mjx-c[c="266E"]:before{width:.389em;padding:.734em 0 .223em;content:"\266E"}.MJX-TEX mjx-c[c="266F"]:before{width:.389em;padding:.723em 0 .223em;content:"\266F"}.MJX-TEX mjx-c[c="2713"]:before{width:.833em;padding:.706em 0 .034em;content:"\2713"}.MJX-TEX mjx-c[c="2720"]:before{width:.833em;padding:.716em 0 .022em;content:"\2720"}.MJX-TEX mjx-c[c="2758"]:before{width:.278em;padding:.75em 0 .249em;content:"\2223"}.MJX-TEX mjx-c[c="27E8"]:before{width:.389em;padding:.75em 0 .25em;content:"\27E8"}.MJX-TEX mjx-c[c="27E9"]:before{width:.389em;padding:.75em 0 .25em;content:"\27E9"}.MJX-TEX mjx-c[c="27EE"]:before{width:.412em;padding:.744em 0 .244em;content:"\27EE"}.MJX-TEX mjx-c[c="27EF"]:before{width:.412em;padding:.744em 0 .244em;content:"\27EF"}.MJX-TEX mjx-c[c="27F5"]:before{width:1.609em;padding:.511em 0 .011em;content:"\27F5"}.MJX-TEX mjx-c[c="27F6"]:before{width:1.638em;padding:.511em 0 .011em;content:"\27F6"}.MJX-TEX mjx-c[c="27F7"]:before{width:1.859em;padding:.511em 0 .011em;content:"\27F7"}.MJX-TEX mjx-c[c="27F8"]:before{width:1.609em;padding:.525em 0 .024em;content:"\27F8"}.MJX-TEX mjx-c[c="27F9"]:before{width:1.638em;padding:.525em 0 .024em;content:"\27F9"}.MJX-TEX mjx-c[c="27FA"]:before{width:1.858em;padding:.525em 0 .024em;content:"\27FA"}.MJX-TEX mjx-c[c="27FC"]:before{width:1.638em;padding:.511em 0 .011em;content:"\27FC"}.MJX-TEX mjx-c[c="29EB"]:before{width:.667em;padding:.716em 0 .132em;content:"\29EB"}.MJX-TEX mjx-c[c="29F8"]:before{width:.778em;padding:.716em 0 .215em;content:"/";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="2A00"]:before{width:1.111em;padding:.75em 0 .25em;content:"\2A00"}.MJX-TEX mjx-c[c="2A01"]:before{width:1.111em;padding:.75em 0 .25em;content:"\2A01"}.MJX-TEX mjx-c[c="2A02"]:before{width:1.111em;padding:.75em 0 .25em;content:"\2A02"}.MJX-TEX mjx-c[c="2A04"]:before{width:.833em;padding:.75em 0 .249em;content:"\2A04"}.MJX-TEX mjx-c[c="2A06"]:before{width:.833em;padding:.75em 0 .249em;content:"\2A06"}.MJX-TEX mjx-c[c="2A0C"]:before{width:1.638em;padding:.805em 0 .306em;content:"\222C\222C"}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="2A0C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="2A0C"]:last-child:before{width:1.776em}.MJX-TEX mjx-c[c="2A2F"]:before{width:.778em;padding:.491em 0 0;content:"\D7"}.MJX-TEX mjx-c[c="2A3F"]:before{width:.75em;padding:.683em 0 0;content:"\2A3F"}.MJX-TEX mjx-c[c="2A5E"]:before{width:.611em;padding:.813em 0 .097em;content:"\2A5E"}.MJX-TEX mjx-c[c="2A7D"]:before{width:.778em;padding:.636em 0 .138em;content:"\2A7D"}.MJX-TEX mjx-c[c="2A7E"]:before{width:.778em;padding:.636em 0 .138em;content:"\2A7E"}.MJX-TEX mjx-c[c="2A85"]:before{width:.778em;padding:.762em 0 .29em;content:"\2A85"}.MJX-TEX mjx-c[c="2A86"]:before{width:.778em;padding:.762em 0 .29em;content:"\2A86"}.MJX-TEX mjx-c[c="2A87"]:before{width:.778em;padding:.635em 0 .241em;content:"\2A87"}.MJX-TEX mjx-c[c="2A88"]:before{width:.778em;padding:.635em 0 .241em;content:"\2A88"}.MJX-TEX mjx-c[c="2A89"]:before{width:.778em;padding:.761em 0 .387em;content:"\2A89"}.MJX-TEX mjx-c[c="2A8A"]:before{width:.778em;padding:.761em 0 .387em;content:"\2A8A"}.MJX-TEX mjx-c[c="2A8B"]:before{width:.778em;padding:1.003em 0 .463em;content:"\2A8B"}.MJX-TEX mjx-c[c="2A8C"]:before{width:.778em;padding:1.003em 0 .463em;content:"\2A8C"}.MJX-TEX mjx-c[c="2A95"]:before{width:.778em;padding:.636em 0 .138em;content:"\2A95"}.MJX-TEX mjx-c[c="2A96"]:before{width:.778em;padding:.636em 0 .138em;content:"\2A96"}.MJX-TEX mjx-c[c="2AAF"]:before{width:.778em;padding:.636em 0 .138em;content:"\2AAF"}.MJX-TEX mjx-c[c="2AB0"]:before{width:.778em;padding:.636em 0 .138em;content:"\2AB0"}.MJX-TEX mjx-c[c="2AB5"]:before{width:.778em;padding:.752em 0 .286em;content:"\2AB5"}.MJX-TEX mjx-c[c="2AB6"]:before{width:.778em;padding:.752em 0 .286em;content:"\2AB6"}.MJX-TEX mjx-c[c="2AB7"]:before{width:.778em;padding:.761em 0 .294em;content:"\2AB7"}.MJX-TEX mjx-c[c="2AB8"]:before{width:.778em;padding:.761em 0 .294em;content:"\2AB8"}.MJX-TEX mjx-c[c="2AB9"]:before{width:.778em;padding:.761em 0 .337em;content:"\2AB9"}.MJX-TEX mjx-c[c="2ABA"]:before{width:.778em;padding:.761em 0 .337em;content:"\2ABA"}.MJX-TEX mjx-c[c="2AC5"]:before{width:.778em;padding:.753em 0 .215em;content:"\2AC5"}.MJX-TEX mjx-c[c="2AC6"]:before{width:.778em;padding:.753em 0 .215em;content:"\2AC6"}.MJX-TEX mjx-c[c="2ACB"]:before{width:.778em;padding:.783em 0 .385em;content:"\2ACB"}.MJX-TEX mjx-c[c="2ACC"]:before{width:.778em;padding:.783em 0 .385em;content:"\2ACC"}.MJX-TEX mjx-c[c="3008"]:before{width:.389em;padding:.75em 0 .25em;content:"\27E8"}.MJX-TEX mjx-c[c="3009"]:before{width:.389em;padding:.75em 0 .25em;content:"\27E9"}.MJX-TEX mjx-c[c=E006]:before{width:.222em;padding:.43em 0 .023em;content:"\E006"}.MJX-TEX mjx-c[c=E007]:before{width:.389em;padding:.431em 0 .024em;content:"\E007"}.MJX-TEX mjx-c[c=E008]:before{width:.778em;padding:.605em 0 .085em;content:"\E008"}.MJX-TEX mjx-c[c=E009]:before{width:.667em;padding:.434em 0 .006em;content:"\E009"}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c=E009]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c=E009]:last-child:before{width:.734em}.MJX-TEX mjx-c[c=E00C]:before{width:.778em;padding:.752em 0 .284em;content:"\E00C"}.MJX-TEX mjx-c[c=E00D]:before{width:.778em;padding:.752em 0 .284em;content:"\E00D"}.MJX-TEX mjx-c[c=E00E]:before{width:.778em;padding:.919em 0 .421em;content:"\E00E"}.MJX-TEX mjx-c[c=E00F]:before{width:.778em;padding:.801em 0 .303em;content:"\E00F"}.MJX-TEX mjx-c[c=E010]:before{width:.778em;padding:.801em 0 .303em;content:"\E010"}.MJX-TEX mjx-c[c=E011]:before{width:.778em;padding:.919em 0 .421em;content:"\E011"}.MJX-TEX mjx-c[c=E016]:before{width:.778em;padding:.828em 0 .33em;content:"\E016"}.MJX-TEX mjx-c[c=E017]:before{width:.778em;padding:.752em 0 .332em;content:"\E017"}.MJX-TEX mjx-c[c=E018]:before{width:.778em;padding:.828em 0 .33em;content:"\E018"}.MJX-TEX mjx-c[c=E019]:before{width:.778em;padding:.752em 0 .333em;content:"\E019"}.MJX-TEX mjx-c[c=E01A]:before{width:.778em;padding:.634em 0 .255em;content:"\E01A"}.MJX-TEX mjx-c[c=E01B]:before{width:.778em;padding:.634em 0 .254em;content:"\E01B"}.MJX-TEX mjx-c[c="1D400"]:before{width:.869em;padding:.698em 0 0;content:"A";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D401"]:before{width:.818em;padding:.686em 0 0;content:"B";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D402"]:before{width:.831em;padding:.697em 0 .011em;content:"C";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D403"]:before{width:.882em;padding:.686em 0 0;content:"D";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D404"]:before{width:.756em;padding:.68em 0 0;content:"E";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D405"]:before{width:.724em;padding:.68em 0 0;content:"F";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D406"]:before{width:.904em;padding:.697em 0 .01em;content:"G";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D407"]:before{width:.9em;padding:.686em 0 0;content:"H";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D408"]:before{width:.436em;padding:.686em 0 0;content:"I";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D409"]:before{width:.594em;padding:.686em 0 .011em;content:"J";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D40A"]:before{width:.901em;padding:.686em 0 0;content:"K";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D40B"]:before{width:.692em;padding:.686em 0 0;content:"L";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D40C"]:before{width:1.092em;padding:.686em 0 0;content:"M";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D40D"]:before{width:.9em;padding:.686em 0 0;content:"N";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D40E"]:before{width:.864em;padding:.696em 0 .01em;content:"O";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D40F"]:before{width:.786em;padding:.686em 0 0;content:"P";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D410"]:before{width:.864em;padding:.696em 0 .193em;content:"Q";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D411"]:before{width:.862em;padding:.686em 0 .011em;content:"R";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D412"]:before{width:.639em;padding:.697em 0 .011em;content:"S";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D413"]:before{width:.8em;padding:.675em 0 0;content:"T";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D414"]:before{width:.885em;padding:.686em 0 .011em;content:"U";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D415"]:before{width:.869em;padding:.686em 0 .007em;content:"V";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D416"]:before{width:1.189em;padding:.686em 0 .007em;content:"W";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D417"]:before{width:.869em;padding:.686em 0 0;content:"X";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D418"]:before{width:.869em;padding:.686em 0 0;content:"Y";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D419"]:before{width:.703em;padding:.686em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D41A"]:before{width:.559em;padding:.453em 0 .006em;content:"a";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D41B"]:before{width:.639em;padding:.694em 0 .006em;content:"b";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D41C"]:before{width:.511em;padding:.453em 0 .006em;content:"c";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D41D"]:before{width:.639em;padding:.694em 0 .006em;content:"d";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D41E"]:before{width:.527em;padding:.452em 0 .006em;content:"e";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D41F"]:before{width:.351em;padding:.7em 0 0;content:"f";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D41F"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D41F"]:last-child:before{width:.452em}.MJX-TEX mjx-c[c="1D420"]:before{width:.575em;padding:.455em 0 .201em;content:"g";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D421"]:before{width:.639em;padding:.694em 0 0;content:"h";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D422"]:before{width:.319em;padding:.695em 0 0;content:"i";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D423"]:before{width:.351em;padding:.695em 0 .2em;content:"j";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D424"]:before{width:.607em;padding:.694em 0 0;content:"k";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D425"]:before{width:.319em;padding:.694em 0 0;content:"l";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D426"]:before{width:.958em;padding:.45em 0 0;content:"m";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D427"]:before{width:.639em;padding:.45em 0 0;content:"n";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D428"]:before{width:.575em;padding:.452em 0 .005em;content:"o";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D429"]:before{width:.639em;padding:.45em 0 .194em;content:"p";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D42A"]:before{width:.607em;padding:.45em 0 .194em;content:"q";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D42B"]:before{width:.474em;padding:.45em 0 0;content:"r";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D42C"]:before{width:.454em;padding:.453em 0 .006em;content:"s";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D42D"]:before{width:.447em;padding:.635em 0 .005em;content:"t";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D42E"]:before{width:.639em;padding:.45em 0 .006em;content:"u";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D42F"]:before{width:.607em;padding:.444em 0 0;content:"v";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D430"]:before{width:.831em;padding:.444em 0 0;content:"w";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D431"]:before{width:.607em;padding:.444em 0 0;content:"x";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D432"]:before{width:.607em;padding:.444em 0 .2em;content:"y";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D433"]:before{width:.511em;padding:.444em 0 0;content:"z";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D434"]:before{width:.75em;padding:.716em 0 0;content:"A";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D435"]:before{width:.759em;padding:.683em 0 0;content:"B";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D436"]:before{width:.715em;padding:.705em 0 .022em;content:"C";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D437"]:before{width:.828em;padding:.683em 0 0;content:"D";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D438"]:before{width:.738em;padding:.68em 0 0;content:"E";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D439"]:before{width:.643em;padding:.68em 0 0;content:"F";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D439"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D439"]:last-child:before{width:.749em}.MJX-TEX mjx-c[c="1D43A"]:before{width:.786em;padding:.705em 0 .022em;content:"G";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D43B"]:before{width:.831em;padding:.683em 0 0;content:"H";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D43B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D43B"]:last-child:before{width:.888em}.MJX-TEX mjx-c[c="1D43C"]:before{width:.44em;padding:.683em 0 0;content:"I";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D43C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D43C"]:last-child:before{width:.504em}.MJX-TEX mjx-c[c="1D43D"]:before{width:.555em;padding:.683em 0 .022em;content:"J";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D43D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D43D"]:last-child:before{width:.633em}.MJX-TEX mjx-c[c="1D43E"]:before{width:.849em;padding:.683em 0 0;content:"K";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D43F"]:before{width:.681em;padding:.683em 0 0;content:"L";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D440"]:before{width:.97em;padding:.683em 0 0;content:"M";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D440"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D440"]:last-child:before{width:1.051em}.MJX-TEX mjx-c[c="1D441"]:before{width:.803em;padding:.683em 0 0;content:"N";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D441"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D441"]:last-child:before{width:.888em}.MJX-TEX mjx-c[c="1D442"]:before{width:.763em;padding:.704em 0 .022em;content:"O";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D443"]:before{width:.642em;padding:.683em 0 0;content:"P";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D443"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D443"]:last-child:before{width:.751em}.MJX-TEX mjx-c[c="1D444"]:before{width:.791em;padding:.704em 0 .194em;content:"Q";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D445"]:before{width:.759em;padding:.683em 0 .021em;content:"R";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D446"]:before{width:.613em;padding:.705em 0 .022em;content:"S";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D447"]:before{width:.584em;padding:.677em 0 0;content:"T";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D447"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D447"]:last-child:before{width:.704em}.MJX-TEX mjx-c[c="1D448"]:before{width:.683em;padding:.683em 0 .022em;content:"U";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D448"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D448"]:last-child:before{width:.767em}.MJX-TEX mjx-c[c="1D449"]:before{width:.583em;padding:.683em 0 .022em;content:"V";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D449"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D449"]:last-child:before{width:.769em}.MJX-TEX mjx-c[c="1D44A"]:before{width:.944em;padding:.683em 0 .022em;content:"W";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D44A"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D44A"]:last-child:before{width:1.048em}.MJX-TEX mjx-c[c="1D44B"]:before{width:.828em;padding:.683em 0 0;content:"X";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D44C"]:before{width:.581em;padding:.683em 0 0;content:"Y";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D44C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D44C"]:last-child:before{width:.763em}.MJX-TEX mjx-c[c="1D44D"]:before{width:.683em;padding:.683em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D44E"]:before{width:.529em;padding:.441em 0 .01em;content:"a";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D44F"]:before{width:.429em;padding:.694em 0 .011em;content:"b";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D450"]:before{width:.433em;padding:.442em 0 .011em;content:"c";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D451"]:before{width:.52em;padding:.694em 0 .01em;content:"d";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D452"]:before{width:.466em;padding:.442em 0 .011em;content:"e";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D453"]:before{width:.49em;padding:.705em 0 .205em;content:"f";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D453"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D453"]:last-child:before{width:.55em}.MJX-TEX mjx-c[c="1D454"]:before{width:.477em;padding:.442em 0 .205em;content:"g";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D455"]:before{width:.576em;padding:.694em 0 .011em;content:"h";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D456"]:before{width:.345em;padding:.661em 0 .011em;content:"i";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D457"]:before{width:.412em;padding:.661em 0 .204em;content:"j";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D458"]:before{width:.521em;padding:.694em 0 .011em;content:"k";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D459"]:before{width:.298em;padding:.694em 0 .011em;content:"l";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D45A"]:before{width:.878em;padding:.442em 0 .011em;content:"m";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D45B"]:before{width:.6em;padding:.442em 0 .011em;content:"n";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D45C"]:before{width:.485em;padding:.441em 0 .011em;content:"o";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D45D"]:before{width:.503em;padding:.442em 0 .194em;content:"p";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D45E"]:before{width:.446em;padding:.442em 0 .194em;content:"q";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D45F"]:before{width:.451em;padding:.442em 0 .011em;content:"r";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D460"]:before{width:.469em;padding:.442em 0 .01em;content:"s";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D461"]:before{width:.361em;padding:.626em 0 .011em;content:"t";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D462"]:before{width:.572em;padding:.442em 0 .011em;content:"u";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D463"]:before{width:.485em;padding:.443em 0 .011em;content:"v";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D464"]:before{width:.716em;padding:.443em 0 .011em;content:"w";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D465"]:before{width:.572em;padding:.442em 0 .011em;content:"x";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D466"]:before{width:.49em;padding:.442em 0 .205em;content:"y";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D467"]:before{width:.465em;padding:.442em 0 .011em;content:"z";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D468"]:before{width:.869em;padding:.711em 0 0;content:"A";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D469"]:before{width:.866em;padding:.686em 0 0;content:"B";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D46A"]:before{width:.817em;padding:.703em 0 .017em;content:"C";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D46B"]:before{width:.938em;padding:.686em 0 0;content:"D";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D46C"]:before{width:.81em;padding:.68em 0 0;content:"E";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D46D"]:before{width:.689em;padding:.68em 0 0;content:"F";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D46D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D46D"]:last-child:before{width:.809em}.MJX-TEX mjx-c[c="1D46E"]:before{width:.887em;padding:.703em 0 .016em;content:"G";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D46F"]:before{width:.982em;padding:.686em 0 0;content:"H";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D470"]:before{width:.511em;padding:.686em 0 0;content:"I";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D470"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D470"]:last-child:before{width:.573em}.MJX-TEX mjx-c[c="1D471"]:before{width:.631em;padding:.686em 0 .017em;content:"J";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D471"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D471"]:last-child:before{width:.694em}.MJX-TEX mjx-c[c="1D472"]:before{width:.971em;padding:.686em 0 0;content:"K";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D473"]:before{width:.756em;padding:.686em 0 0;content:"L";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D474"]:before{width:1.142em;padding:.686em 0 0;content:"M";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D474"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D474"]:last-child:before{width:1.219em}.MJX-TEX mjx-c[c="1D475"]:before{width:.95em;padding:.686em 0 0;content:"N";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D475"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D475"]:last-child:before{width:1.027em}.MJX-TEX mjx-c[c="1D476"]:before{width:.837em;padding:.703em 0 .017em;content:"O";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D477"]:before{width:.723em;padding:.686em 0 0;content:"P";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D477"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D477"]:last-child:before{width:.847em}.MJX-TEX mjx-c[c="1D478"]:before{width:.869em;padding:.703em 0 .194em;content:"Q";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D479"]:before{width:.872em;padding:.686em 0 .017em;content:"R";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D47A"]:before{width:.693em;padding:.703em 0 .017em;content:"S";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D47B"]:before{width:.637em;padding:.675em 0 0;content:"T";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D47B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D47B"]:last-child:before{width:.772em}.MJX-TEX mjx-c[c="1D47C"]:before{width:.8em;padding:.686em 0 .016em;content:"U";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D47C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D47C"]:last-child:before{width:.877em}.MJX-TEX mjx-c[c="1D47D"]:before{width:.678em;padding:.686em 0 .016em;content:"V";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D47D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D47D"]:last-child:before{width:.886em}.MJX-TEX mjx-c[c="1D47E"]:before{width:1.093em;padding:.686em 0 .017em;content:"W";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D47E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D47E"]:last-child:before{width:1.207em}.MJX-TEX mjx-c[c="1D47F"]:before{width:.947em;padding:.686em 0 0;content:"X";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D480"]:before{width:.675em;padding:.686em 0 0;content:"Y";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D480"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D480"]:last-child:before{width:.876em}.MJX-TEX mjx-c[c="1D481"]:before{width:.773em;padding:.686em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D482"]:before{width:.633em;padding:.452em 0 .008em;content:"a";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D483"]:before{width:.521em;padding:.694em 0 .008em;content:"b";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D484"]:before{width:.513em;padding:.451em 0 .008em;content:"c";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D485"]:before{width:.61em;padding:.694em 0 .008em;content:"d";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D486"]:before{width:.554em;padding:.452em 0 .008em;content:"e";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D487"]:before{width:.568em;padding:.701em 0 .201em;content:"f";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D487"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D487"]:last-child:before{width:.624em}.MJX-TEX mjx-c[c="1D488"]:before{width:.545em;padding:.452em 0 .202em;content:"g";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D489"]:before{width:.668em;padding:.694em 0 .008em;content:"h";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D48A"]:before{width:.405em;padding:.694em 0 .008em;content:"i";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D48B"]:before{width:.471em;padding:.694em 0 .202em;content:"j";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D48C"]:before{width:.604em;padding:.694em 0 .008em;content:"k";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D48D"]:before{width:.348em;padding:.694em 0 .008em;content:"l";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D48E"]:before{width:1.032em;padding:.452em 0 .008em;content:"m";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D48F"]:before{width:.713em;padding:.452em 0 .008em;content:"n";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D490"]:before{width:.585em;padding:.452em 0 .008em;content:"o";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D491"]:before{width:.601em;padding:.452em 0 .194em;content:"p";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D492"]:before{width:.542em;padding:.452em 0 .194em;content:"q";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D493"]:before{width:.529em;padding:.452em 0 .008em;content:"r";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D494"]:before{width:.531em;padding:.451em 0 .008em;content:"s";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D495"]:before{width:.415em;padding:.643em 0 .007em;content:"t";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D496"]:before{width:.681em;padding:.452em 0 .008em;content:"u";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D497"]:before{width:.567em;padding:.453em 0 .008em;content:"v";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D498"]:before{width:.831em;padding:.453em 0 .008em;content:"w";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D499"]:before{width:.659em;padding:.452em 0 .008em;content:"x";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D49A"]:before{width:.59em;padding:.452em 0 .202em;content:"y";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D49B"]:before{width:.555em;padding:.452em 0 .008em;content:"z";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D49C"]:before{width:.803em;padding:.717em 0 .008em;content:"A";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D49C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D49C"]:last-child:before{width:1.016em}.MJX-TEX mjx-c[c="1D49D"]:before{width:.908em;padding:.708em 0 .028em;content:"B";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-c[c="1D49E"]:before{width:.666em;padding:.728em 0 .026em;content:"C";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D49E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D49E"]:last-child:before{width:.819em}.MJX-TEX mjx-c[c="1D49F"]:before{width:.774em;padding:.708em 0 .031em;content:"D";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D49F"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D49F"]:last-child:before{width:.855em}.MJX-TEX mjx-c[c="1D4A0"]:before{width:.562em;padding:.707em 0 .008em;content:"E";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4A0"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4A0"]:last-child:before{width:.718em}.MJX-TEX mjx-c[c="1D4A1"]:before{width:.895em;padding:.735em 0 .036em;content:"F";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4A1"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4A1"]:last-child:before{width:.99em}.MJX-TEX mjx-c[c="1D4A2"]:before{width:.61em;padding:.717em 0 .037em;content:"G";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4A2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4A2"]:last-child:before{width:.738em}.MJX-TEX mjx-c[c="1D4A3"]:before{width:.969em;padding:.717em 0 .036em;content:"H";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4A3"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4A3"]:last-child:before{width:1.241em}.MJX-TEX mjx-c[c="1D4A4"]:before{width:.809em;padding:.717em 0 .017em;content:"I";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4A4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4A4"]:last-child:before{width:.946em}.MJX-TEX mjx-c[c="1D4A5"]:before{width:1.052em;padding:.717em 0 .314em;content:"J";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4A5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4A5"]:last-child:before{width:1.133em}.MJX-TEX mjx-c[c="1D4A6"]:before{width:.914em;padding:.717em 0 .037em;content:"K";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4A6"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4A6"]:last-child:before{width:1.204em}.MJX-TEX mjx-c[c="1D4A7"]:before{width:.874em;padding:.717em 0 .017em;content:"L";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4A7"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4A7"]:last-child:before{width:1.035em}.MJX-TEX mjx-c[c="1D4A8"]:before{width:1.08em;padding:.721em 0 .05em;content:"M";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4A8"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4A8"]:last-child:before{width:1.216em}.MJX-TEX mjx-c[c="1D4A9"]:before{width:.902em;padding:.726em 0 .036em;content:"N";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4A9"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4A9"]:last-child:before{width:1.208em}.MJX-TEX mjx-c[c="1D4AA"]:before{width:.738em;padding:.707em 0 .008em;content:"O";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4AA"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4AA"]:last-child:before{width:.805em}.MJX-TEX mjx-c[c="1D4AB"]:before{width:1.013em;padding:.716em 0 .037em;content:"P";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-c[c="1D4AC"]:before{width:.883em;padding:.717em 0 .017em;content:"Q";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-c[c="1D4AD"]:before{width:.85em;padding:.717em 0 .017em;content:"R";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-c[c="1D4AE"]:before{width:.868em;padding:.708em 0 .036em;content:"S";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4AE"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4AE"]:last-child:before{width:1.016em}.MJX-TEX mjx-c[c="1D4AF"]:before{width:.747em;padding:.735em 0 .037em;content:"T";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4AF"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4AF"]:last-child:before{width:.996em}.MJX-TEX mjx-c[c="1D4B0"]:before{width:.8em;padding:.717em 0 .017em;content:"U";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4B0"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4B0"]:last-child:before{width:.96em}.MJX-TEX mjx-c[c="1D4B1"]:before{width:.622em;padding:.717em 0 .017em;content:"V";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4B1"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4B1"]:last-child:before{width:.85em}.MJX-TEX mjx-c[c="1D4B2"]:before{width:.805em;padding:.717em 0 .017em;content:"W";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4B2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4B2"]:last-child:before{width:1.026em}.MJX-TEX mjx-c[c="1D4B3"]:before{width:.944em;padding:.717em 0 .017em;content:"X";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4B3"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4B3"]:last-child:before{width:1.131em}.MJX-TEX mjx-c[c="1D4B4"]:before{width:.71em;padding:.716em 0 .017em;content:"Y";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4B4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4B4"]:last-child:before{width:.959em}.MJX-TEX mjx-c[c="1D4B5"]:before{width:.821em;padding:.717em 0 .016em;content:"Z";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4B5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4B5"]:last-child:before{width:1.032em}.MJX-TEX mjx-c[c="1D4B6"]:before{width:.529em;padding:.441em 0 .01em;content:"a";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4B7"]:before{width:.429em;padding:.694em 0 .011em;content:"b";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4B8"]:before{width:.433em;padding:.442em 0 .011em;content:"c";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4B9"]:before{width:.52em;padding:.694em 0 .01em;content:"d";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4BA"]:before{width:.466em;padding:.442em 0 .011em;content:"e";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4BB"]:before{width:.49em;padding:.705em 0 .205em;content:"f";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4BB"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4BB"]:last-child:before{width:.55em}.MJX-TEX mjx-c[c="1D4BC"]:before{width:.477em;padding:.442em 0 .205em;content:"g";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4BD"]:before{width:.576em;padding:.694em 0 .011em;content:"h";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4BE"]:before{width:.345em;padding:.661em 0 .011em;content:"i";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4BF"]:before{width:.412em;padding:.661em 0 .204em;content:"j";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4C0"]:before{width:.521em;padding:.694em 0 .011em;content:"k";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4C1"]:before{width:.298em;padding:.694em 0 .011em;content:"l";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4C2"]:before{width:.878em;padding:.442em 0 .011em;content:"m";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4C3"]:before{width:.6em;padding:.442em 0 .011em;content:"n";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4C4"]:before{width:.485em;padding:.441em 0 .011em;content:"o";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4C5"]:before{width:.503em;padding:.442em 0 .194em;content:"p";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4C6"]:before{width:.446em;padding:.442em 0 .194em;content:"q";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4C7"]:before{width:.451em;padding:.442em 0 .011em;content:"r";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4C8"]:before{width:.469em;padding:.442em 0 .01em;content:"s";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4C9"]:before{width:.361em;padding:.626em 0 .011em;content:"t";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4CA"]:before{width:.572em;padding:.442em 0 .011em;content:"u";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4CB"]:before{width:.485em;padding:.443em 0 .011em;content:"v";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4CC"]:before{width:.716em;padding:.443em 0 .011em;content:"w";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4CD"]:before{width:.572em;padding:.442em 0 .011em;content:"x";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4CE"]:before{width:.49em;padding:.442em 0 .205em;content:"y";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4CF"]:before{width:.465em;padding:.442em 0 .011em;content:"z";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D4D0"]:before{width:.803em;padding:.717em 0 .008em;content:"A";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4D0"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4D0"]:last-child:before{width:1.016em}.MJX-TEX mjx-c[c="1D4D1"]:before{width:.908em;padding:.708em 0 .028em;content:"B";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-c[c="1D4D2"]:before{width:.666em;padding:.728em 0 .026em;content:"C";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4D2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4D2"]:last-child:before{width:.819em}.MJX-TEX mjx-c[c="1D4D3"]:before{width:.774em;padding:.708em 0 .031em;content:"D";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4D3"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4D3"]:last-child:before{width:.855em}.MJX-TEX mjx-c[c="1D4D4"]:before{width:.562em;padding:.707em 0 .008em;content:"E";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4D4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4D4"]:last-child:before{width:.718em}.MJX-TEX mjx-c[c="1D4D5"]:before{width:.895em;padding:.735em 0 .036em;content:"F";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4D5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4D5"]:last-child:before{width:.99em}.MJX-TEX mjx-c[c="1D4D6"]:before{width:.61em;padding:.717em 0 .037em;content:"G";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4D6"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4D6"]:last-child:before{width:.738em}.MJX-TEX mjx-c[c="1D4D7"]:before{width:.969em;padding:.717em 0 .036em;content:"H";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4D7"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4D7"]:last-child:before{width:1.241em}.MJX-TEX mjx-c[c="1D4D8"]:before{width:.809em;padding:.717em 0 .017em;content:"I";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4D8"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4D8"]:last-child:before{width:.946em}.MJX-TEX mjx-c[c="1D4D9"]:before{width:1.052em;padding:.717em 0 .314em;content:"J";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4D9"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4D9"]:last-child:before{width:1.133em}.MJX-TEX mjx-c[c="1D4DA"]:before{width:.914em;padding:.717em 0 .037em;content:"K";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4DA"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4DA"]:last-child:before{width:1.204em}.MJX-TEX mjx-c[c="1D4DB"]:before{width:.874em;padding:.717em 0 .017em;content:"L";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4DB"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4DB"]:last-child:before{width:1.035em}.MJX-TEX mjx-c[c="1D4DC"]:before{width:1.08em;padding:.721em 0 .05em;content:"M";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4DC"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4DC"]:last-child:before{width:1.216em}.MJX-TEX mjx-c[c="1D4DD"]:before{width:.902em;padding:.726em 0 .036em;content:"N";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4DD"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4DD"]:last-child:before{width:1.208em}.MJX-TEX mjx-c[c="1D4DE"]:before{width:.738em;padding:.707em 0 .008em;content:"O";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4DE"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4DE"]:last-child:before{width:.805em}.MJX-TEX mjx-c[c="1D4DF"]:before{width:1.013em;padding:.716em 0 .037em;content:"P";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-c[c="1D4E0"]:before{width:.883em;padding:.717em 0 .017em;content:"Q";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-c[c="1D4E1"]:before{width:.85em;padding:.717em 0 .017em;content:"R";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-c[c="1D4E2"]:before{width:.868em;padding:.708em 0 .036em;content:"S";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4E2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4E2"]:last-child:before{width:1.016em}.MJX-TEX mjx-c[c="1D4E3"]:before{width:.747em;padding:.735em 0 .037em;content:"T";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4E3"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4E3"]:last-child:before{width:.996em}.MJX-TEX mjx-c[c="1D4E4"]:before{width:.8em;padding:.717em 0 .017em;content:"U";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4E4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4E4"]:last-child:before{width:.96em}.MJX-TEX mjx-c[c="1D4E5"]:before{width:.622em;padding:.717em 0 .017em;content:"V";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4E5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4E5"]:last-child:before{width:.85em}.MJX-TEX mjx-c[c="1D4E6"]:before{width:.805em;padding:.717em 0 .017em;content:"W";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4E6"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4E6"]:last-child:before{width:1.026em}.MJX-TEX mjx-c[c="1D4E7"]:before{width:.944em;padding:.717em 0 .017em;content:"X";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4E7"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4E7"]:last-child:before{width:1.131em}.MJX-TEX mjx-c[c="1D4E8"]:before{width:.71em;padding:.716em 0 .017em;content:"Y";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4E8"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4E8"]:last-child:before{width:.959em}.MJX-TEX mjx-c[c="1D4E9"]:before{width:.821em;padding:.717em 0 .016em;content:"Z";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4E9"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4E9"]:last-child:before{width:1.032em}.MJX-TEX mjx-c[c="1D4EA"]:before{width:.633em;padding:.452em 0 .008em;content:"a";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4EB"]:before{width:.521em;padding:.694em 0 .008em;content:"b";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4EC"]:before{width:.513em;padding:.451em 0 .008em;content:"c";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4ED"]:before{width:.61em;padding:.694em 0 .008em;content:"d";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4EE"]:before{width:.554em;padding:.452em 0 .008em;content:"e";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4EF"]:before{width:.568em;padding:.701em 0 .201em;content:"f";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D4EF"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D4EF"]:last-child:before{width:.624em}.MJX-TEX mjx-c[c="1D4F0"]:before{width:.545em;padding:.452em 0 .202em;content:"g";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4F1"]:before{width:.668em;padding:.694em 0 .008em;content:"h";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4F2"]:before{width:.405em;padding:.694em 0 .008em;content:"i";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4F3"]:before{width:.471em;padding:.694em 0 .202em;content:"j";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4F4"]:before{width:.604em;padding:.694em 0 .008em;content:"k";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4F5"]:before{width:.348em;padding:.694em 0 .008em;content:"l";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4F6"]:before{width:1.032em;padding:.452em 0 .008em;content:"m";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4F7"]:before{width:.713em;padding:.452em 0 .008em;content:"n";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4F8"]:before{width:.585em;padding:.452em 0 .008em;content:"o";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4F9"]:before{width:.601em;padding:.452em 0 .194em;content:"p";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4FA"]:before{width:.542em;padding:.452em 0 .194em;content:"q";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4FB"]:before{width:.529em;padding:.452em 0 .008em;content:"r";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4FC"]:before{width:.531em;padding:.451em 0 .008em;content:"s";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4FD"]:before{width:.415em;padding:.643em 0 .007em;content:"t";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4FE"]:before{width:.681em;padding:.452em 0 .008em;content:"u";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D4FF"]:before{width:.567em;padding:.453em 0 .008em;content:"v";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D500"]:before{width:.831em;padding:.453em 0 .008em;content:"w";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D501"]:before{width:.659em;padding:.452em 0 .008em;content:"x";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D502"]:before{width:.59em;padding:.452em 0 .202em;content:"y";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D503"]:before{width:.555em;padding:.452em 0 .008em;content:"z";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D504"]:before{width:.718em;padding:.696em 0 .026em;content:"A";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D505"]:before{width:.884em;padding:.691em 0 .027em;content:"B";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D506"]:before{width:.613em;padding:.685em 0 .024em;content:"C";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D507"]:before{width:.832em;padding:.685em 0 .027em;content:"D";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D508"]:before{width:.663em;padding:.685em 0 .024em;content:"E";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D509"]:before{width:.611em;padding:.686em 0 .153em;content:"F";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D50A"]:before{width:.785em;padding:.69em 0 .026em;content:"G";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D50B"]:before{width:.72em;padding:.666em 0 .133em;content:"H";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D50C"]:before{width:.554em;padding:.686em 0 .026em;content:"I";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D50D"]:before{width:.552em;padding:.686em 0 .139em;content:"J";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D50E"]:before{width:.668em;padding:.68em 0 .027em;content:"K";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D50F"]:before{width:.666em;padding:.686em 0 .026em;content:"L";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D510"]:before{width:1.05em;padding:.692em 0 .027em;content:"M";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D511"]:before{width:.832em;padding:.686em 0 .025em;content:"N";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D512"]:before{width:.827em;padding:.729em 0 .027em;content:"O";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D513"]:before{width:.828em;padding:.692em 0 .218em;content:"P";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D514"]:before{width:.827em;padding:.729em 0 .069em;content:"Q";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D515"]:before{width:.828em;padding:.686em 0 .026em;content:"R";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D516"]:before{width:.829em;padding:.692em 0 .027em;content:"S";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D517"]:before{width:.669em;padding:.701em 0 .027em;content:"T";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D518"]:before{width:.646em;padding:.697em 0 .027em;content:"U";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D519"]:before{width:.831em;padding:.686em 0 .026em;content:"V";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D51A"]:before{width:1.046em;padding:.686em 0 .027em;content:"W";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D51B"]:before{width:.719em;padding:.688em 0 .027em;content:"X";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D51C"]:before{width:.833em;padding:.686em 0 .218em;content:"Y";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D51D"]:before{width:.602em;padding:.729em 0 .139em;content:"Z";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D51E"]:before{width:.5em;padding:.47em 0 .035em;content:"a";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D51F"]:before{width:.513em;padding:.685em 0 .031em;content:"b";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D520"]:before{width:.389em;padding:.466em 0 .029em;content:"c";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D521"]:before{width:.499em;padding:.609em 0 .033em;content:"d";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D522"]:before{width:.401em;padding:.467em 0 .03em;content:"e";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D523"]:before{width:.326em;padding:.681em 0 .221em;content:"f";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D524"]:before{width:.504em;padding:.47em 0 .209em;content:"g";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D525"]:before{width:.521em;padding:.688em 0 .205em;content:"h";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D526"]:before{width:.279em;padding:.673em 0 .02em;content:"i";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D527"]:before{width:.281em;padding:.672em 0 .208em;content:"j";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D528"]:before{width:.389em;padding:.689em 0 .025em;content:"k";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D529"]:before{width:.28em;padding:.685em 0 .02em;content:"l";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D52A"]:before{width:.767em;padding:.475em 0 .026em;content:"m";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D52B"]:before{width:.527em;padding:.475em 0 .022em;content:"n";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D52C"]:before{width:.489em;padding:.48em 0 .028em;content:"o";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D52D"]:before{width:.5em;padding:.541em 0 .212em;content:"p";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D52E"]:before{width:.489em;padding:.479em 0 .219em;content:"q";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D52F"]:before{width:.389em;padding:.474em 0 .021em;content:"r";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D530"]:before{width:.443em;padding:.478em 0 .029em;content:"s";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D531"]:before{width:.333em;padding:.64em 0 .02em;content:"t";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D532"]:before{width:.517em;padding:.474em 0 .023em;content:"u";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D533"]:before{width:.512em;padding:.53em 0 .028em;content:"v";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D534"]:before{width:.774em;padding:.532em 0 .028em;content:"w";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D535"]:before{width:.389em;padding:.472em 0 .188em;content:"x";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D536"]:before{width:.499em;padding:.528em 0 .218em;content:"y";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D537"]:before{width:.391em;padding:.471em 0 .214em;content:"z";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX mjx-c[c="1D538"]:before{width:.722em;padding:.701em 0 0;content:"A";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D539"]:before{width:.667em;padding:.683em 0 0;content:"B";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D53A"]:before{width:.722em;padding:.702em 0 .019em;content:"C";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D53B"]:before{width:.722em;padding:.683em 0 0;content:"D";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D53C"]:before{width:.667em;padding:.683em 0 0;content:"E";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D53D"]:before{width:.611em;padding:.683em 0 0;content:"F";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D53E"]:before{width:.778em;padding:.702em 0 .019em;content:"G";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D53F"]:before{width:.778em;padding:.683em 0 0;content:"H";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D540"]:before{width:.389em;padding:.683em 0 0;content:"I";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D541"]:before{width:.5em;padding:.683em 0 .077em;content:"J";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D542"]:before{width:.778em;padding:.683em 0 0;content:"K";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D543"]:before{width:.667em;padding:.683em 0 0;content:"L";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D544"]:before{width:.944em;padding:.683em 0 0;content:"M";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D545"]:before{width:.722em;padding:.683em 0 .02em;content:"N";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D546"]:before{width:.778em;padding:.701em 0 .019em;content:"O";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D547"]:before{width:.611em;padding:.683em 0 0;content:"P";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D548"]:before{width:.778em;padding:.701em 0 .181em;content:"Q";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D549"]:before{width:.722em;padding:.683em 0 0;content:"R";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D54A"]:before{width:.556em;padding:.702em 0 .012em;content:"S";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D54B"]:before{width:.667em;padding:.683em 0 0;content:"T";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D54C"]:before{width:.722em;padding:.683em 0 .019em;content:"U";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D54D"]:before{width:.722em;padding:.683em 0 .02em;content:"V";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D54E"]:before{width:1em;padding:.683em 0 .019em;content:"W";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D54F"]:before{width:.722em;padding:.683em 0 0;content:"X";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D550"]:before{width:.722em;padding:.683em 0 0;content:"Y";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D551"]:before{width:.667em;padding:.683em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D552"]:before{width:.559em;padding:.453em 0 .006em;content:"a";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D553"]:before{width:.639em;padding:.694em 0 .006em;content:"b";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D554"]:before{width:.511em;padding:.453em 0 .006em;content:"c";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D555"]:before{width:.639em;padding:.694em 0 .006em;content:"d";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D556"]:before{width:.527em;padding:.452em 0 .006em;content:"e";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D557"]:before{width:.351em;padding:.7em 0 0;content:"f";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D557"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D557"]:last-child:before{width:.452em}.MJX-TEX mjx-c[c="1D558"]:before{width:.575em;padding:.455em 0 .201em;content:"g";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D559"]:before{width:.639em;padding:.694em 0 0;content:"h";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D55A"]:before{width:.319em;padding:.695em 0 0;content:"i";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D55B"]:before{width:.351em;padding:.695em 0 .2em;content:"j";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D55C"]:before{width:.556em;padding:.683em 0 0;content:"k";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D55D"]:before{width:.319em;padding:.694em 0 0;content:"l";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D55E"]:before{width:.958em;padding:.45em 0 0;content:"m";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D55F"]:before{width:.639em;padding:.45em 0 0;content:"n";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D560"]:before{width:.575em;padding:.452em 0 .005em;content:"o";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D561"]:before{width:.639em;padding:.45em 0 .194em;content:"p";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D562"]:before{width:.607em;padding:.45em 0 .194em;content:"q";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D563"]:before{width:.474em;padding:.45em 0 0;content:"r";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D564"]:before{width:.454em;padding:.453em 0 .006em;content:"s";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D565"]:before{width:.447em;padding:.635em 0 .005em;content:"t";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D566"]:before{width:.639em;padding:.45em 0 .006em;content:"u";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D567"]:before{width:.607em;padding:.444em 0 0;content:"v";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D568"]:before{width:.831em;padding:.444em 0 0;content:"w";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D569"]:before{width:.607em;padding:.444em 0 0;content:"x";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D56A"]:before{width:.607em;padding:.444em 0 .2em;content:"y";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D56B"]:before{width:.511em;padding:.444em 0 0;content:"z";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D56C"]:before{width:.847em;padding:.686em 0 .031em;content:"A";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D56D"]:before{width:1.044em;padding:.684em 0 .031em;content:"B";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D56E"]:before{width:.723em;padding:.676em 0 .032em;content:"C";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D56F"]:before{width:.982em;padding:.683em 0 .029em;content:"D";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D570"]:before{width:.783em;padding:.686em 0 .029em;content:"E";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D571"]:before{width:.722em;padding:.684em 0 .146em;content:"F";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D572"]:before{width:.927em;padding:.687em 0 .029em;content:"G";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D573"]:before{width:.851em;padding:.683em 0 .126em;content:"H";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D574"]:before{width:.655em;padding:.681em 0 .025em;content:"I";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D575"]:before{width:.652em;padding:.68em 0 .141em;content:"J";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D576"]:before{width:.789em;padding:.681em 0 .026em;content:"K";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D577"]:before{width:.786em;padding:.683em 0 .028em;content:"L";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D578"]:before{width:1.239em;padding:.683em 0 .032em;content:"M";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D579"]:before{width:.983em;padding:.679em 0 .03em;content:"N";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D57A"]:before{width:.976em;padding:.726em 0 .03em;content:"O";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D57B"]:before{width:.977em;padding:.688em 0 .223em;content:"P";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D57C"]:before{width:.976em;padding:.726em 0 .083em;content:"Q";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D57D"]:before{width:.978em;padding:.688em 0 .028em;content:"R";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D57E"]:before{width:.978em;padding:.685em 0 .031em;content:"S";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D57F"]:before{width:.79em;padding:.686em 0 .03em;content:"T";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D580"]:before{width:.851em;padding:.688em 0 .039em;content:"U";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D581"]:before{width:.982em;padding:.685em 0 .029em;content:"V";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D582"]:before{width:1.235em;padding:.683em 0 .03em;content:"W";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D583"]:before{width:.849em;padding:.681em 0 .035em;content:"X";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D584"]:before{width:.984em;padding:.688em 0 .214em;content:"Y";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D585"]:before{width:.711em;padding:.677em 0 .148em;content:"Z";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D586"]:before{width:.603em;padding:.472em 0 .032em;content:"a";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D587"]:before{width:.59em;padding:.69em 0 .032em;content:"b";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D588"]:before{width:.464em;padding:.473em 0 .026em;content:"c";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D589"]:before{width:.589em;padding:.632em 0 .028em;content:"d";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D58A"]:before{width:.472em;padding:.471em 0 .027em;content:"e";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D58B"]:before{width:.388em;padding:.687em 0 .222em;content:"f";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D58C"]:before{width:.595em;padding:.472em 0 .208em;content:"g";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D58D"]:before{width:.615em;padding:.687em 0 .207em;content:"h";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D58E"]:before{width:.331em;padding:.686em 0 .025em;content:"i";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D58F"]:before{width:.332em;padding:.682em 0 .203em;content:"j";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D590"]:before{width:.464em;padding:.682em 0 .025em;content:"k";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D591"]:before{width:.337em;padding:.681em 0 .024em;content:"l";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D592"]:before{width:.921em;padding:.476em 0 .031em;content:"m";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D593"]:before{width:.654em;padding:.473em 0 .028em;content:"n";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D594"]:before{width:.609em;padding:.482em 0 .034em;content:"o";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D595"]:before{width:.604em;padding:.557em 0 .207em;content:"p";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D596"]:before{width:.596em;padding:.485em 0 .211em;content:"q";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D597"]:before{width:.46em;padding:.472em 0 .026em;content:"r";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D598"]:before{width:.523em;padding:.479em 0 .034em;content:"s";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D599"]:before{width:.393em;padding:.648em 0 .027em;content:"t";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D59A"]:before{width:.589em;padding:.472em 0 .032em;content:"u";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D59B"]:before{width:.604em;padding:.546em 0 .027em;content:"v";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D59C"]:before{width:.918em;padding:.549em 0 .032em;content:"w";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D59D"]:before{width:.459em;padding:.471em 0 .188em;content:"x";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D59E"]:before{width:.589em;padding:.557em 0 .221em;content:"y";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D59F"]:before{width:.461em;padding:.471em 0 .214em;content:"z";font-family:MJXZERO,MJXTEX-FR-B}.MJX-TEX mjx-c[c="1D5A0"]:before{width:.667em;padding:.694em 0 0;content:"A";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5A1"]:before{width:.667em;padding:.694em 0 0;content:"B";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5A2"]:before{width:.639em;padding:.705em 0 .011em;content:"C";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5A3"]:before{width:.722em;padding:.694em 0 0;content:"D";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5A4"]:before{width:.597em;padding:.691em 0 0;content:"E";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5A5"]:before{width:.569em;padding:.691em 0 0;content:"F";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5A6"]:before{width:.667em;padding:.704em 0 .011em;content:"G";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5A7"]:before{width:.708em;padding:.694em 0 0;content:"H";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5A8"]:before{width:.278em;padding:.694em 0 0;content:"I";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5A9"]:before{width:.472em;padding:.694em 0 .022em;content:"J";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5AA"]:before{width:.694em;padding:.694em 0 0;content:"K";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5AB"]:before{width:.542em;padding:.694em 0 0;content:"L";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5AC"]:before{width:.875em;padding:.694em 0 0;content:"M";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5AD"]:before{width:.708em;padding:.694em 0 0;content:"N";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5AE"]:before{width:.736em;padding:.715em 0 .022em;content:"O";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5AF"]:before{width:.639em;padding:.694em 0 0;content:"P";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5B0"]:before{width:.736em;padding:.715em 0 .125em;content:"Q";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5B1"]:before{width:.646em;padding:.694em 0 0;content:"R";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5B2"]:before{width:.556em;padding:.716em 0 .022em;content:"S";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5B3"]:before{width:.681em;padding:.688em 0 0;content:"T";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5B4"]:before{width:.688em;padding:.694em 0 .022em;content:"U";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5B5"]:before{width:.667em;padding:.694em 0 0;content:"V";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5B6"]:before{width:.944em;padding:.694em 0 0;content:"W";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5B7"]:before{width:.667em;padding:.694em 0 0;content:"X";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5B8"]:before{width:.667em;padding:.694em 0 0;content:"Y";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5B9"]:before{width:.611em;padding:.694em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5BA"]:before{width:.481em;padding:.46em 0 .01em;content:"a";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5BB"]:before{width:.517em;padding:.694em 0 .011em;content:"b";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5BC"]:before{width:.444em;padding:.46em 0 .01em;content:"c";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5BD"]:before{width:.517em;padding:.694em 0 .01em;content:"d";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5BE"]:before{width:.444em;padding:.461em 0 .01em;content:"e";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5BF"]:before{width:.306em;padding:.705em 0 0;content:"f";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5C0"]:before{width:.5em;padding:.455em 0 .206em;content:"g";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5C1"]:before{width:.517em;padding:.694em 0 0;content:"h";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5C2"]:before{width:.239em;padding:.68em 0 0;content:"i";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5C3"]:before{width:.267em;padding:.68em 0 .205em;content:"j";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5C4"]:before{width:.489em;padding:.694em 0 0;content:"k";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5C5"]:before{width:.239em;padding:.694em 0 0;content:"l";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5C6"]:before{width:.794em;padding:.455em 0 0;content:"m";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5C7"]:before{width:.517em;padding:.455em 0 0;content:"n";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5C8"]:before{width:.5em;padding:.46em 0 .01em;content:"o";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5C9"]:before{content:"p"}.MJX-TEX mjx-c[c="1D5C9"]:before,.MJX-TEX mjx-c[c="1D5CA"]:before{width:.517em;padding:.455em 0 .194em;font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5CA"]:before{content:"q"}.MJX-TEX mjx-c[c="1D5CB"]:before{width:.342em;padding:.455em 0 0;content:"r";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5CC"]:before{width:.383em;padding:.46em 0 .01em;content:"s";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5CD"]:before{width:.361em;padding:.571em 0 .01em;content:"t";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5CE"]:before{width:.517em;padding:.444em 0 .01em;content:"u";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5CF"]:before{width:.461em;padding:.444em 0 0;content:"v";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5D0"]:before{width:.683em;padding:.444em 0 0;content:"w";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5D1"]:before{width:.461em;padding:.444em 0 0;content:"x";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5D2"]:before{width:.461em;padding:.444em 0 .204em;content:"y";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5D3"]:before{width:.435em;padding:.444em 0 0;content:"z";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D5D4"]:before{width:.733em;padding:.694em 0 0;content:"A";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5D5"]:before{width:.733em;padding:.694em 0 0;content:"B";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5D6"]:before{width:.703em;padding:.704em 0 .011em;content:"C";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5D7"]:before{width:.794em;padding:.694em 0 0;content:"D";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5D8"]:before{width:.642em;padding:.691em 0 0;content:"E";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5D9"]:before{width:.611em;padding:.691em 0 0;content:"F";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5DA"]:before{width:.733em;padding:.705em 0 .011em;content:"G";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5DB"]:before{width:.794em;padding:.694em 0 0;content:"H";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5DC"]:before{width:.331em;padding:.694em 0 0;content:"I";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5DD"]:before{width:.519em;padding:.694em 0 .022em;content:"J";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5DE"]:before{width:.764em;padding:.694em 0 0;content:"K";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5DF"]:before{width:.581em;padding:.694em 0 0;content:"L";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5E0"]:before{width:.978em;padding:.694em 0 0;content:"M";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5E1"]:before{width:.794em;padding:.694em 0 0;content:"N";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5E2"]:before{width:.794em;padding:.716em 0 .022em;content:"O";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5E3"]:before{width:.703em;padding:.694em 0 0;content:"P";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5E4"]:before{width:.794em;padding:.716em 0 .106em;content:"Q";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5E5"]:before{width:.703em;padding:.694em 0 0;content:"R";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5E6"]:before{width:.611em;padding:.716em 0 .022em;content:"S";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5E7"]:before{width:.733em;padding:.688em 0 0;content:"T";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5E8"]:before{width:.764em;padding:.694em 0 .022em;content:"U";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5E9"]:before{width:.733em;padding:.694em 0 0;content:"V";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5EA"]:before{width:1.039em;padding:.694em 0 0;content:"W";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5EB"]:before{width:.733em;padding:.694em 0 0;content:"X";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5EC"]:before{width:.733em;padding:.694em 0 0;content:"Y";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5ED"]:before{width:.672em;padding:.694em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5EE"]:before{width:.525em;padding:.475em 0 .011em;content:"a";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5EF"]:before{width:.561em;padding:.694em 0 .01em;content:"b";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5F0"]:before{width:.489em;padding:.475em 0 .011em;content:"c";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5F1"]:before{width:.561em;padding:.694em 0 .011em;content:"d";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5F2"]:before{width:.511em;padding:.474em 0 .01em;content:"e";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5F3"]:before{width:.336em;padding:.705em 0 0;content:"f";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5F4"]:before{width:.55em;padding:.469em 0 .206em;content:"g";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5F5"]:before{width:.561em;padding:.694em 0 0;content:"h";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5F6"]:before{width:.256em;padding:.695em 0 0;content:"i";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5F7"]:before{width:.286em;padding:.695em 0 .205em;content:"j";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5F8"]:before{width:.531em;padding:.694em 0 0;content:"k";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5F9"]:before{width:.256em;padding:.694em 0 0;content:"l";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5FA"]:before{width:.867em;padding:.469em 0 0;content:"m";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5FB"]:before{width:.561em;padding:.468em 0 0;content:"n";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5FC"]:before{width:.55em;padding:.474em 0 .011em;content:"o";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5FD"]:before{content:"p"}.MJX-TEX mjx-c[c="1D5FD"]:before,.MJX-TEX mjx-c[c="1D5FE"]:before{width:.561em;padding:.469em 0 .194em;font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D5FE"]:before{content:"q"}.MJX-TEX mjx-c[c="1D5FF"]:before{width:.372em;padding:.469em 0 0;content:"r";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D600"]:before{width:.422em;padding:.474em 0 .01em;content:"s";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D601"]:before{width:.404em;padding:.589em 0 .01em;content:"t";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D602"]:before{width:.561em;padding:.458em 0 .011em;content:"u";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D603"]:before{width:.5em;padding:.458em 0 0;content:"v";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D604"]:before{width:.744em;padding:.458em 0 0;content:"w";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D605"]:before{width:.5em;padding:.458em 0 0;content:"x";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D606"]:before{width:.5em;padding:.458em 0 .205em;content:"y";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D607"]:before{width:.476em;padding:.458em 0 0;content:"z";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D608"]:before{width:.667em;padding:.694em 0 0;content:"A";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D609"]:before{width:.667em;padding:.694em 0 0;content:"B";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D60A"]:before{width:.639em;padding:.705em 0 .01em;content:"C";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D60A"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D60A"]:last-child:before{width:.719em}.MJX-TEX mjx-c[c="1D60B"]:before{width:.722em;padding:.694em 0 0;content:"D";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D60C"]:before{width:.597em;padding:.691em 0 0;content:"E";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D60C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D60C"]:last-child:before{width:.688em}.MJX-TEX mjx-c[c="1D60D"]:before{width:.569em;padding:.691em 0 0;content:"F";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D60D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D60D"]:last-child:before{width:.673em}.MJX-TEX mjx-c[c="1D60E"]:before{width:.667em;padding:.705em 0 .011em;content:"G";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D60E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D60E"]:last-child:before{width:.73em}.MJX-TEX mjx-c[c="1D60F"]:before{width:.708em;padding:.694em 0 0;content:"H";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D60F"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D60F"]:last-child:before{width:.768em}.MJX-TEX mjx-c[c="1D610"]:before{width:.278em;padding:.694em 0 0;content:"I";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D610"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D610"]:last-child:before{width:.338em}.MJX-TEX mjx-c[c="1D611"]:before{width:.472em;padding:.694em 0 .022em;content:"J";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D611"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D611"]:last-child:before{width:.535em}.MJX-TEX mjx-c[c="1D612"]:before{width:.694em;padding:.694em 0 0;content:"K";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D612"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D612"]:last-child:before{width:.785em}.MJX-TEX mjx-c[c="1D613"]:before{width:.542em;padding:.694em 0 0;content:"L";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D614"]:before{width:.875em;padding:.694em 0 0;content:"M";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D614"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D614"]:last-child:before{width:.929em}.MJX-TEX mjx-c[c="1D615"]:before{width:.708em;padding:.694em 0 0;content:"N";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D615"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D615"]:last-child:before{width:.766em}.MJX-TEX mjx-c[c="1D616"]:before{width:.736em;padding:.716em 0 .022em;content:"O";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D617"]:before{width:.639em;padding:.694em 0 0;content:"P";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D617"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D617"]:last-child:before{width:.69em}.MJX-TEX mjx-c[c="1D618"]:before{width:.736em;padding:.716em 0 .125em;content:"Q";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D619"]:before{width:.646em;padding:.694em 0 0;content:"R";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D619"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D619"]:last-child:before{width:.698em}.MJX-TEX mjx-c[c="1D61A"]:before{width:.556em;padding:.716em 0 .022em;content:"S";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D61A"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D61A"]:last-child:before{width:.609em}.MJX-TEX mjx-c[c="1D61B"]:before{width:.681em;padding:.688em 0 0;content:"T";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D61B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D61B"]:last-child:before{width:.79em}.MJX-TEX mjx-c[c="1D61C"]:before{width:.688em;padding:.694em 0 .022em;content:"U";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D61C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D61C"]:last-child:before{width:.747em}.MJX-TEX mjx-c[c="1D61D"]:before{width:.667em;padding:.694em 0 0;content:"V";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D61D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D61D"]:last-child:before{width:.799em}.MJX-TEX mjx-c[c="1D61E"]:before{width:.944em;padding:.694em 0 0;content:"W";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D61E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D61E"]:last-child:before{width:1.076em}.MJX-TEX mjx-c[c="1D61F"]:before{width:.667em;padding:.694em 0 0;content:"X";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D61F"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D61F"]:last-child:before{width:.758em}.MJX-TEX mjx-c[c="1D620"]:before{width:.667em;padding:.694em 0 0;content:"Y";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D620"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D620"]:last-child:before{width:.81em}.MJX-TEX mjx-c[c="1D621"]:before{width:.611em;padding:.694em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D621"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D621"]:last-child:before{width:.702em}.MJX-TEX mjx-c[c="1D622"]:before{width:.481em;padding:.461em 0 .01em;content:"a";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D623"]:before{width:.517em;padding:.694em 0 .011em;content:"b";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D624"]:before{width:.444em;padding:.46em 0 .011em;content:"c";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D624"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D624"]:last-child:before{width:.499em}.MJX-TEX mjx-c[c="1D625"]:before{width:.517em;padding:.694em 0 .01em;content:"d";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D625"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D625"]:last-child:before{width:.588em}.MJX-TEX mjx-c[c="1D626"]:before{width:.444em;padding:.46em 0 .011em;content:"e";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D627"]:before{width:.306em;padding:.705em 0 0;content:"f";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D627"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D627"]:last-child:before{width:.494em}.MJX-TEX mjx-c[c="1D628"]:before{width:.5em;padding:.455em 0 .206em;content:"g";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D628"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D628"]:last-child:before{width:.568em}.MJX-TEX mjx-c[c="1D629"]:before{width:.517em;padding:.694em 0 0;content:"h";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D62A"]:before{width:.239em;padding:.68em 0 0;content:"i";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D62A"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D62A"]:last-child:before{width:.315em}.MJX-TEX mjx-c[c="1D62B"]:before{width:.267em;padding:.68em 0 .204em;content:"j";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D62B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D62B"]:last-child:before{width:.336em}.MJX-TEX mjx-c[c="1D62C"]:before{width:.489em;padding:.694em 0 0;content:"k";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D62C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D62C"]:last-child:before{width:.543em}.MJX-TEX mjx-c[c="1D62D"]:before{width:.239em;padding:.694em 0 0;content:"l";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D62D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D62D"]:last-child:before{width:.311em}.MJX-TEX mjx-c[c="1D62E"]:before{width:.794em;padding:.455em 0 0;content:"m";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D62F"]:before{width:.517em;padding:.454em 0 0;content:"n";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D630"]:before{width:.5em;padding:.461em 0 .011em;content:"o";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D631"]:before{content:"p"}.MJX-TEX mjx-c[c="1D631"]:before,.MJX-TEX mjx-c[c="1D632"]:before{width:.517em;padding:.455em 0 .194em;font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D632"]:before{content:"q"}.MJX-TEX mjx-c[c="1D633"]:before{width:.342em;padding:.455em 0 0;content:"r";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D633"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D633"]:last-child:before{width:.424em}.MJX-TEX mjx-c[c="1D634"]:before{width:.383em;padding:.461em 0 .011em;content:"s";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D634"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D634"]:last-child:before{width:.436em}.MJX-TEX mjx-c[c="1D635"]:before{width:.361em;padding:.571em 0 .011em;content:"t";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D636"]:before{width:.517em;padding:.444em 0 .01em;content:"u";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D637"]:before{width:.461em;padding:.444em 0 0;content:"v";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D637"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D637"]:last-child:before{width:.54em}.MJX-TEX mjx-c[c="1D638"]:before{width:.683em;padding:.444em 0 0;content:"w";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D638"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D638"]:last-child:before{width:.762em}.MJX-TEX mjx-c[c="1D639"]:before{width:.461em;padding:.444em 0 0;content:"x";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D639"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D639"]:last-child:before{width:.537em}.MJX-TEX mjx-c[c="1D63A"]:before{width:.461em;padding:.444em 0 .205em;content:"y";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D63A"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D63A"]:last-child:before{width:.54em}.MJX-TEX mjx-c[c="1D63B"]:before{width:.435em;padding:.444em 0 0;content:"z";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D63B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D63B"]:last-child:before{width:.494em}.MJX-TEX mjx-c[c="1D63C"]:before{width:.667em;padding:.694em 0 0;content:"A";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D63D"]:before{width:.667em;padding:.694em 0 0;content:"B";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D63E"]:before{width:.639em;padding:.705em 0 .01em;content:"C";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D63E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D63E"]:last-child:before{width:.719em}.MJX-TEX mjx-c[c="1D63F"]:before{width:.722em;padding:.694em 0 0;content:"D";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D640"]:before{width:.597em;padding:.691em 0 0;content:"E";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D640"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D640"]:last-child:before{width:.688em}.MJX-TEX mjx-c[c="1D641"]:before{width:.569em;padding:.691em 0 0;content:"F";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D641"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D641"]:last-child:before{width:.673em}.MJX-TEX mjx-c[c="1D642"]:before{width:.667em;padding:.705em 0 .011em;content:"G";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D642"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D642"]:last-child:before{width:.73em}.MJX-TEX mjx-c[c="1D643"]:before{width:.708em;padding:.694em 0 0;content:"H";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D643"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D643"]:last-child:before{width:.768em}.MJX-TEX mjx-c[c="1D644"]:before{width:.278em;padding:.694em 0 0;content:"I";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D644"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D644"]:last-child:before{width:.338em}.MJX-TEX mjx-c[c="1D645"]:before{width:.472em;padding:.694em 0 .022em;content:"J";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D645"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D645"]:last-child:before{width:.535em}.MJX-TEX mjx-c[c="1D646"]:before{width:.694em;padding:.694em 0 0;content:"K";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D646"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D646"]:last-child:before{width:.785em}.MJX-TEX mjx-c[c="1D647"]:before{width:.542em;padding:.694em 0 0;content:"L";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D648"]:before{width:.875em;padding:.694em 0 0;content:"M";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D648"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D648"]:last-child:before{width:.929em}.MJX-TEX mjx-c[c="1D649"]:before{width:.708em;padding:.694em 0 0;content:"N";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D649"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D649"]:last-child:before{width:.766em}.MJX-TEX mjx-c[c="1D64A"]:before{width:.736em;padding:.716em 0 .022em;content:"O";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D64B"]:before{width:.639em;padding:.694em 0 0;content:"P";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D64B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D64B"]:last-child:before{width:.69em}.MJX-TEX mjx-c[c="1D64C"]:before{width:.736em;padding:.716em 0 .125em;content:"Q";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D64D"]:before{width:.646em;padding:.694em 0 0;content:"R";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D64D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D64D"]:last-child:before{width:.698em}.MJX-TEX mjx-c[c="1D64E"]:before{width:.556em;padding:.716em 0 .022em;content:"S";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D64E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D64E"]:last-child:before{width:.609em}.MJX-TEX mjx-c[c="1D64F"]:before{width:.681em;padding:.688em 0 0;content:"T";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D64F"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D64F"]:last-child:before{width:.79em}.MJX-TEX mjx-c[c="1D650"]:before{width:.688em;padding:.694em 0 .022em;content:"U";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D650"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D650"]:last-child:before{width:.747em}.MJX-TEX mjx-c[c="1D651"]:before{width:.667em;padding:.694em 0 0;content:"V";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D651"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D651"]:last-child:before{width:.799em}.MJX-TEX mjx-c[c="1D652"]:before{width:.944em;padding:.694em 0 0;content:"W";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D652"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D652"]:last-child:before{width:1.076em}.MJX-TEX mjx-c[c="1D653"]:before{width:.667em;padding:.694em 0 0;content:"X";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D653"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D653"]:last-child:before{width:.758em}.MJX-TEX mjx-c[c="1D654"]:before{width:.667em;padding:.694em 0 0;content:"Y";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D654"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D654"]:last-child:before{width:.81em}.MJX-TEX mjx-c[c="1D655"]:before{width:.611em;padding:.694em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D655"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D655"]:last-child:before{width:.702em}.MJX-TEX mjx-c[c="1D656"]:before{width:.481em;padding:.461em 0 .01em;content:"a";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D657"]:before{width:.517em;padding:.694em 0 .011em;content:"b";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D658"]:before{width:.444em;padding:.46em 0 .011em;content:"c";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D658"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D658"]:last-child:before{width:.499em}.MJX-TEX mjx-c[c="1D659"]:before{width:.517em;padding:.694em 0 .01em;content:"d";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D659"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D659"]:last-child:before{width:.588em}.MJX-TEX mjx-c[c="1D65A"]:before{width:.444em;padding:.46em 0 .011em;content:"e";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D65B"]:before{width:.306em;padding:.705em 0 0;content:"f";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D65B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D65B"]:last-child:before{width:.494em}.MJX-TEX mjx-c[c="1D65C"]:before{width:.5em;padding:.455em 0 .206em;content:"g";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D65C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D65C"]:last-child:before{width:.568em}.MJX-TEX mjx-c[c="1D65D"]:before{width:.517em;padding:.694em 0 0;content:"h";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D65E"]:before{width:.239em;padding:.68em 0 0;content:"i";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D65E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D65E"]:last-child:before{width:.315em}.MJX-TEX mjx-c[c="1D65F"]:before{width:.267em;padding:.68em 0 .204em;content:"j";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D65F"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D65F"]:last-child:before{width:.336em}.MJX-TEX mjx-c[c="1D660"]:before{width:.489em;padding:.694em 0 0;content:"k";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D660"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D660"]:last-child:before{width:.543em}.MJX-TEX mjx-c[c="1D661"]:before{width:.239em;padding:.694em 0 0;content:"l";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D661"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D661"]:last-child:before{width:.311em}.MJX-TEX mjx-c[c="1D662"]:before{width:.794em;padding:.455em 0 0;content:"m";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D663"]:before{width:.517em;padding:.454em 0 0;content:"n";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D664"]:before{width:.5em;padding:.461em 0 .011em;content:"o";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D665"]:before{content:"p"}.MJX-TEX mjx-c[c="1D665"]:before,.MJX-TEX mjx-c[c="1D666"]:before{width:.517em;padding:.455em 0 .194em;font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D666"]:before{content:"q"}.MJX-TEX mjx-c[c="1D667"]:before{width:.342em;padding:.455em 0 0;content:"r";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D667"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D667"]:last-child:before{width:.424em}.MJX-TEX mjx-c[c="1D668"]:before{width:.383em;padding:.461em 0 .011em;content:"s";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D668"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D668"]:last-child:before{width:.436em}.MJX-TEX mjx-c[c="1D669"]:before{width:.361em;padding:.571em 0 .011em;content:"t";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D66A"]:before{width:.517em;padding:.444em 0 .01em;content:"u";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D66B"]:before{width:.461em;padding:.444em 0 0;content:"v";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D66B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D66B"]:last-child:before{width:.54em}.MJX-TEX mjx-c[c="1D66C"]:before{width:.683em;padding:.444em 0 0;content:"w";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D66C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D66C"]:last-child:before{width:.762em}.MJX-TEX mjx-c[c="1D66D"]:before{width:.461em;padding:.444em 0 0;content:"x";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D66D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D66D"]:last-child:before{width:.537em}.MJX-TEX mjx-c[c="1D66E"]:before{width:.461em;padding:.444em 0 .205em;content:"y";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D66E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D66E"]:last-child:before{width:.54em}.MJX-TEX mjx-c[c="1D66F"]:before{width:.435em;padding:.444em 0 0;content:"z";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D66F"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D66F"]:last-child:before{width:.494em}.MJX-TEX mjx-c[c="1D670"]:before{width:.525em;padding:.623em 0 0;content:"A";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D671"]:before{width:.525em;padding:.611em 0 0;content:"B";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D672"]:before{width:.525em;padding:.622em 0 .011em;content:"C";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D673"]:before{width:.525em;padding:.611em 0 0;content:"D";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D674"]:before{width:.525em;padding:.611em 0 0;content:"E";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D675"]:before{width:.525em;padding:.611em 0 0;content:"F";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D676"]:before{width:.525em;padding:.622em 0 .011em;content:"G";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D677"]:before{width:.525em;padding:.611em 0 0;content:"H";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D678"]:before{width:.525em;padding:.611em 0 0;content:"I";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D679"]:before{width:.525em;padding:.611em 0 .011em;content:"J";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D67A"]:before{width:.525em;padding:.611em 0 0;content:"K";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D67B"]:before{width:.525em;padding:.611em 0 0;content:"L";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D67C"]:before{width:.525em;padding:.611em 0 0;content:"M";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D67D"]:before{width:.525em;padding:.611em 0 0;content:"N";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D67E"]:before{width:.525em;padding:.621em 0 .01em;content:"O";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D67F"]:before{width:.525em;padding:.611em 0 0;content:"P";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D680"]:before{width:.525em;padding:.621em 0 .138em;content:"Q";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D681"]:before{width:.525em;padding:.611em 0 .011em;content:"R";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D682"]:before{width:.525em;padding:.622em 0 .011em;content:"S";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D683"]:before{width:.525em;padding:.611em 0 0;content:"T";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D684"]:before{width:.525em;padding:.611em 0 .011em;content:"U";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D685"]:before{width:.525em;padding:.611em 0 .007em;content:"V";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D686"]:before{width:.525em;padding:.611em 0 .007em;content:"W";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D687"]:before{width:.525em;padding:.611em 0 0;content:"X";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D688"]:before{width:.525em;padding:.611em 0 0;content:"Y";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D689"]:before{width:.525em;padding:.611em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D68A"]:before{width:.525em;padding:.439em 0 .006em;content:"a";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D68B"]:before{width:.525em;padding:.611em 0 .006em;content:"b";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D68C"]:before{width:.525em;padding:.44em 0 .006em;content:"c";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D68D"]:before{width:.525em;padding:.611em 0 .006em;content:"d";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D68E"]:before{width:.525em;padding:.44em 0 .006em;content:"e";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D68F"]:before{width:.525em;padding:.617em 0 0;content:"f";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D690"]:before{width:.525em;padding:.442em 0 .229em;content:"g";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D691"]:before{width:.525em;padding:.611em 0 0;content:"h";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D692"]:before{width:.525em;padding:.612em 0 0;content:"i";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D693"]:before{width:.525em;padding:.612em 0 .228em;content:"j";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D694"]:before{width:.525em;padding:.611em 0 0;content:"k";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D695"]:before{width:.525em;padding:.611em 0 0;content:"l";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D696"]:before{width:.525em;padding:.436em 0 0;content:"m";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D697"]:before{width:.525em;padding:.436em 0 0;content:"n";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D698"]:before{width:.525em;padding:.44em 0 .006em;content:"o";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D699"]:before{width:.525em;padding:.437em 0 .221em;content:"p";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D69A"]:before{width:.525em;padding:.437em 0 .221em;content:"q";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D69B"]:before{width:.525em;padding:.437em 0 0;content:"r";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D69C"]:before{width:.525em;padding:.44em 0 .006em;content:"s";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D69D"]:before{width:.525em;padding:.554em 0 .006em;content:"t";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D69E"]:before{width:.525em;padding:.431em 0 .005em;content:"u";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D69F"]:before{width:.525em;padding:.431em 0 0;content:"v";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D6A0"]:before{width:.525em;padding:.431em 0 0;content:"w";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D6A1"]:before{width:.525em;padding:.431em 0 0;content:"x";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D6A2"]:before{width:.525em;padding:.431em 0 .228em;content:"y";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D6A3"]:before{width:.525em;padding:.431em 0 0;content:"z";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D6A4"]:before{width:.307em;padding:.441em 0 .01em;content:"\131";font-family:MJXZERO,MJXTEX-MI}.MJX-TEX mjx-c[c="1D6A5"]:before{width:.332em;padding:.442em 0 .204em;content:"\237";font-family:MJXZERO,MJXTEX-MI}.MJX-TEX mjx-c[c="1D6A8"]:before{width:.869em;padding:.698em 0 0;content:"A";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6A9"]:before{width:.818em;padding:.686em 0 0;content:"B";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6AA"]:before{width:.692em;padding:.68em 0 0;content:"\393";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6AB"]:before{width:.958em;padding:.698em 0 0;content:"\394";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6AC"]:before{width:.756em;padding:.68em 0 0;content:"E";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6AD"]:before{width:.703em;padding:.686em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6AE"]:before{width:.9em;padding:.686em 0 0;content:"H";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6AF"]:before{width:.894em;padding:.696em 0 .01em;content:"\398";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6B0"]:before{width:.436em;padding:.686em 0 0;content:"I";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6B1"]:before{width:.901em;padding:.686em 0 0;content:"K";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6B2"]:before{width:.806em;padding:.698em 0 0;content:"\39B";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6B3"]:before{width:1.092em;padding:.686em 0 0;content:"M";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6B4"]:before{width:.9em;padding:.686em 0 0;content:"N";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6B5"]:before{width:.767em;padding:.675em 0 0;content:"\39E";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6B6"]:before{width:.864em;padding:.696em 0 .01em;content:"O";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6B7"]:before{width:.9em;padding:.68em 0 0;content:"\3A0";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6B8"]:before{width:.786em;padding:.686em 0 0;content:"P";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6B9"]:before{width:.894em;padding:.696em 0 .01em;content:"\398";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6BA"]:before{width:.831em;padding:.686em 0 0;content:"\3A3";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6BB"]:before{width:.8em;padding:.675em 0 0;content:"T";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6BC"]:before{width:.894em;padding:.697em 0 0;content:"\3A5";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6BD"]:before{width:.831em;padding:.686em 0 0;content:"\3A6";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6BE"]:before{width:.869em;padding:.686em 0 0;content:"X";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6BF"]:before{width:.894em;padding:.686em 0 0;content:"\3A8";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6C0"]:before{width:.831em;padding:.696em 0 0;content:"\3A9";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6C1"]:before{width:.958em;padding:.686em 0 .024em;content:"\2207";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D6C2"]:before{width:.761em;padding:.452em 0 .008em;content:"\3B1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6C3"]:before{width:.66em;padding:.701em 0 .194em;content:"\3B2";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6C4"]:before{width:.59em;padding:.451em 0 .211em;content:"\3B3";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6C5"]:before{width:.522em;padding:.725em 0 .008em;content:"\3B4";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6C6"]:before{width:.529em;padding:.461em 0 .017em;content:"\3B5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6C7"]:before{width:.508em;padding:.711em 0 .202em;content:"\3B6";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6C8"]:before{width:.6em;padding:.452em 0 .211em;content:"\3B7";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6C9"]:before{width:.562em;padding:.702em 0 .008em;content:"\3B8";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6CA"]:before{width:.412em;padding:.452em 0 .008em;content:"\3B9";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6CB"]:before{width:.668em;padding:.452em 0 .008em;content:"\3BA";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6CC"]:before{width:.671em;padding:.694em 0 .013em;content:"\3BB";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6CD"]:before{width:.708em;padding:.452em 0 .211em;content:"\3BC";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6CE"]:before{width:.577em;padding:.452em 0 0;content:"\3BD";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6CF"]:before{width:.508em;padding:.711em 0 .201em;content:"\3BE";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6D0"]:before{width:.585em;padding:.452em 0 .008em;content:"\3BF";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6D1"]:before{width:.682em;padding:.444em 0 .008em;content:"\3C0";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6D2"]:before{width:.612em;padding:.451em 0 .211em;content:"\3C1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6D3"]:before{width:.424em;padding:.451em 0 .105em;content:"\3C2";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6D4"]:before{width:.686em;padding:.444em 0 .008em;content:"\3C3";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6D5"]:before{width:.521em;padding:.444em 0 .013em;content:"\3C4";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D6D5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D6D5"]:last-child:before{width:.61em}.MJX-TEX mjx-c[c="1D6D6"]:before{width:.631em;padding:.453em 0 .008em;content:"\3C5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6D7"]:before{width:.747em;padding:.452em 0 .216em;content:"\3C6";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6D8"]:before{width:.718em;padding:.452em 0 .201em;content:"\3C7";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6D9"]:before{width:.758em;padding:.694em 0 .202em;content:"\3C8";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6DA"]:before{width:.718em;padding:.453em 0 .008em;content:"\3C9";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6DB"]:before{width:.628em;padding:.71em 0 .017em;content:"\2202";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6DC"]:before{width:.483em;padding:.444em 0 .007em;content:"\3F5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6DD"]:before{width:.692em;padding:.701em 0 .008em;content:"\3D1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6DE"]:before{width:.667em;padding:.434em 0 .006em;content:"\E009";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D6DE"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D6DE"]:last-child:before{width:.734em}.MJX-TEX mjx-c[c="1D6DF"]:before{width:.712em;padding:.694em 0 .202em;content:"\3D5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6E0"]:before{width:.612em;padding:.451em 0 .194em;content:"\3F1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6E1"]:before{width:.975em;padding:.444em 0 .008em;content:"\3D6";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D6E2"]:before{width:.75em;padding:.716em 0 0;content:"A";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6E3"]:before{width:.759em;padding:.683em 0 0;content:"B";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6E4"]:before{width:.615em;padding:.68em 0 0;content:"\393";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D6E4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D6E4"]:last-child:before{width:.721em}.MJX-TEX mjx-c[c="1D6E5"]:before{width:.833em;padding:.716em 0 0;content:"\394";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6E6"]:before{width:.738em;padding:.68em 0 0;content:"E";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6E7"]:before{width:.683em;padding:.683em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6E8"]:before{width:.831em;padding:.683em 0 0;content:"H";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D6E8"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D6E8"]:last-child:before{width:.888em}.MJX-TEX mjx-c[c="1D6E9"]:before{width:.763em;padding:.704em 0 .022em;content:"\398";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6EA"]:before{width:.44em;padding:.683em 0 0;content:"I";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D6EA"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D6EA"]:last-child:before{width:.504em}.MJX-TEX mjx-c[c="1D6EB"]:before{width:.849em;padding:.683em 0 0;content:"K";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6EC"]:before{width:.694em;padding:.716em 0 0;content:"\39B";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6ED"]:before{width:.97em;padding:.683em 0 0;content:"M";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D6ED"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D6ED"]:last-child:before{width:1.051em}.MJX-TEX mjx-c[c="1D6EE"]:before{width:.803em;padding:.683em 0 0;content:"N";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D6EE"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D6EE"]:last-child:before{width:.888em}.MJX-TEX mjx-c[c="1D6EF"]:before{width:.742em;padding:.677em 0 0;content:"\39E";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6F0"]:before{width:.763em;padding:.704em 0 .022em;content:"O";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6F1"]:before{width:.831em;padding:.68em 0 0;content:"\3A0";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D6F1"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D6F1"]:last-child:before{width:.887em}.MJX-TEX mjx-c[c="1D6F2"]:before{width:.642em;padding:.683em 0 0;content:"P";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D6F2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D6F2"]:last-child:before{width:.751em}.MJX-TEX mjx-c[c="1D6F3"]:before{width:.763em;padding:.704em 0 .022em;content:"\398";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6F4"]:before{width:.78em;padding:.683em 0 0;content:"\3A3";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6F5"]:before{width:.584em;padding:.677em 0 0;content:"T";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D6F5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D6F5"]:last-child:before{width:.704em}.MJX-TEX mjx-c[c="1D6F6"]:before{width:.583em;padding:.705em 0 0;content:"\3A5";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D6F6"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D6F6"]:last-child:before{width:.7em}.MJX-TEX mjx-c[c="1D6F7"]:before{width:.667em;padding:.683em 0 0;content:"\3A6";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6F8"]:before{width:.828em;padding:.683em 0 0;content:"X";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6F9"]:before{width:.612em;padding:.683em 0 0;content:"\3A8";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D6F9"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D6F9"]:last-child:before{width:.692em}.MJX-TEX mjx-c[c="1D6FA"]:before{width:.772em;padding:.704em 0 0;content:"\3A9";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6FB"]:before{width:.833em;padding:.683em 0 .033em;content:"\2207";font-family:MJXZERO,MJXTEX}.MJX-TEX mjx-c[c="1D6FC"]:before{width:.64em;padding:.442em 0 .011em;content:"\3B1";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6FD"]:before{width:.566em;padding:.705em 0 .194em;content:"\3B2";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6FE"]:before{width:.518em;padding:.441em 0 .216em;content:"\3B3";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D6FF"]:before{width:.444em;padding:.717em 0 .01em;content:"\3B4";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D700"]:before{width:.466em;padding:.452em 0 .022em;content:"\3B5";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D701"]:before{width:.438em;padding:.704em 0 .204em;content:"\3B6";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D702"]:before{width:.497em;padding:.442em 0 .216em;content:"\3B7";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D703"]:before{width:.469em;padding:.705em 0 .01em;content:"\3B8";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D704"]:before{width:.354em;padding:.442em 0 .01em;content:"\3B9";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D705"]:before{width:.576em;padding:.442em 0 .011em;content:"\3BA";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D706"]:before{width:.583em;padding:.694em 0 .012em;content:"\3BB";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D707"]:before{width:.603em;padding:.442em 0 .216em;content:"\3BC";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D708"]:before{width:.494em;padding:.442em 0 0;content:"\3BD";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D709"]:before{width:.438em;padding:.704em 0 .205em;content:"\3BE";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D70A"]:before{width:.485em;padding:.441em 0 .011em;content:"\3BF";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D70B"]:before{width:.57em;padding:.431em 0 .011em;content:"\3C0";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D70C"]:before{width:.517em;padding:.442em 0 .216em;content:"\3C1";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D70D"]:before{width:.363em;padding:.442em 0 .107em;content:"\3C2";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D70E"]:before{width:.571em;padding:.431em 0 .011em;content:"\3C3";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D70F"]:before{width:.437em;padding:.431em 0 .013em;content:"\3C4";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D70F"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D70F"]:last-child:before{width:.517em}.MJX-TEX mjx-c[c="1D710"]:before{width:.54em;padding:.443em 0 .01em;content:"\3C5";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D711"]:before{width:.654em;padding:.442em 0 .218em;content:"\3C6";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D712"]:before{width:.626em;padding:.442em 0 .204em;content:"\3C7";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D713"]:before{width:.651em;padding:.694em 0 .205em;content:"\3C8";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D714"]:before{width:.622em;padding:.443em 0 .011em;content:"\3C9";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D715"]:before{width:.531em;padding:.715em 0 .022em;content:"\2202";font-family:MJXZERO,MJXTEX}.MJX-TEX mjx-c[c="1D716"]:before{width:.406em;padding:.431em 0 .011em;content:"\3F5";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D717"]:before{width:.591em;padding:.705em 0 .011em;content:"\3D1";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D718"]:before{width:.667em;padding:.434em 0 .006em;content:"\E009";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D718"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D718"]:last-child:before{width:.734em}.MJX-TEX mjx-c[c="1D719"]:before{width:.596em;padding:.694em 0 .205em;content:"\3D5";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D71A"]:before{width:.517em;padding:.442em 0 .194em;content:"\3F1";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D71B"]:before{width:.828em;padding:.431em 0 .01em;content:"\3D6";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-c[c="1D71C"]:before{width:.869em;padding:.711em 0 0;content:"A";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D71D"]:before{width:.866em;padding:.686em 0 0;content:"B";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D71E"]:before{width:.657em;padding:.68em 0 0;content:"\393";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D71E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D71E"]:last-child:before{width:.777em}.MJX-TEX mjx-c[c="1D71F"]:before{width:.958em;padding:.711em 0 0;content:"\394";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D720"]:before{width:.81em;padding:.68em 0 0;content:"E";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D721"]:before{width:.773em;padding:.686em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D722"]:before{width:.982em;padding:.686em 0 0;content:"H";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D723"]:before{width:.867em;padding:.702em 0 .017em;content:"\398";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D724"]:before{width:.511em;padding:.686em 0 0;content:"I";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D724"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D724"]:last-child:before{width:.573em}.MJX-TEX mjx-c[c="1D725"]:before{width:.971em;padding:.686em 0 0;content:"K";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D726"]:before{width:.806em;padding:.711em 0 0;content:"\39B";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D727"]:before{width:1.142em;padding:.686em 0 0;content:"M";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D727"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D727"]:last-child:before{width:1.219em}.MJX-TEX mjx-c[c="1D728"]:before{width:.95em;padding:.686em 0 0;content:"N";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D728"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D728"]:last-child:before{width:1.027em}.MJX-TEX mjx-c[c="1D729"]:before{width:.841em;padding:.675em 0 0;content:"\39E";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D72A"]:before{width:.837em;padding:.703em 0 .017em;content:"O";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D72B"]:before{width:.982em;padding:.68em 0 0;content:"\3A0";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D72C"]:before{width:.723em;padding:.686em 0 0;content:"P";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D72C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D72C"]:last-child:before{width:.847em}.MJX-TEX mjx-c[c="1D72D"]:before{width:.867em;padding:.702em 0 .017em;content:"\398";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D72E"]:before{width:.885em;padding:.686em 0 0;content:"\3A3";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D72F"]:before{width:.637em;padding:.675em 0 0;content:"T";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D72F"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D72F"]:last-child:before{width:.772em}.MJX-TEX mjx-c[c="1D730"]:before{width:.671em;padding:.703em 0 0;content:"\3A5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D730"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D730"]:last-child:before{width:.802em}.MJX-TEX mjx-c[c="1D731"]:before{width:.767em;padding:.686em 0 0;content:"\3A6";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D732"]:before{width:.947em;padding:.686em 0 0;content:"X";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D733"]:before{width:.714em;padding:.686em 0 0;content:"\3A8";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D733"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D733"]:last-child:before{width:.79em}.MJX-TEX mjx-c[c="1D734"]:before{width:.879em;padding:.703em 0 0;content:"\3A9";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D735"]:before{width:.833em;padding:.683em 0 .033em;content:"\2207";font-family:MJXZERO,MJXTEX}.MJX-TEX mjx-c[c="1D736"]:before{width:.761em;padding:.452em 0 .008em;content:"\3B1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D737"]:before{width:.66em;padding:.701em 0 .194em;content:"\3B2";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D738"]:before{width:.59em;padding:.451em 0 .211em;content:"\3B3";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D739"]:before{width:.522em;padding:.725em 0 .008em;content:"\3B4";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D73A"]:before{width:.529em;padding:.461em 0 .017em;content:"\3B5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D73B"]:before{width:.508em;padding:.711em 0 .202em;content:"\3B6";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D73C"]:before{width:.6em;padding:.452em 0 .211em;content:"\3B7";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D73D"]:before{width:.562em;padding:.702em 0 .008em;content:"\3B8";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D73E"]:before{width:.412em;padding:.452em 0 .008em;content:"\3B9";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D73F"]:before{width:.668em;padding:.452em 0 .008em;content:"\3BA";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D740"]:before{width:.671em;padding:.694em 0 .013em;content:"\3BB";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D741"]:before{width:.708em;padding:.452em 0 .211em;content:"\3BC";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D742"]:before{width:.577em;padding:.452em 0 0;content:"\3BD";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D743"]:before{width:.508em;padding:.711em 0 .201em;content:"\3BE";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D744"]:before{width:.585em;padding:.452em 0 .008em;content:"\3BF";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D745"]:before{width:.682em;padding:.444em 0 .008em;content:"\3C0";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D746"]:before{width:.612em;padding:.451em 0 .211em;content:"\3C1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D747"]:before{width:.424em;padding:.451em 0 .105em;content:"\3C2";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D748"]:before{width:.686em;padding:.444em 0 .008em;content:"\3C3";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D749"]:before{width:.521em;padding:.444em 0 .013em;content:"\3C4";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D749"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D749"]:last-child:before{width:.61em}.MJX-TEX mjx-c[c="1D74A"]:before{width:.631em;padding:.453em 0 .008em;content:"\3C5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D74B"]:before{width:.747em;padding:.452em 0 .216em;content:"\3C6";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D74C"]:before{width:.718em;padding:.452em 0 .201em;content:"\3C7";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D74D"]:before{width:.758em;padding:.694em 0 .202em;content:"\3C8";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D74E"]:before{width:.718em;padding:.453em 0 .008em;content:"\3C9";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D74F"]:before{width:.531em;padding:.715em 0 .022em;content:"\2202";font-family:MJXZERO,MJXTEX}.MJX-TEX mjx-c[c="1D750"]:before{width:.483em;padding:.444em 0 .007em;content:"\3F5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D751"]:before{width:.692em;padding:.701em 0 .008em;content:"\3D1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D752"]:before{width:.667em;padding:.434em 0 .006em;content:"\E009";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D752"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D752"]:last-child:before{width:.734em}.MJX-TEX mjx-c[c="1D753"]:before{width:.712em;padding:.694em 0 .202em;content:"\3D5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D754"]:before{width:.612em;padding:.451em 0 .194em;content:"\3F1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D755"]:before{width:.975em;padding:.444em 0 .008em;content:"\3D6";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D756"]:before{width:.733em;padding:.694em 0 0;content:"A";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D757"]:before{width:.733em;padding:.694em 0 0;content:"B";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D758"]:before{width:.581em;padding:.691em 0 0;content:"\393";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D759"]:before{width:.917em;padding:.694em 0 0;content:"\394";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D75A"]:before{width:.642em;padding:.691em 0 0;content:"E";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D75B"]:before{width:.672em;padding:.694em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D75C"]:before{width:.794em;padding:.694em 0 0;content:"H";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D75D"]:before{width:.856em;padding:.716em 0 .022em;content:"\398";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D75E"]:before{width:.331em;padding:.694em 0 0;content:"I";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D75F"]:before{width:.764em;padding:.694em 0 0;content:"K";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D760"]:before{width:.672em;padding:.694em 0 0;content:"\39B";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D761"]:before{width:.978em;padding:.694em 0 0;content:"M";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D762"]:before{width:.794em;padding:.694em 0 0;content:"N";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D763"]:before{width:.733em;padding:.688em 0 0;content:"\39E";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D764"]:before{width:.794em;padding:.716em 0 .022em;content:"O";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D765"]:before{width:.794em;padding:.691em 0 0;content:"\3A0";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D766"]:before{width:.703em;padding:.694em 0 0;content:"P";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D767"]:before{width:.856em;padding:.716em 0 .022em;content:"\398";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D768"]:before{width:.794em;padding:.694em 0 0;content:"\3A3";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D769"]:before{width:.733em;padding:.688em 0 0;content:"T";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D76A"]:before{width:.856em;padding:.715em 0 0;content:"\3A5";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D76B"]:before{width:.794em;padding:.694em 0 0;content:"\3A6";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D76C"]:before{width:.733em;padding:.694em 0 0;content:"X";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D76D"]:before{width:.856em;padding:.694em 0 0;content:"\3A8";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D76E"]:before{width:.794em;padding:.716em 0 0;content:"\3A9";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D76F"]:before{width:.833em;padding:.683em 0 .033em;content:"\2207";font-family:MJXZERO,MJXTEX}.MJX-TEX mjx-c[c="1D770"]:before{width:.761em;padding:.452em 0 .008em;content:"\3B1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D771"]:before{width:.66em;padding:.701em 0 .194em;content:"\3B2";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D772"]:before{width:.59em;padding:.451em 0 .211em;content:"\3B3";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D773"]:before{width:.522em;padding:.725em 0 .008em;content:"\3B4";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D774"]:before{width:.529em;padding:.461em 0 .017em;content:"\3B5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D775"]:before{width:.508em;padding:.711em 0 .202em;content:"\3B6";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D776"]:before{width:.6em;padding:.452em 0 .211em;content:"\3B7";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D777"]:before{width:.562em;padding:.702em 0 .008em;content:"\3B8";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D778"]:before{width:.412em;padding:.452em 0 .008em;content:"\3B9";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D779"]:before{width:.668em;padding:.452em 0 .008em;content:"\3BA";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D77A"]:before{width:.671em;padding:.694em 0 .013em;content:"\3BB";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D77B"]:before{width:.708em;padding:.452em 0 .211em;content:"\3BC";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D77C"]:before{width:.577em;padding:.452em 0 0;content:"\3BD";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D77D"]:before{width:.508em;padding:.711em 0 .201em;content:"\3BE";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D77E"]:before{width:.585em;padding:.452em 0 .008em;content:"\3BF";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D77F"]:before{width:.682em;padding:.444em 0 .008em;content:"\3C0";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D780"]:before{width:.612em;padding:.451em 0 .211em;content:"\3C1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D781"]:before{width:.424em;padding:.451em 0 .105em;content:"\3C2";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D782"]:before{width:.686em;padding:.444em 0 .008em;content:"\3C3";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D783"]:before{width:.521em;padding:.444em 0 .013em;content:"\3C4";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D783"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D783"]:last-child:before{width:.61em}.MJX-TEX mjx-c[c="1D784"]:before{width:.631em;padding:.453em 0 .008em;content:"\3C5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D785"]:before{width:.747em;padding:.452em 0 .216em;content:"\3C6";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D786"]:before{width:.718em;padding:.452em 0 .201em;content:"\3C7";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D787"]:before{width:.758em;padding:.694em 0 .202em;content:"\3C8";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D788"]:before{width:.718em;padding:.453em 0 .008em;content:"\3C9";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D789"]:before{width:.531em;padding:.715em 0 .022em;content:"\2202";font-family:MJXZERO,MJXTEX}.MJX-TEX mjx-c[c="1D78A"]:before{width:.483em;padding:.444em 0 .007em;content:"\3F5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D78B"]:before{width:.692em;padding:.701em 0 .008em;content:"\3D1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D78C"]:before{width:.667em;padding:.434em 0 .006em;content:"\E009";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D78C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D78C"]:last-child:before{width:.734em}.MJX-TEX mjx-c[c="1D78D"]:before{width:.712em;padding:.694em 0 .202em;content:"\3D5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D78E"]:before{width:.612em;padding:.451em 0 .194em;content:"\3F1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D78F"]:before{width:.975em;padding:.444em 0 .008em;content:"\3D6";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D790"]:before{width:.667em;padding:.694em 0 0;content:"A";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D791"]:before{width:.667em;padding:.694em 0 0;content:"B";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D792"]:before{width:.542em;padding:.691em 0 0;content:"\393";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D792"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D792"]:last-child:before{width:.646em}.MJX-TEX mjx-c[c="1D793"]:before{width:.833em;padding:.694em 0 0;content:"\394";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D794"]:before{width:.597em;padding:.691em 0 0;content:"E";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D794"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D794"]:last-child:before{width:.688em}.MJX-TEX mjx-c[c="1D795"]:before{width:.611em;padding:.694em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D795"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D795"]:last-child:before{width:.702em}.MJX-TEX mjx-c[c="1D796"]:before{width:.708em;padding:.694em 0 0;content:"H";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D796"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D796"]:last-child:before{width:.768em}.MJX-TEX mjx-c[c="1D797"]:before{width:.778em;padding:.715em 0 .022em;content:"\398";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D798"]:before{width:.278em;padding:.694em 0 0;content:"I";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D798"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D798"]:last-child:before{width:.338em}.MJX-TEX mjx-c[c="1D799"]:before{width:.694em;padding:.694em 0 0;content:"K";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D799"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D799"]:last-child:before{width:.785em}.MJX-TEX mjx-c[c="1D79A"]:before{width:.611em;padding:.694em 0 0;content:"\39B";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D79B"]:before{width:.875em;padding:.694em 0 0;content:"M";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D79B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D79B"]:last-child:before{width:.929em}.MJX-TEX mjx-c[c="1D79C"]:before{width:.708em;padding:.694em 0 0;content:"N";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D79C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D79C"]:last-child:before{width:.766em}.MJX-TEX mjx-c[c="1D79D"]:before{width:.667em;padding:.688em 0 0;content:"\39E";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D79D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D79D"]:last-child:before{width:.765em}.MJX-TEX mjx-c[c="1D79E"]:before{width:.736em;padding:.716em 0 .022em;content:"O";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D79F"]:before{width:.708em;padding:.691em 0 0;content:"\3A0";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D79F"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D79F"]:last-child:before{width:.768em}.MJX-TEX mjx-c[c="1D7A0"]:before{width:.639em;padding:.694em 0 0;content:"P";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D7A0"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D7A0"]:last-child:before{width:.69em}.MJX-TEX mjx-c[c="1D7A1"]:before{width:.778em;padding:.715em 0 .022em;content:"\398";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D7A2"]:before{width:.722em;padding:.694em 0 0;content:"\3A3";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D7A2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D7A2"]:last-child:before{width:.813em}.MJX-TEX mjx-c[c="1D7A3"]:before{width:.681em;padding:.688em 0 0;content:"T";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D7A3"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D7A3"]:last-child:before{width:.79em}.MJX-TEX mjx-c[c="1D7A4"]:before{width:.778em;padding:.716em 0 0;content:"\3A5";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D7A4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D7A4"]:last-child:before{width:.843em}.MJX-TEX mjx-c[c="1D7A5"]:before{width:.722em;padding:.694em 0 0;content:"\3A6";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D7A6"]:before{width:.667em;padding:.694em 0 0;content:"X";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D7A6"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D7A6"]:last-child:before{width:.758em}.MJX-TEX mjx-c[c="1D7A7"]:before{width:.778em;padding:.694em 0 0;content:"\3A8";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D7A7"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D7A7"]:last-child:before{width:.854em}.MJX-TEX mjx-c[c="1D7A8"]:before{width:.722em;padding:.716em 0 0;content:"\3A9";font-family:MJXZERO,MJXTEX-SS-I}.MJX-TEX mjx-c[c="1D7A9"]:before{width:.833em;padding:.683em 0 .033em;content:"\2207";font-family:MJXZERO,MJXTEX}.MJX-TEX mjx-c[c="1D7AA"]:before{width:.761em;padding:.452em 0 .008em;content:"\3B1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7AB"]:before{width:.66em;padding:.701em 0 .194em;content:"\3B2";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7AC"]:before{width:.59em;padding:.451em 0 .211em;content:"\3B3";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7AD"]:before{width:.522em;padding:.725em 0 .008em;content:"\3B4";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7AE"]:before{width:.529em;padding:.461em 0 .017em;content:"\3B5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7AF"]:before{width:.508em;padding:.711em 0 .202em;content:"\3B6";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7B0"]:before{width:.6em;padding:.452em 0 .211em;content:"\3B7";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7B1"]:before{width:.562em;padding:.702em 0 .008em;content:"\3B8";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7B2"]:before{width:.412em;padding:.452em 0 .008em;content:"\3B9";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7B3"]:before{width:.668em;padding:.452em 0 .008em;content:"\3BA";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7B4"]:before{width:.671em;padding:.694em 0 .013em;content:"\3BB";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7B5"]:before{width:.708em;padding:.452em 0 .211em;content:"\3BC";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7B6"]:before{width:.577em;padding:.452em 0 0;content:"\3BD";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7B7"]:before{width:.508em;padding:.711em 0 .201em;content:"\3BE";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7B8"]:before{width:.585em;padding:.452em 0 .008em;content:"\3BF";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7B9"]:before{width:.682em;padding:.444em 0 .008em;content:"\3C0";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7BA"]:before{width:.612em;padding:.451em 0 .211em;content:"\3C1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7BB"]:before{width:.424em;padding:.451em 0 .105em;content:"\3C2";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7BC"]:before{width:.686em;padding:.444em 0 .008em;content:"\3C3";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7BD"]:before{width:.521em;padding:.444em 0 .013em;content:"\3C4";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D7BD"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D7BD"]:last-child:before{width:.61em}.MJX-TEX mjx-c[c="1D7BE"]:before{width:.631em;padding:.453em 0 .008em;content:"\3C5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7BF"]:before{width:.747em;padding:.452em 0 .216em;content:"\3C6";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7C0"]:before{width:.718em;padding:.452em 0 .201em;content:"\3C7";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7C1"]:before{width:.758em;padding:.694em 0 .202em;content:"\3C8";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7C2"]:before{width:.718em;padding:.453em 0 .008em;content:"\3C9";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7C3"]:before{width:.531em;padding:.715em 0 .022em;content:"\2202";font-family:MJXZERO,MJXTEX}.MJX-TEX mjx-c[c="1D7C4"]:before{width:.483em;padding:.444em 0 .007em;content:"\3F5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7C5"]:before{width:.692em;padding:.701em 0 .008em;content:"\3D1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7C6"]:before{width:.667em;padding:.434em 0 .006em;content:"\E009";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D7C6"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D7C6"]:last-child:before{width:.734em}.MJX-TEX mjx-c[c="1D7C7"]:before{width:.712em;padding:.694em 0 .202em;content:"\3D5";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7C8"]:before{width:.612em;padding:.451em 0 .194em;content:"\3F1";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7C9"]:before{width:.975em;padding:.444em 0 .008em;content:"\3D6";font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-c[c="1D7CA"]:before{width:.643em;padding:.68em 0 0;content:"F";font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true])mjx-c[c="1D7CA"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true])mjx-c[c="1D7CA"]:last-child:before{width:.749em}.MJX-TEX mjx-c[c="1D7CB"]:before{width:.778em;padding:.605em 0 .085em;content:"\3DD";font-family:MJXZERO,MJXTEX-A}.MJX-TEX mjx-c[c="1D7CE"]:before{width:.575em;padding:.654em 0 .01em;content:"0";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7CF"]:before{width:.575em;padding:.655em 0 0;content:"1";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7D0"]:before{width:.575em;padding:.654em 0 0;content:"2";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7D1"]:before{width:.575em;padding:.655em 0 .011em;content:"3";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7D2"]:before{width:.575em;padding:.656em 0 0;content:"4";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7D3"]:before{width:.575em;padding:.655em 0 .011em;content:"5";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7D4"]:before{width:.575em;padding:.655em 0 .011em;content:"6";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7D5"]:before{width:.575em;padding:.676em 0 .011em;content:"7";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7D6"]:before{width:.575em;padding:.654em 0 .011em;content:"8";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7D7"]:before{width:.575em;padding:.654em 0 .011em;content:"9";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7D8"]:before{width:.575em;padding:.654em 0 .01em;content:"0";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7D9"]:before{width:.575em;padding:.655em 0 0;content:"1";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7DA"]:before{width:.575em;padding:.654em 0 0;content:"2";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7DB"]:before{width:.575em;padding:.655em 0 .011em;content:"3";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7DC"]:before{width:.575em;padding:.656em 0 0;content:"4";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7DD"]:before{width:.575em;padding:.655em 0 .011em;content:"5";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7DE"]:before{width:.575em;padding:.655em 0 .011em;content:"6";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7DF"]:before{width:.575em;padding:.676em 0 .011em;content:"7";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7E0"]:before{width:.575em;padding:.654em 0 .011em;content:"8";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7E1"]:before{width:.575em;padding:.654em 0 .011em;content:"9";font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-c[c="1D7E2"]:before{width:.5em;padding:.678em 0 .022em;content:"0";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D7E3"]:before{width:.5em;padding:.678em 0 0;content:"1";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D7E4"]:before{width:.5em;padding:.677em 0 0;content:"2";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D7E5"]:before{width:.5em;padding:.678em 0 .022em;content:"3";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D7E6"]:before{width:.5em;padding:.656em 0 0;content:"4";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D7E7"]:before{width:.5em;padding:.656em 0 .021em;content:"5";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D7E8"]:before{width:.5em;padding:.677em 0 .022em;content:"6";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D7E9"]:before{width:.5em;padding:.656em 0 .011em;content:"7";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D7EA"]:before{width:.5em;padding:.678em 0 .022em;content:"8";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D7EB"]:before{width:.5em;padding:.677em 0 .022em;content:"9";font-family:MJXZERO,MJXTEX-SS}.MJX-TEX mjx-c[c="1D7EC"]:before{width:.55em;padding:.715em 0 .022em;content:"0";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D7ED"]:before{width:.55em;padding:.716em 0 0;content:"1";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D7EE"]:before{width:.55em;padding:.716em 0 0;content:"2";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D7EF"]:before{width:.55em;padding:.716em 0 .022em;content:"3";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D7F0"]:before{width:.55em;padding:.694em 0 0;content:"4";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D7F1"]:before{width:.55em;padding:.694em 0 .022em;content:"5";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D7F2"]:before{width:.55em;padding:.716em 0 .022em;content:"6";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D7F3"]:before{width:.55em;padding:.695em 0 .011em;content:"7";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D7F4"]:before{width:.55em;padding:.715em 0 .022em;content:"8";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D7F5"]:before{width:.55em;padding:.716em 0 .022em;content:"9";font-family:MJXZERO,MJXTEX-SS-B}.MJX-TEX mjx-c[c="1D7F6"]:before{width:.525em;padding:.621em 0 .01em;content:"0";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D7F7"]:before{width:.525em;padding:.622em 0 0;content:"1";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D7F8"]:before{width:.525em;padding:.622em 0 0;content:"2";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D7F9"]:before{width:.525em;padding:.622em 0 .011em;content:"3";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D7FA"]:before{width:.525em;padding:.624em 0 0;content:"4";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D7FB"]:before{width:.525em;padding:.611em 0 .01em;content:"5";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D7FC"]:before{width:.525em;padding:.622em 0 .011em;content:"6";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D7FD"]:before{width:.525em;padding:.627em 0 .01em;content:"7";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D7FE"]:before{width:.525em;padding:.621em 0 .01em;content:"8";font-family:MJXZERO,MJXTEX-T}.MJX-TEX mjx-c[c="1D7FF"]:before{width:.525em;padding:.622em 0 .011em;content:"9";font-family:MJXZERO,MJXTEX-T}.MJX-TEX .mjx-b mjx-c[c="!"]:before{width:.35em;padding:.705em 0 0}.MJX-TEX .mjx-b mjx-c[c="22"]:before{width:.603em}.MJX-TEX .mjx-b mjx-c[c="#"]:before{width:.958em}.MJX-TEX .mjx-b mjx-c[c="$"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="%"]:before{width:.958em}.MJX-TEX .mjx-b mjx-c[c="&"]:before{width:.894em;padding:.705em 0 .011em}.MJX-TEX .mjx-b mjx-c[c="27"]:before{width:.319em}.MJX-TEX .mjx-b mjx-c[c="("]:before,.MJX-TEX .mjx-b mjx-c[c=")"]:before{width:.447em}.MJX-TEX .mjx-b mjx-c[c="*"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="+"]:before{width:.894em;padding:.633em 0 .131em}.MJX-TEX .mjx-b mjx-c[c=","]:before{width:.319em;padding:.171em 0 .194em}.MJX-TEX .mjx-b mjx-c[c="-"]:before{width:.383em;padding:.278em 0 0}.MJX-TEX .mjx-b mjx-c[c="."]:before{width:.319em;padding:.171em 0 0}.MJX-TEX .mjx-b mjx-c[c="/"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="0"]:before{width:.575em;padding:.654em 0 .01em}.MJX-TEX .mjx-b mjx-c[c="1"]:before{width:.575em;padding:.655em 0 0}.MJX-TEX .mjx-b mjx-c[c="2"]:before{width:.575em;padding:.654em 0 0}.MJX-TEX .mjx-b mjx-c[c="3"]:before{width:.575em;padding:.655em 0 .011em}.MJX-TEX .mjx-b mjx-c[c="4"]:before{width:.575em;padding:.656em 0 0}.MJX-TEX .mjx-b mjx-c[c="5"]:before,.MJX-TEX .mjx-b mjx-c[c="6"]:before{width:.575em;padding:.655em 0 .011em}.MJX-TEX .mjx-b mjx-c[c="7"]:before{width:.575em;padding:.676em 0 .011em}.MJX-TEX .mjx-b mjx-c[c="8"]:before,.MJX-TEX .mjx-b mjx-c[c="9"]:before{width:.575em;padding:.654em 0 .011em}.MJX-TEX .mjx-b mjx-c[c=":"]:before{width:.319em;padding:.444em 0 0}.MJX-TEX .mjx-b mjx-c[c=";"]:before{width:.319em;padding:.444em 0 .194em}.MJX-TEX .mjx-b mjx-c[c="<"]:before{width:.894em;padding:.587em 0 .085em}.MJX-TEX .mjx-b mjx-c[c="="]:before{width:.894em;padding:.393em 0 0}.MJX-TEX .mjx-b mjx-c[c=">"]:before{width:.894em;padding:.587em 0 .085em}.MJX-TEX .mjx-b mjx-c[c="?"]:before{width:.543em;padding:.7em 0 0}.MJX-TEX .mjx-b mjx-c[c="@"]:before{width:.894em;padding:.699em 0 .006em}.MJX-TEX .mjx-b mjx-c[c=A]:before{width:.869em;padding:.698em 0 0}.MJX-TEX .mjx-b mjx-c[c=B]:before{width:.818em}.MJX-TEX .mjx-b mjx-c[c=C]:before{width:.831em;padding:.697em 0 .011em}.MJX-TEX .mjx-b mjx-c[c=D]:before{width:.882em}.MJX-TEX .mjx-b mjx-c[c=E]:before{width:.756em}.MJX-TEX .mjx-b mjx-c[c=F]:before{width:.724em}.MJX-TEX .mjx-b mjx-c[c=G]:before{width:.904em;padding:.697em 0 .01em}.MJX-TEX .mjx-b mjx-c[c=H]:before{width:.9em}.MJX-TEX .mjx-b mjx-c[c=I]:before{width:.436em}.MJX-TEX .mjx-b mjx-c[c=J]:before{width:.594em;padding:.686em 0 .011em}.MJX-TEX .mjx-b mjx-c[c=K]:before{width:.901em}.MJX-TEX .mjx-b mjx-c[c=L]:before{width:.692em}.MJX-TEX .mjx-b mjx-c[c=M]:before{width:1.092em}.MJX-TEX .mjx-b mjx-c[c=N]:before{width:.9em}.MJX-TEX .mjx-b mjx-c[c=O]:before{width:.864em;padding:.696em 0 .01em}.MJX-TEX .mjx-b mjx-c[c=P]:before{width:.786em}.MJX-TEX .mjx-b mjx-c[c=Q]:before{width:.864em;padding:.696em 0 .193em}.MJX-TEX .mjx-b mjx-c[c=R]:before{width:.862em;padding:.686em 0 .011em}.MJX-TEX .mjx-b mjx-c[c=S]:before{width:.639em;padding:.697em 0 .011em}.MJX-TEX .mjx-b mjx-c[c=T]:before{width:.8em}.MJX-TEX .mjx-b mjx-c[c=U]:before{width:.885em;padding:.686em 0 .011em}.MJX-TEX .mjx-b mjx-c[c=V]:before{width:.869em;padding:.686em 0 .007em}.MJX-TEX .mjx-b mjx-c[c=W]:before{width:1.189em;padding:.686em 0 .007em}.MJX-TEX .mjx-b mjx-c[c=X]:before,.MJX-TEX .mjx-b mjx-c[c=Y]:before{width:.869em}.MJX-TEX .mjx-b mjx-c[c=Z]:before{width:.703em}.MJX-TEX .mjx-b mjx-c[c="["]:before{width:.319em}.MJX-TEX .mjx-b mjx-c[c="5C"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="]"]:before{width:.319em}.MJX-TEX .mjx-b mjx-c[c="^"]:before,.MJX-TEX .mjx-b mjx-c[c=_]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="`"]:before{width:.575em;padding:.706em 0 0}.MJX-TEX .mjx-b mjx-c[c=a]:before{width:.559em;padding:.453em 0 .006em}.MJX-TEX .mjx-b mjx-c[c=b]:before{width:.639em}.MJX-TEX .mjx-b mjx-c[c=c]:before{width:.511em;padding:.453em 0 .006em}.MJX-TEX .mjx-b mjx-c[c=d]:before{width:.639em}.MJX-TEX .mjx-b mjx-c[c=e]:before{width:.527em}.MJX-TEX .mjx-b mjx-c[c=f]:before{width:.351em;padding:.7em 0 0}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b mjx-c[c=f]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b mjx-c[c=f]:last-child:before{width:.452em}.MJX-TEX .mjx-b mjx-c[c=g]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c=h]:before{width:.639em}.MJX-TEX .mjx-b mjx-c[c=i]:before{width:.319em;padding:.695em 0 0}.MJX-TEX .mjx-b mjx-c[c=j]:before{width:.351em;padding:.695em 0 .2em}.MJX-TEX .mjx-b mjx-c[c=k]:before{width:.607em}.MJX-TEX .mjx-b mjx-c[c=l]:before{width:.319em}.MJX-TEX .mjx-b mjx-c[c=m]:before{width:.958em;padding:.45em 0 0}.MJX-TEX .mjx-b mjx-c[c=n]:before{width:.639em;padding:.45em 0 0}.MJX-TEX .mjx-b mjx-c[c=o]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c=p]:before{width:.639em;padding:.45em 0 .194em}.MJX-TEX .mjx-b mjx-c[c=q]:before{width:.607em;padding:.45em 0 .194em}.MJX-TEX .mjx-b mjx-c[c=r]:before{width:.474em;padding:.45em 0 0}.MJX-TEX .mjx-b mjx-c[c=s]:before{width:.454em;padding:.453em 0 .006em}.MJX-TEX .mjx-b mjx-c[c=t]:before{width:.447em;padding:.635em 0 .005em}.MJX-TEX .mjx-b mjx-c[c=u]:before{width:.639em;padding:.45em 0 .006em}.MJX-TEX .mjx-b mjx-c[c=v]:before{width:.607em;padding:.444em 0 0}.MJX-TEX .mjx-b mjx-c[c=w]:before{width:.831em;padding:.444em 0 0}.MJX-TEX .mjx-b mjx-c[c=x]:before{width:.607em;padding:.444em 0 0}.MJX-TEX .mjx-b mjx-c[c=y]:before{width:.607em;padding:.444em 0 .2em}.MJX-TEX .mjx-b mjx-c[c=z]:before{width:.511em;padding:.444em 0 0}.MJX-TEX .mjx-b mjx-c[c="{"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="|"]:before{width:.319em}.MJX-TEX .mjx-b mjx-c[c="}"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="~"]:before{width:.575em;padding:.344em 0 0}.MJX-TEX .mjx-b mjx-c[c=A8]:before{width:.575em;padding:.695em 0 0}.MJX-TEX .mjx-b mjx-c[c=AC]:before{width:.767em;padding:.371em 0 0}.MJX-TEX .mjx-b mjx-c[c=AF]:before{width:.575em;padding:.607em 0 0}.MJX-TEX .mjx-b mjx-c[c=B0]:before{width:.575em;padding:.702em 0 0}.MJX-TEX .mjx-b mjx-c[c=B1]:before{width:.894em;padding:.728em 0 .035em}.MJX-TEX .mjx-b mjx-c[c=B4]:before{width:.575em;padding:.706em 0 0}.MJX-TEX .mjx-b mjx-c[c=B7]:before{width:.319em;padding:.336em 0 0}.MJX-TEX .mjx-b mjx-c[c=D7]:before{width:.894em;padding:.53em 0 .028em}.MJX-TEX .mjx-b mjx-c[c=F7]:before{width:.894em;padding:.597em 0 .096em}.MJX-TEX .mjx-b mjx-c[c="131"]:before{width:.394em;padding:.452em 0 .008em}.MJX-TEX .mjx-b mjx-c[c="237"]:before{width:.439em;padding:.451em 0 .201em}.MJX-TEX .mjx-b mjx-c[c="2B9"]:before{width:.344em}.MJX-TEX .mjx-b mjx-c[c="2C6"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="2C7"]:before{width:.575em;padding:.66em 0 0}.MJX-TEX .mjx-b mjx-c[c="2C9"]:before{width:.575em;padding:.607em 0 0}.MJX-TEX .mjx-b mjx-c[c="2CA"]:before,.MJX-TEX .mjx-b mjx-c[c="2CB"]:before{width:.575em;padding:.706em 0 0}.MJX-TEX .mjx-b mjx-c[c="2D8"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="2D9"]:before{width:.575em;padding:.695em 0 0}.MJX-TEX .mjx-b mjx-c[c="2DA"]:before{width:.575em;padding:.702em 0 0}.MJX-TEX .mjx-b mjx-c[c="2DC"]:before{width:.575em;padding:.694em 0 0}.MJX-TEX .mjx-b mjx-c[c="300"]:before,.MJX-TEX .mjx-b mjx-c[c="301"]:before{padding:.706em 0 0}.MJX-TEX .mjx-b mjx-c[c="303"]:before{padding:.694em 0 0}.MJX-TEX .mjx-b mjx-c[c="304"]:before{padding:.607em 0 0}.MJX-TEX .mjx-b mjx-c[c="307"]:before,.MJX-TEX .mjx-b mjx-c[c="308"]:before{padding:.695em 0 0}.MJX-TEX .mjx-b mjx-c[c="30A"]:before{padding:.702em 0 0}.MJX-TEX .mjx-b mjx-c[c="30B"]:before{padding:.714em 0 0}.MJX-TEX .mjx-b mjx-c[c="30C"]:before{padding:.66em 0 0}.MJX-TEX .mjx-b mjx-c[c="338"]:before{padding:.711em 0 .21em}.MJX-TEX .mjx-b mjx-c[c="391"]:before{width:.869em;padding:.698em 0 0}.MJX-TEX .mjx-b mjx-c[c="392"]:before{width:.818em}.MJX-TEX .mjx-b mjx-c[c="393"]:before{width:.692em}.MJX-TEX .mjx-b mjx-c[c="394"]:before{width:.958em;padding:.698em 0 0}.MJX-TEX .mjx-b mjx-c[c="395"]:before{width:.756em}.MJX-TEX .mjx-b mjx-c[c="396"]:before{width:.703em}.MJX-TEX .mjx-b mjx-c[c="397"]:before{width:.9em}.MJX-TEX .mjx-b mjx-c[c="398"]:before{width:.894em;padding:.696em 0 .01em}.MJX-TEX .mjx-b mjx-c[c="399"]:before{width:.436em}.MJX-TEX .mjx-b mjx-c[c="39A"]:before{width:.901em}.MJX-TEX .mjx-b mjx-c[c="39B"]:before{width:.806em;padding:.698em 0 0}.MJX-TEX .mjx-b mjx-c[c="39C"]:before{width:1.092em}.MJX-TEX .mjx-b mjx-c[c="39D"]:before{width:.9em}.MJX-TEX .mjx-b mjx-c[c="39E"]:before{width:.767em}.MJX-TEX .mjx-b mjx-c[c="39F"]:before{width:.864em;padding:.696em 0 .01em}.MJX-TEX .mjx-b mjx-c[c="3A0"]:before{width:.9em}.MJX-TEX .mjx-b mjx-c[c="3A1"]:before{width:.786em}.MJX-TEX .mjx-b mjx-c[c="3A2"]:before{width:.894em;padding:.696em 0 .01em}.MJX-TEX .mjx-b mjx-c[c="3A3"]:before{width:.831em}.MJX-TEX .mjx-b mjx-c[c="3A4"]:before{width:.8em}.MJX-TEX .mjx-b mjx-c[c="3A5"]:before{width:.894em;padding:.697em 0 0}.MJX-TEX .mjx-b mjx-c[c="3A6"]:before{width:.831em}.MJX-TEX .mjx-b mjx-c[c="3A7"]:before{width:.869em}.MJX-TEX .mjx-b mjx-c[c="3A8"]:before{width:.894em}.MJX-TEX .mjx-b mjx-c[c="3A9"]:before{width:.831em;padding:.696em 0 0}.MJX-TEX .mjx-b mjx-c[c="3B1"]:before{width:.761em;padding:.452em 0 .008em;content:"\3B1"}.MJX-TEX .mjx-b mjx-c[c="3B2"]:before{width:.66em;padding:.701em 0 .194em;content:"\3B2"}.MJX-TEX .mjx-b mjx-c[c="3B3"]:before{width:.59em;padding:.451em 0 .211em;content:"\3B3"}.MJX-TEX .mjx-b mjx-c[c="3B4"]:before{width:.522em;padding:.725em 0 .008em;content:"\3B4"}.MJX-TEX .mjx-b mjx-c[c="3B5"]:before{width:.529em;padding:.461em 0 .017em;content:"\3B5"}.MJX-TEX .mjx-b mjx-c[c="3B6"]:before{width:.508em;padding:.711em 0 .202em;content:"\3B6"}.MJX-TEX .mjx-b mjx-c[c="3B7"]:before{width:.6em;padding:.452em 0 .211em;content:"\3B7"}.MJX-TEX .mjx-b mjx-c[c="3B8"]:before{width:.562em;padding:.702em 0 .008em;content:"\3B8"}.MJX-TEX .mjx-b mjx-c[c="3B9"]:before{width:.412em;padding:.452em 0 .008em;content:"\3B9"}.MJX-TEX .mjx-b mjx-c[c="3BA"]:before{width:.668em;padding:.452em 0 .008em;content:"\3BA"}.MJX-TEX .mjx-b mjx-c[c="3BB"]:before{width:.671em;padding:.694em 0 .013em;content:"\3BB"}.MJX-TEX .mjx-b mjx-c[c="3BC"]:before{width:.708em;padding:.452em 0 .211em;content:"\3BC"}.MJX-TEX .mjx-b mjx-c[c="3BD"]:before{width:.577em;padding:.452em 0 0;content:"\3BD"}.MJX-TEX .mjx-b mjx-c[c="3BE"]:before{width:.508em;padding:.711em 0 .201em;content:"\3BE"}.MJX-TEX .mjx-b mjx-c[c="3BF"]:before{width:.585em;padding:.452em 0 .008em;content:"\3BF"}.MJX-TEX .mjx-b mjx-c[c="3C0"]:before{width:.682em;padding:.444em 0 .008em;content:"\3C0"}.MJX-TEX .mjx-b mjx-c[c="3C1"]:before{width:.612em;padding:.451em 0 .211em;content:"\3C1"}.MJX-TEX .mjx-b mjx-c[c="3C2"]:before{width:.424em;padding:.451em 0 .105em;content:"\3C2"}.MJX-TEX .mjx-b mjx-c[c="3C3"]:before{width:.686em;padding:.444em 0 .008em;content:"\3C3"}.MJX-TEX .mjx-b mjx-c[c="3C4"]:before{width:.521em;padding:.444em 0 .013em;content:"\3C4"}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b mjx-c[c="3C4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b mjx-c[c="3C4"]:last-child:before{width:.61em}.MJX-TEX .mjx-b mjx-c[c="3C5"]:before{width:.631em;padding:.453em 0 .008em;content:"\3C5"}.MJX-TEX .mjx-b mjx-c[c="3C6"]:before{width:.747em;padding:.452em 0 .216em;content:"\3C6"}.MJX-TEX .mjx-b mjx-c[c="3C7"]:before{width:.718em;padding:.452em 0 .201em;content:"\3C7"}.MJX-TEX .mjx-b mjx-c[c="3C8"]:before{width:.758em;padding:.694em 0 .202em;content:"\3C8"}.MJX-TEX .mjx-b mjx-c[c="3C9"]:before{width:.718em;padding:.453em 0 .008em;content:"\3C9"}.MJX-TEX .mjx-b mjx-c[c="3D1"]:before{width:.692em;padding:.701em 0 .008em;content:"\3D1"}.MJX-TEX .mjx-b mjx-c[c="3D2"]:before{width:.894em;padding:.697em 0 0}.MJX-TEX .mjx-b mjx-c[c="3D5"]:before{width:.712em;padding:.694em 0 .202em;content:"\3D5"}.MJX-TEX .mjx-b mjx-c[c="3D6"]:before{width:.975em;padding:.444em 0 .008em;content:"\3D6"}.MJX-TEX .mjx-b mjx-c[c="3DC"]:before{width:.724em}.MJX-TEX .mjx-b mjx-c[c="3F1"]:before{width:.612em;padding:.451em 0 .194em;content:"\3F1"}.MJX-TEX .mjx-b mjx-c[c="3F5"]:before{width:.483em;padding:.444em 0 .007em;content:"\3F5"}.MJX-TEX .mjx-b mjx-c[c="2003"]:before{width:.999em}.MJX-TEX .mjx-b mjx-c[c="200A"]:before{width:.083em}.MJX-TEX .mjx-b mjx-c[c="2013"]:before{width:.575em;padding:.3em 0 0}.MJX-TEX .mjx-b mjx-c[c="2014"]:before,.MJX-TEX .mjx-b mjx-c[c="2015"]:before{width:1.15em;padding:.3em 0 0}.MJX-TEX .mjx-b mjx-c[c="2016"]:before,.MJX-TEX .mjx-b mjx-c[c="2017"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="2018"]:before,.MJX-TEX .mjx-b mjx-c[c="2019"]:before{width:.319em}.MJX-TEX .mjx-b mjx-c[c="201C"]:before,.MJX-TEX .mjx-b mjx-c[c="201D"]:before{width:.603em}.MJX-TEX .mjx-b mjx-c[c="2020"]:before{width:.511em;padding:.702em 0 .211em}.MJX-TEX .mjx-b mjx-c[c="2021"]:before{width:.511em}.MJX-TEX .mjx-b mjx-c[c="2022"]:before{width:.575em;padding:.474em 0 0}.MJX-TEX .mjx-b mjx-c[c="2026"]:before{width:1.295em;padding:.171em 0 0}.MJX-TEX .mjx-b mjx-c[c="2032"]:before{width:.344em}.MJX-TEX .mjx-b mjx-c[c="2033"]:before{width:.688em}.MJX-TEX .mjx-b mjx-c[c="2034"]:before{width:1.032em}.MJX-TEX .mjx-b mjx-c[c="203E"]:before{width:.575em;padding:.607em 0 0}.MJX-TEX .mjx-b mjx-c[c="2044"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="2057"]:before{width:1.376em}.MJX-TEX .mjx-b mjx-c[c="20D7"]:before{width:.575em;padding:.723em 0 0;font-family:MJXZERO,MJXTEX-VB}.MJX-TEX .mjx-b mjx-c[c="210F"]:before{width:.668em}.MJX-TEX .mjx-b mjx-c[c="2113"]:before{width:.474em}.MJX-TEX .mjx-b mjx-c[c="2118"]:before{width:.74em;padding:.461em 0 .21em}.MJX-TEX .mjx-b mjx-c[c="2135"]:before{width:.703em}.MJX-TEX .mjx-b mjx-c[c="2190"]:before{width:1.15em;padding:.518em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="2191"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="2192"]:before{width:1.15em;padding:.518em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="2193"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="2194"]:before{width:1.15em;padding:.518em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="2195"]:before{width:.575em;padding:.767em 0 .267em}.MJX-TEX .mjx-b mjx-c[c="2196"]:before,.MJX-TEX .mjx-b mjx-c[c="2197"]:before,.MJX-TEX .mjx-b mjx-c[c="2198"]:before,.MJX-TEX .mjx-b mjx-c[c="2199"]:before{width:1.15em}.MJX-TEX .mjx-b mjx-c[c="219A"]:before{width:1.15em;padding:.711em 0 .21em;content:"\2190\338"}.MJX-TEX .mjx-b mjx-c[c="219B"]:before{width:1.15em;padding:.711em 0 .21em;content:"\2192\338"}.MJX-TEX .mjx-b mjx-c[c="21A6"]:before{width:1.15em;padding:.518em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="21A9"]:before,.MJX-TEX .mjx-b mjx-c[c="21AA"]:before{width:1.282em;padding:.518em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="21AE"]:before{width:1.15em;padding:.711em 0 .21em;content:"\2194\338"}.MJX-TEX .mjx-b mjx-c[c="21BC"]:before{width:1.15em;padding:.518em 0 0}.MJX-TEX .mjx-b mjx-c[c="21BD"]:before{width:1.15em;padding:.281em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="21C0"]:before{width:1.15em;padding:.518em 0 0}.MJX-TEX .mjx-b mjx-c[c="21C1"]:before{width:1.15em;padding:.281em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="21CC"]:before{width:1.15em;padding:.718em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="21CD"]:before{width:1.15em;padding:.711em 0 .21em;content:"\21D0\338"}.MJX-TEX .mjx-b mjx-c[c="21CE"]:before{width:1.15em;padding:.711em 0 .21em;content:"\21D4\338"}.MJX-TEX .mjx-b mjx-c[c="21CF"]:before{width:1.15em;padding:.711em 0 .21em;content:"\21D2\338"}.MJX-TEX .mjx-b mjx-c[c="21D0"]:before{width:1.15em;padding:.547em 0 .046em}.MJX-TEX .mjx-b mjx-c[c="21D1"]:before{width:.703em}.MJX-TEX .mjx-b mjx-c[c="21D2"]:before{width:1.15em;padding:.547em 0 .046em}.MJX-TEX .mjx-b mjx-c[c="21D3"]:before{width:.703em}.MJX-TEX .mjx-b mjx-c[c="21D4"]:before{width:1.15em;padding:.547em 0 .046em}.MJX-TEX .mjx-b mjx-c[c="21D5"]:before{width:.703em;padding:.767em 0 .267em}.MJX-TEX .mjx-b mjx-c[c="2200"]:before{width:.639em;padding:.694em 0 .016em}.MJX-TEX .mjx-b mjx-c[c="2202"]:before{width:.628em;padding:.71em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="2203"]:before{width:.639em}.MJX-TEX .mjx-b mjx-c[c="2204"]:before{width:.639em;padding:.711em 0 .21em}.MJX-TEX .mjx-b mjx-c[c="2205"]:before{width:.575em;padding:.767em 0 .073em}.MJX-TEX .mjx-b mjx-c[c="2206"]:before{width:.958em;padding:.698em 0 0}.MJX-TEX .mjx-b mjx-c[c="2207"]:before{width:.958em;padding:.686em 0 .024em}.MJX-TEX .mjx-b mjx-c[c="2208"]:before{width:.767em;padding:.587em 0 .086em}.MJX-TEX .mjx-b mjx-c[c="2209"]:before{width:.767em;padding:.711em 0 .21em}.MJX-TEX .mjx-b mjx-c[c="220B"]:before{width:.767em;padding:.587em 0 .086em}.MJX-TEX .mjx-b mjx-c[c="220C"]:before{width:.767em;padding:.711em 0 .21em}.MJX-TEX .mjx-b mjx-c[c="2212"]:before{width:.894em;padding:.281em 0 0}.MJX-TEX .mjx-b mjx-c[c="2213"]:before{width:.894em;padding:.537em 0 .227em}.MJX-TEX .mjx-b mjx-c[c="2215"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="2216"]:before{width:.575em;padding:.75em 0 .25em}.MJX-TEX .mjx-b mjx-c[c="2217"]:before{width:.575em;padding:.472em 0 0}.MJX-TEX .mjx-b mjx-c[c="2218"]:before,.MJX-TEX .mjx-b mjx-c[c="2219"]:before{width:.575em;padding:.474em 0 0}.MJX-TEX .mjx-b mjx-c[c="221A"]:before{width:.958em;padding:.82em 0 .18em}.MJX-TEX .mjx-b mjx-c[c="221D"]:before{width:.894em;padding:.451em 0 .008em}.MJX-TEX .mjx-b mjx-c[c="221E"]:before{width:1.15em;padding:.452em 0 .008em}.MJX-TEX .mjx-b mjx-c[c="2220"]:before{padding:.714em 0 0}.MJX-TEX .mjx-b mjx-c[c="2223"]:before{width:.319em}.MJX-TEX .mjx-b mjx-c[c="2224"]:before{width:.319em;content:"\2223\338"}.MJX-TEX .mjx-b mjx-c[c="2225"]:before{width:.575em}.MJX-TEX .mjx-b mjx-c[c="2226"]:before{width:.575em;content:"\2225\338"}.MJX-TEX .mjx-b mjx-c[c="2227"]:before{width:.767em;padding:.604em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="2228"]:before{width:.767em;padding:.604em 0 .016em}.MJX-TEX .mjx-b mjx-c[c="2229"]:before{width:.767em;padding:.603em 0 .016em}.MJX-TEX .mjx-b mjx-c[c="222A"]:before{width:.767em;padding:.604em 0 .016em}.MJX-TEX .mjx-b mjx-c[c="222B"]:before{width:.569em;padding:.711em 0 .211em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b mjx-c[c="222B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b mjx-c[c="222B"]:last-child:before{width:.632em}.MJX-TEX .mjx-b mjx-c[c="223C"]:before{width:.894em;padding:.391em 0 0}.MJX-TEX .mjx-b mjx-c[c="2240"]:before{width:.319em}.MJX-TEX .mjx-b mjx-c[c="2241"]:before{width:.894em;padding:.711em 0 .21em;content:"\223C\338"}.MJX-TEX .mjx-b mjx-c[c="2243"]:before{width:.894em;padding:.502em 0 0}.MJX-TEX .mjx-b mjx-c[c="2244"]:before{width:.894em;padding:.711em 0 .21em}.MJX-TEX .mjx-b mjx-c[c="2245"]:before{width:.894em;padding:.638em 0 .027em}.MJX-TEX .mjx-b mjx-c[c="2247"]:before{width:.894em;padding:.711em 0 .21em;content:"\2245\338"}.MJX-TEX .mjx-b mjx-c[c="2248"]:before{width:.894em;padding:.524em 0 0}.MJX-TEX .mjx-b mjx-c[c="2249"]:before{width:.894em;padding:.711em 0 .21em}.MJX-TEX .mjx-b mjx-c[c="224D"]:before{width:.894em;padding:.533em 0 .032em}.MJX-TEX .mjx-b mjx-c[c="2250"]:before{width:.894em;padding:.721em 0 0}.MJX-TEX .mjx-b mjx-c[c="2260"]:before{width:.894em;padding:.711em 0 .21em}.MJX-TEX .mjx-b mjx-c[c="2261"]:before{width:.894em;padding:.505em 0 0}.MJX-TEX .mjx-b mjx-c[c="2262"]:before{width:.894em;padding:.711em 0 .21em}.MJX-TEX .mjx-b mjx-c[c="2264"]:before,.MJX-TEX .mjx-b mjx-c[c="2265"]:before{width:.894em;padding:.697em 0 .199em}.MJX-TEX .mjx-b mjx-c[c="226A"]:before{width:1.15em;padding:.617em 0 .116em}.MJX-TEX .mjx-b mjx-c[c="226B"]:before{width:1.15em;padding:.618em 0 .116em}.MJX-TEX .mjx-b mjx-c[c="226D"]:before{width:.894em;padding:.711em 0 .21em}.MJX-TEX .mjx-b mjx-c[c="226E"]:before{width:.894em;content:"<\338"}.MJX-TEX .mjx-b mjx-c[c="226F"]:before{width:.894em;content:">\338"}.MJX-TEX .mjx-b mjx-c[c="2270"]:before{width:.894em;padding:.711em 0 .21em;content:"\2264\338"}.MJX-TEX .mjx-b mjx-c[c="2271"]:before{width:.894em;padding:.711em 0 .21em;content:"\2265\338"}.MJX-TEX .mjx-b mjx-c[c="227A"]:before{width:.894em;padding:.585em 0 .086em}.MJX-TEX .mjx-b mjx-c[c="227B"]:before{width:.894em;padding:.586em 0 .086em}.MJX-TEX .mjx-b mjx-c[c="2280"]:before{width:.894em;padding:.711em 0 .21em;content:"\227A\338"}.MJX-TEX .mjx-b mjx-c[c="2281"]:before{width:.894em;padding:.711em 0 .21em;content:"\227B\338"}.MJX-TEX .mjx-b mjx-c[c="2282"]:before{width:.894em;padding:.587em 0 .085em}.MJX-TEX .mjx-b mjx-c[c="2283"]:before{width:.894em;padding:.587em 0 .086em}.MJX-TEX .mjx-b mjx-c[c="2284"]:before,.MJX-TEX .mjx-b mjx-c[c="2285"]:before{width:.894em;padding:.711em 0 .21em}.MJX-TEX .mjx-b mjx-c[c="2286"]:before,.MJX-TEX .mjx-b mjx-c[c="2287"]:before{width:.894em;padding:.697em 0 .199em}.MJX-TEX .mjx-b mjx-c[c="2288"]:before{width:.894em;padding:.711em 0 .21em;content:"\2286\338"}.MJX-TEX .mjx-b mjx-c[c="2289"]:before{width:.894em;padding:.711em 0 .21em;content:"\2287\338"}.MJX-TEX .mjx-b mjx-c[c="228E"]:before{width:.767em;padding:.604em 0 .016em}.MJX-TEX .mjx-b mjx-c[c="2291"]:before,.MJX-TEX .mjx-b mjx-c[c="2292"]:before{width:.894em;padding:.697em 0 .199em}.MJX-TEX .mjx-b mjx-c[c="2293"]:before,.MJX-TEX .mjx-b mjx-c[c="2294"]:before{width:.767em;padding:.604em 0 0}.MJX-TEX .mjx-b mjx-c[c="2295"]:before,.MJX-TEX .mjx-b mjx-c[c="2296"]:before,.MJX-TEX .mjx-b mjx-c[c="2297"]:before,.MJX-TEX .mjx-b mjx-c[c="2298"]:before,.MJX-TEX .mjx-b mjx-c[c="2299"]:before{width:.894em;padding:.632em 0 .132em}.MJX-TEX .mjx-b mjx-c[c="22A2"]:before,.MJX-TEX .mjx-b mjx-c[c="22A3"]:before{width:.703em}.MJX-TEX .mjx-b mjx-c[c="22A4"]:before{width:.894em;padding:.694em 0 0}.MJX-TEX .mjx-b mjx-c[c="22A5"]:before{width:.894em;padding:.693em 0 0}.MJX-TEX .mjx-b mjx-c[c="22A8"]:before{width:.974em}.MJX-TEX .mjx-b mjx-c[c="22AC"]:before{width:.703em;padding:.711em 0 .21em;content:"\22A2\338"}.MJX-TEX .mjx-b mjx-c[c="22AD"]:before{width:.974em;padding:.75em 0 .249em;content:"\22A8\338"}.MJX-TEX .mjx-b mjx-c[c="22C4"]:before{width:.575em;padding:.523em 0 .021em}.MJX-TEX .mjx-b mjx-c[c="22C5"]:before{width:.319em;padding:.336em 0 0}.MJX-TEX .mjx-b mjx-c[c="22C6"]:before{width:.575em;padding:.502em 0 0}.MJX-TEX .mjx-b mjx-c[c="22C8"]:before{width:1em;padding:.54em 0 .039em}.MJX-TEX .mjx-b mjx-c[c="22E2"]:before,.MJX-TEX .mjx-b mjx-c[c="22E3"]:before{width:.894em;padding:.711em 0 .21em}.MJX-TEX .mjx-b mjx-c[c="22EE"]:before{width:.319em;padding:.951em 0 .029em}.MJX-TEX .mjx-b mjx-c[c="22EF"]:before{width:1.295em;padding:.336em 0 0}.MJX-TEX .mjx-b mjx-c[c="22F1"]:before{width:1.323em;padding:.871em 0 0}.MJX-TEX .mjx-b mjx-c[c="230A"]:before,.MJX-TEX .mjx-b mjx-c[c="230B"]:before,.MJX-TEX .mjx-b mjx-c[c="2308"]:before,.MJX-TEX .mjx-b mjx-c[c="2309"]:before{width:.511em}.MJX-TEX .mjx-b mjx-c[c="2322"]:before{width:1.15em;padding:.405em 0 0}.MJX-TEX .mjx-b mjx-c[c="2323"]:before{width:1.15em;padding:.392em 0 0}.MJX-TEX .mjx-b mjx-c[c="232A"]:before,.MJX-TEX .mjx-b mjx-c[c="2329"]:before{width:.447em}.MJX-TEX .mjx-b mjx-c[c="25B3"]:before,.MJX-TEX .mjx-b mjx-c[c="25B5"]:before{width:1.022em;padding:.711em 0 0}.MJX-TEX .mjx-b mjx-c[c="25B9"]:before{width:.575em;padding:.54em 0 .039em}.MJX-TEX .mjx-b mjx-c[c="25BD"]:before,.MJX-TEX .mjx-b mjx-c[c="25BF"]:before{width:1.022em;padding:.5em 0 .21em}.MJX-TEX .mjx-b mjx-c[c="25C3"]:before{width:.575em;padding:.539em 0 .038em}.MJX-TEX .mjx-b mjx-c[c="25EF"]:before{width:1.15em}.MJX-TEX .mjx-b mjx-c[c="2660"]:before{width:.894em;padding:.719em 0 .129em}.MJX-TEX .mjx-b mjx-c[c="2661"]:before{width:.894em;padding:.711em 0 .024em}.MJX-TEX .mjx-b mjx-c[c="2662"]:before{width:.894em;padding:.719em 0 .154em}.MJX-TEX .mjx-b mjx-c[c="2663"]:before{width:.894em;padding:.719em 0 .129em}.MJX-TEX .mjx-b mjx-c[c="266D"]:before{width:.447em}.MJX-TEX .mjx-b mjx-c[c="266E"]:before{width:.447em;padding:.741em 0 .223em}.MJX-TEX .mjx-b mjx-c[c="266F"]:before{width:.447em}.MJX-TEX .mjx-b mjx-c[c="2758"]:before{width:.319em}.MJX-TEX .mjx-b mjx-c[c="27E8"]:before,.MJX-TEX .mjx-b mjx-c[c="27E9"]:before{width:.447em}.MJX-TEX .mjx-b mjx-c[c="27F5"]:before{width:1.805em;padding:.518em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="27F6"]:before{width:1.833em;padding:.518em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="27F7"]:before{width:2.126em;padding:.518em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="27F8"]:before{width:1.868em;padding:.547em 0 .046em}.MJX-TEX .mjx-b mjx-c[c="27F9"]:before{width:1.87em;padding:.547em 0 .046em}.MJX-TEX .mjx-b mjx-c[c="27FA"]:before{width:2.126em;padding:.547em 0 .046em}.MJX-TEX .mjx-b mjx-c[c="27FC"]:before{width:1.833em;padding:.518em 0 .017em}.MJX-TEX .mjx-b mjx-c[c="29F8"]:before{width:.894em;padding:.711em 0 .21em;font-family:MJXZERO,MJXTEX-BI}.MJX-TEX .mjx-b mjx-c[c="2A2F"]:before{width:.894em;padding:.53em 0 .028em}.MJX-TEX .mjx-b mjx-c[c="2A3F"]:before{width:.9em}.MJX-TEX .mjx-b mjx-c[c="2AAF"]:before{width:.894em;padding:.696em 0 .199em}.MJX-TEX .mjx-b mjx-c[c="2AB0"]:before{width:.894em;padding:.697em 0 .199em}.MJX-TEX .mjx-b mjx-c[c="3008"]:before,.MJX-TEX .mjx-b mjx-c[c="3009"]:before{width:.447em}.MJX-TEX .mjx-i mjx-c[c="!"]:before{width:.307em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="!"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="!"]:last-child:before{width:.38em}.MJX-TEX .mjx-i mjx-c[c="22"]:before{width:.514em}.MJX-TEX .mjx-i mjx-c[c="#"]:before,.MJX-TEX .mjx-i mjx-c[c="%"]:before{width:.818em}.MJX-TEX .mjx-i mjx-c[c="&"]:before{width:.767em}.MJX-TEX .mjx-i mjx-c[c="27"]:before{width:.307em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="27"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="27"]:last-child:before{width:.377em}.MJX-TEX .mjx-i mjx-c[c="("]:before{width:.409em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="("]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="("]:last-child:before{width:.517em}.MJX-TEX .mjx-i mjx-c[c=")"]:before{width:.409em}.MJX-TEX .mjx-i mjx-c[c="*"]:before{width:.511em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="*"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="*"]:last-child:before{width:.584em}.MJX-TEX .mjx-i mjx-c[c="+"]:before{width:.767em;padding:.557em 0 .057em}.MJX-TEX .mjx-i mjx-c[c=","]:before{width:.307em}.MJX-TEX .mjx-i mjx-c[c="-"]:before{width:.358em}.MJX-TEX .mjx-i mjx-c[c="."]:before{width:.307em}.MJX-TEX .mjx-i mjx-c[c="/"]:before{width:.778em;padding:.716em 0 .215em}.MJX-TEX .mjx-i mjx-c[c="0"]:before{width:.511em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="0"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="0"]:last-child:before{width:.562em}.MJX-TEX .mjx-i mjx-c[c="1"]:before{width:.511em}.MJX-TEX .mjx-i mjx-c[c="2"]:before{width:.511em;padding:.666em 0 .022em}.MJX-TEX .mjx-i mjx-c[c="3"]:before{width:.511em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="3"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="3"]:last-child:before{width:.562em}.MJX-TEX .mjx-i mjx-c[c="4"]:before{width:.511em;padding:.666em 0 .194em}.MJX-TEX .mjx-i mjx-c[c="5"]:before{width:.511em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="5"]:last-child:before{width:.567em}.MJX-TEX .mjx-i mjx-c[c="6"]:before{width:.511em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="6"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="6"]:last-child:before{width:.565em}.MJX-TEX .mjx-i mjx-c[c="7"]:before{width:.511em;padding:.666em 0 .022em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="7"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="7"]:last-child:before{width:.634em}.MJX-TEX .mjx-i mjx-c[c="8"]:before,.MJX-TEX .mjx-i mjx-c[c="9"]:before{width:.511em}.MJX-TEX .mjx-i mjx-c[c=":"]:before,.MJX-TEX .mjx-i mjx-c[c=";"]:before{width:.307em}.MJX-TEX .mjx-i mjx-c[c="="]:before{width:.767em;padding:.367em 0 0}.MJX-TEX .mjx-i mjx-c[c="?"]:before{width:.511em;padding:.716em 0 0}.MJX-TEX .mjx-i mjx-c[c="@"]:before{width:.767em}.MJX-TEX .mjx-i mjx-c[c=B]:before{width:.759em}.MJX-TEX .mjx-i mjx-c[c=C]:before{width:.715em}.MJX-TEX .mjx-i mjx-c[c=D]:before{width:.828em}.MJX-TEX .mjx-i mjx-c[c=E]:before{width:.738em}.MJX-TEX .mjx-i mjx-c[c=F]:before{width:.643em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c=F]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c=F]:last-child:before{width:.749em}.MJX-TEX .mjx-i mjx-c[c=G]:before{width:.786em}.MJX-TEX .mjx-i mjx-c[c=H]:before{width:.831em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c=H]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c=H]:last-child:before{width:.888em}.MJX-TEX .mjx-i mjx-c[c=I]:before{width:.44em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c=I]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c=I]:last-child:before{width:.504em}.MJX-TEX .mjx-i mjx-c[c=J]:before{width:.555em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c=J]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c=J]:last-child:before{width:.633em}.MJX-TEX .mjx-i mjx-c[c=K]:before{width:.849em}.MJX-TEX .mjx-i mjx-c[c=L]:before{width:.681em}.MJX-TEX .mjx-i mjx-c[c=M]:before{width:.97em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c=M]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c=M]:last-child:before{width:1.051em}.MJX-TEX .mjx-i mjx-c[c=N]:before{width:.803em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c=N]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c=N]:last-child:before{width:.888em}.MJX-TEX .mjx-i mjx-c[c=O]:before{width:.763em}.MJX-TEX .mjx-i mjx-c[c=P]:before{width:.642em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c=P]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c=P]:last-child:before{width:.751em}.MJX-TEX .mjx-i mjx-c[c=Q]:before{width:.791em}.MJX-TEX .mjx-i mjx-c[c=R]:before{width:.759em}.MJX-TEX .mjx-i mjx-c[c=S]:before{width:.613em}.MJX-TEX .mjx-i mjx-c[c=T]:before{width:.584em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c=T]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c=T]:last-child:before{width:.704em}.MJX-TEX .mjx-i mjx-c[c=U]:before{width:.683em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c=U]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c=U]:last-child:before{width:.767em}.MJX-TEX .mjx-i mjx-c[c=V]:before{width:.583em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c=V]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c=V]:last-child:before{width:.769em}.MJX-TEX .mjx-i mjx-c[c=W]:before{width:.944em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c=W]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c=W]:last-child:before{width:1.048em}.MJX-TEX .mjx-i mjx-c[c=X]:before{width:.828em}.MJX-TEX .mjx-i mjx-c[c=Y]:before{width:.581em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c=Y]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c=Y]:last-child:before{width:.763em}.MJX-TEX .mjx-i mjx-c[c=Z]:before{width:.683em}.MJX-TEX .mjx-i mjx-c[c="["]:before{width:.307em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="["]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="["]:last-child:before{width:.446em}.MJX-TEX .mjx-i mjx-c[c="]"]:before{width:.307em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="]"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="]"]:last-child:before{width:.359em}.MJX-TEX .mjx-i mjx-c[c="^"]:before,.MJX-TEX .mjx-i mjx-c[c=_]:before{width:.511em}.MJX-TEX .mjx-i mjx-c[c=a]:before{width:.529em;padding:.441em 0 .01em}.MJX-TEX .mjx-i mjx-c[c=b]:before{width:.429em}.MJX-TEX .mjx-i mjx-c[c=c]:before{width:.433em;padding:.442em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=d]:before{width:.52em}.MJX-TEX .mjx-i mjx-c[c=e]:before{width:.466em;padding:.442em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=f]:before{width:.49em;padding:.705em 0 .205em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c=f]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c=f]:last-child:before{width:.55em}.MJX-TEX .mjx-i mjx-c[c=g]:before{width:.477em;padding:.442em 0 .205em}.MJX-TEX .mjx-i mjx-c[c=h]:before{width:.576em;padding:.694em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=i]:before{width:.345em;padding:.661em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=j]:before{width:.412em;padding:.661em 0 .204em}.MJX-TEX .mjx-i mjx-c[c=k]:before{width:.521em;padding:.694em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=l]:before{width:.298em;padding:.694em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=m]:before{width:.878em;padding:.442em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=n]:before{width:.6em;padding:.442em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=o]:before{width:.485em;padding:.441em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=p]:before{width:.503em}.MJX-TEX .mjx-i mjx-c[c=q]:before{width:.446em}.MJX-TEX .mjx-i mjx-c[c=r]:before{width:.451em;padding:.442em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=s]:before{width:.469em;padding:.442em 0 .01em}.MJX-TEX .mjx-i mjx-c[c=t]:before{width:.361em;padding:.626em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=u]:before{width:.572em}.MJX-TEX .mjx-i mjx-c[c=v]:before{width:.485em;padding:.443em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=w]:before{width:.716em;padding:.443em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=x]:before{width:.572em;padding:.442em 0 .011em}.MJX-TEX .mjx-i mjx-c[c=y]:before{width:.49em;padding:.442em 0 .205em}.MJX-TEX .mjx-i mjx-c[c=z]:before{width:.465em;padding:.442em 0 .011em}.MJX-TEX .mjx-i mjx-c[c="~"]:before{width:.511em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="~"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="~"]:last-child:before{width:.571em}.MJX-TEX .mjx-i mjx-c[c="131"]:before{width:.307em;padding:.441em 0 .01em}.MJX-TEX .mjx-i mjx-c[c="237"]:before{width:.332em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="303"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="303"]:last-child:before{width:.06em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="304"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="304"]:last-child:before{width:.054em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="306"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="306"]:last-child:before{width:.062em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="30B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="30B"]:last-child:before{width:.065em}.MJX-TEX .mjx-i mjx-c[c="30C"]:before{padding:.638em 0 0}.MJX-TEX .mjx-i mjx-c[c="392"]:before{width:.759em}.MJX-TEX .mjx-i mjx-c[c="393"]:before{width:.615em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="393"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="393"]:last-child:before{width:.721em}.MJX-TEX .mjx-i mjx-c[c="395"]:before{width:.738em}.MJX-TEX .mjx-i mjx-c[c="396"]:before{width:.683em}.MJX-TEX .mjx-i mjx-c[c="397"]:before{width:.831em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="397"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="397"]:last-child:before{width:.888em}.MJX-TEX .mjx-i mjx-c[c="398"]:before{width:.763em}.MJX-TEX .mjx-i mjx-c[c="399"]:before{width:.44em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="399"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="399"]:last-child:before{width:.504em}.MJX-TEX .mjx-i mjx-c[c="39A"]:before{width:.849em}.MJX-TEX .mjx-i mjx-c[c="39C"]:before{width:.97em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="39C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="39C"]:last-child:before{width:1.051em}.MJX-TEX .mjx-i mjx-c[c="39D"]:before{width:.803em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="39D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="39D"]:last-child:before{width:.888em}.MJX-TEX .mjx-i mjx-c[c="39E"]:before{width:.742em}.MJX-TEX .mjx-i mjx-c[c="39F"]:before{width:.763em}.MJX-TEX .mjx-i mjx-c[c="3A0"]:before{width:.831em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="3A0"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="3A0"]:last-child:before{width:.887em}.MJX-TEX .mjx-i mjx-c[c="3A1"]:before{width:.642em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="3A1"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="3A1"]:last-child:before{width:.751em}.MJX-TEX .mjx-i mjx-c[c="3A2"]:before{width:.763em}.MJX-TEX .mjx-i mjx-c[c="3A3"]:before{width:.78em}.MJX-TEX .mjx-i mjx-c[c="3A4"]:before{width:.584em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="3A4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="3A4"]:last-child:before{width:.704em}.MJX-TEX .mjx-i mjx-c[c="3A5"]:before{width:.583em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="3A5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="3A5"]:last-child:before{width:.7em}.MJX-TEX .mjx-i mjx-c[c="3A6"]:before{width:.667em}.MJX-TEX .mjx-i mjx-c[c="3A7"]:before{width:.828em}.MJX-TEX .mjx-i mjx-c[c="3A8"]:before{width:.612em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="3A8"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="3A8"]:last-child:before{width:.692em}.MJX-TEX .mjx-i mjx-c[c="3A9"]:before{width:.772em}.MJX-TEX .mjx-i mjx-c[c="3B1"]:before{width:.64em;padding:.442em 0 .011em;content:"\3B1"}.MJX-TEX .mjx-i mjx-c[c="3B2"]:before{width:.566em;padding:.705em 0 .194em;content:"\3B2"}.MJX-TEX .mjx-i mjx-c[c="3B3"]:before{width:.518em;padding:.441em 0 .216em;content:"\3B3"}.MJX-TEX .mjx-i mjx-c[c="3B4"]:before{width:.444em;padding:.717em 0 .01em;content:"\3B4"}.MJX-TEX .mjx-i mjx-c[c="3B5"]:before{width:.466em;padding:.452em 0 .022em;content:"\3B5"}.MJX-TEX .mjx-i mjx-c[c="3B6"]:before{width:.438em;padding:.704em 0 .204em;content:"\3B6"}.MJX-TEX .mjx-i mjx-c[c="3B7"]:before{width:.497em;padding:.442em 0 .216em;content:"\3B7"}.MJX-TEX .mjx-i mjx-c[c="3B8"]:before{width:.469em;padding:.705em 0 .01em;content:"\3B8"}.MJX-TEX .mjx-i mjx-c[c="3B9"]:before{width:.354em;padding:.442em 0 .01em;content:"\3B9"}.MJX-TEX .mjx-i mjx-c[c="3BA"]:before{width:.576em;padding:.442em 0 .011em;content:"\3BA"}.MJX-TEX .mjx-i mjx-c[c="3BB"]:before{width:.583em;padding:.694em 0 .012em;content:"\3BB"}.MJX-TEX .mjx-i mjx-c[c="3BC"]:before{width:.603em;padding:.442em 0 .216em;content:"\3BC"}.MJX-TEX .mjx-i mjx-c[c="3BD"]:before{width:.494em;padding:.442em 0 0;content:"\3BD"}.MJX-TEX .mjx-i mjx-c[c="3BE"]:before{width:.438em;padding:.704em 0 .205em;content:"\3BE"}.MJX-TEX .mjx-i mjx-c[c="3BF"]:before{width:.485em;padding:.441em 0 .011em;content:"\3BF"}.MJX-TEX .mjx-i mjx-c[c="3C0"]:before{width:.57em;padding:.431em 0 .011em;content:"\3C0"}.MJX-TEX .mjx-i mjx-c[c="3C1"]:before{width:.517em;padding:.442em 0 .216em;content:"\3C1"}.MJX-TEX .mjx-i mjx-c[c="3C2"]:before{width:.363em;padding:.442em 0 .107em;content:"\3C2"}.MJX-TEX .mjx-i mjx-c[c="3C3"]:before{width:.571em;padding:.431em 0 .011em;content:"\3C3"}.MJX-TEX .mjx-i mjx-c[c="3C4"]:before{width:.437em;padding:.431em 0 .013em;content:"\3C4"}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="3C4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="3C4"]:last-child:before{width:.517em}.MJX-TEX .mjx-i mjx-c[c="3C5"]:before{width:.54em;padding:.443em 0 .01em;content:"\3C5"}.MJX-TEX .mjx-i mjx-c[c="3C6"]:before{width:.654em;padding:.442em 0 .218em;content:"\3C6"}.MJX-TEX .mjx-i mjx-c[c="3C7"]:before{width:.626em;padding:.442em 0 .204em;content:"\3C7"}.MJX-TEX .mjx-i mjx-c[c="3C8"]:before{width:.651em;padding:.694em 0 .205em;content:"\3C8"}.MJX-TEX .mjx-i mjx-c[c="3C9"]:before{width:.622em;padding:.443em 0 .011em;content:"\3C9"}.MJX-TEX .mjx-i mjx-c[c="3D1"]:before{width:.591em;padding:.705em 0 .011em;content:"\3D1"}.MJX-TEX .mjx-i mjx-c[c="3D2"]:before{width:.583em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="3D2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="3D2"]:last-child:before{width:.7em}.MJX-TEX .mjx-i mjx-c[c="3D5"]:before{width:.596em;padding:.694em 0 .205em;content:"\3D5"}.MJX-TEX .mjx-i mjx-c[c="3D6"]:before{width:.828em;padding:.431em 0 .01em;content:"\3D6"}.MJX-TEX .mjx-i mjx-c[c="3DC"]:before{width:.643em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="3DC"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="3DC"]:last-child:before{width:.749em}.MJX-TEX .mjx-i mjx-c[c="3F1"]:before{width:.517em;padding:.442em 0 .194em;content:"\3F1"}.MJX-TEX .mjx-i mjx-c[c="3F5"]:before{width:.406em;padding:.431em 0 .011em;content:"\3F5"}.MJX-TEX .mjx-i mjx-c[c="2013"]:before{width:.511em}.MJX-TEX .mjx-i mjx-c[c="2014"]:before,.MJX-TEX .mjx-i mjx-c[c="2015"]:before{width:1.022em}.MJX-TEX .mjx-i mjx-c[c="2017"]:before{width:.511em}.MJX-TEX .mjx-i mjx-c[c="2018"]:before{width:.307em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="2018"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="2018"]:last-child:before{width:.362em}.MJX-TEX .mjx-i mjx-c[c="2019"]:before{width:.307em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="2019"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="2019"]:last-child:before{width:.377em}.MJX-TEX .mjx-i mjx-c[c="201C"]:before{width:.514em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-i mjx-c[c="201C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-i mjx-c[c="201C"]:last-child:before{width:.606em}.MJX-TEX .mjx-i mjx-c[c="201D"]:before{width:.514em}.MJX-TEX .mjx-i mjx-c[c="2044"]:before{width:.778em;padding:.716em 0 .215em}.MJX-TEX .mjx-i mjx-c[c="210E"]:before{width:.576em;padding:.694em 0 .011em;content:"h";font-family:MJXZERO,MJXTEX-I}.MJX-TEX .mjx-i mjx-c[c="29F8"]:before{width:.778em;padding:.716em 0 .215em;content:"/";font-family:MJXZERO,MJXTEX-I}.MJX-TEX .mjx-b.mjx-i mjx-c[c="/"]:before{width:.894em;padding:.711em 0 .21em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=A]:before{padding:.711em 0 0}.MJX-TEX .mjx-b.mjx-i mjx-c[c=B]:before{width:.866em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=C]:before{width:.817em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=D]:before{width:.938em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=E]:before{width:.81em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=F]:before{width:.689em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c=F]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c=F]:last-child:before{width:.809em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=G]:before{width:.887em;padding:.703em 0 .016em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=H]:before{width:.982em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=I]:before{width:.511em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c=I]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c=I]:last-child:before{width:.573em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=J]:before{width:.631em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c=J]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c=J]:last-child:before{width:.694em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=K]:before{width:.971em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=L]:before{width:.756em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=M]:before{width:1.142em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c=M]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c=M]:last-child:before{width:1.219em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=N]:before{width:.95em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c=N]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c=N]:last-child:before{width:1.027em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=O]:before{width:.837em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=P]:before{width:.723em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c=P]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c=P]:last-child:before{width:.847em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=Q]:before{width:.869em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=R]:before{width:.872em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=S]:before{width:.693em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=T]:before{width:.637em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c=T]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c=T]:last-child:before{width:.772em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=U]:before{width:.8em;padding:.686em 0 .016em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c=U]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c=U]:last-child:before{width:.877em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=V]:before{width:.678em;padding:.686em 0 .016em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c=V]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c=V]:last-child:before{width:.886em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=W]:before{width:1.093em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c=W]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c=W]:last-child:before{width:1.207em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=X]:before{width:.947em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=Y]:before{width:.675em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c=Y]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c=Y]:last-child:before{width:.876em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=Z]:before{width:.773em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=a]:before{width:.633em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=b]:before{width:.521em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=c]:before{width:.513em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=d]:before{width:.61em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=e]:before{width:.554em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=f]:before{width:.568em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c=f]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c=f]:last-child:before{width:.624em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=g]:before{width:.545em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=h]:before{width:.668em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=i]:before{width:.405em;padding:.694em 0 .008em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=j]:before{width:.471em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=k]:before{width:.604em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=l]:before{width:.348em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=m]:before{width:1.032em;padding:.452em 0 .008em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=n]:before{width:.713em;padding:.452em 0 .008em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=o]:before{width:.585em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=p]:before{width:.601em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=q]:before{width:.542em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=r]:before{width:.529em;padding:.452em 0 .008em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=s]:before{width:.531em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=t]:before{width:.415em;padding:.643em 0 .007em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=u]:before{width:.681em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=v]:before{width:.567em;padding:.453em 0 .008em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=w]:before{padding:.453em 0 .008em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=x]:before{width:.659em;padding:.452em 0 .008em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=y]:before{width:.59em;padding:.452em 0 .202em}.MJX-TEX .mjx-b.mjx-i mjx-c[c=z]:before{width:.555em;padding:.452em 0 .008em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="391"]:before{padding:.711em 0 0}.MJX-TEX .mjx-b.mjx-i mjx-c[c="392"]:before{width:.866em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="393"]:before{width:.657em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c="393"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c="393"]:last-child:before{width:.777em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="394"]:before{padding:.711em 0 0}.MJX-TEX .mjx-b.mjx-i mjx-c[c="395"]:before{width:.81em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="396"]:before{width:.773em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="397"]:before{width:.982em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="398"]:before{width:.867em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="399"]:before{width:.511em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c="399"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c="399"]:last-child:before{width:.573em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="39A"]:before{width:.971em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="39B"]:before{padding:.711em 0 0}.MJX-TEX .mjx-b.mjx-i mjx-c[c="39C"]:before{width:1.142em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c="39C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c="39C"]:last-child:before{width:1.219em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="39D"]:before{width:.95em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c="39D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c="39D"]:last-child:before{width:1.027em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="39E"]:before{width:.841em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="39F"]:before{width:.837em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="3A0"]:before{width:.982em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="3A1"]:before{width:.723em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3A1"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3A1"]:last-child:before{width:.847em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="3A2"]:before{width:.867em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="3A3"]:before{width:.885em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="3A4"]:before{width:.637em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3A4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3A4"]:last-child:before{width:.772em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="3A5"]:before{width:.671em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3A5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3A5"]:last-child:before{width:.802em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="3A6"]:before{width:.767em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="3A7"]:before{width:.947em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="3A8"]:before{width:.714em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3A8"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3A8"]:last-child:before{width:.79em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="3A9"]:before{width:.879em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3C4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3C4"]:last-child:before{width:.61em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="3D2"]:before{width:.671em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3D2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3D2"]:last-child:before{width:.802em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="3DC"]:before{width:.689em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3DC"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-b.mjx-i mjx-c[c="3DC"]:last-child:before{width:.809em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="2044"]:before{width:.894em;padding:.711em 0 .21em}.MJX-TEX .mjx-b.mjx-i mjx-c[c="2206"]:before{padding:.711em 0 0}.MJX-TEX .mjx-b.mjx-i mjx-c[c="29F8"]:before{width:.894em;padding:.711em 0 .21em;font-family:MJXZERO,MJXTEX-BI}.MJX-TEX .mjx-ds mjx-c[c=A]:before{width:.722em}.MJX-TEX .mjx-ds mjx-c[c=B]:before{width:.667em}.MJX-TEX .mjx-ds mjx-c[c=D]:before{width:.722em}.MJX-TEX .mjx-ds mjx-c[c=E]:before{width:.667em}.MJX-TEX .mjx-ds mjx-c[c=F]:before{width:.611em}.MJX-TEX .mjx-ds mjx-c[c=G]:before,.MJX-TEX .mjx-ds mjx-c[c=H]:before{width:.778em}.MJX-TEX .mjx-ds mjx-c[c=I]:before{width:.389em}.MJX-TEX .mjx-ds mjx-c[c=J]:before{width:.5em;padding:.683em 0 .077em}.MJX-TEX .mjx-ds mjx-c[c=L]:before{width:.667em}.MJX-TEX .mjx-ds mjx-c[c=M]:before{width:.944em}.MJX-TEX .mjx-ds mjx-c[c=N]:before{width:.722em;padding:.683em 0 .02em}.MJX-TEX .mjx-ds mjx-c[c=P]:before{width:.611em}.MJX-TEX .mjx-ds mjx-c[c=Q]:before{padding:.701em 0 .181em}.MJX-TEX .mjx-ds mjx-c[c=R]:before{width:.722em;padding:.683em 0 0}.MJX-TEX .mjx-ds mjx-c[c=S]:before{padding:.702em 0 .012em}.MJX-TEX .mjx-ds mjx-c[c=T]:before{width:.667em;padding:.683em 0 0}.MJX-TEX .mjx-ds mjx-c[c=U]:before,.MJX-TEX .mjx-ds mjx-c[c=V]:before{width:.722em}.MJX-TEX .mjx-ds mjx-c[c=W]:before{width:1em}.MJX-TEX .mjx-ds mjx-c[c=X]:before,.MJX-TEX .mjx-ds mjx-c[c=Y]:before{width:.722em}.MJX-TEX .mjx-ds mjx-c[c=Z]:before{width:.667em}.MJX-TEX .mjx-ds mjx-c[c=k]:before{width:.556em;padding:.683em 0 0}.MJX-TEX .mjx-ds mjx-c[c="3A1"]:before,.MJX-TEX .mjx-ds mjx-c[c="3A2"]:before,.MJX-TEX .mjx-ds mjx-c[c="3A4"]:before,.MJX-TEX .mjx-ds mjx-c[c="3A7"]:before,.MJX-TEX .mjx-ds mjx-c[c="3D2"]:before,.MJX-TEX .mjx-ds mjx-c[c="3DC"]:before,.MJX-TEX .mjx-ds mjx-c[c="39A"]:before,.MJX-TEX .mjx-ds mjx-c[c="39C"]:before,.MJX-TEX .mjx-ds mjx-c[c="39D"]:before,.MJX-TEX .mjx-ds mjx-c[c="39F"]:before,.MJX-TEX .mjx-ds mjx-c[c="391"]:before,.MJX-TEX .mjx-ds mjx-c[c="392"]:before,.MJX-TEX .mjx-ds mjx-c[c="395"]:before,.MJX-TEX .mjx-ds mjx-c[c="396"]:before,.MJX-TEX .mjx-ds mjx-c[c="397"]:before,.MJX-TEX .mjx-ds mjx-c[c="399"]:before{font-family:MJXZERO,MJXTEX-B}.MJX-TEX .mjx-ds mjx-c[c="2102"]:before{width:.722em;padding:.702em 0 .019em;content:"C";font-family:MJXZERO,MJXTEX-A}.MJX-TEX .mjx-ds mjx-c[c="210D"]:before{width:.778em;padding:.683em 0 0;content:"H";font-family:MJXZERO,MJXTEX-A}.MJX-TEX .mjx-ds mjx-c[c="2115"]:before{width:.722em;padding:.683em 0 .02em;content:"N";font-family:MJXZERO,MJXTEX-A}.MJX-TEX .mjx-ds mjx-c[c="2119"]:before{width:.611em;padding:.683em 0 0;content:"P";font-family:MJXZERO,MJXTEX-A}.MJX-TEX .mjx-ds mjx-c[c="211A"]:before{width:.778em;padding:.701em 0 .181em;content:"Q";font-family:MJXZERO,MJXTEX-A}.MJX-TEX .mjx-ds mjx-c[c="211D"]:before{width:.722em;padding:.683em 0 0;content:"R";font-family:MJXZERO,MJXTEX-A}.MJX-TEX .mjx-ds mjx-c[c="2124"]:before{width:.667em;padding:.683em 0 0;content:"Z";font-family:MJXZERO,MJXTEX-A}.MJX-TEX .mjx-fr mjx-c[c="!"]:before{width:.296em;padding:.689em 0 .012em}.MJX-TEX .mjx-fr mjx-c[c="22"]:before{width:.215em}.MJX-TEX .mjx-fr mjx-c[c="&"]:before{width:.738em;padding:.698em 0 .011em}.MJX-TEX .mjx-fr mjx-c[c="27"]:before{width:.212em}.MJX-TEX .mjx-fr mjx-c[c="("]:before{padding:.737em 0 .186em}.MJX-TEX .mjx-fr mjx-c[c=")"]:before{padding:.735em 0 .187em}.MJX-TEX .mjx-fr mjx-c[c="*"]:before{width:.278em;padding:.692em 0 0}.MJX-TEX .mjx-fr mjx-c[c="+"]:before{width:.756em;padding:.598em 0 .082em}.MJX-TEX .mjx-fr mjx-c[c=","]:before{padding:.107em 0 .191em}.MJX-TEX .mjx-fr mjx-c[c="-"]:before{width:.756em;padding:.275em 0 0}.MJX-TEX .mjx-fr mjx-c[c="."]:before{padding:.102em 0 .015em}.MJX-TEX .mjx-fr mjx-c[c="/"]:before{width:.502em;padding:.721em 0 .182em}.MJX-TEX .mjx-fr mjx-c[c="0"]:before{width:.502em;padding:.492em 0 .013em}.MJX-TEX .mjx-fr mjx-c[c="1"]:before{width:.502em;padding:.468em 0 0}.MJX-TEX .mjx-fr mjx-c[c="2"]:before{width:.502em;padding:.474em 0 0}.MJX-TEX .mjx-fr mjx-c[c="3"]:before{width:.502em;padding:.473em 0 .182em}.MJX-TEX .mjx-fr mjx-c[c="4"]:before{width:.502em;padding:.476em 0 .191em}.MJX-TEX .mjx-fr mjx-c[c="5"]:before{width:.502em;padding:.458em 0 .184em}.MJX-TEX .mjx-fr mjx-c[c="6"]:before{width:.502em;padding:.7em 0 .013em}.MJX-TEX .mjx-fr mjx-c[c="7"]:before{width:.502em;padding:.468em 0 .181em}.MJX-TEX .mjx-fr mjx-c[c="8"]:before{width:.502em;padding:.705em 0 .01em}.MJX-TEX .mjx-fr mjx-c[c="9"]:before{width:.502em;padding:.469em 0 .182em}.MJX-TEX .mjx-fr mjx-c[c=":"]:before{width:.216em;padding:.457em 0 .012em}.MJX-TEX .mjx-fr mjx-c[c=";"]:before{width:.216em;padding:.458em 0 .189em}.MJX-TEX .mjx-fr mjx-c[c="="]:before{width:.756em;padding:.368em 0 0}.MJX-TEX .mjx-fr mjx-c[c="?"]:before{width:.362em;padding:.693em 0 .011em}.MJX-TEX .mjx-fr mjx-c[c=A]:before{width:.718em;padding:.696em 0 .026em}.MJX-TEX .mjx-fr mjx-c[c=B]:before{width:.884em;padding:.691em 0 .027em}.MJX-TEX .mjx-fr mjx-c[c=C]:before{width:.613em;padding:.685em 0 .024em}.MJX-TEX .mjx-fr mjx-c[c=D]:before{width:.832em;padding:.685em 0 .027em}.MJX-TEX .mjx-fr mjx-c[c=E]:before{width:.663em;padding:.685em 0 .024em}.MJX-TEX .mjx-fr mjx-c[c=F]:before{width:.611em;padding:.686em 0 .153em}.MJX-TEX .mjx-fr mjx-c[c=G]:before{padding:.69em 0 .026em}.MJX-TEX .mjx-fr mjx-c[c=H]:before{width:.72em;padding:.666em 0 .133em}.MJX-TEX .mjx-fr mjx-c[c=I]:before{width:.554em;padding:.686em 0 .026em}.MJX-TEX .mjx-fr mjx-c[c=J]:before{width:.552em;padding:.686em 0 .139em}.MJX-TEX .mjx-fr mjx-c[c=K]:before{width:.668em;padding:.68em 0 .027em}.MJX-TEX .mjx-fr mjx-c[c=L]:before{width:.666em;padding:.686em 0 .026em}.MJX-TEX .mjx-fr mjx-c[c=M]:before{width:1.05em;padding:.692em 0 .027em}.MJX-TEX .mjx-fr mjx-c[c=N]:before{width:.832em;padding:.686em 0 .025em}.MJX-TEX .mjx-fr mjx-c[c=O]:before{width:.827em;padding:.729em 0 .027em}.MJX-TEX .mjx-fr mjx-c[c=P]:before{width:.828em;padding:.692em 0 .218em}.MJX-TEX .mjx-fr mjx-c[c=Q]:before{width:.827em;padding:.729em 0 .069em}.MJX-TEX .mjx-fr mjx-c[c=R]:before{width:.828em}.MJX-TEX .mjx-fr mjx-c[c=S]:before{width:.829em;padding:.692em 0 .027em}.MJX-TEX .mjx-fr mjx-c[c=T]:before{width:.669em;padding:.701em 0 .027em}.MJX-TEX .mjx-fr mjx-c[c=U]:before{width:.646em;padding:.697em 0 .027em}.MJX-TEX .mjx-fr mjx-c[c=V]:before{width:.831em}.MJX-TEX .mjx-fr mjx-c[c=W]:before{width:1.046em;padding:.686em 0 .027em}.MJX-TEX .mjx-fr mjx-c[c=X]:before{width:.719em;padding:.688em 0 .027em}.MJX-TEX .mjx-fr mjx-c[c=Y]:before{width:.833em;padding:.686em 0 .218em}.MJX-TEX .mjx-fr mjx-c[c=Z]:before{width:.602em;padding:.729em 0 .139em}.MJX-TEX .mjx-fr mjx-c[c="["]:before{padding:.74em 0 .13em}.MJX-TEX .mjx-fr mjx-c[c="]"]:before{padding:.738em 0 .131em}.MJX-TEX .mjx-fr mjx-c[c="^"]:before{padding:.734em 0 0}.MJX-TEX .mjx-fr mjx-c[c=a]:before{padding:.47em 0 .035em}.MJX-TEX .mjx-fr mjx-c[c=b]:before{width:.513em;padding:.685em 0 .031em}.MJX-TEX .mjx-fr mjx-c[c=c]:before{width:.389em;padding:.466em 0 .029em}.MJX-TEX .mjx-fr mjx-c[c=d]:before{width:.499em;padding:.609em 0 .033em}.MJX-TEX .mjx-fr mjx-c[c=e]:before{width:.401em;padding:.467em 0 .03em}.MJX-TEX .mjx-fr mjx-c[c=f]:before{width:.326em;padding:.681em 0 .221em}.MJX-TEX .mjx-fr mjx-c[c=g]:before{width:.504em;padding:.47em 0 .209em}.MJX-TEX .mjx-fr mjx-c[c=h]:before{width:.521em;padding:.688em 0 .205em}.MJX-TEX .mjx-fr mjx-c[c=i]:before{width:.279em;padding:.673em 0 .02em}.MJX-TEX .mjx-fr mjx-c[c=j]:before{width:.281em}.MJX-TEX .mjx-fr mjx-c[c=k]:before{width:.389em;padding:.689em 0 .025em}.MJX-TEX .mjx-fr mjx-c[c=l]:before{width:.28em;padding:.685em 0 .02em}.MJX-TEX .mjx-fr mjx-c[c=m]:before{width:.767em;padding:.475em 0 .026em}.MJX-TEX .mjx-fr mjx-c[c=n]:before{width:.527em;padding:.475em 0 .022em}.MJX-TEX .mjx-fr mjx-c[c=o]:before{width:.489em;padding:.48em 0 .028em}.MJX-TEX .mjx-fr mjx-c[c=p]:before{width:.5em;padding:.541em 0 .212em}.MJX-TEX .mjx-fr mjx-c[c=q]:before{width:.489em;padding:.479em 0 .219em}.MJX-TEX .mjx-fr mjx-c[c=r]:before{width:.389em;padding:.474em 0 .021em}.MJX-TEX .mjx-fr mjx-c[c=s]:before{width:.443em;padding:.478em 0 .029em}.MJX-TEX .mjx-fr mjx-c[c=t]:before{width:.333em;padding:.64em 0 .02em}.MJX-TEX .mjx-fr mjx-c[c=u]:before{width:.517em;padding:.474em 0 .023em}.MJX-TEX .mjx-fr mjx-c[c=v]:before{width:.512em;padding:.53em 0 .028em}.MJX-TEX .mjx-fr mjx-c[c=w]:before{width:.774em;padding:.532em 0 .028em}.MJX-TEX .mjx-fr mjx-c[c=x]:before{width:.389em;padding:.472em 0 .188em}.MJX-TEX .mjx-fr mjx-c[c=y]:before{width:.499em;padding:.528em 0 .218em}.MJX-TEX .mjx-fr mjx-c[c=z]:before{width:.391em;padding:.471em 0 .214em}.MJX-TEX .mjx-fr mjx-c[c="3A1"]:before,.MJX-TEX .mjx-fr mjx-c[c="3A2"]:before,.MJX-TEX .mjx-fr mjx-c[c="3A4"]:before,.MJX-TEX .mjx-fr mjx-c[c="3A7"]:before,.MJX-TEX .mjx-fr mjx-c[c="3D2"]:before,.MJX-TEX .mjx-fr mjx-c[c="3DC"]:before,.MJX-TEX .mjx-fr mjx-c[c="39A"]:before,.MJX-TEX .mjx-fr mjx-c[c="39C"]:before,.MJX-TEX .mjx-fr mjx-c[c="39D"]:before,.MJX-TEX .mjx-fr mjx-c[c="39F"]:before,.MJX-TEX .mjx-fr mjx-c[c="391"]:before,.MJX-TEX .mjx-fr mjx-c[c="392"]:before,.MJX-TEX .mjx-fr mjx-c[c="395"]:before,.MJX-TEX .mjx-fr mjx-c[c="396"]:before,.MJX-TEX .mjx-fr mjx-c[c="397"]:before,.MJX-TEX .mjx-fr mjx-c[c="399"]:before{font-family:MJXZERO,MJXTEX}.MJX-TEX .mjx-fr mjx-c[c="2018"]:before{width:.215em;padding:.708em 0 0}.MJX-TEX .mjx-fr mjx-c[c="2019"]:before{width:.215em}.MJX-TEX .mjx-fr mjx-c[c="2044"]:before{width:.502em;padding:.721em 0 .182em}.MJX-TEX .mjx-fr mjx-c[c="210C"]:before{width:.72em;padding:.666em 0 .133em;content:"H";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX .mjx-fr mjx-c[c="2111"]:before{width:.554em;padding:.686em 0 .026em;content:"I";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX .mjx-fr mjx-c[c="211C"]:before{width:.828em;padding:.686em 0 .026em;content:"R";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX .mjx-fr mjx-c[c="2128"]:before{width:.602em;padding:.729em 0 .139em;content:"Z";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX .mjx-fr mjx-c[c="212D"]:before{width:.613em;padding:.685em 0 .024em;content:"C";font-family:MJXZERO,MJXTEX-FR}.MJX-TEX .mjx-fr mjx-c[c=E300]:before{width:.497em;padding:.683em 0 .032em;content:"\E300"}.MJX-TEX .mjx-fr mjx-c[c=E301]:before{width:.498em;padding:.616em 0 .03em;content:"\E301"}.MJX-TEX .mjx-fr mjx-c[c=E302]:before{width:.333em;padding:.68em 0 .215em;content:"\E302"}.MJX-TEX .mjx-fr mjx-c[c=E303]:before{width:.329em;padding:.679em 0 .224em;content:"\E303"}.MJX-TEX .mjx-fr mjx-c[c=E304]:before{width:.503em;padding:.471em 0 .214em;content:"\E304"}.MJX-TEX .mjx-fr mjx-c[c=E305]:before{width:.333em;padding:.686em 0 .02em;content:"\E305"}.MJX-TEX .mjx-fr mjx-c[c=E306]:before{width:.334em;padding:.577em 0 .021em;content:"\E306"}.MJX-TEX .mjx-fr mjx-c[c=E307]:before{width:.501em;padding:.475em 0 .022em;content:"\E307"}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="!"]:before{width:.349em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="22"]:before{width:.254em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="&"]:before{width:.871em;padding:.696em 0 .016em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="27"]:before{width:.25em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="("]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c=")"]:before{width:.459em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="*"]:before{width:.328em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="+"]:before{width:.893em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=","]:before{width:.328em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="-"]:before{width:.893em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="."]:before{width:.328em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="/"]:before{width:.593em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="0"]:before{width:.593em;padding:.501em 0 .012em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="1"]:before{width:.593em;padding:.489em 0 0}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="2"]:before{width:.593em;padding:.491em 0 0}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="3"]:before{width:.593em;padding:.487em 0 .193em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="4"]:before{width:.593em;padding:.495em 0 .196em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="5"]:before{width:.593em;padding:.481em 0 .19em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="6"]:before{width:.593em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="7"]:before{width:.593em;padding:.479em 0 .197em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="8"]:before{width:.593em;padding:.714em 0 .005em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="9"]:before{width:.593em;padding:.487em 0 .195em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=":"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c=";"]:before{width:.255em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="="]:before{width:.582em;padding:.343em 0 0}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="?"]:before{width:.428em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=A]:before{width:.847em;padding:.686em 0 .031em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=B]:before{width:1.044em;padding:.684em 0 .031em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=C]:before{width:.723em;padding:.676em 0 .032em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=D]:before{width:.982em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=E]:before{width:.783em;padding:.686em 0 .029em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=F]:before{width:.722em;padding:.684em 0 .146em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=G]:before{width:.927em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=H]:before{width:.851em;padding:.683em 0 .126em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=I]:before{width:.655em;padding:.681em 0 .025em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=J]:before{width:.652em;padding:.68em 0 .141em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=K]:before{width:.789em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=L]:before{width:.786em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=M]:before{width:1.239em;padding:.683em 0 .032em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=N]:before{width:.983em;padding:.679em 0 .03em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=O]:before{width:.976em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=P]:before{width:.977em;padding:.688em 0 .223em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=Q]:before{width:.976em;padding:.726em 0 .083em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=R]:before{width:.978em;padding:.688em 0 .028em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=S]:before{width:.978em;padding:.685em 0 .031em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=T]:before{width:.79em;padding:.686em 0 .03em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=U]:before{width:.851em;padding:.688em 0 .039em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=V]:before{width:.982em;padding:.685em 0 .029em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=W]:before{width:1.235em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=X]:before{width:.849em;padding:.681em 0 .035em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=Y]:before{width:.984em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=Z]:before{width:.711em;padding:.677em 0 .148em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="["]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="]"]:before{width:.257em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="^"]:before{width:.59em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=a]:before{width:.603em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=b]:before{width:.59em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=c]:before{width:.464em;padding:.473em 0 .026em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=d]:before{width:.589em;padding:.632em 0 .028em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=e]:before{width:.472em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=f]:before{width:.388em;padding:.687em 0 .222em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=g]:before{width:.595em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=h]:before{width:.615em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=i]:before{width:.331em;padding:.686em 0 .025em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=j]:before{width:.332em;padding:.682em 0 .203em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=k]:before{width:.464em;padding:.682em 0 .025em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=l]:before{width:.337em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=m]:before{width:.921em;padding:.476em 0 .031em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=n]:before{width:.654em;padding:.473em 0 .028em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=o]:before{width:.609em;padding:.482em 0 .034em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=p]:before{width:.604em;padding:.557em 0 .207em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=q]:before{width:.596em;padding:.485em 0 .211em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=r]:before{width:.46em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=s]:before{width:.523em;padding:.479em 0 .034em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=t]:before{width:.393em;padding:.648em 0 .027em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=u]:before{width:.589em;padding:.472em 0 .032em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=v]:before{width:.604em;padding:.546em 0 .027em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=w]:before{width:.918em;padding:.549em 0 .032em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=x]:before{width:.459em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=y]:before{width:.589em;padding:.557em 0 .221em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=z]:before{width:.461em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="3A1"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="3A2"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="3A4"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="3A7"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="3D2"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="3DC"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="39A"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="39C"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="39D"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="39F"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="391"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="392"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="395"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="396"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="397"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="399"]:before{font-family:MJXZERO,MJXTEX-B}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="2018"]:before,.MJX-TEX .mjx-fr.mjx-b mjx-c[c="2019"]:before{width:.254em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c="2044"]:before{width:.593em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=E301]:before{width:.587em;padding:.63em 0 .027em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=E302]:before{width:.394em;padding:.693em 0 .212em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=E303]:before{width:.387em;padding:.681em 0 .219em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=E304]:before{width:.593em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=E305]:before{width:.393em;padding:.684em 0 .027em}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=E308]:before{width:.981em;padding:.679em 0 .22em;content:"\E308"}.MJX-TEX .mjx-fr.mjx-b mjx-c[c=E309]:before{width:.727em;padding:.717em 0 .137em;content:"\E309"}.MJX-TEX .mjx-sc mjx-c[c=A]:before{width:.803em;padding:.717em 0 .008em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=A]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=A]:last-child:before{width:1.016em}.MJX-TEX .mjx-sc mjx-c[c=B]:before{width:.908em;padding:.708em 0 .028em}.MJX-TEX .mjx-sc mjx-c[c=C]:before{width:.666em;padding:.728em 0 .026em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=C]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=C]:last-child:before{width:.819em}.MJX-TEX .mjx-sc mjx-c[c=D]:before{width:.774em;padding:.708em 0 .031em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=D]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=D]:last-child:before{width:.855em}.MJX-TEX .mjx-sc mjx-c[c=E]:before{width:.562em;padding:.707em 0 .008em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=E]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=E]:last-child:before{width:.718em}.MJX-TEX .mjx-sc mjx-c[c=F]:before{width:.895em;padding:.735em 0 .036em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=F]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=F]:last-child:before{width:.99em}.MJX-TEX .mjx-sc mjx-c[c=G]:before{width:.61em;padding:.717em 0 .037em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=G]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=G]:last-child:before{width:.738em}.MJX-TEX .mjx-sc mjx-c[c=H]:before{width:.969em;padding:.717em 0 .036em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=H]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=H]:last-child:before{width:1.241em}.MJX-TEX .mjx-sc mjx-c[c=I]:before{width:.809em;padding:.717em 0 .017em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=I]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=I]:last-child:before{width:.946em}.MJX-TEX .mjx-sc mjx-c[c=J]:before{width:1.052em;padding:.717em 0 .314em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=J]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=J]:last-child:before{width:1.133em}.MJX-TEX .mjx-sc mjx-c[c=K]:before{width:.914em;padding:.717em 0 .037em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=K]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=K]:last-child:before{width:1.204em}.MJX-TEX .mjx-sc mjx-c[c=L]:before{width:.874em;padding:.717em 0 .017em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=L]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=L]:last-child:before{width:1.035em}.MJX-TEX .mjx-sc mjx-c[c=M]:before{width:1.08em;padding:.721em 0 .05em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=M]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=M]:last-child:before{width:1.216em}.MJX-TEX .mjx-sc mjx-c[c=N]:before{width:.902em;padding:.726em 0 .036em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=N]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=N]:last-child:before{width:1.208em}.MJX-TEX .mjx-sc mjx-c[c=O]:before{width:.738em;padding:.707em 0 .008em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=O]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=O]:last-child:before{width:.805em}.MJX-TEX .mjx-sc mjx-c[c=P]:before{width:1.013em;padding:.716em 0 .037em}.MJX-TEX .mjx-sc mjx-c[c=Q]:before{width:.883em;padding:.717em 0 .017em}.MJX-TEX .mjx-sc mjx-c[c=R]:before{width:.85em;padding:.717em 0 .017em}.MJX-TEX .mjx-sc mjx-c[c=S]:before{width:.868em;padding:.708em 0 .036em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=S]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=S]:last-child:before{width:1.016em}.MJX-TEX .mjx-sc mjx-c[c=T]:before{width:.747em;padding:.735em 0 .037em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=T]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=T]:last-child:before{width:.996em}.MJX-TEX .mjx-sc mjx-c[c=U]:before{width:.8em;padding:.717em 0 .017em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=U]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=U]:last-child:before{width:.96em}.MJX-TEX .mjx-sc mjx-c[c=V]:before{width:.622em;padding:.717em 0 .017em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=V]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=V]:last-child:before{width:.85em}.MJX-TEX .mjx-sc mjx-c[c=W]:before{width:.805em;padding:.717em 0 .017em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=W]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=W]:last-child:before{width:1.026em}.MJX-TEX .mjx-sc mjx-c[c=X]:before{width:.944em;padding:.717em 0 .017em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=X]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=X]:last-child:before{width:1.131em}.MJX-TEX .mjx-sc mjx-c[c=Y]:before{width:.71em;padding:.716em 0 .017em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=Y]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=Y]:last-child:before{width:.959em}.MJX-TEX .mjx-sc mjx-c[c=Z]:before{width:.821em;padding:.717em 0 .016em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c=Z]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c=Z]:last-child:before{width:1.032em}.MJX-TEX .mjx-sc mjx-c[c="3A1"]:before,.MJX-TEX .mjx-sc mjx-c[c="3A2"]:before,.MJX-TEX .mjx-sc mjx-c[c="3A4"]:before,.MJX-TEX .mjx-sc mjx-c[c="3A7"]:before,.MJX-TEX .mjx-sc mjx-c[c="3D2"]:before,.MJX-TEX .mjx-sc mjx-c[c="3DC"]:before,.MJX-TEX .mjx-sc mjx-c[c="39A"]:before,.MJX-TEX .mjx-sc mjx-c[c="39C"]:before,.MJX-TEX .mjx-sc mjx-c[c="39D"]:before,.MJX-TEX .mjx-sc mjx-c[c="39F"]:before,.MJX-TEX .mjx-sc mjx-c[c="391"]:before,.MJX-TEX .mjx-sc mjx-c[c="392"]:before,.MJX-TEX .mjx-sc mjx-c[c="395"]:before,.MJX-TEX .mjx-sc mjx-c[c="396"]:before,.MJX-TEX .mjx-sc mjx-c[c="397"]:before,.MJX-TEX .mjx-sc mjx-c[c="399"]:before{font-family:MJXZERO,MJXTEX}.MJX-TEX .mjx-sc mjx-c[c="210B"]:before{width:.969em;padding:.717em 0 .036em;content:"H";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c="210B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c="210B"]:last-child:before{width:1.241em}.MJX-TEX .mjx-sc mjx-c[c="2110"]:before{width:1.052em;padding:.717em 0 .314em;content:"J";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c="2110"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c="2110"]:last-child:before{width:1.133em}.MJX-TEX .mjx-sc mjx-c[c="2112"]:before{width:.874em;padding:.717em 0 .017em;content:"L";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c="2112"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c="2112"]:last-child:before{width:1.035em}.MJX-TEX .mjx-sc mjx-c[c="211B"]:before{width:.85em;padding:.717em 0 .017em;content:"R";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX .mjx-sc mjx-c[c="212C"]:before{width:.908em;padding:.708em 0 .028em;content:"B";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX .mjx-sc mjx-c[c="2130"]:before{width:.562em;padding:.707em 0 .008em;content:"E";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c="2130"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c="2130"]:last-child:before{width:.718em}.MJX-TEX .mjx-sc mjx-c[c="2131"]:before{width:.895em;padding:.735em 0 .036em;content:"F";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c="2131"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c="2131"]:last-child:before{width:.99em}.MJX-TEX .mjx-sc mjx-c[c="2133"]:before{width:1.08em;padding:.721em 0 .05em;content:"M";font-family:MJXZERO,MJXTEX-SC}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc mjx-c[c="2133"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc mjx-c[c="2133"]:last-child:before{width:1.216em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=A]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=A]:last-child:before{width:1.016em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=C]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=C]:last-child:before{width:.819em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=D]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=D]:last-child:before{width:.855em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=E]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=E]:last-child:before{width:.718em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=F]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=F]:last-child:before{width:.99em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=G]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=G]:last-child:before{width:.738em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=H]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=H]:last-child:before{width:1.241em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=I]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=I]:last-child:before{width:.946em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=J]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=J]:last-child:before{width:1.133em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=K]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=K]:last-child:before{width:1.204em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=L]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=L]:last-child:before{width:1.035em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=M]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=M]:last-child:before{width:1.216em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=N]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=N]:last-child:before{width:1.208em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=O]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=O]:last-child:before{width:.805em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=S]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=S]:last-child:before{width:1.016em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=T]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=T]:last-child:before{width:.996em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=U]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=U]:last-child:before{width:.96em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=V]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=V]:last-child:before{width:.85em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=W]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=W]:last-child:before{width:1.026em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=X]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=X]:last-child:before{width:1.131em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=Y]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=Y]:last-child:before{width:.959em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=Z]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sc.mjx-b mjx-c[c=Z]:last-child:before{width:1.032em}.MJX-TEX .mjx-sc.mjx-b mjx-c[c="3A1"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="3A2"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="3A4"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="3A7"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="3D2"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="3DC"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="39A"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="39C"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="39D"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="39F"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="391"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="392"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="395"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="396"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="397"]:before,.MJX-TEX .mjx-sc.mjx-b mjx-c[c="399"]:before{font-family:MJXZERO,MJXTEX-B}.MJX-TEX .mjx-ss mjx-c[c="!"]:before{width:.319em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="&"]:before{width:.758em}.MJX-TEX .mjx-ss mjx-c[c=","]:before{padding:.098em 0 .125em}.MJX-TEX .mjx-ss mjx-c[c="-"]:before{padding:.259em 0 0}.MJX-TEX .mjx-ss mjx-c[c="."]:before{padding:.098em 0 0}.MJX-TEX .mjx-ss mjx-c[c="0"]:before{padding:.678em 0 .022em}.MJX-TEX .mjx-ss mjx-c[c="1"]:before{padding:.678em 0 0}.MJX-TEX .mjx-ss mjx-c[c="2"]:before{padding:.677em 0 0}.MJX-TEX .mjx-ss mjx-c[c="3"]:before{padding:.678em 0 .022em}.MJX-TEX .mjx-ss mjx-c[c="4"]:before{padding:.656em 0 0}.MJX-TEX .mjx-ss mjx-c[c="5"]:before{padding:.656em 0 .021em}.MJX-TEX .mjx-ss mjx-c[c="6"]:before{padding:.677em 0 .022em}.MJX-TEX .mjx-ss mjx-c[c="7"]:before{padding:.656em 0 .011em}.MJX-TEX .mjx-ss mjx-c[c="8"]:before{padding:.678em 0 .022em}.MJX-TEX .mjx-ss mjx-c[c="9"]:before{padding:.677em 0 .022em}.MJX-TEX .mjx-ss mjx-c[c=":"]:before{padding:.444em 0 0}.MJX-TEX .mjx-ss mjx-c[c=";"]:before{padding:.444em 0 .125em}.MJX-TEX .mjx-ss mjx-c[c="="]:before{padding:.37em 0 0}.MJX-TEX .mjx-ss mjx-c[c="@"]:before{width:.667em}.MJX-TEX .mjx-ss mjx-c[c=A]:before,.MJX-TEX .mjx-ss mjx-c[c=B]:before{width:.667em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c=C]:before{width:.639em;padding:.705em 0 .011em}.MJX-TEX .mjx-ss mjx-c[c=D]:before{width:.722em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c=E]:before{width:.597em;padding:.691em 0 0}.MJX-TEX .mjx-ss mjx-c[c=F]:before{width:.569em;padding:.691em 0 0}.MJX-TEX .mjx-ss mjx-c[c=G]:before{width:.667em;padding:.704em 0 .011em}.MJX-TEX .mjx-ss mjx-c[c=H]:before{width:.708em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c=I]:before{width:.278em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c=J]:before{width:.472em;padding:.694em 0 .022em}.MJX-TEX .mjx-ss mjx-c[c=K]:before{width:.694em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c=L]:before{width:.542em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c=M]:before{width:.875em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c=N]:before{width:.708em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c=O]:before{width:.736em;padding:.715em 0 .022em}.MJX-TEX .mjx-ss mjx-c[c=P]:before{width:.639em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c=Q]:before{width:.736em;padding:.715em 0 .125em}.MJX-TEX .mjx-ss mjx-c[c=R]:before{width:.646em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c=S]:before{padding:.716em 0 .022em}.MJX-TEX .mjx-ss mjx-c[c=T]:before{width:.681em;padding:.688em 0 0}.MJX-TEX .mjx-ss mjx-c[c=U]:before{width:.688em;padding:.694em 0 .022em}.MJX-TEX .mjx-ss mjx-c[c=V]:before{width:.667em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c=W]:before{width:.944em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c=X]:before,.MJX-TEX .mjx-ss mjx-c[c=Y]:before{width:.667em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c=Z]:before{padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="["]:before,.MJX-TEX .mjx-ss mjx-c[c="]"]:before{width:.289em}.MJX-TEX .mjx-ss mjx-c[c=_]:before{padding:0 0 .114em}.MJX-TEX .mjx-ss mjx-c[c=a]:before{width:.481em;padding:.46em 0 .01em}.MJX-TEX .mjx-ss mjx-c[c=b]:before{width:.517em}.MJX-TEX .mjx-ss mjx-c[c=c]:before{padding:.46em 0 .01em}.MJX-TEX .mjx-ss mjx-c[c=d]:before{width:.517em}.MJX-TEX .mjx-ss mjx-c[c=e]:before{padding:.461em 0 .01em}.MJX-TEX .mjx-ss mjx-c[c=h]:before{width:.517em}.MJX-TEX .mjx-ss mjx-c[c=i]:before{width:.239em;padding:.68em 0 0}.MJX-TEX .mjx-ss mjx-c[c=j]:before{width:.267em;padding:.68em 0 .205em}.MJX-TEX .mjx-ss mjx-c[c=k]:before{width:.489em}.MJX-TEX .mjx-ss mjx-c[c=l]:before{width:.239em}.MJX-TEX .mjx-ss mjx-c[c=m]:before{width:.794em;padding:.455em 0 0}.MJX-TEX .mjx-ss mjx-c[c=n]:before{width:.517em;padding:.455em 0 0}.MJX-TEX .mjx-ss mjx-c[c=o]:before{padding:.46em 0 .01em}.MJX-TEX .mjx-ss mjx-c[c=p]:before,.MJX-TEX .mjx-ss mjx-c[c=q]:before{width:.517em;padding:.455em 0 .194em}.MJX-TEX .mjx-ss mjx-c[c=r]:before{width:.342em;padding:.455em 0 0}.MJX-TEX .mjx-ss mjx-c[c=s]:before{width:.383em;padding:.46em 0 .01em}.MJX-TEX .mjx-ss mjx-c[c=t]:before{width:.361em;padding:.571em 0 .01em}.MJX-TEX .mjx-ss mjx-c[c=u]:before{width:.517em}.MJX-TEX .mjx-ss mjx-c[c=v]:before{width:.461em;padding:.444em 0 0}.MJX-TEX .mjx-ss mjx-c[c=w]:before{width:.683em;padding:.444em 0 0}.MJX-TEX .mjx-ss mjx-c[c=x]:before{width:.461em;padding:.444em 0 0}.MJX-TEX .mjx-ss mjx-c[c=y]:before{width:.461em;padding:.444em 0 .204em}.MJX-TEX .mjx-ss mjx-c[c=z]:before{width:.435em;padding:.444em 0 0}.MJX-TEX .mjx-ss mjx-c[c="~"]:before{padding:.327em 0 0}.MJX-TEX .mjx-ss mjx-c[c="131"]:before{width:.239em}.MJX-TEX .mjx-ss mjx-c[c="237"]:before{width:.267em}.MJX-TEX .mjx-ss mjx-c[c="300"]:before,.MJX-TEX .mjx-ss mjx-c[c="301"]:before{padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="303"]:before{padding:.677em 0 0}.MJX-TEX .mjx-ss mjx-c[c="304"]:before{padding:.631em 0 0}.MJX-TEX .mjx-ss mjx-c[c="307"]:before,.MJX-TEX .mjx-ss mjx-c[c="308"]:before{padding:.68em 0 0}.MJX-TEX .mjx-ss mjx-c[c="30A"]:before,.MJX-TEX .mjx-ss mjx-c[c="30B"]:before{padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="30C"]:before{padding:.654em 0 0}.MJX-TEX .mjx-ss mjx-c[c="391"]:before,.MJX-TEX .mjx-ss mjx-c[c="392"]:before{width:.667em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="393"]:before{width:.542em;padding:.691em 0 0}.MJX-TEX .mjx-ss mjx-c[c="394"]:before{padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="395"]:before{width:.597em;padding:.691em 0 0}.MJX-TEX .mjx-ss mjx-c[c="396"]:before{padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="397"]:before{width:.708em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="398"]:before{padding:.716em 0 .021em}.MJX-TEX .mjx-ss mjx-c[c="399"]:before{width:.278em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="39A"]:before{width:.694em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="39B"]:before{width:.611em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="39C"]:before{width:.875em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="39D"]:before{width:.708em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="39E"]:before{padding:.688em 0 0}.MJX-TEX .mjx-ss mjx-c[c="39F"]:before{width:.736em;padding:.715em 0 .022em}.MJX-TEX .mjx-ss mjx-c[c="3A0"]:before{width:.708em;padding:.691em 0 0}.MJX-TEX .mjx-ss mjx-c[c="3A1"]:before{width:.639em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="3A2"]:before{padding:.716em 0 .021em}.MJX-TEX .mjx-ss mjx-c[c="3A3"]:before{padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="3A4"]:before{width:.681em;padding:.688em 0 0}.MJX-TEX .mjx-ss mjx-c[c="3A5"]:before{padding:.716em 0 0}.MJX-TEX .mjx-ss mjx-c[c="3A6"]:before{padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="3A7"]:before{width:.667em;padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="3A8"]:before{padding:.694em 0 0}.MJX-TEX .mjx-ss mjx-c[c="3A9"]:before,.MJX-TEX .mjx-ss mjx-c[c="3D2"]:before{padding:.716em 0 0}.MJX-TEX .mjx-ss mjx-c[c="3DC"]:before{width:.569em;padding:.691em 0 0}.MJX-TEX .mjx-ss mjx-c[c="2013"]:before,.MJX-TEX .mjx-ss mjx-c[c="2014"]:before,.MJX-TEX .mjx-ss mjx-c[c="2015"]:before{padding:.312em 0 0}.MJX-TEX .mjx-ss mjx-c[c="2017"]:before{padding:0 0 .114em}.MJX-TEX .mjx-ss mjx-c[c="2206"]:before{padding:.694em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="!"]:before{width:.367em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="22"]:before{width:.558em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="#"]:before{width:.917em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="$"]:before{width:.55em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="%"]:before{width:1.029em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="&"]:before{width:.831em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="27"]:before{width:.306em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="("]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c=")"]:before{width:.428em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="*"]:before{width:.55em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="+"]:before{width:.856em;padding:.617em 0 .116em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=","]:before{width:.306em;padding:.146em 0 .106em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="-"]:before{width:.367em;padding:.273em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="."]:before{width:.306em;padding:.146em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="/"]:before{width:.55em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="0"]:before{width:.55em;padding:.715em 0 .022em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="1"]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c="2"]:before{width:.55em;padding:.716em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="3"]:before{width:.55em;padding:.716em 0 .022em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="4"]:before{width:.55em;padding:.694em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="5"]:before{width:.55em;padding:.694em 0 .022em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="6"]:before{width:.55em;padding:.716em 0 .022em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="7"]:before{width:.55em;padding:.695em 0 .011em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="8"]:before{width:.55em;padding:.715em 0 .022em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="9"]:before{width:.55em;padding:.716em 0 .022em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=":"]:before{width:.306em;padding:.458em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=";"]:before{width:.306em;padding:.458em 0 .106em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="="]:before{width:.856em;padding:.407em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="?"]:before{width:.519em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="@"]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c=A]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c=B]:before{width:.733em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=C]:before{width:.703em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=D]:before{width:.794em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=E]:before{width:.642em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=F]:before{width:.611em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=G]:before{width:.733em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=H]:before{width:.794em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=I]:before{width:.331em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=J]:before{width:.519em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=K]:before{width:.764em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=L]:before{width:.581em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=M]:before{width:.978em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=N]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c=O]:before{width:.794em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=P]:before{width:.703em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=Q]:before{width:.794em;padding:.716em 0 .106em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=R]:before{width:.703em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=S]:before{width:.611em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=T]:before{width:.733em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=U]:before{width:.764em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=V]:before{width:.733em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=W]:before{width:1.039em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=X]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c=Y]:before{width:.733em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=Z]:before{width:.672em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="["]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c="]"]:before{width:.343em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="^"]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c=_]:before{width:.55em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=a]:before{width:.525em;padding:.475em 0 .011em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=b]:before{width:.561em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=c]:before{width:.489em;padding:.475em 0 .011em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=d]:before{width:.561em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=e]:before{width:.511em;padding:.474em 0 .01em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=f]:before{width:.336em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=g]:before{width:.55em;padding:.469em 0 .206em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=h]:before{width:.561em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=i]:before{width:.256em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=j]:before{width:.286em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=k]:before{width:.531em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=l]:before{width:.256em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=m]:before{width:.867em;padding:.469em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=n]:before{width:.561em;padding:.468em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=o]:before{width:.55em;padding:.474em 0 .011em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=p]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c=q]:before{width:.561em;padding:.469em 0 .194em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=r]:before{width:.372em;padding:.469em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=s]:before{width:.422em;padding:.474em 0 .01em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=t]:before{width:.404em;padding:.589em 0 .01em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=u]:before{width:.561em;padding:.458em 0 .011em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=v]:before{width:.5em;padding:.458em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=w]:before{width:.744em;padding:.458em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=x]:before{width:.5em;padding:.458em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=y]:before{width:.5em;padding:.458em 0 .205em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c=z]:before{width:.476em;padding:.458em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="~"]:before{width:.55em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="131"]:before{width:.256em;padding:.458em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="237"]:before{width:.286em;padding:.458em 0 .205em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="304"]:before{padding:.66em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="391"]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c="392"]:before{width:.733em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="393"]:before{width:.581em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="394"]:before{width:.917em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="395"]:before{width:.642em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="396"]:before{width:.672em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="397"]:before{width:.794em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="398"]:before{width:.856em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="399"]:before{width:.331em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="39A"]:before{width:.764em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="39B"]:before{width:.672em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="39C"]:before{width:.978em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="39D"]:before{width:.794em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="39E"]:before{width:.733em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="3A0"]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c="39F"]:before{width:.794em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="3A1"]:before{width:.703em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="3A2"]:before{width:.856em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="3A3"]:before{width:.794em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="3A4"]:before{width:.733em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="3A5"]:before{width:.856em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="3A6"]:before{width:.794em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="3A7"]:before{width:.733em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="3A8"]:before{width:.856em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="3A9"]:before{width:.794em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="3D2"]:before{width:.856em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="3DC"]:before{width:.611em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="2013"]:before{width:.55em;padding:.327em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="2014"]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c="2015"]:before{width:1.1em;padding:.327em 0 0}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="2017"]:before{width:.55em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="2018"]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c="2019"]:before{width:.306em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="201C"]:before,.MJX-TEX .mjx-ss.mjx-b mjx-c[c="201D"]:before{width:.558em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="2044"]:before{width:.55em}.MJX-TEX .mjx-ss.mjx-b mjx-c[c="2206"]:before{width:.917em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="$"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="$"]:last-child:before{width:.565em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="27"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="27"]:last-child:before{width:.335em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="("]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="("]:last-child:before{width:.491em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="*"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="*"]:last-child:before{width:.568em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="/"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="/"]:last-child:before{width:.6em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2"]:last-child:before{width:.551em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="5"]:last-child:before{width:.555em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="7"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="7"]:last-child:before{width:.596em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="8"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="8"]:last-child:before{width:.554em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="?"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="?"]:last-child:before{width:.536em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=C]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=C]:last-child:before{width:.719em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=E]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=E]:last-child:before{width:.688em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=F]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=F]:last-child:before{width:.673em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=G]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=G]:last-child:before{width:.73em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=H]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=H]:last-child:before{width:.768em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=I]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=I]:last-child:before{width:.338em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=J]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=J]:last-child:before{width:.535em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=K]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=K]:last-child:before{width:.785em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=M]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=M]:last-child:before{width:.929em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=N]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=N]:last-child:before{width:.766em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=P]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=P]:last-child:before{width:.69em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=R]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=R]:last-child:before{width:.698em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=S]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=S]:last-child:before{width:.609em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=T]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=T]:last-child:before{width:.79em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=U]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=U]:last-child:before{width:.747em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=V]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=V]:last-child:before{width:.799em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=W]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=W]:last-child:before{width:1.076em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=X]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=X]:last-child:before{width:.758em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=Y]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=Y]:last-child:before{width:.81em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=Z]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=Z]:last-child:before{width:.702em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="["]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="["]:last-child:before{width:.425em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="]"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="]"]:last-child:before{width:.353em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=_]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=_]:last-child:before{width:.565em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=c]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=c]:last-child:before{width:.499em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=d]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=d]:last-child:before{width:.588em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=f]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=f]:last-child:before{width:.494em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=g]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=g]:last-child:before{width:.568em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=i]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=i]:last-child:before{width:.315em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=j]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=j]:last-child:before{width:.336em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=k]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=k]:last-child:before{width:.543em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=l]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=l]:last-child:before{width:.311em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=r]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=r]:last-child:before{width:.424em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=s]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=s]:last-child:before{width:.436em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=v]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=v]:last-child:before{width:.54em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=w]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=w]:last-child:before{width:.762em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=x]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=x]:last-child:before{width:.537em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=y]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=y]:last-child:before{width:.54em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=z]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c=z]:last-child:before{width:.494em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="~"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="~"]:last-child:before{width:.56em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="301"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="301"]:last-child:before{width:.063em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="303"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="303"]:last-child:before{width:.06em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="304"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="304"]:last-child:before{width:.064em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="306"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="306"]:last-child:before{width:.073em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="30B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="30B"]:last-child:before{width:.063em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="30C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="30C"]:last-child:before{width:.06em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="393"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="393"]:last-child:before{width:.646em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="395"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="395"]:last-child:before{width:.688em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="396"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="396"]:last-child:before{width:.702em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="397"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="397"]:last-child:before{width:.768em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="399"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="399"]:last-child:before{width:.338em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="39A"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="39A"]:last-child:before{width:.785em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="39C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="39C"]:last-child:before{width:.929em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="39D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="39D"]:last-child:before{width:.766em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="39E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="39E"]:last-child:before{width:.765em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A0"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A0"]:last-child:before{width:.768em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A1"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A1"]:last-child:before{width:.69em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A3"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A3"]:last-child:before{width:.813em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A4"]:last-child:before{width:.79em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A5"]:last-child:before{width:.843em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A7"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A7"]:last-child:before{width:.758em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A8"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3A8"]:last-child:before{width:.854em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3D2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3D2"]:last-child:before{width:.843em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3DC"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="3DC"]:last-child:before{width:.673em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2013"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2013"]:last-child:before{width:.565em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2014"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2014"]:last-child:before{width:1.065em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2015"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2015"]:last-child:before{width:1.065em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2017"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2017"]:last-child:before{width:.565em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2018"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2018"]:last-child:before{width:.336em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2019"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2019"]:last-child:before{width:.335em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="201C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="201C"]:last-child:before{width:.614em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2044"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-i mjx-c[c="2044"]:last-child:before{width:.6em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="$"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="$"]:last-child:before{width:.565em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="27"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="27"]:last-child:before{width:.335em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="("]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="("]:last-child:before{width:.491em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="*"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="*"]:last-child:before{width:.568em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="/"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="/"]:last-child:before{width:.6em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2"]:last-child:before{width:.551em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="5"]:last-child:before{width:.555em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="7"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="7"]:last-child:before{width:.596em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="8"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="8"]:last-child:before{width:.554em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="?"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="?"]:last-child:before{width:.536em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=C]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=C]:last-child:before{width:.719em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=E]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=E]:last-child:before{width:.688em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=F]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=F]:last-child:before{width:.673em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=G]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=G]:last-child:before{width:.73em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=H]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=H]:last-child:before{width:.768em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=I]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=I]:last-child:before{width:.338em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=J]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=J]:last-child:before{width:.535em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=K]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=K]:last-child:before{width:.785em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=M]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=M]:last-child:before{width:.929em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=N]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=N]:last-child:before{width:.766em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=P]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=P]:last-child:before{width:.69em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=R]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=R]:last-child:before{width:.698em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=S]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=S]:last-child:before{width:.609em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=T]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=T]:last-child:before{width:.79em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=U]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=U]:last-child:before{width:.747em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=V]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=V]:last-child:before{width:.799em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=W]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=W]:last-child:before{width:1.076em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=X]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=X]:last-child:before{width:.758em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=Y]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=Y]:last-child:before{width:.81em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=Z]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=Z]:last-child:before{width:.702em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="["]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="["]:last-child:before{width:.425em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="]"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="]"]:last-child:before{width:.353em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=_]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=_]:last-child:before{width:.565em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=c]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=c]:last-child:before{width:.499em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=d]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=d]:last-child:before{width:.588em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=f]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=f]:last-child:before{width:.494em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=g]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=g]:last-child:before{width:.568em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=i]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=i]:last-child:before{width:.315em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=j]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=j]:last-child:before{width:.336em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=k]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=k]:last-child:before{width:.543em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=l]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=l]:last-child:before{width:.311em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=r]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=r]:last-child:before{width:.424em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=s]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=s]:last-child:before{width:.436em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=v]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=v]:last-child:before{width:.54em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=w]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=w]:last-child:before{width:.762em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=x]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=x]:last-child:before{width:.537em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=y]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=y]:last-child:before{width:.54em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=z]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c=z]:last-child:before{width:.494em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="~"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="~"]:last-child:before{width:.56em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="301"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="301"]:last-child:before{width:.063em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="303"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="303"]:last-child:before{width:.06em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="304"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="304"]:last-child:before{width:.064em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="306"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="306"]:last-child:before{width:.073em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="30B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="30B"]:last-child:before{width:.063em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="30C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="30C"]:last-child:before{width:.06em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="393"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="393"]:last-child:before{width:.646em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="395"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="395"]:last-child:before{width:.688em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="396"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="396"]:last-child:before{width:.702em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="397"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="397"]:last-child:before{width:.768em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="399"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="399"]:last-child:before{width:.338em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="39A"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="39A"]:last-child:before{width:.785em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="39C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="39C"]:last-child:before{width:.929em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="39D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="39D"]:last-child:before{width:.766em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="39E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="39E"]:last-child:before{width:.765em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A0"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A0"]:last-child:before{width:.768em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A1"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A1"]:last-child:before{width:.69em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A3"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A3"]:last-child:before{width:.813em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A4"]:last-child:before{width:.79em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A5"]:last-child:before{width:.843em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A7"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A7"]:last-child:before{width:.758em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A8"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3A8"]:last-child:before{width:.854em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3D2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3D2"]:last-child:before{width:.843em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3DC"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="3DC"]:last-child:before{width:.673em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2013"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2013"]:last-child:before{width:.565em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2014"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2014"]:last-child:before{width:1.065em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2015"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2015"]:last-child:before{width:1.065em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2017"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2017"]:last-child:before{width:.565em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2018"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2018"]:last-child:before{width:.336em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2019"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2019"]:last-child:before{width:.335em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="201C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="201C"]:last-child:before{width:.614em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2044"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-ss.mjx-b.mjx-i mjx-c[c="2044"]:last-child:before{width:.6em}.MJX-TEX .mjx-ty mjx-c[c=" "]:before{width:.525em}.MJX-TEX .mjx-ty mjx-c[c="!"]:before{width:.525em;padding:.622em 0 0}.MJX-TEX .mjx-ty mjx-c[c="22"]:before{width:.525em;padding:.623em 0 0}.MJX-TEX .mjx-ty mjx-c[c="#"]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="$"]:before{width:.525em;padding:.694em 0 .082em}.MJX-TEX .mjx-ty mjx-c[c="%"]:before{width:.525em;padding:.694em 0 .083em}.MJX-TEX .mjx-ty mjx-c[c="&"]:before{width:.525em;padding:.622em 0 .011em}.MJX-TEX .mjx-ty mjx-c[c="27"]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="("]:before,.MJX-TEX .mjx-ty mjx-c[c=")"]:before{width:.525em;padding:.694em 0 .082em}.MJX-TEX .mjx-ty mjx-c[c="*"]:before{width:.525em;padding:.52em 0 0}.MJX-TEX .mjx-ty mjx-c[c="+"]:before{width:.525em;padding:.531em 0 0}.MJX-TEX .mjx-ty mjx-c[c=","]:before{width:.525em;padding:.14em 0 .139em}.MJX-TEX .mjx-ty mjx-c[c="-"]:before{width:.525em;padding:.341em 0 0}.MJX-TEX .mjx-ty mjx-c[c="."]:before{width:.525em;padding:.14em 0 0}.MJX-TEX .mjx-ty mjx-c[c="/"]:before{width:.525em;padding:.694em 0 .083em}.MJX-TEX .mjx-ty mjx-c[c="0"]:before{width:.525em;padding:.621em 0 .01em}.MJX-TEX .mjx-ty mjx-c[c="1"]:before,.MJX-TEX .mjx-ty mjx-c[c="2"]:before{width:.525em;padding:.622em 0 0}.MJX-TEX .mjx-ty mjx-c[c="3"]:before{width:.525em;padding:.622em 0 .011em}.MJX-TEX .mjx-ty mjx-c[c="4"]:before{width:.525em;padding:.624em 0 0}.MJX-TEX .mjx-ty mjx-c[c="5"]:before{width:.525em;padding:.611em 0 .01em}.MJX-TEX .mjx-ty mjx-c[c="6"]:before{width:.525em;padding:.622em 0 .011em}.MJX-TEX .mjx-ty mjx-c[c="7"]:before{width:.525em;padding:.627em 0 .01em}.MJX-TEX .mjx-ty mjx-c[c="8"]:before{width:.525em;padding:.621em 0 .01em}.MJX-TEX .mjx-ty mjx-c[c="9"]:before{width:.525em;padding:.622em 0 .011em}.MJX-TEX .mjx-ty mjx-c[c=":"]:before{width:.525em}.MJX-TEX .mjx-ty mjx-c[c=";"]:before{width:.525em;padding:.431em 0 .139em}.MJX-TEX .mjx-ty mjx-c[c="<"]:before{width:.525em;padding:.557em 0 0}.MJX-TEX .mjx-ty mjx-c[c="="]:before{width:.525em;padding:.417em 0 0}.MJX-TEX .mjx-ty mjx-c[c=">"]:before{width:.525em;padding:.557em 0 0}.MJX-TEX .mjx-ty mjx-c[c="?"]:before{width:.525em;padding:.617em 0 0}.MJX-TEX .mjx-ty mjx-c[c="@"]:before{width:.525em;padding:.617em 0 .006em}.MJX-TEX .mjx-ty mjx-c[c=A]:before{width:.525em;padding:.623em 0 0}.MJX-TEX .mjx-ty mjx-c[c=B]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c=C]:before{width:.525em;padding:.622em 0 .011em}.MJX-TEX .mjx-ty mjx-c[c=D]:before,.MJX-TEX .mjx-ty mjx-c[c=E]:before,.MJX-TEX .mjx-ty mjx-c[c=F]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c=G]:before{width:.525em;padding:.622em 0 .011em}.MJX-TEX .mjx-ty mjx-c[c=H]:before,.MJX-TEX .mjx-ty mjx-c[c=I]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c=J]:before{width:.525em;padding:.611em 0 .011em}.MJX-TEX .mjx-ty mjx-c[c=K]:before,.MJX-TEX .mjx-ty mjx-c[c=L]:before,.MJX-TEX .mjx-ty mjx-c[c=M]:before,.MJX-TEX .mjx-ty mjx-c[c=N]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c=O]:before{width:.525em;padding:.621em 0 .01em}.MJX-TEX .mjx-ty mjx-c[c=P]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c=Q]:before{width:.525em;padding:.621em 0 .138em}.MJX-TEX .mjx-ty mjx-c[c=R]:before{width:.525em;padding:.611em 0 .011em}.MJX-TEX .mjx-ty mjx-c[c=S]:before{width:.525em;padding:.622em 0 .011em}.MJX-TEX .mjx-ty mjx-c[c=T]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c=U]:before{width:.525em;padding:.611em 0 .011em}.MJX-TEX .mjx-ty mjx-c[c=V]:before,.MJX-TEX .mjx-ty mjx-c[c=W]:before{width:.525em;padding:.611em 0 .007em}.MJX-TEX .mjx-ty mjx-c[c=X]:before,.MJX-TEX .mjx-ty mjx-c[c=Y]:before,.MJX-TEX .mjx-ty mjx-c[c=Z]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="["]:before{width:.525em;padding:.694em 0 .082em}.MJX-TEX .mjx-ty mjx-c[c="5C"]:before{width:.525em;padding:.694em 0 .083em}.MJX-TEX .mjx-ty mjx-c[c="]"]:before{width:.525em;padding:.694em 0 .082em}.MJX-TEX .mjx-ty mjx-c[c="^"]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c=_]:before{width:.525em;padding:0 0 .095em}.MJX-TEX .mjx-ty mjx-c[c="`"]:before{width:.525em;padding:.681em 0 0}.MJX-TEX .mjx-ty mjx-c[c=a]:before{width:.525em;padding:.439em 0 .006em}.MJX-TEX .mjx-ty mjx-c[c=b]:before{width:.525em;padding:.611em 0 .006em}.MJX-TEX .mjx-ty mjx-c[c=c]:before{width:.525em;padding:.44em 0 .006em}.MJX-TEX .mjx-ty mjx-c[c=d]:before{width:.525em;padding:.611em 0 .006em}.MJX-TEX .mjx-ty mjx-c[c=e]:before{width:.525em;padding:.44em 0 .006em}.MJX-TEX .mjx-ty mjx-c[c=f]:before{width:.525em;padding:.617em 0 0}.MJX-TEX .mjx-ty mjx-c[c=g]:before{width:.525em;padding:.442em 0 .229em}.MJX-TEX .mjx-ty mjx-c[c=h]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c=i]:before{width:.525em;padding:.612em 0 0}.MJX-TEX .mjx-ty mjx-c[c=j]:before{width:.525em;padding:.612em 0 .228em}.MJX-TEX .mjx-ty mjx-c[c=k]:before,.MJX-TEX .mjx-ty mjx-c[c=l]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c=m]:before,.MJX-TEX .mjx-ty mjx-c[c=n]:before{width:.525em;padding:.436em 0 0}.MJX-TEX .mjx-ty mjx-c[c=o]:before{width:.525em;padding:.44em 0 .006em}.MJX-TEX .mjx-ty mjx-c[c=p]:before,.MJX-TEX .mjx-ty mjx-c[c=q]:before{width:.525em;padding:.437em 0 .221em}.MJX-TEX .mjx-ty mjx-c[c=r]:before{width:.525em;padding:.437em 0 0}.MJX-TEX .mjx-ty mjx-c[c=s]:before{width:.525em;padding:.44em 0 .006em}.MJX-TEX .mjx-ty mjx-c[c=t]:before{width:.525em;padding:.554em 0 .006em}.MJX-TEX .mjx-ty mjx-c[c=u]:before{width:.525em;padding:.431em 0 .005em}.MJX-TEX .mjx-ty mjx-c[c=v]:before,.MJX-TEX .mjx-ty mjx-c[c=w]:before{width:.525em;padding:.431em 0 0}.MJX-TEX .mjx-ty mjx-c[c=x]:before{width:.525em}.MJX-TEX .mjx-ty mjx-c[c=y]:before{width:.525em;padding:.431em 0 .228em}.MJX-TEX .mjx-ty mjx-c[c=z]:before{width:.525em}.MJX-TEX .mjx-ty mjx-c[c="{"]:before{width:.525em;padding:.694em 0 .083em}.MJX-TEX .mjx-ty mjx-c[c="|"]:before{width:.525em;padding:.694em 0 .082em}.MJX-TEX .mjx-ty mjx-c[c="}"]:before{width:.525em;padding:.694em 0 .083em}.MJX-TEX .mjx-ty mjx-c[c="~"]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="7F"]:before{width:.525em;padding:.612em 0 0;content:"\7F"}.MJX-TEX .mjx-ty mjx-c[c=A0]:before{width:.525em}.MJX-TEX .mjx-ty mjx-c[c="131"]:before{width:.525em;padding:.431em 0 0}.MJX-TEX .mjx-ty mjx-c[c="237"]:before{width:.525em;padding:.431em 0 .228em}.MJX-TEX .mjx-ty mjx-c[c="2B9"]:before{width:.525em;padding:.623em 0 0}.MJX-TEX .mjx-ty mjx-c[c="300"]:before,.MJX-TEX .mjx-ty mjx-c[c="301"]:before,.MJX-TEX .mjx-ty mjx-c[c="302"]:before,.MJX-TEX .mjx-ty mjx-c[c="303"]:before{padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="304"]:before{padding:.577em 0 0}.MJX-TEX .mjx-ty mjx-c[c="306"]:before{padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="308"]:before{padding:.612em 0 0}.MJX-TEX .mjx-ty mjx-c[c="30A"]:before{padding:.619em 0 0}.MJX-TEX .mjx-ty mjx-c[c="30C"]:before{padding:.577em 0 0}.MJX-TEX .mjx-ty mjx-c[c="391"]:before{width:.525em;padding:.623em 0 0}.MJX-TEX .mjx-ty mjx-c[c="392"]:before,.MJX-TEX .mjx-ty mjx-c[c="393"]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="394"]:before{width:.525em;padding:.623em 0 0}.MJX-TEX .mjx-ty mjx-c[c="395"]:before,.MJX-TEX .mjx-ty mjx-c[c="396"]:before,.MJX-TEX .mjx-ty mjx-c[c="397"]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="398"]:before{width:.525em;padding:.621em 0 .01em}.MJX-TEX .mjx-ty mjx-c[c="39A"]:before,.MJX-TEX .mjx-ty mjx-c[c="399"]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="39B"]:before{width:.525em;padding:.623em 0 0}.MJX-TEX .mjx-ty mjx-c[c="39C"]:before,.MJX-TEX .mjx-ty mjx-c[c="39D"]:before,.MJX-TEX .mjx-ty mjx-c[c="39E"]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="39F"]:before{width:.525em;padding:.621em 0 .01em}.MJX-TEX .mjx-ty mjx-c[c="3A0"]:before,.MJX-TEX .mjx-ty mjx-c[c="3A1"]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="3A2"]:before{width:.525em;padding:.621em 0 .01em}.MJX-TEX .mjx-ty mjx-c[c="3A3"]:before,.MJX-TEX .mjx-ty mjx-c[c="3A4"]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="3A5"]:before{width:.525em;padding:.622em 0 0}.MJX-TEX .mjx-ty mjx-c[c="3A6"]:before,.MJX-TEX .mjx-ty mjx-c[c="3A7"]:before,.MJX-TEX .mjx-ty mjx-c[c="3A8"]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="3A9"]:before,.MJX-TEX .mjx-ty mjx-c[c="3D2"]:before{width:.525em;padding:.622em 0 0}.MJX-TEX .mjx-ty mjx-c[c="3DC"]:before{width:.525em;padding:.611em 0 0}.MJX-TEX .mjx-ty mjx-c[c="2017"]:before{width:.525em;padding:0 0 .095em}.MJX-TEX .mjx-ty mjx-c[c="2032"]:before{width:.525em;padding:.623em 0 0}.MJX-TEX .mjx-ty mjx-c[c="2033"]:before{width:1.05em;padding:.623em 0 0}.MJX-TEX .mjx-ty mjx-c[c="2034"]:before{width:1.575em;padding:.623em 0 0}.MJX-TEX .mjx-ty mjx-c[c="2044"]:before{width:.525em;padding:.694em 0 .083em}.MJX-TEX .mjx-ty mjx-c[c="2057"]:before{width:2.1em;padding:.623em 0 0}.MJX-TEX .mjx-ty mjx-c[c="2206"]:before{width:.525em;padding:.623em 0 0}.MJX-TEX .mjx-sop mjx-c[c="("]:before,.MJX-TEX .mjx-sop mjx-c[c=")"]:before{width:.458em;padding:.85em 0 .349em}.MJX-TEX .mjx-sop mjx-c[c="/"]:before{width:.578em;padding:.85em 0 .349em}.MJX-TEX .mjx-sop mjx-c[c="["]:before{width:.417em;padding:.85em 0 .349em}.MJX-TEX .mjx-sop mjx-c[c="5C"]:before{width:.578em;padding:.85em 0 .349em}.MJX-TEX .mjx-sop mjx-c[c="]"]:before{width:.417em;padding:.85em 0 .349em}.MJX-TEX .mjx-sop mjx-c[c="{"]:before,.MJX-TEX .mjx-sop mjx-c[c="}"]:before{width:.583em;padding:.85em 0 .349em}.MJX-TEX .mjx-sop mjx-c[c="2C6"]:before{width:.556em;padding:.744em 0 0}.MJX-TEX .mjx-sop mjx-c[c="2DC"]:before{width:.556em;padding:.722em 0 0}.MJX-TEX .mjx-sop mjx-c[c="302"]:before{padding:.744em 0 0}.MJX-TEX .mjx-sop mjx-c[c="303"]:before{padding:.722em 0 0}.MJX-TEX .mjx-sop mjx-c[c="2016"]:before{width:.778em;padding:.602em 0 0;content:"\2016"}.MJX-TEX .mjx-sop mjx-c[c="2044"]:before{width:.578em;padding:.85em 0 .349em}.MJX-TEX .mjx-sop mjx-c[c="2191"]:before,.MJX-TEX .mjx-sop mjx-c[c="2193"]:before{width:.667em;padding:.6em 0 0}.MJX-TEX .mjx-sop mjx-c[c="21D1"]:before{width:.778em;padding:.599em 0 0}.MJX-TEX .mjx-sop mjx-c[c="21D3"]:before{width:.778em;padding:.6em 0 0}.MJX-TEX .mjx-sop mjx-c[c="221A"]:before{width:1em;padding:.85em 0 .35em}.MJX-TEX .mjx-sop mjx-c[c="2223"]:before{width:.333em;padding:.627em 0 .015em}.MJX-TEX .mjx-sop mjx-c[c="2225"]:before{width:.556em;padding:.627em 0 .015em}.MJX-TEX .mjx-sop mjx-c[c="222B"]:before{width:.472em;padding:.805em 0 .306em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sop mjx-c[c="222B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sop mjx-c[c="222B"]:last-child:before{width:.61em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sop mjx-c[c="222C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sop mjx-c[c="222C"]:last-child:before{width:.957em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sop mjx-c[c="222D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sop mjx-c[c="222D"]:last-child:before{width:1.304em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sop mjx-c[c="222E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sop mjx-c[c="222E"]:last-child:before{width:.61em}.MJX-TEX .mjx-sop mjx-c[c="230A"]:before,.MJX-TEX .mjx-sop mjx-c[c="230B"]:before,.MJX-TEX .mjx-sop mjx-c[c="2308"]:before,.MJX-TEX .mjx-sop mjx-c[c="2309"]:before{width:.472em;padding:.85em 0 .349em}.MJX-TEX .mjx-sop mjx-c[c="232A"]:before,.MJX-TEX .mjx-sop mjx-c[c="2329"]:before{width:.472em;padding:.85em 0 .35em}.MJX-TEX .mjx-sop mjx-c[c="2758"]:before{width:.333em;padding:.627em 0 .015em}.MJX-TEX .mjx-sop mjx-c[c="27E8"]:before,.MJX-TEX .mjx-sop mjx-c[c="27E9"]:before{width:.472em;padding:.85em 0 .35em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-sop mjx-c[c="2A0C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-sop mjx-c[c="2A0C"]:last-child:before{width:1.776em}.MJX-TEX .mjx-sop mjx-c[c="3008"]:before,.MJX-TEX .mjx-sop mjx-c[c="3009"]:before{width:.472em;padding:.85em 0 .35em}.MJX-TEX .mjx-lop mjx-c[c="("]:before,.MJX-TEX .mjx-lop mjx-c[c=")"]:before{width:.597em;padding:1.15em 0 .649em}.MJX-TEX .mjx-lop mjx-c[c="/"]:before{width:.811em;padding:1.15em 0 .649em}.MJX-TEX .mjx-lop mjx-c[c="["]:before{width:.472em;padding:1.15em 0 .649em}.MJX-TEX .mjx-lop mjx-c[c="5C"]:before{width:.811em;padding:1.15em 0 .649em}.MJX-TEX .mjx-lop mjx-c[c="]"]:before{width:.472em;padding:1.15em 0 .649em}.MJX-TEX .mjx-lop mjx-c[c="{"]:before,.MJX-TEX .mjx-lop mjx-c[c="}"]:before{width:.667em;padding:1.15em 0 .649em}.MJX-TEX .mjx-lop mjx-c[c="2C6"]:before{width:1em;padding:.772em 0 0}.MJX-TEX .mjx-lop mjx-c[c="2DC"]:before{width:1em;padding:.75em 0 0}.MJX-TEX .mjx-lop mjx-c[c="302"]:before{padding:.772em 0 0}.MJX-TEX .mjx-lop mjx-c[c="303"]:before{padding:.75em 0 0}.MJX-TEX .mjx-lop mjx-c[c="2016"]:before{width:.778em;padding:.602em 0 0;content:"\2016"}.MJX-TEX .mjx-lop mjx-c[c="2044"]:before{width:.811em;padding:1.15em 0 .649em}.MJX-TEX .mjx-lop mjx-c[c="2191"]:before,.MJX-TEX .mjx-lop mjx-c[c="2193"]:before{width:.667em;padding:.6em 0 0}.MJX-TEX .mjx-lop mjx-c[c="21D1"]:before{width:.778em;padding:.599em 0 0}.MJX-TEX .mjx-lop mjx-c[c="21D3"]:before{width:.778em;padding:.6em 0 0}.MJX-TEX .mjx-lop mjx-c[c="220F"]:before,.MJX-TEX .mjx-lop mjx-c[c="2210"]:before{width:1.278em;padding:.95em 0 .45em}.MJX-TEX .mjx-lop mjx-c[c="2211"]:before{width:1.444em;padding:.95em 0 .45em}.MJX-TEX .mjx-lop mjx-c[c="221A"]:before{width:1em;padding:1.15em 0 .65em}.MJX-TEX .mjx-lop mjx-c[c="2223"]:before{width:.333em;padding:.627em 0 .015em}.MJX-TEX .mjx-lop mjx-c[c="2225"]:before{width:.556em;padding:.627em 0 .015em}.MJX-TEX .mjx-lop mjx-c[c="222B"]:before{width:.556em;padding:1.36em 0 .862em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-lop mjx-c[c="222B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-lop mjx-c[c="222B"]:last-child:before{width:.944em}.MJX-TEX .mjx-lop mjx-c[c="222C"]:before{width:1.084em;padding:1.36em 0 .862em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-lop mjx-c[c="222C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-lop mjx-c[c="222C"]:last-child:before{width:1.472em}.MJX-TEX .mjx-lop mjx-c[c="222D"]:before{width:1.592em;padding:1.36em 0 .862em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-lop mjx-c[c="222D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-lop mjx-c[c="222D"]:last-child:before{width:1.98em}.MJX-TEX .mjx-lop mjx-c[c="222E"]:before{width:.556em;padding:1.36em 0 .862em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-lop mjx-c[c="222E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-lop mjx-c[c="222E"]:last-child:before{width:.944em}.MJX-TEX .mjx-lop mjx-c[c="22C0"]:before,.MJX-TEX .mjx-lop mjx-c[c="22C1"]:before{width:1.111em;padding:.95em 0 .45em}.MJX-TEX .mjx-lop mjx-c[c="22C2"]:before{width:1.111em;padding:.949em 0 .45em}.MJX-TEX .mjx-lop mjx-c[c="22C3"]:before{width:1.111em;padding:.95em 0 .449em}.MJX-TEX .mjx-lop mjx-c[c="230A"]:before,.MJX-TEX .mjx-lop mjx-c[c="230B"]:before,.MJX-TEX .mjx-lop mjx-c[c="2308"]:before,.MJX-TEX .mjx-lop mjx-c[c="2309"]:before{width:.528em;padding:1.15em 0 .649em}.MJX-TEX .mjx-lop mjx-c[c="232A"]:before,.MJX-TEX .mjx-lop mjx-c[c="2329"]:before{width:.611em;padding:1.15em 0 .649em}.MJX-TEX .mjx-lop mjx-c[c="2758"]:before{width:.333em;padding:.627em 0 .015em}.MJX-TEX .mjx-lop mjx-c[c="27E8"]:before,.MJX-TEX .mjx-lop mjx-c[c="27E9"]:before{width:.611em;padding:1.15em 0 .649em}.MJX-TEX .mjx-lop mjx-c[c="2A00"]:before,.MJX-TEX .mjx-lop mjx-c[c="2A01"]:before,.MJX-TEX .mjx-lop mjx-c[c="2A02"]:before{width:1.511em;padding:.949em 0 .449em}.MJX-TEX .mjx-lop mjx-c[c="2A04"]:before{width:1.111em;padding:.95em 0 .449em}.MJX-TEX .mjx-lop mjx-c[c="2A06"]:before{width:1.111em;padding:.95em 0 .45em}.MJX-TEX .mjx-lop mjx-c[c="2A0C"]:before{width:2.168em;padding:1.36em 0 .862em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-lop mjx-c[c="2A0C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-lop mjx-c[c="2A0C"]:last-child:before{width:2.556em}.MJX-TEX .mjx-lop mjx-c[c="3008"]:before,.MJX-TEX .mjx-lop mjx-c[c="3009"]:before{width:.611em;padding:1.15em 0 .649em}.MJX-TEX .mjx-s3 mjx-c[c="("]:before,.MJX-TEX .mjx-s3 mjx-c[c=")"]:before{width:.736em;padding:1.45em 0 .949em}.MJX-TEX .mjx-s3 mjx-c[c="/"]:before{width:1.044em;padding:1.45em 0 .949em}.MJX-TEX .mjx-s3 mjx-c[c="["]:before{width:.528em;padding:1.45em 0 .949em}.MJX-TEX .mjx-s3 mjx-c[c="5C"]:before{width:1.044em;padding:1.45em 0 .949em}.MJX-TEX .mjx-s3 mjx-c[c="]"]:before{width:.528em;padding:1.45em 0 .949em}.MJX-TEX .mjx-s3 mjx-c[c="{"]:before,.MJX-TEX .mjx-s3 mjx-c[c="}"]:before{width:.75em;padding:1.45em 0 .949em}.MJX-TEX .mjx-s3 mjx-c[c="2C6"]:before{width:1.444em;padding:.772em 0 0}.MJX-TEX .mjx-s3 mjx-c[c="2DC"]:before{width:1.444em;padding:.749em 0 0}.MJX-TEX .mjx-s3 mjx-c[c="302"]:before{padding:.772em 0 0}.MJX-TEX .mjx-s3 mjx-c[c="303"]:before{padding:.749em 0 0}.MJX-TEX .mjx-s3 mjx-c[c="2044"]:before{width:1.044em;padding:1.45em 0 .949em}.MJX-TEX .mjx-s3 mjx-c[c="221A"]:before{width:1em;padding:1.45em 0 .95em}.MJX-TEX .mjx-s3 mjx-c[c="230A"]:before,.MJX-TEX .mjx-s3 mjx-c[c="230B"]:before,.MJX-TEX .mjx-s3 mjx-c[c="2308"]:before,.MJX-TEX .mjx-s3 mjx-c[c="2309"]:before{width:.583em;padding:1.45em 0 .949em}.MJX-TEX .mjx-s3 mjx-c[c="2329"]:before{width:.75em;padding:1.45em 0 .95em}.MJX-TEX .mjx-s3 mjx-c[c="232A"]:before{width:.75em;padding:1.45em 0 .949em}.MJX-TEX .mjx-s3 mjx-c[c="27E8"]:before{width:.75em;padding:1.45em 0 .95em}.MJX-TEX .mjx-s3 mjx-c[c="27E9"]:before{width:.75em;padding:1.45em 0 .949em}.MJX-TEX .mjx-s3 mjx-c[c="3008"]:before{width:.75em;padding:1.45em 0 .95em}.MJX-TEX .mjx-s3 mjx-c[c="3009"]:before{width:.75em;padding:1.45em 0 .949em}.MJX-TEX .mjx-s4 mjx-c[c="("]:before,.MJX-TEX .mjx-s4 mjx-c[c=")"]:before{width:.792em;padding:1.75em 0 1.249em}.MJX-TEX .mjx-s4 mjx-c[c="/"]:before{width:1.278em;padding:1.75em 0 1.249em}.MJX-TEX .mjx-s4 mjx-c[c="["]:before{width:.583em;padding:1.75em 0 1.249em}.MJX-TEX .mjx-s4 mjx-c[c="5C"]:before{width:1.278em;padding:1.75em 0 1.249em}.MJX-TEX .mjx-s4 mjx-c[c="]"]:before{width:.583em;padding:1.75em 0 1.249em}.MJX-TEX .mjx-s4 mjx-c[c="{"]:before,.MJX-TEX .mjx-s4 mjx-c[c="}"]:before{width:.806em;padding:1.75em 0 1.249em}.MJX-TEX .mjx-s4 mjx-c[c="2C6"]:before{width:1.889em;padding:.845em 0 0}.MJX-TEX .mjx-s4 mjx-c[c="2DC"]:before{width:1.889em;padding:.823em 0 0}.MJX-TEX .mjx-s4 mjx-c[c="302"]:before{padding:.845em 0 0}.MJX-TEX .mjx-s4 mjx-c[c="303"]:before{padding:.823em 0 0}.MJX-TEX .mjx-s4 mjx-c[c="2044"]:before{width:1.278em;padding:1.75em 0 1.249em}.MJX-TEX .mjx-s4 mjx-c[c="221A"]:before{width:1em;padding:1.75em 0 1.25em}.MJX-TEX .mjx-s4 mjx-c[c="230A"]:before,.MJX-TEX .mjx-s4 mjx-c[c="230B"]:before,.MJX-TEX .mjx-s4 mjx-c[c="2308"]:before,.MJX-TEX .mjx-s4 mjx-c[c="2309"]:before{width:.639em;padding:1.75em 0 1.249em}.MJX-TEX .mjx-s4 mjx-c[c="232A"]:before,.MJX-TEX .mjx-s4 mjx-c[c="2329"]:before{width:.806em;padding:1.75em 0 1.248em}.MJX-TEX .mjx-s4 mjx-c[c="239B"]:before{width:.875em;padding:1.154em 0 .655em;content:"\239B"}.MJX-TEX .mjx-s4 mjx-c[c="239C"]:before{width:.875em;padding:.61em 0 .01em;content:"\239C"}.MJX-TEX .mjx-s4 mjx-c[c="239D"]:before{width:.875em;padding:1.165em 0 .644em;content:"\239D"}.MJX-TEX .mjx-s4 mjx-c[c="239E"]:before{width:.875em;padding:1.154em 0 .655em;content:"\239E"}.MJX-TEX .mjx-s4 mjx-c[c="239F"]:before{width:.875em;padding:.61em 0 .01em;content:"\239F"}.MJX-TEX .mjx-s4 mjx-c[c="23A0"]:before{width:.875em;padding:1.165em 0 .644em;content:"\23A0"}.MJX-TEX .mjx-s4 mjx-c[c="23A1"]:before{width:.667em;padding:1.154em 0 .645em;content:"\23A1"}.MJX-TEX .mjx-s4 mjx-c[c="23A2"]:before{width:.667em;padding:.602em 0 0;content:"\23A2"}.MJX-TEX .mjx-s4 mjx-c[c="23A3"]:before{width:.667em;padding:1.155em 0 .644em;content:"\23A3"}.MJX-TEX .mjx-s4 mjx-c[c="23A4"]:before{width:.667em;padding:1.154em 0 .645em;content:"\23A4"}.MJX-TEX .mjx-s4 mjx-c[c="23A5"]:before{width:.667em;padding:.602em 0 0;content:"\23A5"}.MJX-TEX .mjx-s4 mjx-c[c="23A6"]:before{width:.667em;padding:1.155em 0 .644em;content:"\23A6"}.MJX-TEX .mjx-s4 mjx-c[c="23A7"]:before{width:.889em;padding:.899em 0 .01em;content:"\23A7"}.MJX-TEX .mjx-s4 mjx-c[c="23A8"]:before{width:.889em;padding:1.16em 0 .66em;content:"\23A8"}.MJX-TEX .mjx-s4 mjx-c[c="23A9"]:before{width:.889em;padding:.01em 0 .899em;content:"\23A9"}.MJX-TEX .mjx-s4 mjx-c[c="23AA"]:before{width:.889em;padding:.29em 0 .015em;content:"\23AA"}.MJX-TEX .mjx-s4 mjx-c[c="23AB"]:before{width:.889em;padding:.899em 0 .01em;content:"\23AB"}.MJX-TEX .mjx-s4 mjx-c[c="23AC"]:before{width:.889em;padding:1.16em 0 .66em;content:"\23AC"}.MJX-TEX .mjx-s4 mjx-c[c="23AD"]:before{width:.889em;padding:.01em 0 .899em;content:"\23AD"}.MJX-TEX .mjx-s4 mjx-c[c="23B7"]:before{width:1.056em;padding:.935em 0 .885em;content:"\23B7"}.MJX-TEX .mjx-s4 mjx-c[c="27E8"]:before,.MJX-TEX .mjx-s4 mjx-c[c="27E9"]:before,.MJX-TEX .mjx-s4 mjx-c[c="3008"]:before,.MJX-TEX .mjx-s4 mjx-c[c="3009"]:before{width:.806em;padding:1.75em 0 1.248em}.MJX-TEX .mjx-s4 mjx-c[c=E000]:before{width:1.056em;padding:.625em 0 .014em;content:"\E000"}.MJX-TEX .mjx-s4 mjx-c[c=E001]:before{width:1.056em;padding:.605em 0 .014em;content:"\E001"}.MJX-TEX .mjx-s4 mjx-c[c=E150]:before{width:.45em;padding:.12em 0 .213em;content:"\E150"}.MJX-TEX .mjx-s4 mjx-c[c=E151]:before{width:.45em;padding:.12em 0 .213em;content:"\E151"}.MJX-TEX .mjx-s4 mjx-c[c=E152]:before{width:.45em;padding:.333em 0 0;content:"\E152"}.MJX-TEX .mjx-s4 mjx-c[c=E153]:before{width:.45em;padding:.333em 0 0;content:"\E153"}.MJX-TEX .mjx-s4 mjx-c[c=E154]:before{width:.4em;padding:.32em 0 .2em;content:"\E154"}.MJX-TEX .mjx-s4 mjx-c[c=E155]:before{width:.9em;padding:.333em 0 0;content:"\E153\E152"}.MJX-TEX .mjx-s4 mjx-c[c=E156]:before{width:.9em;padding:.12em 0 .213em;content:"\E151\E150"}.MJX-TEX .mjx-cal mjx-c[c="0"]:before{padding:.452em 0 .022em}.MJX-TEX .mjx-cal mjx-c[c="1"]:before,.MJX-TEX .mjx-cal mjx-c[c="2"]:before{padding:.453em 0 0}.MJX-TEX .mjx-cal mjx-c[c="3"]:before{padding:.452em 0 .216em}.MJX-TEX .mjx-cal mjx-c[c="4"]:before{padding:.464em 0 .194em}.MJX-TEX .mjx-cal mjx-c[c="5"]:before{padding:.453em 0 .216em}.MJX-TEX .mjx-cal mjx-c[c="7"]:before{padding:.463em 0 .216em}.MJX-TEX .mjx-cal mjx-c[c="9"]:before{padding:.453em 0 .216em}.MJX-TEX .mjx-cal mjx-c[c=A]:before{width:.798em;padding:.728em 0 .05em}.MJX-TEX .mjx-cal mjx-c[c=B]:before{width:.657em;padding:.705em 0 .022em}.MJX-TEX .mjx-cal mjx-c[c=C]:before{width:.527em}.MJX-TEX .mjx-cal mjx-c[c=D]:before{width:.771em}.MJX-TEX .mjx-cal mjx-c[c=E]:before{width:.528em;padding:.705em 0 .022em}.MJX-TEX .mjx-cal mjx-c[c=F]:before{width:.719em;padding:.683em 0 .032em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c=F]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c=F]:last-child:before{width:.829em}.MJX-TEX .mjx-cal mjx-c[c=G]:before{width:.595em;padding:.704em 0 .119em}.MJX-TEX .mjx-cal mjx-c[c=H]:before{width:.845em;padding:.683em 0 .048em}.MJX-TEX .mjx-cal mjx-c[c=I]:before{width:.545em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c=I]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c=I]:last-child:before{width:.642em}.MJX-TEX .mjx-cal mjx-c[c=J]:before{width:.678em;padding:.683em 0 .119em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c=J]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c=J]:last-child:before{width:.839em}.MJX-TEX .mjx-cal mjx-c[c=K]:before{width:.762em;padding:.705em 0 .022em}.MJX-TEX .mjx-cal mjx-c[c=L]:before{width:.69em;padding:.705em 0 .022em}.MJX-TEX .mjx-cal mjx-c[c=M]:before{width:1.201em;padding:.705em 0 .05em}.MJX-TEX .mjx-cal mjx-c[c=N]:before{width:.82em;padding:.789em 0 .05em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c=N]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c=N]:last-child:before{width:.979em}.MJX-TEX .mjx-cal mjx-c[c=O]:before{width:.796em}.MJX-TEX .mjx-cal mjx-c[c=P]:before{width:.696em;padding:.683em 0 .057em}.MJX-TEX .mjx-cal mjx-c[c=Q]:before{width:.817em;padding:.705em 0 .131em}.MJX-TEX .mjx-cal mjx-c[c=R]:before{width:.848em}.MJX-TEX .mjx-cal mjx-c[c=S]:before{width:.606em}.MJX-TEX .mjx-cal mjx-c[c=T]:before{width:.545em;padding:.717em 0 .068em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c=T]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c=T]:last-child:before{width:.833em}.MJX-TEX .mjx-cal mjx-c[c=U]:before{width:.626em;padding:.683em 0 .028em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c=U]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c=U]:last-child:before{width:.687em}.MJX-TEX .mjx-cal mjx-c[c=V]:before{width:.613em;padding:.683em 0 .052em}.MJX-TEX .mjx-cal mjx-c[c=W]:before{width:.988em;padding:.683em 0 .053em}.MJX-TEX .mjx-cal mjx-c[c=X]:before{width:.713em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c=X]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c=X]:last-child:before{width:.807em}.MJX-TEX .mjx-cal mjx-c[c=Y]:before{width:.668em;padding:.683em 0 .143em}.MJX-TEX .mjx-cal mjx-c[c=Z]:before{width:.725em}.MJX-TEX .mjx-cal mjx-c[c="391"]:before,.MJX-TEX .mjx-cal mjx-c[c="392"]:before,.MJX-TEX .mjx-cal mjx-c[c="395"]:before,.MJX-TEX .mjx-cal mjx-c[c="396"]:before,.MJX-TEX .mjx-cal mjx-c[c="397"]:before{font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c="397"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c="397"]:last-child:before{width:.888em}.MJX-TEX .mjx-cal mjx-c[c="399"]:before{font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c="399"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c="399"]:last-child:before{width:.504em}.MJX-TEX .mjx-cal mjx-c[c="39A"]:before,.MJX-TEX .mjx-cal mjx-c[c="39C"]:before{font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c="39C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c="39C"]:last-child:before{width:1.051em}.MJX-TEX .mjx-cal mjx-c[c="39D"]:before{font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c="39D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c="39D"]:last-child:before{width:.888em}.MJX-TEX .mjx-cal mjx-c[c="3A1"]:before,.MJX-TEX .mjx-cal mjx-c[c="39F"]:before{font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c="3A1"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c="3A1"]:last-child:before{width:.751em}.MJX-TEX .mjx-cal mjx-c[c="3A2"]:before,.MJX-TEX .mjx-cal mjx-c[c="3A4"]:before{font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c="3A4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c="3A4"]:last-child:before{width:.704em}.MJX-TEX .mjx-cal mjx-c[c="3A7"]:before,.MJX-TEX .mjx-cal mjx-c[c="3D2"]:before{font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c="3D2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c="3D2"]:last-child:before{width:.7em}.MJX-TEX .mjx-cal mjx-c[c="3DC"]:before{font-family:MJXZERO,MJXTEX-I}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal mjx-c[c="3DC"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal mjx-c[c="3DC"]:last-child:before{width:.749em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="0"]:before{padding:.46em 0 .017em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="1"]:before{padding:.461em 0 0}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="2"]:before{padding:.46em 0 0}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="3"]:before{padding:.461em 0 .211em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="5"]:before{padding:.461em 0 .211em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="6"]:before{padding:.66em 0 .017em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="7"]:before{padding:.476em 0 .211em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="8"]:before{padding:.661em 0 .017em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="9"]:before{padding:.461em 0 .21em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=A]:before{width:.921em;padding:.751em 0 .049em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=A]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=A]:last-child:before{width:.989em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=B]:before{width:.748em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=C]:before{width:.613em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=D]:before{width:.892em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=E]:before{width:.607em;padding:.703em 0 .016em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=F]:before{width:.814em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=F]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=F]:last-child:before{width:.93em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=G]:before{width:.682em;padding:.703em 0 .113em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=H]:before{width:.987em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=I]:before{width:.642em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=I]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=I]:last-child:before{width:.746em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=J]:before{width:.779em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=J]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=J]:last-child:before{width:.937em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=K]:before{width:.871em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=L]:before{width:.788em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=M]:before{width:1.378em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=N]:before{width:.937em;padding:.84em 0 .049em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=N]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=N]:last-child:before{width:1.105em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=O]:before{width:.906em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=P]:before{width:.81em;padding:.686em 0 .067em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=Q]:before{width:.939em;padding:.703em 0 .146em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=R]:before{width:.99em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=S]:before{width:.696em;padding:.703em 0 .016em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=T]:before{width:.644em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=T]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=T]:last-child:before{width:.947em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=U]:before{width:.715em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=U]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=U]:last-child:before{width:.771em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=V]:before{width:.737em;padding:.686em 0 .077em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=W]:before{width:1.169em;padding:.686em 0 .077em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=X]:before{width:.817em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=X]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=X]:last-child:before{width:.906em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=Y]:before{width:.759em;padding:.686em 0 .164em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=Z]:before{width:.818em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=f]:before{padding:.701em 0 .201em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=f]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c=f]:last-child:before{width:.624em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=h]:before{padding:.694em 0 .008em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c=k]:before,.MJX-TEX .mjx-cal.mjx-b mjx-c[c=l]:before{padding:.694em 0 .008em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="391"]:before,.MJX-TEX .mjx-cal.mjx-b mjx-c[c="392"]:before{font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="393"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="393"]:last-child:before{width:.777em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="395"]:before,.MJX-TEX .mjx-cal.mjx-b mjx-c[c="396"]:before,.MJX-TEX .mjx-cal.mjx-b mjx-c[c="397"]:before{font-family:MJXZERO,MJXTEX-BI}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="399"]:before{font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="399"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="399"]:last-child:before{width:.573em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="39A"]:before{font-family:MJXZERO,MJXTEX-BI}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="39C"]:before{font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="39C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="39C"]:last-child:before{width:1.219em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="39D"]:before{font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="39D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="39D"]:last-child:before{width:1.027em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="39F"]:before{font-family:MJXZERO,MJXTEX-BI}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="3A1"]:before{font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3A1"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3A1"]:last-child:before{width:.847em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="3A2"]:before{font-family:MJXZERO,MJXTEX-BI}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="3A4"]:before{font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3A4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3A4"]:last-child:before{width:.772em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3A5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3A5"]:last-child:before{width:.802em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="3A7"]:before{font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3A8"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3A8"]:last-child:before{width:.79em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3C4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3C4"]:last-child:before{width:.61em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="3D2"]:before{font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3D2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3D2"]:last-child:before{width:.802em}.MJX-TEX .mjx-cal.mjx-b mjx-c[c="3DC"]:before{font-family:MJXZERO,MJXTEX-BI}.MJX-TEX mjx-mi:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3DC"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-cal.mjx-b mjx-c[c="3DC"]:last-child:before{width:.809em}.MJX-TEX .mjx-os mjx-c[c="0"]:before{padding:.452em 0 .022em}.MJX-TEX .mjx-os mjx-c[c="1"]:before,.MJX-TEX .mjx-os mjx-c[c="2"]:before{padding:.453em 0 0}.MJX-TEX .mjx-os mjx-c[c="3"]:before{padding:.452em 0 .216em}.MJX-TEX .mjx-os mjx-c[c="4"]:before{padding:.464em 0 .194em}.MJX-TEX .mjx-os mjx-c[c="5"]:before{padding:.453em 0 .216em}.MJX-TEX .mjx-os mjx-c[c="7"]:before{padding:.463em 0 .216em}.MJX-TEX .mjx-os mjx-c[c="9"]:before{padding:.453em 0 .216em}.MJX-TEX .mjx-os mjx-c[c=A]:before{width:.798em;padding:.728em 0 .05em}.MJX-TEX .mjx-os mjx-c[c=B]:before{width:.657em;padding:.705em 0 .022em}.MJX-TEX .mjx-os mjx-c[c=C]:before{width:.527em}.MJX-TEX .mjx-os mjx-c[c=D]:before{width:.771em}.MJX-TEX .mjx-os mjx-c[c=E]:before{width:.528em;padding:.705em 0 .022em}.MJX-TEX .mjx-os mjx-c[c=F]:before{width:.719em;padding:.683em 0 .032em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os mjx-c[c=F]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os mjx-c[c=F]:last-child:before{width:.829em}.MJX-TEX .mjx-os mjx-c[c=G]:before{width:.595em;padding:.704em 0 .119em}.MJX-TEX .mjx-os mjx-c[c=H]:before{width:.845em;padding:.683em 0 .048em}.MJX-TEX .mjx-os mjx-c[c=I]:before{width:.545em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os mjx-c[c=I]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os mjx-c[c=I]:last-child:before{width:.642em}.MJX-TEX .mjx-os mjx-c[c=J]:before{width:.678em;padding:.683em 0 .119em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os mjx-c[c=J]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os mjx-c[c=J]:last-child:before{width:.839em}.MJX-TEX .mjx-os mjx-c[c=K]:before{width:.762em;padding:.705em 0 .022em}.MJX-TEX .mjx-os mjx-c[c=L]:before{width:.69em;padding:.705em 0 .022em}.MJX-TEX .mjx-os mjx-c[c=M]:before{width:1.201em;padding:.705em 0 .05em}.MJX-TEX .mjx-os mjx-c[c=N]:before{width:.82em;padding:.789em 0 .05em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os mjx-c[c=N]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os mjx-c[c=N]:last-child:before{width:.979em}.MJX-TEX .mjx-os mjx-c[c=O]:before{width:.796em}.MJX-TEX .mjx-os mjx-c[c=P]:before{width:.696em;padding:.683em 0 .057em}.MJX-TEX .mjx-os mjx-c[c=Q]:before{width:.817em;padding:.705em 0 .131em}.MJX-TEX .mjx-os mjx-c[c=R]:before{width:.848em}.MJX-TEX .mjx-os mjx-c[c=S]:before{width:.606em}.MJX-TEX .mjx-os mjx-c[c=T]:before{width:.545em;padding:.717em 0 .068em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os mjx-c[c=T]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os mjx-c[c=T]:last-child:before{width:.833em}.MJX-TEX .mjx-os mjx-c[c=U]:before{width:.626em;padding:.683em 0 .028em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os mjx-c[c=U]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os mjx-c[c=U]:last-child:before{width:.687em}.MJX-TEX .mjx-os mjx-c[c=V]:before{width:.613em;padding:.683em 0 .052em}.MJX-TEX .mjx-os mjx-c[c=W]:before{width:.988em;padding:.683em 0 .053em}.MJX-TEX .mjx-os mjx-c[c=X]:before{width:.713em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os mjx-c[c=X]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os mjx-c[c=X]:last-child:before{width:.807em}.MJX-TEX .mjx-os mjx-c[c=Y]:before{width:.668em;padding:.683em 0 .143em}.MJX-TEX .mjx-os mjx-c[c=Z]:before{width:.725em}.MJX-TEX .mjx-os mjx-c[c="3A1"]:before,.MJX-TEX .mjx-os mjx-c[c="3A2"]:before,.MJX-TEX .mjx-os mjx-c[c="3A4"]:before,.MJX-TEX .mjx-os mjx-c[c="3A7"]:before,.MJX-TEX .mjx-os mjx-c[c="3D2"]:before,.MJX-TEX .mjx-os mjx-c[c="3DC"]:before,.MJX-TEX .mjx-os mjx-c[c="39A"]:before,.MJX-TEX .mjx-os mjx-c[c="39C"]:before,.MJX-TEX .mjx-os mjx-c[c="39D"]:before,.MJX-TEX .mjx-os mjx-c[c="39F"]:before,.MJX-TEX .mjx-os mjx-c[c="391"]:before,.MJX-TEX .mjx-os mjx-c[c="392"]:before,.MJX-TEX .mjx-os mjx-c[c="395"]:before,.MJX-TEX .mjx-os mjx-c[c="396"]:before,.MJX-TEX .mjx-os mjx-c[c="397"]:before,.MJX-TEX .mjx-os mjx-c[c="399"]:before{font-family:MJXZERO,MJXTEX}.MJX-TEX .mjx-os.mjx-b mjx-c[c="0"]:before{padding:.46em 0 .017em}.MJX-TEX .mjx-os.mjx-b mjx-c[c="1"]:before{padding:.461em 0 0}.MJX-TEX .mjx-os.mjx-b mjx-c[c="2"]:before{padding:.46em 0 0}.MJX-TEX .mjx-os.mjx-b mjx-c[c="3"]:before{padding:.461em 0 .211em}.MJX-TEX .mjx-os.mjx-b mjx-c[c="5"]:before{padding:.461em 0 .211em}.MJX-TEX .mjx-os.mjx-b mjx-c[c="6"]:before{padding:.66em 0 .017em}.MJX-TEX .mjx-os.mjx-b mjx-c[c="7"]:before{padding:.476em 0 .211em}.MJX-TEX .mjx-os.mjx-b mjx-c[c="8"]:before{padding:.661em 0 .017em}.MJX-TEX .mjx-os.mjx-b mjx-c[c="9"]:before{padding:.461em 0 .21em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=A]:before{width:.921em;padding:.751em 0 .049em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os.mjx-b mjx-c[c=A]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os.mjx-b mjx-c[c=A]:last-child:before{width:.989em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=B]:before{width:.748em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=C]:before{width:.613em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=D]:before{width:.892em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=E]:before{width:.607em;padding:.703em 0 .016em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=F]:before{width:.814em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os.mjx-b mjx-c[c=F]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os.mjx-b mjx-c[c=F]:last-child:before{width:.93em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=G]:before{width:.682em;padding:.703em 0 .113em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=H]:before{width:.987em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=I]:before{width:.642em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os.mjx-b mjx-c[c=I]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os.mjx-b mjx-c[c=I]:last-child:before{width:.746em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=J]:before{width:.779em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os.mjx-b mjx-c[c=J]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os.mjx-b mjx-c[c=J]:last-child:before{width:.937em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=K]:before{width:.871em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=L]:before{width:.788em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=M]:before{width:1.378em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=N]:before{width:.937em;padding:.84em 0 .049em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os.mjx-b mjx-c[c=N]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os.mjx-b mjx-c[c=N]:last-child:before{width:1.105em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=O]:before{width:.906em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=P]:before{width:.81em;padding:.686em 0 .067em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=Q]:before{width:.939em;padding:.703em 0 .146em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=R]:before{width:.99em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=S]:before{width:.696em;padding:.703em 0 .016em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=T]:before{width:.644em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os.mjx-b mjx-c[c=T]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os.mjx-b mjx-c[c=T]:last-child:before{width:.947em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=U]:before{width:.715em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os.mjx-b mjx-c[c=U]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os.mjx-b mjx-c[c=U]:last-child:before{width:.771em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=V]:before{width:.737em;padding:.686em 0 .077em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=W]:before{width:1.169em;padding:.686em 0 .077em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=X]:before{width:.817em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-os.mjx-b mjx-c[c=X]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-os.mjx-b mjx-c[c=X]:last-child:before{width:.906em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=Y]:before{width:.759em;padding:.686em 0 .164em}.MJX-TEX .mjx-os.mjx-b mjx-c[c=Z]:before{width:.818em}.MJX-TEX .mjx-os.mjx-b mjx-c[c="3A1"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="3A2"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="3A4"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="3A7"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="3D2"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="3DC"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="39A"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="39C"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="39D"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="39F"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="391"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="392"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="395"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="396"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="397"]:before,.MJX-TEX .mjx-os.mjx-b mjx-c[c="399"]:before{font-family:MJXZERO,MJXTEX-B}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="!"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="!"]:last-child:before{width:.38em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="27"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="27"]:last-child:before{width:.377em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="("]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="("]:last-child:before{width:.517em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="*"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="*"]:last-child:before{width:.584em}.MJX-TEX .mjx-mit mjx-c[c="/"]:before{width:.511em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="/"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="/"]:last-child:before{width:.617em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="0"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="0"]:last-child:before{width:.562em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="3"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="3"]:last-child:before{width:.562em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="5"]:last-child:before{width:.567em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="6"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="6"]:last-child:before{width:.565em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="7"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="7"]:last-child:before{width:.634em}.MJX-TEX .mjx-mit mjx-c[c=A]:before{width:.743em}.MJX-TEX .mjx-mit mjx-c[c=B]:before{width:.704em}.MJX-TEX .mjx-mit mjx-c[c=C]:before{width:.716em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=C]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=C]:last-child:before{width:.812em}.MJX-TEX .mjx-mit mjx-c[c=D]:before{width:.755em}.MJX-TEX .mjx-mit mjx-c[c=E]:before{width:.678em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=E]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=E]:last-child:before{width:.743em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=F]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=F]:last-child:before{width:.731em}.MJX-TEX .mjx-mit mjx-c[c=G]:before{width:.774em}.MJX-TEX .mjx-mit mjx-c[c=H]:before{width:.743em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=H]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=H]:last-child:before{width:.86em}.MJX-TEX .mjx-mit mjx-c[c=I]:before{width:.386em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=I]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=I]:last-child:before{width:.508em}.MJX-TEX .mjx-mit mjx-c[c=J]:before{width:.525em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=J]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=J]:last-child:before{width:.622em}.MJX-TEX .mjx-mit mjx-c[c=K]:before{width:.769em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=K]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=K]:last-child:before{width:.859em}.MJX-TEX .mjx-mit mjx-c[c=L]:before{width:.627em}.MJX-TEX .mjx-mit mjx-c[c=M]:before{width:.897em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=M]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=M]:last-child:before{width:1.01em}.MJX-TEX .mjx-mit mjx-c[c=N]:before{width:.743em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=N]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=N]:last-child:before{width:.86em}.MJX-TEX .mjx-mit mjx-c[c=O]:before{width:.767em}.MJX-TEX .mjx-mit mjx-c[c=P]:before{width:.678em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=P]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=P]:last-child:before{width:.729em}.MJX-TEX .mjx-mit mjx-c[c=Q]:before{width:.767em}.MJX-TEX .mjx-mit mjx-c[c=R]:before{width:.729em}.MJX-TEX .mjx-mit mjx-c[c=S]:before{width:.562em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=S]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=S]:last-child:before{width:.633em}.MJX-TEX .mjx-mit mjx-c[c=T]:before{width:.716em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=T]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=T]:last-child:before{width:.806em}.MJX-TEX .mjx-mit mjx-c[c=U]:before{width:.743em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=U]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=U]:last-child:before{width:.86em}.MJX-TEX .mjx-mit mjx-c[c=V]:before{width:.743em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=V]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=V]:last-child:before{width:.868em}.MJX-TEX .mjx-mit mjx-c[c=W]:before{width:.999em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=W]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=W]:last-child:before{width:1.124em}.MJX-TEX .mjx-mit mjx-c[c=X]:before{width:.743em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=X]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=X]:last-child:before{width:.825em}.MJX-TEX .mjx-mit mjx-c[c=Y]:before{width:.743em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=Y]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=Y]:last-child:before{width:.875em}.MJX-TEX .mjx-mit mjx-c[c=Z]:before{width:.613em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=Z]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=Z]:last-child:before{width:.704em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="["]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="["]:last-child:before{width:.446em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="]"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="]"]:last-child:before{width:.359em}.MJX-TEX .mjx-mit mjx-c[c=a]:before{width:.511em}.MJX-TEX .mjx-mit mjx-c[c=b]:before,.MJX-TEX .mjx-mit mjx-c[c=c]:before{width:.46em}.MJX-TEX .mjx-mit mjx-c[c=d]:before{width:.511em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=d]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=d]:last-child:before{width:.567em}.MJX-TEX .mjx-mit mjx-c[c=e]:before{width:.46em}.MJX-TEX .mjx-mit mjx-c[c=f]:before{width:.307em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=f]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=f]:last-child:before{width:.45em}.MJX-TEX .mjx-mit mjx-c[c=g]:before{width:.46em}.MJX-TEX .mjx-mit mjx-c[c=h]:before{width:.511em}.MJX-TEX .mjx-mit mjx-c[c=i]:before{width:.307em;padding:.656em 0 .01em}.MJX-TEX .mjx-mit mjx-c[c=j]:before{width:.307em;padding:.656em 0 .204em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=j]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=j]:last-child:before{width:.364em}.MJX-TEX .mjx-mit mjx-c[c=k]:before{width:.46em}.MJX-TEX .mjx-mit mjx-c[c=l]:before{width:.256em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=l]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=l]:last-child:before{width:.312em}.MJX-TEX .mjx-mit mjx-c[c=m]:before{width:.818em}.MJX-TEX .mjx-mit mjx-c[c=n]:before{width:.562em}.MJX-TEX .mjx-mit mjx-c[c=o]:before,.MJX-TEX .mjx-mit mjx-c[c=p]:before{width:.511em}.MJX-TEX .mjx-mit mjx-c[c=q]:before{width:.46em}.MJX-TEX .mjx-mit mjx-c[c=r]:before{width:.422em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=r]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=r]:last-child:before{width:.484em}.MJX-TEX .mjx-mit mjx-c[c=s]:before{width:.409em}.MJX-TEX .mjx-mit mjx-c[c=t]:before{width:.332em}.MJX-TEX .mjx-mit mjx-c[c=u]:before{width:.537em}.MJX-TEX .mjx-mit mjx-c[c=v]:before{width:.46em}.MJX-TEX .mjx-mit mjx-c[c=w]:before{width:.664em}.MJX-TEX .mjx-mit mjx-c[c=x]:before{width:.464em}.MJX-TEX .mjx-mit mjx-c[c=y]:before{width:.486em}.MJX-TEX .mjx-mit mjx-c[c=z]:before{width:.409em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c=z]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c=z]:last-child:before{width:.466em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="~"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="~"]:last-child:before{width:.571em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="303"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="303"]:last-child:before{width:.06em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="304"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="304"]:last-child:before{width:.054em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="306"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="306"]:last-child:before{width:.062em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="30B"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="30B"]:last-child:before{width:.065em}.MJX-TEX .mjx-mit mjx-c[c="391"]:before{width:.743em}.MJX-TEX .mjx-mit mjx-c[c="392"]:before{width:.704em}.MJX-TEX .mjx-mit mjx-c[c="393"]:before{width:.627em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="393"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="393"]:last-child:before{width:.705em}.MJX-TEX .mjx-mit mjx-c[c="394"]:before{width:.818em}.MJX-TEX .mjx-mit mjx-c[c="395"]:before{width:.678em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="395"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="395"]:last-child:before{width:.743em}.MJX-TEX .mjx-mit mjx-c[c="396"]:before{width:.613em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="396"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="396"]:last-child:before{width:.704em}.MJX-TEX .mjx-mit mjx-c[c="397"]:before{width:.743em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="397"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="397"]:last-child:before{width:.86em}.MJX-TEX .mjx-mit mjx-c[c="398"]:before{width:.767em}.MJX-TEX .mjx-mit mjx-c[c="399"]:before{width:.386em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="399"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="399"]:last-child:before{width:.508em}.MJX-TEX .mjx-mit mjx-c[c="39A"]:before{width:.769em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="39A"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="39A"]:last-child:before{width:.859em}.MJX-TEX .mjx-mit mjx-c[c="39B"]:before{width:.692em}.MJX-TEX .mjx-mit mjx-c[c="39C"]:before{width:.897em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="39C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="39C"]:last-child:before{width:1.01em}.MJX-TEX .mjx-mit mjx-c[c="39D"]:before{width:.743em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="39D"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="39D"]:last-child:before{width:.86em}.MJX-TEX .mjx-mit mjx-c[c="39E"]:before{width:.664em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="39E"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="39E"]:last-child:before{width:.754em}.MJX-TEX .mjx-mit mjx-c[c="39F"]:before{width:.767em}.MJX-TEX .mjx-mit mjx-c[c="3A0"]:before{width:.743em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="3A0"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="3A0"]:last-child:before{width:.859em}.MJX-TEX .mjx-mit mjx-c[c="3A1"]:before{width:.678em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="3A1"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="3A1"]:last-child:before{width:.729em}.MJX-TEX .mjx-mit mjx-c[c="3A2"]:before{width:.767em}.MJX-TEX .mjx-mit mjx-c[c="3A3"]:before{width:.716em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="3A3"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="3A3"]:last-child:before{width:.782em}.MJX-TEX .mjx-mit mjx-c[c="3A4"]:before{width:.716em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="3A4"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="3A4"]:last-child:before{width:.806em}.MJX-TEX .mjx-mit mjx-c[c="3A5"]:before{width:.767em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="3A5"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="3A5"]:last-child:before{width:.832em}.MJX-TEX .mjx-mit mjx-c[c="3A6"]:before{width:.716em}.MJX-TEX .mjx-mit mjx-c[c="3A7"]:before{width:.743em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="3A7"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="3A7"]:last-child:before{width:.825em}.MJX-TEX .mjx-mit mjx-c[c="3A8"]:before{width:.767em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="3A8"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="3A8"]:last-child:before{width:.824em}.MJX-TEX .mjx-mit mjx-c[c="3A9"]:before{width:.716em}.MJX-TEX .mjx-mit mjx-c[c="3D2"]:before{width:.767em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="3D2"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="3D2"]:last-child:before{width:.832em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="3DC"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="3DC"]:last-child:before{width:.731em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="2018"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="2018"]:last-child:before{width:.362em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="2019"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="2019"]:last-child:before{width:.377em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="201C"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="201C"]:last-child:before{width:.606em}.MJX-TEX .mjx-mit mjx-c[c="2044"]:before{width:.511em}.MJX-TEX mjx-mi:not([noIC=true]).mjx-mit mjx-c[c="2044"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-mit mjx-c[c="2044"]:last-child:before{width:.617em}.MJX-TEX .mjx-mit mjx-c[c="2206"]:before{width:.818em}.MJX-TEX .mjx-v mjx-c[c=A]:before{width:.722em;padding:.701em 0 0}.MJX-TEX .mjx-v mjx-c[c=B]:before{width:.667em}.MJX-TEX .mjx-v mjx-c[c=D]:before{width:.722em}.MJX-TEX .mjx-v mjx-c[c=E]:before{width:.667em}.MJX-TEX .mjx-v mjx-c[c=F]:before{width:.611em}.MJX-TEX .mjx-v mjx-c[c=G]:before,.MJX-TEX .mjx-v mjx-c[c=H]:before{width:.778em}.MJX-TEX .mjx-v mjx-c[c=I]:before{width:.389em}.MJX-TEX .mjx-v mjx-c[c=J]:before{width:.5em;padding:.683em 0 .077em}.MJX-TEX .mjx-v mjx-c[c=L]:before{width:.667em}.MJX-TEX .mjx-v mjx-c[c=M]:before{width:.944em}.MJX-TEX .mjx-v mjx-c[c=N]:before{width:.722em;padding:.683em 0 .02em}.MJX-TEX .mjx-v mjx-c[c=P]:before{width:.611em}.MJX-TEX .mjx-v mjx-c[c=Q]:before{padding:.701em 0 .181em}.MJX-TEX .mjx-v mjx-c[c=R]:before{width:.722em;padding:.683em 0 0}.MJX-TEX .mjx-v mjx-c[c=S]:before{padding:.702em 0 .012em}.MJX-TEX .mjx-v mjx-c[c=T]:before{width:.667em;padding:.683em 0 0}.MJX-TEX .mjx-v mjx-c[c=U]:before,.MJX-TEX .mjx-v mjx-c[c=V]:before{width:.722em}.MJX-TEX .mjx-v mjx-c[c=W]:before{width:1em}.MJX-TEX .mjx-v mjx-c[c=X]:before,.MJX-TEX .mjx-v mjx-c[c=Y]:before{width:.722em}.MJX-TEX .mjx-v mjx-c[c=Z]:before{width:.667em}.MJX-TEX .mjx-v mjx-c[c=k]:before{width:.556em;padding:.683em 0 0}.MJX-TEX .mjx-v mjx-c[c="2C6"]:before{width:2.333em;padding:.845em 0 0}.MJX-TEX .mjx-v mjx-c[c="2DC"]:before{width:2.333em;padding:.899em 0 0}.MJX-TEX .mjx-v mjx-c[c="302"]:before{padding:.845em 0 0}.MJX-TEX .mjx-v mjx-c[c="303"]:before{padding:.899em 0 0}.MJX-TEX .mjx-v mjx-c[c="3DC"]:before{width:.778em;padding:.605em 0 .085em;content:"\E008"}.MJX-TEX .mjx-v mjx-c[c="3F0"]:before{content:"\E009"}.MJX-TEX mjx-mi:not([noIC=true]).mjx-v mjx-c[c="3F0"]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-v mjx-c[c="3F0"]:last-child:before{width:.734em}.MJX-TEX .mjx-v mjx-c[c="2190"]:before,.MJX-TEX .mjx-v mjx-c[c="2192"]:before{width:.5em;padding:.437em 0 0}.MJX-TEX .mjx-v mjx-c[c="21CC"]:before{padding:.514em 0 .014em}.MJX-TEX .mjx-v mjx-c[c="2204"]:before{padding:.86em 0 .166em;content:"\2204"}.MJX-TEX .mjx-v mjx-c[c="2205"]:before{width:.778em;padding:.587em 0 0}.MJX-TEX .mjx-v mjx-c[c="2212"]:before{width:.5em;padding:.27em 0 0}.MJX-TEX .mjx-v mjx-c[c="221D"]:before{padding:.472em 0 0}.MJX-TEX .mjx-v mjx-c[c="2223"]:before{width:.222em;padding:.43em 0 .023em}.MJX-TEX .mjx-v mjx-c[c="2224"]:before{width:.222em;padding:.43em 0 .023em;content:"\E006"}.MJX-TEX .mjx-v mjx-c[c="2225"]:before{width:.389em;padding:.431em 0 .023em}.MJX-TEX .mjx-v mjx-c[c="2226"]:before{width:.389em;padding:.431em 0 .024em;content:"\E007"}.MJX-TEX .mjx-v mjx-c[c="2268"]:before{content:"\E00C"}.MJX-TEX .mjx-v mjx-c[c="2269"]:before{content:"\E00D"}.MJX-TEX .mjx-v mjx-c[c="2270"]:before{padding:.919em 0 .421em;content:"\E011"}.MJX-TEX .mjx-v mjx-c[c="2271"]:before{padding:.919em 0 .421em;content:"\E00E"}.MJX-TEX .mjx-v mjx-c[c="2288"]:before{padding:.828em 0 .33em;content:"\E016"}.MJX-TEX .mjx-v mjx-c[c="2289"]:before{padding:.828em 0 .33em;content:"\E018"}.MJX-TEX .mjx-v mjx-c[c="228A"]:before{padding:.634em 0 .255em;content:"\E01A"}.MJX-TEX .mjx-v mjx-c[c="228B"]:before{padding:.634em 0 .254em;content:"\E01B"}.MJX-TEX .mjx-v mjx-c[c="22A8"]:before{width:.611em;padding:.694em 0 0}.MJX-TEX .mjx-v mjx-c[c="22C5"]:before{padding:.189em 0 0}.MJX-TEX .mjx-v mjx-c[c="2322"]:before{width:.778em;padding:.378em 0 0}.MJX-TEX .mjx-v mjx-c[c="2323"]:before{width:.778em}.MJX-TEX .mjx-v mjx-c[c="25B3"]:before{width:.722em;padding:.575em 0 .02em}.MJX-TEX .mjx-v mjx-c[c="25BD"]:before{width:.722em;padding:.576em 0 .019em}.MJX-TEX .mjx-v mjx-c[c="2A87"]:before{padding:.801em 0 .303em;content:"\E010"}.MJX-TEX .mjx-v mjx-c[c="2A88"]:before{padding:.801em 0 .303em;content:"\E00F"}.MJX-TEX .mjx-v mjx-c[c="2ACB"]:before{padding:.752em 0 .332em;content:"\E017"}.MJX-TEX .mjx-v mjx-c[c="2ACC"]:before{padding:.752em 0 .333em;content:"\E019"}.MJX-TEX mjx-mi:not([noIC=true]).mjx-v mjx-c[c=E009]:last-child:before,.MJX-TEX mjx-mo:not([noIC=true]).mjx-v mjx-c[c=E009]:last-child:before{width:.734em}mjx-container[display=true]{overflow-x:auto;overflow-y:hidden}.icon.outbound{color:#aaa;display:inline-block;vertical-align:middle;position:relative;top:-1px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.algolia-search-wrapper>span{vertical-align:middle}.algolia-search-wrapper .algolia-autocomplete{line-height:normal}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu{background-color:#fff;border:1px solid #999;border-radius:4px;font-size:16px;margin:6px 0 0;padding:4px;text-align:left}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu:before{border-color:#999}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu [class*=ds-dataset-]{border:none;padding:0}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu .ds-suggestions{margin-top:0}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu .ds-suggestion{border-bottom:1px solid #eaecef}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#2c815b}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion{border-color:#eaecef;padding:0}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--category-header{padding:5px 10px;margin-top:0;background:#3eaf7c;color:#fff;font-weight:600}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--highlight{background:hsla(0,0%,100%,.6)}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--wrapper{padding:0}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--title{font-weight:600;margin-bottom:0;color:#2c3e50}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{vertical-align:top;padding:5px 7px 5px 5px;border-color:#eaecef;background:#f1f3f5}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:after{display:none}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column-text{color:#555}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-footer{border-color:#eaecef}.algolia-search-wrapper .algolia-autocomplete .ds-cursor .algolia-docsearch-suggestion--content{background-color:#e7edf3!important;color:#2c3e50}@media (min-width:719px){.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{float:none;width:150px;min-width:150px;display:table-cell}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content{float:none;display:table-cell;width:100%;vertical-align:top}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .ds-dropdown-menu{min-width:515px!important}}@media (max-width:719px){.algolia-search-wrapper .ds-dropdown-menu{min-width:calc(100vw - 4rem)!important;max-width:calc(100vw - 4rem)!important}.algolia-search-wrapper .algolia-docsearch-suggestion--wrapper{padding:5px 7px 5px 5px!important}.algolia-search-wrapper .algolia-docsearch-suggestion--subcategory-column{padding:0!important;background:#fff!important}.algolia-search-wrapper .algolia-docsearch-suggestion--subcategory-column-text:after{content:" > ";font-size:10px;line-height:14.4px;display:inline-block;width:5px;margin:-3px 3px 0;vertical-align:middle}}.home{padding:3.6rem 2rem 0;max-width:960px;margin:0 auto;display:block}.home .hero{text-align:center}.home .hero img{max-width:100%;max-height:280px;display:block;margin:3rem auto 1.5rem}.home .hero h1{font-size:3rem}.home .hero .action,.home .hero .description,.home .hero h1{margin:1.8rem auto}.home .hero .description{max-width:35rem;font-size:1.6rem;line-height:1.3;color:#6a8bad}.home .hero .action-button{display:inline-block;font-size:1.2rem;color:#fff;background-color:#3eaf7c;padding:.8rem 1.6rem;border-radius:4px;transition:background-color .1s ease;box-sizing:border-box;border-bottom:1px solid #389d70}.home .hero .action-button:hover{background-color:#4abf8a}.home .features{border-top:1px solid #eaecef;padding:1.2rem 0;margin-top:2.5rem;display:flex;flex-wrap:wrap;align-items:flex-start;align-content:stretch;justify-content:space-between}.home .feature{flex-grow:1;flex-basis:30%;max-width:30%}.home .feature h2{font-size:1.4rem;font-weight:500;border-bottom:none;padding-bottom:0;color:#3a5169}.home .feature p{color:#4e6e8e}.home .footer{padding:2.5rem;border-top:1px solid #eaecef;text-align:center;color:#4e6e8e}@media (max-width:719px){.home .features{flex-direction:column}.home .feature{max-width:100%;padding:0 2.5rem}}@media (max-width:419px){.home{padding-left:1.5rem;padding-right:1.5rem}.home .hero img{max-height:210px;margin:2rem auto 1.2rem}.home .hero h1{font-size:2rem}.home .hero .action,.home .hero .description,.home .hero h1{margin:1.2rem auto}.home .hero .description{font-size:1.2rem}.home .hero .action-button{font-size:1rem;padding:.6rem 1.2rem}.home .feature h2{font-size:1.25rem}}.search-box{display:inline-block;position:relative;margin-right:1rem}.search-box input{cursor:text;width:10rem;height:2rem;color:#4e6e8e;display:inline-block;border:1px solid #cfd4db;border-radius:2rem;font-size:.9rem;line-height:2rem;padding:0 .5rem 0 2rem;outline:none;transition:all .2s ease;background:#fff url(/Blog/assets/img/search.83621669.svg) .6rem .5rem no-repeat;background-size:1rem}.search-box input:focus{cursor:auto;border-color:#3eaf7c}.search-box .suggestions{background:#fff;width:20rem;position:absolute;top:2rem;border:1px solid #cfd4db;border-radius:6px;padding:.4rem;list-style-type:none}.search-box .suggestions.align-right{right:0}.search-box .suggestion{line-height:1.4;padding:.4rem .6rem;border-radius:4px;cursor:pointer}.search-box .suggestion a{white-space:normal;color:#5d82a6}.search-box .suggestion a .page-title{font-weight:600}.search-box .suggestion a .header{font-size:.9em;margin-left:.25em}.search-box .suggestion.focused{background-color:#f3f4f5}.search-box .suggestion.focused a{color:#3eaf7c}@media (max-width:959px){.search-box input{cursor:pointer;width:0;border-color:transparent;position:relative}.search-box input:focus{cursor:text;left:0;width:10rem}}@media (-ms-high-contrast:none){.search-box input{height:2rem}}@media (max-width:959px) and (min-width:719px){.search-box .suggestions{left:0}}@media (max-width:719px){.search-box{margin-right:0}.search-box input{left:1rem}.search-box .suggestions{right:0}}@media (max-width:419px){.search-box .suggestions{width:calc(100vw - 4rem)}.search-box input:focus{width:8rem}}.sidebar-button{cursor:pointer;display:none;width:1.25rem;height:1.25rem;position:absolute;padding:.6rem;top:.6rem;left:1rem}.sidebar-button .icon{display:block;width:1.25rem;height:1.25rem}@media (max-width:719px){.sidebar-button{display:block}}.dropdown-enter,.dropdown-leave-to{height:0!important}.badge[data-v-15b7b770]{display:inline-block;font-size:14px;height:18px;line-height:18px;border-radius:3px;padding:0 6px;color:#fff}.badge.green[data-v-15b7b770],.badge.tip[data-v-15b7b770],.badge[data-v-15b7b770]{background-color:#42b983}.badge.error[data-v-15b7b770]{background-color:#da5961}.badge.warn[data-v-15b7b770],.badge.warning[data-v-15b7b770],.badge.yellow[data-v-15b7b770]{background-color:#e7c000}.badge+.badge[data-v-15b7b770]{margin-left:5px}.theme-code-block[data-v-759a7d02]{display:none}.theme-code-block__active[data-v-759a7d02]{display:block}.theme-code-block>pre[data-v-759a7d02]{background-color:orange}.theme-code-group__nav[data-v-deefee04]{margin-bottom:-35px;background-color:#282c34;padding-bottom:22px;border-top-left-radius:6px;border-top-right-radius:6px;padding-left:10px;padding-top:10px}.theme-code-group__ul[data-v-deefee04]{margin:auto 0;padding-left:0;display:inline-flex;list-style:none}.theme-code-group__nav-tab[data-v-deefee04]{border:0;padding:5px;cursor:pointer;background-color:transparent;font-size:.85em;line-height:1.4;color:hsla(0,0%,100%,.9);font-weight:600}.theme-code-group__nav-tab-active[data-v-deefee04]{border-bottom:1px solid #42b983}.pre-blank[data-v-deefee04]{color:#42b983}.searchbox{display:inline-block;position:relative;width:200px;height:32px!important;white-space:nowrap;box-sizing:border-box;visibility:visible!important}.searchbox .algolia-autocomplete{display:block;width:100%;height:100%}.searchbox__wrapper{width:100%;height:100%;z-index:999;position:relative}.searchbox__input{display:inline-block;box-sizing:border-box;transition:box-shadow .4s ease,background .4s ease;border:0;border-radius:16px;box-shadow:inset 0 0 0 1px #ccc;background:#fff!important;padding:0 26px 0 32px;width:100%;height:100%;vertical-align:middle;white-space:normal;font-size:12px;-webkit-appearance:none;-moz-appearance:none;appearance:none}.searchbox__input::-webkit-search-cancel-button,.searchbox__input::-webkit-search-decoration,.searchbox__input::-webkit-search-results-button,.searchbox__input::-webkit-search-results-decoration{display:none}.searchbox__input:hover{box-shadow:inset 0 0 0 1px #b3b3b3}.searchbox__input:active,.searchbox__input:focus{outline:0;box-shadow:inset 0 0 0 1px #aaa;background:#fff}.searchbox__input::-moz-placeholder{color:#aaa}.searchbox__input::placeholder{color:#aaa}.searchbox__submit{position:absolute;top:0;margin:0;border:0;border-radius:16px 0 0 16px;background-color:rgba(69,142,225,0);padding:0;width:32px;height:100%;vertical-align:middle;text-align:center;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;user-select:none;right:inherit;left:0}.searchbox__submit:before{display:inline-block;margin-right:-4px;height:100%;vertical-align:middle;content:""}.searchbox__submit:active,.searchbox__submit:hover{cursor:pointer}.searchbox__submit:focus{outline:0}.searchbox__submit svg{width:14px;height:14px;vertical-align:middle;fill:#6d7e96}.searchbox__reset{display:block;position:absolute;top:8px;right:8px;margin:0;border:0;background:none;cursor:pointer;padding:0;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;user-select:none;fill:rgba(0,0,0,.5)}.searchbox__reset.hide{display:none}.searchbox__reset:focus{outline:0}.searchbox__reset svg{display:block;margin:4px;width:8px;height:8px}.searchbox__input:valid~.searchbox__reset{display:block;animation-name:sbx-reset-in;animation-duration:.15s}@keyframes sbx-reset-in{0%{transform:translate3d(-20%,0,0);opacity:0}to{transform:none;opacity:1}}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu{right:0!important;left:inherit!important}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu:before{right:48px}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu{left:0!important;right:inherit!important}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu:before{left:48px}.algolia-autocomplete .ds-dropdown-menu{top:-6px;border-radius:4px;margin:6px 0 0;padding:0;text-align:left;height:auto;position:relative;background:transparent;border:none;z-index:999;max-width:600px;min-width:500px;box-shadow:0 1px 0 0 rgba(0,0,0,.2),0 2px 3px 0 rgba(0,0,0,.1)}.algolia-autocomplete .ds-dropdown-menu:before{display:block;position:absolute;content:"";width:14px;height:14px;background:#fff;z-index:1000;top:-7px;border-top:1px solid #d9d9d9;border-right:1px solid #d9d9d9;transform:rotate(-45deg);border-radius:2px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions{position:relative;z-index:1000;margin-top:8px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions a:hover{text-decoration:none}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion{cursor:pointer}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion.suggestion-layout-simple,.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion:not(.suggestion-layout-simple) .algolia-docsearch-suggestion--content{background-color:rgba(69,142,225,.05)}.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-]{position:relative;border:1px solid #d9d9d9;background:#fff;border-radius:4px;overflow:auto;padding:0 8px 8px}.algolia-autocomplete .ds-dropdown-menu *{box-sizing:border-box}.algolia-autocomplete .algolia-docsearch-suggestion{display:block;position:relative;padding:0 8px;background:#fff;color:#02060c;overflow:hidden}.algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#174d8c;background:rgba(143,187,237,.1);padding:.1em .05em}.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl0 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl1 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{padding:0 0 1px;background:inherit;box-shadow:inset 0 -2px 0 0 rgba(69,142,225,.8);color:inherit}.algolia-autocomplete .algolia-docsearch-suggestion--content{display:block;float:right;width:70%;position:relative;padding:5.33333px 0 5.33333px 10.66667px;cursor:pointer}.algolia-autocomplete .algolia-docsearch-suggestion--content:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;left:-1px}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{position:relative;border-bottom:1px solid #ddd;display:none;margin-top:8px;padding:4px 0;font-size:1em;color:#33363d}.algolia-autocomplete .algolia-docsearch-suggestion--wrapper{width:100%;float:left;padding:8px 0 0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{float:left;width:30%;text-align:right;position:relative;padding:5.33333px 10.66667px;color:#a4a7ae;font-size:.9em;word-wrap:break-word}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;right:0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline{display:none}.algolia-autocomplete .algolia-docsearch-suggestion--title{margin-bottom:4px;color:#02060c;font-size:.9em;font-weight:700}.algolia-autocomplete .algolia-docsearch-suggestion--text{display:block;line-height:1.2em;font-size:.85em;color:#63676d}.algolia-autocomplete .algolia-docsearch-suggestion--no-results{width:100%;padding:8px 0;text-align:center;font-size:1.2em}.algolia-autocomplete .algolia-docsearch-suggestion--no-results:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion code{padding:1px 5px;font-size:90%;border:none;color:#222;background-color:#ebebeb;border-radius:3px;font-family:Menlo,Monaco,Consolas,Courier New,monospace}.algolia-autocomplete .algolia-docsearch-suggestion code .algolia-docsearch-suggestion--highlight{background:none}.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--category-header,.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__secondary{display:block}@media (min-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:block}}@media (max-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:inline-block;width:auto;float:left;padding:0;color:#02060c;font-size:.9em;font-weight:700;text-align:left;opacity:.5}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:after{content:"|"}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content{display:inline-block;width:auto;text-align:left;float:left;padding:0}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content:before{display:none}}.algolia-autocomplete .suggestion-layout-simple.algolia-docsearch-suggestion{border-bottom:1px solid #eee;padding:8px;margin:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content{width:100%;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content:before{display:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header{margin:0;padding:0;display:block;width:100%;border:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl0,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1{opacity:.6;font-size:.85em}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1:before{background-image:url('data:image/svg+xml;utf8,');content:"";width:10px;height:10px;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--wrapper{width:100%;float:left;margin:0;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--duplicate-content,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--subcategory-inline{display:none!important}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title{margin:0;color:#458ee1;font-size:.9em;font-weight:400}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title:before{content:"#";font-weight:700;color:#458ee1;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text{margin:4px 0 0;display:block;line-height:1.4em;padding:5.33333px 8px;background:#f8f8f8;font-size:.85em;opacity:.8}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{color:#3f4145;font-weight:700;box-shadow:none}.algolia-autocomplete .algolia-docsearch-footer{width:134px;height:20px;z-index:2000;margin-top:10.66667px;float:right;font-size:0;line-height:0}.algolia-autocomplete .algolia-docsearch-footer--logo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='168' height='24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath d='M78.988.938h16.594a2.968 2.968 0 012.966 2.966V20.5a2.967 2.967 0 01-2.966 2.964H78.988a2.967 2.967 0 01-2.966-2.964V3.897A2.961 2.961 0 0178.988.938zm41.937 17.866c-4.386.02-4.386-3.54-4.386-4.106l-.007-13.336 2.675-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-10.846-2.18c.821 0 1.43-.047 1.855-.129v-2.719a6.334 6.334 0 00-1.574-.199 5.7 5.7 0 00-.897.069 2.699 2.699 0 00-.814.24c-.24.116-.439.28-.582.491-.15.212-.219.335-.219.656 0 .628.219.991.616 1.23s.938.362 1.615.362zm-.233-9.7c.883 0 1.629.109 2.231.328.602.218 1.088.525 1.444.915.363.396.609.922.76 1.483.157.56.232 1.175.232 1.85v6.874a32.5 32.5 0 01-1.868.314c-.834.123-1.772.185-2.813.185-.69 0-1.327-.069-1.895-.198a4.001 4.001 0 01-1.471-.636 3.085 3.085 0 01-.951-1.134c-.226-.465-.343-1.12-.343-1.803 0-.656.13-1.073.384-1.525a3.24 3.24 0 011.047-1.106c.445-.287.95-.492 1.532-.615a8.8 8.8 0 011.82-.185 8.404 8.404 0 011.972.24v-.438c0-.307-.035-.6-.11-.874a1.88 1.88 0 00-.384-.73 1.784 1.784 0 00-.724-.493 3.164 3.164 0 00-1.143-.205c-.616 0-1.177.075-1.69.164a7.735 7.735 0 00-1.26.307l-.321-2.192c.335-.117.834-.233 1.478-.349a10.98 10.98 0 012.073-.178zm52.842 9.626c.822 0 1.43-.048 1.854-.13V13.7a6.347 6.347 0 00-1.574-.199c-.294 0-.595.021-.896.069a2.7 2.7 0 00-.814.24 1.46 1.46 0 00-.582.491c-.15.212-.218.335-.218.656 0 .628.218.991.615 1.23.404.245.938.362 1.615.362zm-.226-9.694c.883 0 1.629.108 2.231.327.602.219 1.088.526 1.444.915.355.39.609.923.759 1.483a6.8 6.8 0 01.233 1.852v6.873c-.41.088-1.034.19-1.868.314-.834.123-1.772.184-2.813.184-.69 0-1.327-.068-1.895-.198a4.001 4.001 0 01-1.471-.635 3.085 3.085 0 01-.951-1.134c-.226-.465-.343-1.12-.343-1.804 0-.656.13-1.073.384-1.524.26-.45.608-.82 1.047-1.107.445-.286.95-.491 1.532-.614a8.803 8.803 0 012.751-.13c.329.034.671.096 1.04.185v-.437a3.3 3.3 0 00-.109-.875 1.873 1.873 0 00-.384-.731 1.784 1.784 0 00-.724-.492 3.165 3.165 0 00-1.143-.205c-.616 0-1.177.075-1.69.164a7.75 7.75 0 00-1.26.307l-.321-2.193c.335-.116.834-.232 1.478-.348a11.633 11.633 0 012.073-.177zm-8.034-1.271a1.626 1.626 0 01-1.628-1.62c0-.895.725-1.62 1.628-1.62.904 0 1.63.725 1.63 1.62 0 .895-.733 1.62-1.63 1.62zm1.348 13.22h-2.689V7.27l2.69-.423v11.956zm-4.714 0c-4.386.02-4.386-3.54-4.386-4.107l-.008-13.336 2.676-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-8.698-5.903c0-1.156-.253-2.119-.746-2.788-.493-.677-1.183-1.01-2.067-1.01-.882 0-1.574.333-2.065 1.01-.493.676-.733 1.632-.733 2.788 0 1.168.246 1.953.74 2.63.492.683 1.183 1.018 2.066 1.018.882 0 1.574-.342 2.067-1.019.492-.683.738-1.46.738-2.63zm2.737-.007c0 .902-.13 1.584-.397 2.33a5.52 5.52 0 01-1.128 1.906 4.986 4.986 0 01-1.752 1.223c-.685.286-1.739.45-2.265.45-.528-.006-1.574-.157-2.252-.45a5.096 5.096 0 01-1.744-1.223c-.487-.527-.863-1.162-1.137-1.906a6.345 6.345 0 01-.41-2.33c0-.902.123-1.77.397-2.508a5.554 5.554 0 011.15-1.892 5.133 5.133 0 011.75-1.216c.679-.287 1.425-.423 2.232-.423.808 0 1.553.142 2.237.423a4.88 4.88 0 011.753 1.216 5.644 5.644 0 011.135 1.892c.287.738.431 1.606.431 2.508zm-20.138 0c0 1.12.246 2.363.738 2.882.493.52 1.13.78 1.91.78.424 0 .828-.062 1.204-.178.377-.116.677-.253.917-.417V9.33a10.476 10.476 0 00-1.766-.226c-.971-.028-1.71.37-2.23 1.004-.513.636-.773 1.75-.773 2.788zm7.438 5.274c0 1.824-.466 3.156-1.404 4.004-.936.846-2.367 1.27-4.296 1.27-.705 0-2.17-.137-3.34-.396l.431-2.118c.98.205 2.272.26 2.95.26 1.074 0 1.84-.219 2.299-.656.459-.437.684-1.086.684-1.948v-.437a8.07 8.07 0 01-1.047.397c-.43.13-.93.198-1.492.198-.739 0-1.41-.116-2.018-.349a4.206 4.206 0 01-1.567-1.025c-.431-.45-.774-1.017-1.013-1.694-.24-.677-.363-1.885-.363-2.773 0-.834.13-1.88.384-2.577.26-.696.629-1.298 1.129-1.796.493-.498 1.095-.881 1.8-1.162a6.605 6.605 0 012.428-.457c.87 0 1.67.109 2.45.24.78.129 1.444.265 1.985.415V18.17z' fill='%235468FF'/%3E%3Cpath d='M6.972 6.677v1.627c-.712-.446-1.52-.67-2.425-.67-.585 0-1.045.13-1.38.391a1.24 1.24 0 00-.502 1.03c0 .425.164.765.494 1.02.33.256.835.532 1.516.83.447.192.795.356 1.045.495.25.138.537.332.862.582.324.25.563.548.718.894.154.345.23.741.23 1.188 0 .947-.334 1.691-1.004 2.234-.67.542-1.537.814-2.601.814-1.18 0-2.16-.229-2.936-.686v-1.708c.84.628 1.814.942 2.92.942.585 0 1.048-.136 1.388-.407.34-.271.51-.646.51-1.125 0-.287-.1-.55-.302-.79-.203-.24-.42-.42-.655-.542-.234-.123-.585-.29-1.053-.503a61.27 61.27 0 01-.582-.271 13.67 13.67 0 01-.55-.287 4.275 4.275 0 01-.567-.351 6.92 6.92 0 01-.455-.4c-.18-.17-.31-.34-.39-.51-.08-.17-.155-.37-.224-.598a2.553 2.553 0 01-.104-.742c0-.915.333-1.638.998-2.17.664-.532 1.523-.798 2.576-.798.968 0 1.793.17 2.473.51zm7.468 5.696v-.287c-.022-.607-.187-1.088-.495-1.444-.309-.357-.75-.535-1.324-.535-.532 0-.99.194-1.373.583-.382.388-.622.949-.717 1.683h3.909zm1.005 2.792v1.404c-.596.34-1.383.51-2.362.51-1.255 0-2.255-.377-3-1.132-.744-.755-1.116-1.744-1.116-2.968 0-1.297.34-2.316 1.021-3.055.68-.74 1.548-1.11 2.6-1.11 1.033 0 1.852.323 2.458.966.606.644.91 1.572.91 2.784 0 .33-.033.676-.096 1.038h-5.314c.107.702.405 1.239.894 1.611.49.372 1.106.558 1.85.558.862 0 1.58-.202 2.155-.606zm6.605-1.77h-1.212c-.596 0-1.045.116-1.349.35-.303.234-.454.532-.454.894 0 .372.117.664.35.877.235.213.575.32 1.022.32.51 0 .912-.142 1.204-.424.293-.281.44-.651.44-1.108v-.91zm-4.068-2.554V9.325c.627-.361 1.457-.542 2.489-.542 2.116 0 3.175 1.026 3.175 3.08V17h-1.548v-.957c-.415.68-1.143 1.02-2.186 1.02-.766 0-1.38-.22-1.843-.661-.462-.442-.694-1.003-.694-1.684 0-.776.293-1.38.878-1.81.585-.431 1.404-.647 2.457-.647h1.34V11.8c0-.554-.133-.971-.399-1.253-.266-.282-.707-.423-1.324-.423a4.07 4.07 0 00-2.345.718zm9.333-1.93v1.42c.394-1 1.101-1.5 2.123-1.5.148 0 .313.016.494.048v1.531a1.885 1.885 0 00-.75-.143c-.542 0-.989.24-1.34.718-.351.479-.527 1.048-.527 1.707V17h-1.563V8.91h1.563zm5.01 4.084c.022.82.272 1.492.75 2.019.479.526 1.15.79 2.01.79.639 0 1.235-.176 1.788-.527v1.404c-.521.319-1.186.479-1.995.479-1.265 0-2.276-.4-3.031-1.197-.755-.798-1.133-1.792-1.133-2.984 0-1.16.38-2.151 1.14-2.975.761-.825 1.79-1.237 3.088-1.237.702 0 1.346.149 1.93.447v1.436a3.242 3.242 0 00-1.77-.495c-.84 0-1.513.266-2.019.798-.505.532-.758 1.213-.758 2.042zM40.24 5.72v4.579c.458-1 1.293-1.5 2.505-1.5.787 0 1.42.245 1.899.734.479.49.718 1.17.718 2.042V17h-1.564v-5.106c0-.553-.14-.98-.422-1.284-.282-.303-.652-.455-1.11-.455-.531 0-1.002.202-1.411.606-.41.405-.615 1.022-.615 1.851V17h-1.563V5.72h1.563zm14.966 10.02c.596 0 1.096-.253 1.5-.758.404-.506.606-1.157.606-1.955 0-.915-.202-1.62-.606-2.114-.404-.495-.92-.742-1.548-.742-.553 0-1.05.224-1.491.67-.442.447-.662 1.133-.662 2.058 0 .958.212 1.67.638 2.138.425.469.946.703 1.563.703zM53.004 5.72v4.42c.574-.894 1.388-1.341 2.44-1.341 1.022 0 1.857.383 2.506 1.149.649.766.973 1.781.973 3.047 0 1.138-.309 2.109-.925 2.912-.617.803-1.463 1.205-2.537 1.205-1.075 0-1.894-.447-2.457-1.34V17h-1.58V5.72h1.58zm9.908 11.104l-3.223-7.913h1.739l1.005 2.632 1.26 3.415c.096-.32.48-1.458 1.15-3.415l.909-2.632h1.66l-2.92 7.866c-.777 2.074-1.963 3.11-3.559 3.11a2.92 2.92 0 01-.734-.079v-1.34c.17.042.351.064.543.064 1.032 0 1.755-.57 2.17-1.708z' fill='%235D6494'/%3E%3Cpath d='M89.632 5.967v-.772a.978.978 0 00-.978-.977h-2.28a.978.978 0 00-.978.977v.793c0 .088.082.15.171.13a7.127 7.127 0 011.984-.28c.65 0 1.295.088 1.917.259.082.02.164-.04.164-.13m-6.248 1.01l-.39-.389a.977.977 0 00-1.382 0l-.465.465a.973.973 0 000 1.38l.383.383c.062.061.15.047.205-.014.226-.307.472-.601.746-.874.281-.28.568-.526.883-.751.068-.042.075-.137.02-.2m4.16 2.453v3.341c0 .096.104.165.192.117l2.97-1.537c.068-.034.089-.117.055-.184a3.695 3.695 0 00-3.08-1.866c-.068 0-.136.054-.136.13m0 8.048a4.489 4.489 0 01-4.49-4.482 4.488 4.488 0 014.49-4.482 4.488 4.488 0 014.489 4.482 4.484 4.484 0 01-4.49 4.482m0-10.85a6.363 6.363 0 100 12.729 6.37 6.37 0 006.372-6.368 6.358 6.358 0 00-6.371-6.36' fill='%23FFF'/%3E%3C/g%3E%3C/svg%3E");background-repeat:no-repeat;background-position:50%;background-size:100%;overflow:hidden;text-indent:-9000px;padding:0!important;width:100%;height:100%;display:block}.dropdown-wrapper{cursor:pointer}.dropdown-wrapper .dropdown-title,.dropdown-wrapper .mobile-dropdown-title{display:block;font-size:.9rem;font-family:inherit;cursor:inherit;padding:inherit;line-height:1.4rem;background:transparent;border:none;font-weight:500;color:#2c3e50}.dropdown-wrapper .dropdown-title:hover,.dropdown-wrapper .mobile-dropdown-title:hover{border-color:transparent}.dropdown-wrapper .dropdown-title .arrow,.dropdown-wrapper .mobile-dropdown-title .arrow{vertical-align:middle;margin-top:-1px;margin-left:.4rem}.dropdown-wrapper .mobile-dropdown-title{display:none;font-weight:600}.dropdown-wrapper .mobile-dropdown-title font-size inherit:hover{color:#3eaf7c}.dropdown-wrapper .nav-dropdown .dropdown-item{color:inherit;line-height:1.7rem}.dropdown-wrapper .nav-dropdown .dropdown-item h4{margin:.45rem 0 0;border-top:1px solid #eee;padding:1rem 1.5rem .45rem 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper{padding:0;list-style:none}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper .dropdown-subitem{font-size:.9em}.dropdown-wrapper .nav-dropdown .dropdown-item a{display:block;line-height:1.7rem;position:relative;border-bottom:none;font-weight:400;margin-bottom:0;padding:0 1.5rem 0 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active,.dropdown-wrapper .nav-dropdown .dropdown-item a:hover{color:#3eaf7c}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{content:"";width:0;height:0;border-left:5px solid #3eaf7c;border-top:3px solid transparent;border-bottom:3px solid transparent;position:absolute;top:calc(50% - 2px);left:9px}.dropdown-wrapper .nav-dropdown .dropdown-item:first-child h4{margin-top:0;padding-top:0;border-top:0}@media (max-width:719px){.dropdown-wrapper.open .dropdown-title{margin-bottom:.5rem}.dropdown-wrapper .dropdown-title{display:none}.dropdown-wrapper .mobile-dropdown-title{display:block}.dropdown-wrapper .nav-dropdown{transition:height .1s ease-out;overflow:hidden}.dropdown-wrapper .nav-dropdown .dropdown-item h4{border-top:0;margin-top:0;padding-top:0}.dropdown-wrapper .nav-dropdown .dropdown-item>a,.dropdown-wrapper .nav-dropdown .dropdown-item h4{font-size:15px;line-height:2rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem{font-size:14px;padding-left:1rem}}@media (min-width:719px){.dropdown-wrapper{height:1.8rem}.dropdown-wrapper.open .nav-dropdown,.dropdown-wrapper:hover .nav-dropdown{display:block!important}.dropdown-wrapper .nav-dropdown{display:none;height:auto!important;box-sizing:border-box;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;background-color:#fff;padding:.6rem 0;border:1px solid;border-color:#ddd #ddd #ccc;text-align:left;border-radius:.25rem;white-space:nowrap;margin:0}}.nav-links{display:inline-block}.nav-links a{line-height:1.4rem;color:inherit}.nav-links a.router-link-active,.nav-links a:hover{color:#3eaf7c}.nav-links .nav-item{position:relative;display:inline-block;margin-left:1.5rem;line-height:2rem}.nav-links .nav-item:first-child{margin-left:0}.nav-links .repo-link{margin-left:1.5rem}@media (max-width:719px){.nav-links .nav-item,.nav-links .repo-link{margin-left:0}}@media (min-width:719px){.nav-links a.router-link-active,.nav-links a:hover{color:#2c3e50}.nav-item>a:not(.external).router-link-active,.nav-item>a:not(.external):hover{margin-bottom:-2px;border-bottom:2px solid #46bd87}}.navbar{padding:.7rem 1.5rem;line-height:2.2rem}.navbar a,.navbar img,.navbar span{display:inline-block}.navbar .logo{height:2.2rem;min-width:2.2rem;margin-right:.8rem;vertical-align:top}.navbar .site-name{font-size:1.3rem;font-weight:600;color:#2c3e50;position:relative}.navbar .links{padding-left:1.5rem;box-sizing:border-box;background-color:#fff;white-space:nowrap;font-size:.9rem;position:absolute;right:1.5rem;top:.7rem;display:flex}.navbar .links .search-box{flex:0 0 auto;vertical-align:top}@media (max-width:719px){.navbar{padding-left:4rem}.navbar .can-hide{display:none}.navbar .links{padding-left:1.5rem}.navbar .site-name{width:calc(100vw - 9.4rem);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}}.page-edit{max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.page-edit{padding:2rem}}@media (max-width:419px){.page-edit{padding:1.5rem}}.page-edit{padding-top:1rem;padding-bottom:1rem;overflow:auto}.page-edit .edit-link{display:inline-block}.page-edit .edit-link a{color:#4e6e8e;margin-right:.25rem}.page-edit .last-updated{float:right;font-size:.9em}.page-edit .last-updated .prefix{font-weight:500;color:#4e6e8e}.page-edit .last-updated .time{font-weight:400;color:#767676}@media (max-width:719px){.page-edit .edit-link{margin-bottom:.5rem}.page-edit .last-updated{font-size:.8em;float:none;text-align:left}}.page-nav{max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.page-nav{padding:2rem}}@media (max-width:419px){.page-nav{padding:1.5rem}}.page-nav{padding-top:1rem;padding-bottom:0}.page-nav .inner{min-height:2rem;margin-top:0;border-top:1px solid #eaecef;padding-top:1rem;overflow:auto}.page-nav .next{float:right}.page{padding-bottom:2rem;display:block}.sidebar-group .sidebar-group{padding-left:.5em}.sidebar-group:not(.collapsable) .sidebar-heading:not(.clickable){cursor:auto;color:inherit}.sidebar-group.is-sub-group{padding-left:0}.sidebar-group.is-sub-group>.sidebar-heading{font-size:.95em;line-height:1.4;font-weight:400;padding-left:2rem}.sidebar-group.is-sub-group>.sidebar-heading:not(.clickable){opacity:.5}.sidebar-group.is-sub-group>.sidebar-group-items{padding-left:1rem}.sidebar-group.is-sub-group>.sidebar-group-items>li>.sidebar-link{font-size:.95em;border-left:none}.sidebar-group.depth-2>.sidebar-heading{border-left:none}.sidebar-heading{color:#2c3e50;transition:color .15s ease;cursor:pointer;font-size:1.1em;font-weight:700;padding:.35rem 1.5rem .35rem 1.25rem;width:100%;box-sizing:border-box;margin:0;border-left:.25rem solid transparent}.sidebar-heading.open,.sidebar-heading:hover{color:inherit}.sidebar-heading .arrow{position:relative;top:-.12em;left:.5em}.sidebar-heading.clickable.active{font-weight:600;color:#3eaf7c;border-left-color:#3eaf7c}.sidebar-heading.clickable:hover{color:#3eaf7c}.sidebar-group-items{transition:height .1s ease-out;font-size:.95em;overflow:hidden}.sidebar .sidebar-sub-headers{padding-left:1rem;font-size:.95em}a.sidebar-link{font-size:1em;font-weight:400;display:inline-block;color:#2c3e50;border-left:.25rem solid transparent;padding:.35rem 1rem .35rem 1.25rem;line-height:1.4;width:100%;box-sizing:border-box}a.sidebar-link:hover{color:#3eaf7c}a.sidebar-link.active{font-weight:600;color:#3eaf7c;border-left-color:#3eaf7c}.sidebar-group a.sidebar-link{padding-left:2rem}.sidebar-sub-headers a.sidebar-link{padding-top:.25rem;padding-bottom:.25rem;border-left:none}.sidebar-sub-headers a.sidebar-link.active{font-weight:500}.sidebar ul{padding:0;margin:0;list-style-type:none}.sidebar a{display:inline-block}.sidebar .nav-links{display:none;border-bottom:1px solid #eaecef;padding:.5rem 0 .75rem}.sidebar .nav-links a{font-weight:600}.sidebar .nav-links .nav-item,.sidebar .nav-links .repo-link{display:block;line-height:1.25rem;font-size:1.1em;padding:.5rem 0 .5rem 1.5rem}.sidebar>.sidebar-links{padding:1.5rem 0}.sidebar>.sidebar-links>li>a.sidebar-link{font-size:1.1em;line-height:1.7;font-weight:700}.sidebar>.sidebar-links>li:not(:first-child){margin-top:.75rem}@media (max-width:719px){.sidebar .nav-links{display:block}.sidebar .nav-links .dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{top:calc(1rem - 2px)}.sidebar>.sidebar-links{padding:1rem 0}} \ No newline at end of file diff --git a/assets/fonts/MathJax_AMS-Regular.07173fb7.woff b/assets/fonts/MathJax_AMS-Regular.07173fb7.woff new file mode 100644 index 0000000..1bf198f Binary files /dev/null and b/assets/fonts/MathJax_AMS-Regular.07173fb7.woff differ diff --git a/assets/fonts/MathJax_Fraktur-Bold.bc421258.woff b/assets/fonts/MathJax_Fraktur-Bold.bc421258.woff new file mode 100644 index 0000000..f5df023 Binary files /dev/null and b/assets/fonts/MathJax_Fraktur-Bold.bc421258.woff differ diff --git a/assets/fonts/MathJax_Fraktur-Regular.b80e08d5.woff b/assets/fonts/MathJax_Fraktur-Regular.b80e08d5.woff new file mode 100644 index 0000000..175301e Binary files /dev/null and b/assets/fonts/MathJax_Fraktur-Regular.b80e08d5.woff differ diff --git a/assets/fonts/MathJax_Main-Bold.c9423d5d.woff b/assets/fonts/MathJax_Main-Bold.c9423d5d.woff new file mode 100644 index 0000000..2805af5 Binary files /dev/null and b/assets/fonts/MathJax_Main-Bold.c9423d5d.woff differ diff --git a/assets/fonts/MathJax_Main-Italic.7e83626b.woff b/assets/fonts/MathJax_Main-Italic.7e83626b.woff new file mode 100644 index 0000000..36cb2b6 Binary files /dev/null and b/assets/fonts/MathJax_Main-Italic.7e83626b.woff differ diff --git a/assets/fonts/MathJax_Main-Regular.9995de47.woff b/assets/fonts/MathJax_Main-Regular.9995de47.woff new file mode 100644 index 0000000..c28398e Binary files /dev/null and b/assets/fonts/MathJax_Main-Regular.9995de47.woff differ diff --git a/assets/fonts/MathJax_Math-BoldItalic.77dbcee3.woff b/assets/fonts/MathJax_Math-BoldItalic.77dbcee3.woff new file mode 100644 index 0000000..6496d17 Binary files /dev/null and b/assets/fonts/MathJax_Math-BoldItalic.77dbcee3.woff differ diff --git a/assets/fonts/MathJax_Math-Italic.5589d1a8.woff b/assets/fonts/MathJax_Math-Italic.5589d1a8.woff new file mode 100644 index 0000000..e62ff5f Binary files /dev/null and b/assets/fonts/MathJax_Math-Italic.5589d1a8.woff differ diff --git a/assets/fonts/MathJax_SansSerif-Bold.07281897.woff b/assets/fonts/MathJax_SansSerif-Bold.07281897.woff new file mode 100644 index 0000000..bd27726 Binary files /dev/null and b/assets/fonts/MathJax_SansSerif-Bold.07281897.woff differ diff --git a/assets/fonts/MathJax_SansSerif-Italic.3d580bd5.woff b/assets/fonts/MathJax_SansSerif-Italic.3d580bd5.woff new file mode 100644 index 0000000..22e5eff Binary files /dev/null and b/assets/fonts/MathJax_SansSerif-Italic.3d580bd5.woff differ diff --git a/assets/fonts/MathJax_SansSerif-Regular.bc3af04f.woff b/assets/fonts/MathJax_SansSerif-Regular.bc3af04f.woff new file mode 100644 index 0000000..d1ff7c6 Binary files /dev/null and b/assets/fonts/MathJax_SansSerif-Regular.bc3af04f.woff differ diff --git a/assets/fonts/MathJax_Script-Regular.4c74e33b.woff b/assets/fonts/MathJax_Script-Regular.4c74e33b.woff new file mode 100644 index 0000000..a9d1f34 Binary files /dev/null and b/assets/fonts/MathJax_Script-Regular.4c74e33b.woff differ diff --git a/assets/fonts/MathJax_Typewriter-Regular.72815766.woff b/assets/fonts/MathJax_Typewriter-Regular.72815766.woff new file mode 100644 index 0000000..510a8da Binary files /dev/null and b/assets/fonts/MathJax_Typewriter-Regular.72815766.woff differ diff --git a/assets/img/0101.1b2216b4.png b/assets/img/0101.1b2216b4.png new file mode 100644 index 0000000..37b03cc Binary files /dev/null and b/assets/img/0101.1b2216b4.png differ diff --git a/assets/img/0102.bf7542ae.png b/assets/img/0102.bf7542ae.png new file mode 100644 index 0000000..3950497 Binary files /dev/null and b/assets/img/0102.bf7542ae.png differ diff --git a/assets/img/0103.67b2bee9.png b/assets/img/0103.67b2bee9.png new file mode 100644 index 0000000..dc17e81 Binary files /dev/null and b/assets/img/0103.67b2bee9.png differ diff --git a/assets/img/0105.51a5549d.png b/assets/img/0105.51a5549d.png new file mode 100644 index 0000000..ed0466e Binary files /dev/null and b/assets/img/0105.51a5549d.png differ diff --git a/assets/img/0106.a9dd398c.png b/assets/img/0106.a9dd398c.png new file mode 100644 index 0000000..78186c0 Binary files /dev/null and b/assets/img/0106.a9dd398c.png differ diff --git a/assets/img/0107.21b3e1d2.png b/assets/img/0107.21b3e1d2.png new file mode 100644 index 0000000..7259405 Binary files /dev/null and b/assets/img/0107.21b3e1d2.png differ diff --git a/assets/img/10.3fdd2e73.png b/assets/img/10.3fdd2e73.png new file mode 100644 index 0000000..5852a03 Binary files /dev/null and b/assets/img/10.3fdd2e73.png differ diff --git a/assets/img/100.f1925d8e.png b/assets/img/100.f1925d8e.png new file mode 100644 index 0000000..7e3fa26 Binary files /dev/null and b/assets/img/100.f1925d8e.png differ diff --git a/assets/img/11.8de292dd.png b/assets/img/11.8de292dd.png new file mode 100644 index 0000000..57595e4 Binary files /dev/null and b/assets/img/11.8de292dd.png differ diff --git a/assets/img/12.738b1aa1.png b/assets/img/12.738b1aa1.png new file mode 100644 index 0000000..48cf439 Binary files /dev/null and b/assets/img/12.738b1aa1.png differ diff --git a/assets/img/1212.4aca9893.png b/assets/img/1212.4aca9893.png new file mode 100644 index 0000000..a97fe16 Binary files /dev/null and b/assets/img/1212.4aca9893.png differ diff --git a/assets/img/13.aeaf6857.png b/assets/img/13.aeaf6857.png new file mode 100644 index 0000000..0367d64 Binary files /dev/null and b/assets/img/13.aeaf6857.png differ diff --git a/assets/img/150.02b9f277.png b/assets/img/150.02b9f277.png new file mode 100644 index 0000000..750a250 Binary files /dev/null and b/assets/img/150.02b9f277.png differ diff --git a/assets/img/151.c440b711.png b/assets/img/151.c440b711.png new file mode 100644 index 0000000..0afdbc1 Binary files /dev/null and b/assets/img/151.c440b711.png differ diff --git a/assets/img/160.f3a7ce3c.png b/assets/img/160.f3a7ce3c.png new file mode 100644 index 0000000..f05c90a Binary files /dev/null and b/assets/img/160.f3a7ce3c.png differ diff --git a/assets/img/161.17ec9311.png b/assets/img/161.17ec9311.png new file mode 100644 index 0000000..ab78695 Binary files /dev/null and b/assets/img/161.17ec9311.png differ diff --git a/assets/img/162.638197d7.png b/assets/img/162.638197d7.png new file mode 100644 index 0000000..d1adc0d Binary files /dev/null and b/assets/img/162.638197d7.png differ diff --git a/assets/img/163.7b78786e.png b/assets/img/163.7b78786e.png new file mode 100644 index 0000000..067f300 Binary files /dev/null and b/assets/img/163.7b78786e.png differ diff --git a/assets/img/164.d8ddcf2a.png b/assets/img/164.d8ddcf2a.png new file mode 100644 index 0000000..ec45e57 Binary files /dev/null and b/assets/img/164.d8ddcf2a.png differ diff --git a/assets/img/170.3b319b11.png b/assets/img/170.3b319b11.png new file mode 100644 index 0000000..a2577c6 Binary files /dev/null and b/assets/img/170.3b319b11.png differ diff --git a/assets/img/171.5368cde2.png b/assets/img/171.5368cde2.png new file mode 100644 index 0000000..f701619 Binary files /dev/null and b/assets/img/171.5368cde2.png differ diff --git a/assets/img/180.4124ca07.png b/assets/img/180.4124ca07.png new file mode 100644 index 0000000..1ec96c4 Binary files /dev/null and b/assets/img/180.4124ca07.png differ diff --git a/assets/img/181.614e612d.png b/assets/img/181.614e612d.png new file mode 100644 index 0000000..2f91037 Binary files /dev/null and b/assets/img/181.614e612d.png differ diff --git a/assets/img/182.907e9a86.png b/assets/img/182.907e9a86.png new file mode 100644 index 0000000..68e7684 Binary files /dev/null and b/assets/img/182.907e9a86.png differ diff --git a/assets/img/183.aeedd703.png b/assets/img/183.aeedd703.png new file mode 100644 index 0000000..fd3ec3c Binary files /dev/null and b/assets/img/183.aeedd703.png differ diff --git a/assets/img/184.e236f620.png b/assets/img/184.e236f620.png new file mode 100644 index 0000000..a436baa Binary files /dev/null and b/assets/img/184.e236f620.png differ diff --git a/assets/img/20.0ec3fffd.png b/assets/img/20.0ec3fffd.png new file mode 100644 index 0000000..cb1ec09 Binary files /dev/null and b/assets/img/20.0ec3fffd.png differ diff --git a/assets/img/22.d7d4f076.png b/assets/img/22.d7d4f076.png new file mode 100644 index 0000000..f8838dc Binary files /dev/null and b/assets/img/22.d7d4f076.png differ diff --git a/assets/img/23.5d2a18d3.png b/assets/img/23.5d2a18d3.png new file mode 100644 index 0000000..46fc294 Binary files /dev/null and b/assets/img/23.5d2a18d3.png differ diff --git a/assets/img/24.ef298398.png b/assets/img/24.ef298398.png new file mode 100644 index 0000000..9550234 Binary files /dev/null and b/assets/img/24.ef298398.png differ diff --git a/assets/img/25.292bd7a3.png b/assets/img/25.292bd7a3.png new file mode 100644 index 0000000..147ecb4 Binary files /dev/null and b/assets/img/25.292bd7a3.png differ diff --git a/assets/img/2Untitled.a0446167.png b/assets/img/2Untitled.a0446167.png new file mode 100644 index 0000000..374dc19 Binary files /dev/null and b/assets/img/2Untitled.a0446167.png differ diff --git a/assets/img/2Untitled1.27be85d1.png b/assets/img/2Untitled1.27be85d1.png new file mode 100644 index 0000000..5841222 Binary files /dev/null and b/assets/img/2Untitled1.27be85d1.png differ diff --git a/assets/img/330.d5f6b243.png b/assets/img/330.d5f6b243.png new file mode 100644 index 0000000..2f28abc Binary files /dev/null and b/assets/img/330.d5f6b243.png differ diff --git a/assets/img/331.87f2f64d.png b/assets/img/331.87f2f64d.png new file mode 100644 index 0000000..8637094 Binary files /dev/null and b/assets/img/331.87f2f64d.png differ diff --git a/assets/img/332.055be097.png b/assets/img/332.055be097.png new file mode 100644 index 0000000..76616a0 Binary files /dev/null and b/assets/img/332.055be097.png differ diff --git a/assets/img/4-inputSort.a02239ea.png b/assets/img/4-inputSort.a02239ea.png new file mode 100644 index 0000000..de9df22 Binary files /dev/null and b/assets/img/4-inputSort.a02239ea.png differ diff --git a/assets/img/4.5c72e81f.png b/assets/img/4.5c72e81f.png new file mode 100644 index 0000000..7826414 Binary files /dev/null and b/assets/img/4.5c72e81f.png differ diff --git a/assets/img/40.64b5a4ec.png b/assets/img/40.64b5a4ec.png new file mode 100644 index 0000000..c377944 Binary files /dev/null and b/assets/img/40.64b5a4ec.png differ diff --git a/assets/img/41.6f90f7f4.png b/assets/img/41.6f90f7f4.png new file mode 100644 index 0000000..cba464c Binary files /dev/null and b/assets/img/41.6f90f7f4.png differ diff --git a/assets/img/42.17353efa.png b/assets/img/42.17353efa.png new file mode 100644 index 0000000..c126f21 Binary files /dev/null and b/assets/img/42.17353efa.png differ diff --git a/assets/img/420.6fdcd694.png b/assets/img/420.6fdcd694.png new file mode 100644 index 0000000..2920b8d Binary files /dev/null and b/assets/img/420.6fdcd694.png differ diff --git a/assets/img/421.bf08c958.png b/assets/img/421.bf08c958.png new file mode 100644 index 0000000..632bf4c Binary files /dev/null and b/assets/img/421.bf08c958.png differ diff --git a/assets/img/440.73503d7b.png b/assets/img/440.73503d7b.png new file mode 100644 index 0000000..7094bb5 Binary files /dev/null and b/assets/img/440.73503d7b.png differ diff --git a/assets/img/50.9f171ce6.png b/assets/img/50.9f171ce6.png new file mode 100644 index 0000000..b6cd319 Binary files /dev/null and b/assets/img/50.9f171ce6.png differ diff --git a/assets/img/51.5a54b6e7.png b/assets/img/51.5a54b6e7.png new file mode 100644 index 0000000..01dcb0e Binary files /dev/null and b/assets/img/51.5a54b6e7.png differ diff --git a/assets/img/60.a7076894.png b/assets/img/60.a7076894.png new file mode 100644 index 0000000..fc9f50d Binary files /dev/null and b/assets/img/60.a7076894.png differ diff --git a/assets/img/61.0a944134.png b/assets/img/61.0a944134.png new file mode 100644 index 0000000..35ada49 Binary files /dev/null and b/assets/img/61.0a944134.png differ diff --git a/assets/img/62.cbedfc07.png b/assets/img/62.cbedfc07.png new file mode 100644 index 0000000..835dc21 Binary files /dev/null and b/assets/img/62.cbedfc07.png differ diff --git a/assets/img/63.8cd20bf2.png b/assets/img/63.8cd20bf2.png new file mode 100644 index 0000000..47aada8 Binary files /dev/null and b/assets/img/63.8cd20bf2.png differ diff --git a/assets/img/64.e0f8e26d.png b/assets/img/64.e0f8e26d.png new file mode 100644 index 0000000..d552d47 Binary files /dev/null and b/assets/img/64.e0f8e26d.png differ diff --git a/assets/img/65.2e30e1f0.png b/assets/img/65.2e30e1f0.png new file mode 100644 index 0000000..8eddbad Binary files /dev/null and b/assets/img/65.2e30e1f0.png differ diff --git a/assets/img/66.ea7a75f7.png b/assets/img/66.ea7a75f7.png new file mode 100644 index 0000000..62cbcae Binary files /dev/null and b/assets/img/66.ea7a75f7.png differ diff --git a/assets/img/67.26b875f2.png b/assets/img/67.26b875f2.png new file mode 100644 index 0000000..afb4d58 Binary files /dev/null and b/assets/img/67.26b875f2.png differ diff --git a/assets/img/68.36e5a893.png b/assets/img/68.36e5a893.png new file mode 100644 index 0000000..4ff01f5 Binary files /dev/null and b/assets/img/68.36e5a893.png differ diff --git a/assets/img/71.7cb849c0.png b/assets/img/71.7cb849c0.png new file mode 100644 index 0000000..492a1b2 Binary files /dev/null and b/assets/img/71.7cb849c0.png differ diff --git a/assets/img/72.921c6bb2.png b/assets/img/72.921c6bb2.png new file mode 100644 index 0000000..7cece70 Binary files /dev/null and b/assets/img/72.921c6bb2.png differ diff --git a/assets/img/73.4dfb177b.png b/assets/img/73.4dfb177b.png new file mode 100644 index 0000000..ab0df5c Binary files /dev/null and b/assets/img/73.4dfb177b.png differ diff --git a/assets/img/74.35cba8aa.png b/assets/img/74.35cba8aa.png new file mode 100644 index 0000000..6a736bf Binary files /dev/null and b/assets/img/74.35cba8aa.png differ diff --git a/assets/img/80.45baf6aa.png b/assets/img/80.45baf6aa.png new file mode 100644 index 0000000..00f8972 Binary files /dev/null and b/assets/img/80.45baf6aa.png differ diff --git a/assets/img/81.91d115e8.png b/assets/img/81.91d115e8.png new file mode 100644 index 0000000..1d2ecc5 Binary files /dev/null and b/assets/img/81.91d115e8.png differ diff --git a/assets/img/82.ee29aaa1.png b/assets/img/82.ee29aaa1.png new file mode 100644 index 0000000..40458f2 Binary files /dev/null and b/assets/img/82.ee29aaa1.png differ diff --git a/assets/img/83.1991b8e8.png b/assets/img/83.1991b8e8.png new file mode 100644 index 0000000..e10fd79 Binary files /dev/null and b/assets/img/83.1991b8e8.png differ diff --git a/assets/img/84.e8508045.png b/assets/img/84.e8508045.png new file mode 100644 index 0000000..64ad76e Binary files /dev/null and b/assets/img/84.e8508045.png differ diff --git a/assets/img/85.92a58c83.png b/assets/img/85.92a58c83.png new file mode 100644 index 0000000..997c169 Binary files /dev/null and b/assets/img/85.92a58c83.png differ diff --git a/assets/img/90.1771be5f.png b/assets/img/90.1771be5f.png new file mode 100644 index 0000000..c4ef6a4 Binary files /dev/null and b/assets/img/90.1771be5f.png differ diff --git a/assets/img/91.c7cffbcc.png b/assets/img/91.c7cffbcc.png new file mode 100644 index 0000000..397504b Binary files /dev/null and b/assets/img/91.c7cffbcc.png differ diff --git a/assets/img/92.e9c4a47f.png b/assets/img/92.e9c4a47f.png new file mode 100644 index 0000000..f9d3c8e Binary files /dev/null and b/assets/img/92.e9c4a47f.png differ diff --git a/assets/img/93.b74ca16a.png b/assets/img/93.b74ca16a.png new file mode 100644 index 0000000..7f1ec61 Binary files /dev/null and b/assets/img/93.b74ca16a.png differ diff --git a/assets/img/Arbiter.0f715328.png b/assets/img/Arbiter.0f715328.png new file mode 100644 index 0000000..a26796e Binary files /dev/null and b/assets/img/Arbiter.0f715328.png differ diff --git a/assets/img/ArtificialNeuronModel_english.741f68e5.png b/assets/img/ArtificialNeuronModel_english.741f68e5.png new file mode 100644 index 0000000..3273117 Binary files /dev/null and b/assets/img/ArtificialNeuronModel_english.741f68e5.png differ diff --git a/assets/img/FIR.5888a130.jpeg b/assets/img/FIR.5888a130.jpeg new file mode 100644 index 0000000..aaa77a7 Binary files /dev/null and b/assets/img/FIR.5888a130.jpeg differ diff --git a/assets/img/FSM.a8105ac5.png b/assets/img/FSM.a8105ac5.png new file mode 100644 index 0000000..bf52277 Binary files /dev/null and b/assets/img/FSM.a8105ac5.png differ diff --git a/assets/img/G4E.f2c635d7.jpeg b/assets/img/G4E.f2c635d7.jpeg new file mode 100644 index 0000000..34b40af Binary files /dev/null and b/assets/img/G4E.f2c635d7.jpeg differ diff --git a/assets/img/ShiftRegister.c44a0985.svg b/assets/img/ShiftRegister.c44a0985.svg new file mode 100644 index 0000000..a6aa73d --- /dev/null +++ b/assets/img/ShiftRegister.c44a0985.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 2 + 3 + 0 + + + + + + out[3:0] + + in + + + + + + + + + + diff --git a/assets/img/Vivado.3cc10be4.png b/assets/img/Vivado.3cc10be4.png new file mode 100644 index 0000000..d35372b Binary files /dev/null and b/assets/img/Vivado.3cc10be4.png differ diff --git a/assets/img/Vivado1.ffa29b16.png b/assets/img/Vivado1.ffa29b16.png new file mode 100644 index 0000000..4d2ff9d Binary files /dev/null and b/assets/img/Vivado1.ffa29b16.png differ diff --git a/assets/img/block.b5292fb2.png b/assets/img/block.b5292fb2.png new file mode 100644 index 0000000..64691c2 Binary files /dev/null and b/assets/img/block.b5292fb2.png differ diff --git a/assets/img/block1.bbc37b84.png b/assets/img/block1.bbc37b84.png new file mode 100644 index 0000000..67c2283 Binary files /dev/null and b/assets/img/block1.bbc37b84.png differ diff --git a/assets/img/good.png b/assets/img/good.png new file mode 100644 index 0000000..773ff54 Binary files /dev/null and b/assets/img/good.png differ diff --git a/assets/img/mpb.b14b24ec.png b/assets/img/mpb.b14b24ec.png new file mode 100644 index 0000000..864fe4d Binary files /dev/null and b/assets/img/mpb.b14b24ec.png differ diff --git a/assets/img/search.83621669.svg b/assets/img/search.83621669.svg new file mode 100644 index 0000000..03d8391 --- /dev/null +++ b/assets/img/search.83621669.svg @@ -0,0 +1 @@ + diff --git a/assets/img/wenhao.png b/assets/img/wenhao.png new file mode 100644 index 0000000..df29550 Binary files /dev/null and b/assets/img/wenhao.png differ diff --git a/assets/js/1.a4e52cf6.js b/assets/js/1.a4e52cf6.js new file mode 100644 index 0000000..1f7952c --- /dev/null +++ b/assets/js/1.a4e52cf6.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[1,12,15,30,31,38],{241:function(t,e,n){"use strict";n.d(e,"d",(function(){return s})),n.d(e,"a",(function(){return r})),n.d(e,"i",(function(){return o})),n.d(e,"f",(function(){return l})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return c})),n.d(e,"b",(function(){return h})),n.d(e,"e",(function(){return f})),n.d(e,"k",(function(){return p})),n.d(e,"l",(function(){return d})),n.d(e,"c",(function(){return m})),n.d(e,"j",(function(){return k}));n(45);const s=/#.*$/,i=/\.(md|html)$/,r=/\/$/,o=/^[a-z]+:/i;function a(t){return decodeURI(t).replace(s,"").replace(i,"")}function l(t){return o.test(t)}function u(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function h(t){if(l(t))return t;const e=t.match(s),n=e?e[0]:"",i=a(t);return r.test(i)?t:i+".html"+n}function f(t,e){const n=decodeURIComponent(t.hash),i=function(t){const e=t.match(s);if(e)return e[0]}(e);if(i&&n!==i)return!1;return a(t.path)===a(e)}function p(t,e,n){if(l(e))return{type:"external",path:e};n&&(e=function(t,e,n){const s=t.charAt(0);if("/"===s)return t;if("?"===s||"#"===s)return e+t;const i=e.split("/");n&&i[i.length-1]||i.pop();const r=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,s,i=1){if("string"==typeof e)return p(n,e,s);if(Array.isArray(e))return Object.assign(p(n,e[0],s),{title:e[1]});{const r=e.children||[];return 0===r.length&&e.path?Object.assign(p(n,e.path,s),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:r.map(e=>t(e,n,s,i+1)),collapsable:!1!==e.collapsable}}}(t,i,n)):[]}return[]}function g(t){const e=m(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function m(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function k(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},242:function(t,e,n){},243:function(t,e,n){"use strict";n.r(e);var s=n(241),i={name:"NavLink",props:{item:{required:!0}},computed:{link(){return Object(s.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link},isNonHttpURI(){return Object(s.g)(this.link)||Object(s.h)(this.link)},isBlankTarget(){return"_blank"===this.target},isInternal(){return!Object(s.f)(this.link)&&!this.isBlankTarget},target(){return this.isNonHttpURI?null:this.item.target?this.item.target:Object(s.f)(this.link)?"_blank":""},rel(){return this.isNonHttpURI||!1===this.item.rel?null:this.item.rel?this.item.rel:this.isBlankTarget?"noopener noreferrer":null}},methods:{focusoutAction(){this.$emit("focusout")}}},r=n(14),o=Object(r.a)(i,(function(){var t=this,e=t._self._c;return t.isInternal?e("RouterLink",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v("\n "+t._s(t.item.text)+"\n")]):e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.target,rel:t.rel},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),t.isBlankTarget?e("OutboundLink"):t._e()],1)}),[],!1,null,null,null);e.default=o.exports},244:function(t,e,n){"use strict";n.r(e);var s={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},i=(n(245),n(14)),r=Object(i.a)(s,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=r.exports},245:function(t,e,n){"use strict";n(242)},246:function(t,e,n){},249:function(t,e,n){},253:function(t,e,n){"use strict";n(246)},256:function(t,e,n){"use strict";n.r(e);var s=n(243),i=n(244),r=n(90),o=n.n(r),a={name:"DropdownLink",components:{NavLink:s.default,DropdownTransition:i.default},props:{item:{required:!0}},data:()=>({open:!1}),computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},watch:{$route(){this.open=!1}},methods:{setOpen(t){this.open=t},isLastItemOfArray:(t,e)=>o()(e)===t,handleDropdown(){0===event.detail&&this.setOpen(!this.open)}}},l=(n(253),n(14)),u=Object(l.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.handleDropdown}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow down"})]),t._v(" "),e("button",{staticClass:"mobile-dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:function(e){return t.setOpen(!t.open)}}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})]),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(n,s){return e("li",{key:n.link||s,staticClass:"dropdown-item"},["links"===n.type?e("h4",[t._v("\n "+t._s(n.text)+"\n ")]):t._e(),t._v(" "),"links"===n.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(n.items,(function(s){return e("li",{key:s.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:s},on:{focusout:function(e){t.isLastItemOfArray(s,n.items)&&t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0):e("NavLink",{attrs:{item:n},on:{focusout:function(e){t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports},259:function(t,e,n){},260:function(t,e,n){"use strict";n(249)},267:function(t,e,n){"use strict";n.r(e);var s=n(256),i=n(241),r={name:"NavLinks",components:{NavLink:n(243).default,DropdownLink:s.default},computed:{userNav(){return this.$themeLocaleConfig.nav||this.$site.themeConfig.nav||[]},nav(){const{locales:t}=this.$site;if(t&&Object.keys(t).length>1){const e=this.$page.path,n=this.$router.options.routes,s=this.$site.themeConfig.locales||{},i={text:this.$themeLocaleConfig.selectText||"Languages",ariaLabel:this.$themeLocaleConfig.ariaLabel||"Select language",items:Object.keys(t).map(i=>{const r=t[i],o=s[i]&&s[i].label||r.lang;let a;return r.lang===this.$lang?a=e:(a=e.replace(this.$localeConfig.path,i),n.some(t=>t.path===a)||(a=i)),{text:o,link:a}})};return[...this.userNav,i]}return this.userNav},userLinks(){return(this.nav||[]).map(t=>Object.assign(Object(i.j)(t),{items:(t.items||[]).map(i.j)}))},repoLink(){const{repo:t}=this.$site.themeConfig;return t?/^https?:/.test(t)?t:"https://github.com/"+t:null},repoLabel(){if(!this.repoLink)return;if(this.$site.themeConfig.repoLabel)return this.$site.themeConfig.repoLabel;const t=this.repoLink.match(/^https?:\/\/[^/]+/)[0],e=["GitHub","GitLab","Bitbucket"];for(let n=0;n{let s=i()(e,"title","");return i()(e,"frontmatter.tags")&&(s+=" "+e.frontmatter.tags.join(" ")),n&&(s+=" "+n),o(t,s)};const o=(t,e)=>{const n=t=>t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),s=new RegExp("[^\0-]"),i=t.split(/\s+/g).map(t=>t.trim()).filter(t=>!!t);if(s.test(t))return i.some(t=>e.toLowerCase().indexOf(t)>-1);{const s=t.endsWith(" ");return new RegExp(i.map((t,e)=>i.length!==e+1||s?`(?=.*\\b${n(t)}\\b)`:`(?=.*\\b${n(t)})`).join("")+".+","gi").test(e)}};var a={name:"SearchBox",data:()=>({query:"",focused:!1,focusIndex:0,placeholder:void 0}),computed:{showSuggestions(){return this.focused&&this.suggestions&&this.suggestions.length},suggestions(){const t=this.query.trim().toLowerCase();if(!t)return;const{pages:e}=this.$site,n=this.$site.themeConfig.searchMaxSuggestions||5,s=this.$localePath,i=[];for(let o=0;o=n);o++){const a=e[o];if(this.getPageLocalePath(a)===s&&this.isSearchable(a))if(r(t,a))i.push(a);else if(a.headers)for(let e=0;e=n);e++){const n=a.headers[e];n.title&&r(t,a,n.title)&&i.push(Object.assign({},a,{path:a.path+"#"+n.slug,header:n}))}}return i},alignRight(){return(this.$site.themeConfig.nav||[]).length+(this.$site.repo?1:0)<=2}},mounted(){this.placeholder=this.$site.themeConfig.searchPlaceholder||"",document.addEventListener("keydown",this.onHotkey)},beforeDestroy(){document.removeEventListener("keydown",this.onHotkey)},methods:{getPageLocalePath(t){for(const e in this.$site.locales||{})if("/"!==e&&0===t.path.indexOf(e))return e;return"/"},isSearchable(t){let e=null;return null===e||(e=Array.isArray(e)?e:new Array(e),e.filter(e=>t.path.match(e)).length>0)},onHotkey(t){t.srcElement===document.body&&["s","/"].includes(t.key)&&(this.$refs.input.focus(),t.preventDefault())},onUp(){this.showSuggestions&&(this.focusIndex>0?this.focusIndex--:this.focusIndex=this.suggestions.length-1)},onDown(){this.showSuggestions&&(this.focusIndex "+t._s(n.header.title))]):t._e()])])})),0):t._e()])}),[],!1,null,null,null).exports,c=n(285),h=n(267);function f(t,e){return t.ownerDocument.defaultView.getComputedStyle(t,null)[e]}var p={name:"Navbar",components:{SidebarButton:c.default,NavLinks:h.default,SearchBox:u,AlgoliaSearchBox:{}},data:()=>({linksWrapMaxWidth:null}),computed:{algolia(){return this.$themeLocaleConfig.algolia||this.$site.themeConfig.algolia||{}},isAlgoliaSearch(){return this.algolia&&this.algolia.apiKey&&this.algolia.indexName}},mounted(){const t=parseInt(f(this.$el,"paddingLeft"))+parseInt(f(this.$el,"paddingRight")),e=()=>{document.documentElement.clientWidth<719?this.linksWrapMaxWidth=null:this.linksWrapMaxWidth=this.$el.offsetWidth-t-(this.$refs.siteName&&this.$refs.siteName.offsetWidth||0)};e(),window.addEventListener("resize",e,!1)}},d=(n(292),Object(l.a)(p,(function(){var t=this,e=t._self._c;return e("header",{staticClass:"navbar"},[e("SidebarButton",{on:{"toggle-sidebar":function(e){return t.$emit("toggle-sidebar")}}}),t._v(" "),e("RouterLink",{staticClass:"home-link",attrs:{to:t.$localePath}},[t.$site.themeConfig.logo?e("img",{staticClass:"logo",attrs:{src:t.$withBase(t.$site.themeConfig.logo),alt:t.$siteTitle}}):t._e(),t._v(" "),t.$siteTitle?e("span",{ref:"siteName",staticClass:"site-name",class:{"can-hide":t.$site.themeConfig.logo}},[t._v(t._s(t.$siteTitle))]):t._e()]),t._v(" "),e("div",{staticClass:"links",style:t.linksWrapMaxWidth?{"max-width":t.linksWrapMaxWidth+"px"}:{}},[t.isAlgoliaSearch?e("AlgoliaSearchBox",{attrs:{options:t.algolia}}):!1!==t.$site.themeConfig.search&&!1!==t.$page.frontmatter.search?e("SearchBox"):t._e(),t._v(" "),e("NavLinks",{staticClass:"can-hide"})],1)],1)}),[],!1,null,null,null));e.default=d.exports}}]); \ No newline at end of file diff --git a/assets/js/10.c8b6361b.js b/assets/js/10.c8b6361b.js new file mode 100644 index 0000000..2363715 --- /dev/null +++ b/assets/js/10.c8b6361b.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[10,3,12,15,27,30,38],{241:function(t,e,n){"use strict";n.d(e,"d",(function(){return i})),n.d(e,"a",(function(){return r})),n.d(e,"i",(function(){return a})),n.d(e,"f",(function(){return l})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return c})),n.d(e,"b",(function(){return p})),n.d(e,"e",(function(){return h})),n.d(e,"k",(function(){return d})),n.d(e,"l",(function(){return f})),n.d(e,"c",(function(){return m})),n.d(e,"j",(function(){return g}));n(45);const i=/#.*$/,s=/\.(md|html)$/,r=/\/$/,a=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(i,"").replace(s,"")}function l(t){return a.test(t)}function u(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function p(t){if(l(t))return t;const e=t.match(i),n=e?e[0]:"",s=o(t);return r.test(s)?t:s+".html"+n}function h(t,e){const n=decodeURIComponent(t.hash),s=function(t){const e=t.match(i);if(e)return e[0]}(e);if(s&&n!==s)return!1;return o(t.path)===o(e)}function d(t,e,n){if(l(e))return{type:"external",path:e};n&&(e=function(t,e,n){const i=t.charAt(0);if("/"===i)return t;if("?"===i||"#"===i)return e+t;const s=e.split("/");n&&s[s.length-1]||s.pop();const r=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,i,s=1){if("string"==typeof e)return d(n,e,i);if(Array.isArray(e))return Object.assign(d(n,e[0],i),{title:e[1]});{const r=e.children||[];return 0===r.length&&e.path?Object.assign(d(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:r.map(e=>t(e,n,i,s+1)),collapsable:!1!==e.collapsable}}}(t,s,n)):[]}return[]}function b(t){const e=m(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function m(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function g(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},242:function(t,e,n){},243:function(t,e,n){"use strict";n.r(e);var i=n(241),s={name:"NavLink",props:{item:{required:!0}},computed:{link(){return Object(i.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link},isNonHttpURI(){return Object(i.g)(this.link)||Object(i.h)(this.link)},isBlankTarget(){return"_blank"===this.target},isInternal(){return!Object(i.f)(this.link)&&!this.isBlankTarget},target(){return this.isNonHttpURI?null:this.item.target?this.item.target:Object(i.f)(this.link)?"_blank":""},rel(){return this.isNonHttpURI||!1===this.item.rel?null:this.item.rel?this.item.rel:this.isBlankTarget?"noopener noreferrer":null}},methods:{focusoutAction(){this.$emit("focusout")}}},r=n(14),a=Object(r.a)(s,(function(){var t=this,e=t._self._c;return t.isInternal?e("RouterLink",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v("\n "+t._s(t.item.text)+"\n")]):e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.target,rel:t.rel},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),t.isBlankTarget?e("OutboundLink"):t._e()],1)}),[],!1,null,null,null);e.default=a.exports},244:function(t,e,n){"use strict";n.r(e);var i={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},s=(n(245),n(14)),r=Object(s.a)(i,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=r.exports},245:function(t,e,n){"use strict";n(242)},246:function(t,e,n){},247:function(t,e,n){},249:function(t,e,n){},252:function(t,e,n){},253:function(t,e,n){"use strict";n(246)},254:function(t,e,n){"use strict";n(247)},255:function(t,e,n){"use strict";n.r(e);var i=n(268),s=n(257),r=n(241);function a(t,e){if("group"===e.type){const n=e.path&&Object(r.e)(t,e.path),i=e.children.some(e=>"group"===e.type?a(t,e):"page"===e.type&&Object(r.e)(t,e.path));return n||i}return!1}var o={name:"SidebarLinks",components:{SidebarGroup:i.default,SidebarLink:s.default},props:["items","depth","sidebarDepth","initialOpenGroupIndex"],data(){return{openGroupIndex:this.initialOpenGroupIndex||0}},watch:{$route(){this.refreshIndex()}},created(){this.refreshIndex()},methods:{refreshIndex(){const t=function(t,e){for(let n=0;n-1&&(this.openGroupIndex=t)},toggleGroup(t){this.openGroupIndex=t===this.openGroupIndex?-1:t},isActive(t){return Object(r.e)(this.$route,t.regularPath)}}},l=n(14),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return t.items.length?e("ul",{staticClass:"sidebar-links"},t._l(t.items,(function(n,i){return e("li",{key:i},["group"===n.type?e("SidebarGroup",{attrs:{item:n,open:i===t.openGroupIndex,collapsable:n.collapsable||n.collapsible,depth:t.depth},on:{toggle:function(e){return t.toggleGroup(i)}}}):e("SidebarLink",{attrs:{"sidebar-depth":t.sidebarDepth,item:n}})],1)})),0):t._e()}),[],!1,null,null,null);e.default=u.exports},256:function(t,e,n){"use strict";n.r(e);var i=n(243),s=n(244),r=n(90),a=n.n(r),o={name:"DropdownLink",components:{NavLink:i.default,DropdownTransition:s.default},props:{item:{required:!0}},data:()=>({open:!1}),computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},watch:{$route(){this.open=!1}},methods:{setOpen(t){this.open=t},isLastItemOfArray:(t,e)=>a()(e)===t,handleDropdown(){0===event.detail&&this.setOpen(!this.open)}}},l=(n(253),n(14)),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.handleDropdown}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow down"})]),t._v(" "),e("button",{staticClass:"mobile-dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:function(e){return t.setOpen(!t.open)}}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})]),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(n,i){return e("li",{key:n.link||i,staticClass:"dropdown-item"},["links"===n.type?e("h4",[t._v("\n "+t._s(n.text)+"\n ")]):t._e(),t._v(" "),"links"===n.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(n.items,(function(i){return e("li",{key:i.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:i},on:{focusout:function(e){t.isLastItemOfArray(i,n.items)&&t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0):e("NavLink",{attrs:{item:n},on:{focusout:function(e){t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports},257:function(t,e,n){"use strict";n.r(e);var i=n(241);function s(t,e,n,i,s){const r={props:{to:e,activeClass:"",exactActiveClass:""},class:{active:i,"sidebar-link":!0}};return s>2&&(r.style={"padding-left":s+"rem"}),t("RouterLink",r,n)}function r(t,e,n,a,o,l=1){return!e||l>o?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const u=Object(i.e)(a,n+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[s(t,n+"#"+e.slug,e.title,u,e.level-1),r(t,e.children,n,a,o,l+1)])}))}var a={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:n,$route:a,$themeConfig:o,$themeLocaleConfig:l},props:{item:u,sidebarDepth:c}}){const p=Object(i.e)(a,u.path),h="auto"===u.type?p||u.children.some(t=>Object(i.e)(a,u.basePath+"#"+t.slug)):p,d="external"===u.type?function(t,e,n){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[n,t("OutboundLink")])}(t,u.path,u.title||u.path):s(t,u.path,u.title||u.path,h),f=[e.frontmatter.sidebarDepth,c,l.sidebarDepth,o.sidebarDepth,1].find(t=>void 0!==t),b=l.displayAllHeaders||o.displayAllHeaders;if("auto"===u.type)return[d,r(t,u.children,u.basePath,a,f)];if((h||b)&&u.headers&&!i.d.test(u.path)){return[d,r(t,Object(i.c)(u.headers),u.path,a,f)]}return d}},o=(n(254),n(14)),l=Object(o.a)(a,void 0,void 0,!1,null,null,null);e.default=l.exports},260:function(t,e,n){"use strict";n(249)},265:function(t,e,n){"use strict";n(252)},266:function(t,e,n){},267:function(t,e,n){"use strict";n.r(e);var i=n(256),s=n(241),r={name:"NavLinks",components:{NavLink:n(243).default,DropdownLink:i.default},computed:{userNav(){return this.$themeLocaleConfig.nav||this.$site.themeConfig.nav||[]},nav(){const{locales:t}=this.$site;if(t&&Object.keys(t).length>1){const e=this.$page.path,n=this.$router.options.routes,i=this.$site.themeConfig.locales||{},s={text:this.$themeLocaleConfig.selectText||"Languages",ariaLabel:this.$themeLocaleConfig.ariaLabel||"Select language",items:Object.keys(t).map(s=>{const r=t[s],a=i[s]&&i[s].label||r.lang;let o;return r.lang===this.$lang?o=e:(o=e.replace(this.$localeConfig.path,s),n.some(t=>t.path===o)||(o=s)),{text:a,link:o}})};return[...this.userNav,s]}return this.userNav},userLinks(){return(this.nav||[]).map(t=>Object.assign(Object(s.j)(t),{items:(t.items||[]).map(s.j)}))},repoLink(){const{repo:t}=this.$site.themeConfig;return t?/^https?:/.test(t)?t:"https://github.com/"+t:null},repoLabel(){if(!this.repoLink)return;if(this.$site.themeConfig.repoLabel)return this.$site.themeConfig.repoLabel;const t=this.repoLink.match(/^https?:\/\/[^/]+/)[0],e=["GitHub","GitLab","Bitbucket"];for(let n=0;n")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetCurrentSourceto")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("particleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetNumberofSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetPosDist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetCentreCoords")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("G4ThreeVector")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5.0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("cm"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetAngDist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetAngDistType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"iso"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetEneDist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetEnergyDisType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Mono"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetEneDist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetMonoEnergy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("MeV"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetParticleDefinition")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("G4Neutron")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("NeutronDefinition")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Point source")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetPosDist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetPosDisType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Point"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Second particle source")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("AddaSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetCurrentSourceto")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("particleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetNumberofSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetPosDist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetCentreCoords")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("G4ThreeVector")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5.0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("cm"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetAngDist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetAngDistType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"iso"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetEneDist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetEnergyDisType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Mono"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetEneDist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetMonoEnergy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("MeV"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetParticleDefinition")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("G4Proton")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ProtonDefinition")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Plane source")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetPosDist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetPosDisType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Plane"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetPosDist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetPosDisShape")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Circle"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nparticleSource"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetCurrentSource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetPosDist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetRadius")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("cm"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("mac文件内:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("/gps/source/0/intensity "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("500")]),t._v("\n/gps/source/1/intensity "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/104.18a97c2e.js b/assets/js/104.18a97c2e.js new file mode 100644 index 0000000..de0cb78 --- /dev/null +++ b/assets/js/104.18a97c2e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[104],{464:function(a,t,s){"use strict";s.r(t);var e=s(14),n=Object(e.a)({},(function(){var a=this,t=a._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[t("h1",{attrs:{id:"_2023-06-14-geant4各版本的安装"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2023-06-14-geant4各版本的安装"}},[a._v("#")]),a._v(" 2023.06.14-Geant4各版本的安装")]),a._v(" "),t("h2",{attrs:{id:"安装依赖"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#安装依赖"}},[a._v("#")]),a._v(" 安装依赖")]),a._v(" "),t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[t("span",{pre:!0,attrs:{class:"token function"}},[a._v("sudo")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("apt-get")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-y")]),a._v(" build-essential\n"),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("sudo")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("apt-get")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-y")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("wget")]),a._v("\n// "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("sudo")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("apt-get")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-y")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("aptitude")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("sudo")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("apt-get")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-y")]),a._v(" cmake libx11-dev libxext-dev libxtst-dev libxrender-dev libxmu-dev libxmuu-dev libhdf5-serial-dev hdf5-tools\n"),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("sudo")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("apt-get")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-y")]),a._v(" libexpat1-dev libxerces-c-dev libxt-dev libmotif-dev\n"),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("sudo")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("apt")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" qt5* qt6* libqt5opengl5-dev\n")])])]),t("h2",{attrs:{id:"下载安装geant4"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#下载安装geant4"}},[a._v("#")]),a._v(" 下载安装Geant4")]),a._v(" "),t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[t("span",{pre:!0,attrs:{class:"token function"}},[a._v("mkdir")]),a._v(" Geant4_11.1.1\n"),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("wget")]),a._v(" https://geant4-data.web.cern.ch/releases/geant4-v11.1.1.tar.gz\n// https://gitlab.cern.ch/geant4/geant4/-/archive/v10.5.1/geant4-v10.5.1.tar.gz\n"),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("tar")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-xzvf")]),a._v(" geant4-v11.1.1.tar.gz\n\n"),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("mkdir")]),a._v(" build\n"),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("cd")]),a._v(" build\ncmake "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-DCMAKE_INSTALL_PREFIX")]),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("/home/tiancheng/Geant4_11.1.1 /home/tiancheng/geant4-v11.1.1\ncmake "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-DGEANT4_INSTALL_DATA")]),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("ON "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-DGEANT4_BUILD_MULTITHREADED")]),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("ON "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-DGEANT4_USE_GDML")]),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("ON "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-DGEANT4_USE_QT")]),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("ON "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-DGEANT4_USE_OPENGL_X11")]),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("ON "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-DGEANT4_USE_RAYTRACER_X11")]),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("ON "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-DGEANT4_USE_NETWORKDAWN")]),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("ON "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-DGEANT4_USE_XM")]),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("ON "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-DGEANT4_USE_NETWORKVRML")]),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("ON "),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(".")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("make")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-jN")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("make")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v("\n"),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("source")]),a._v(" /root/Geant4/home/geant4/bin/geant4.sh\n"),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("source")]),a._v(" /root/Geant4/home/geant4/share/Geant4/geant4make/geant4make.sh\n")])])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/105.836e5612.js b/assets/js/105.836e5612.js new file mode 100644 index 0000000..0a3d583 --- /dev/null +++ b/assets/js/105.836e5612.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[105],{465:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2023-08-28-geant4-自定义-physicslist"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2023-08-28-geant4-自定义-physicslist"}},[t._v("#")]),t._v(" 2023.08.28-Geant4 自定义 PhysicsList")]),t._v(" "),s("h2",{attrs:{id:"一个最简单的例子"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#一个最简单的例子"}},[t._v("#")]),t._v(" 一个最简单的例子")]),t._v(" "),s("h3",{attrs:{id:"main"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#main"}},[t._v("#")]),t._v(" "),s("code",[t._v("main")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"G4RunManager.hh"')])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 初始化 run manager")]),t._v("\n G4RunManager runManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 设置物理列表")]),t._v("\n runManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetUserInitialization")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SimplePhysicsList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ... 其他初始化和设置")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 开始模拟")]),t._v("\n runManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("BeamOn")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"自定义物理列表类"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#自定义物理列表类"}},[t._v("#")]),t._v(" 自定义物理列表类:")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"G4VModularPhysicsList.hh"')])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"G4ParticleDefinition.hh"')])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"G4ProcessManager.hh"')])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"G4Proton.hh"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 或其他你关心的粒子")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimplePhysicsList")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token base-clause"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("G4VModularPhysicsList")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ConstructParticle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 创建或获取粒子类型")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("G4Proton")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ProtonDefinition")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ... 其他粒子")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ConstructProcess")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 获取粒子的过程管理器")]),t._v("\n G4ProcessManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" pManager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("G4Proton")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Proton")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetProcessManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 添加自定义的碰撞过程")]),t._v("\n pManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("AddDiscreteProcess")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SimpleCollisionProcess")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourCustomPhysicsList")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ConstructProcess")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ... other processes")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("auto")]),t._v(" particleIterator "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetParticleIterator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n particleIterator"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reset")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("particleIterator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n G4ParticleDefinition"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" particle "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" particleIterator"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n G4ProcessManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" pmanager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" particle"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetProcessManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourCustomProcess")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("IsApplicable")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("particle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n pmanager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("AddDiscreteProcess")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("YourCustomProcess")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"自定义碰撞过程类"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#自定义碰撞过程类"}},[t._v("#")]),t._v(" 自定义碰撞过程类:")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"G4VDiscreteProcess.hh"')])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"G4Step.hh"')])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"G4VParticleChange.hh"')])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleCollisionProcess")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token base-clause"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("G4VDiscreteProcess")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n G4VParticleChange"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("PostStepDoIt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" G4Track"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" track"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" G4Step"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*step*/")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 这里执行碰撞后的粒子状态更改")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 例如,改变动量、能量等")]),t._v("\n\n aParticleChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Initialize")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("track"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// aParticleChange.SetXXX(...); // 设置粒子状态")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("aParticleChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n G4double "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetMeanFreePath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" G4Track"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*track*/")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" G4double "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*previousStepSize*/")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" G4ForceCondition"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*condition*/")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返回这个过程的平均自由路径")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 这里只返回一个固定的值作为示例")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" cm"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"_1-关于必须重新定义的函数"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-关于必须重新定义的函数"}},[t._v("#")]),t._v(" 1. 关于必须重新定义的函数:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("PostStepDoIt")]),t._v(": 这个函数用于描述在一步运动后粒子的状态如何改变。这通常是必须要重写的。")]),t._v(" "),s("li",[s("code",[t._v("GetMeanFreePath")]),t._v(": 这个函数返回给定粒子在特定条件下的平均自由路径。这通常也需要重写以适应你的模型。")])]),t._v(" "),s("p",[t._v("这两个函数通常是最主要需要重写的。然而,根据你的具体需求,有时还可能需要重写其他函数,比如:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("AlongStepDoIt")]),t._v(": 如果你从 "),s("code",[t._v("G4VContinuousProcess")]),t._v(" 继承,这个函数用于描述粒子在一步中如何连续地改变。")]),t._v(" "),s("li",[s("code",[t._v("IsApplicable")]),t._v(": 这个函数决定这个过程是否应用于某个粒子。")]),t._v(" "),s("li",[s("code",[t._v("AtRestDoIt")]),t._v(": 用于描述一个静止粒子如何起始一个新的过程(如果适用)。")]),t._v(" "),s("li",[s("code",[t._v("StartTracking")]),t._v("、"),s("code",[t._v("EndTracking")]),t._v(": 这些是在粒子轨迹开始和结束时被调用的。")])]),t._v(" "),s("h2",{attrs:{id:"_2-关于-aparticlechange"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-关于-aparticlechange"}},[t._v("#")]),t._v(" 2. 关于 "),s("code",[t._v("aParticleChange")]),t._v(":")]),t._v(" "),s("p",[s("code",[t._v("aParticleChange")]),t._v(" 是一个 "),s("code",[t._v("G4VParticleChange")]),t._v(" 对象,它用于保存由这个过程产生的粒子状态改变。当 "),s("code",[t._v("PostStepDoIt")]),t._v(" 被调用时,你需要用它来设置新的粒子状态(如位置、动量、能量等)。这个对象通常是 "),s("code",[t._v("G4VDiscreteProcess")]),t._v(" 或 "),s("code",[t._v("G4VContinuousProcess")]),t._v(" 的成员变量,由基类初始化。")]),t._v(" "),s("p",[t._v("例如,你可以这样设置新的动量方向:")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[t._v("aParticleChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ProposeMomentumDirection")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("newDirection"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("或者,设置新的能量:")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[t._v("aParticleChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ProposeEnergy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("newEnergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("这样,在 "),s("code",[t._v("PostStepDoIt")]),t._v(" 函数返回后,Geant4 会用 "),s("code",[t._v("aParticleChange")]),t._v(" 中的信息来更新粒子状态。")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("aParticleChange.Initialize(track)")])])]),t._v(" "),s("p",[t._v("这个函数初始化 "),s("code",[t._v("aParticleChange")]),t._v(" 对象,使其包含给定轨迹("),s("code",[t._v("track")]),t._v(")的当前状态。这通常是你开始修改粒子状态之前的第一步。")]),t._v(" "),s("h2",{attrs:{id:"_3-getmeanfreepath-的作用"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-getmeanfreepath-的作用"}},[t._v("#")]),t._v(" 3. "),s("code",[t._v("GetMeanFreePath")]),t._v(" 的作用")]),t._v(" "),s("p",[s("code",[t._v("GetMeanFreePath")]),t._v(" 函数是用来告知 Geant4 在多长的距离后应该调用 "),s("code",[t._v("PostStepDoIt")]),t._v(' 函数的。简单地说,这个函数决定了一个物理过程发生的"频率"或者概率。在每一步结束后,Geant4 会评估所有的离散过程来看哪一个将被下一个执行,这一决定是基于每个过程的平均自由路径和其他概率性因素来的。')]),t._v(" "),s("p",[t._v("比如说,如果 "),s("code",[t._v("GetMeanFreePath")]),t._v(" 返回了一个很小的数值,这表示该过程非常可能在下一步就会发生。相反地,一个大的返回值意味着该过程相对较不可能发生。")]),t._v(" "),s("h2",{attrs:{id:"_4-多物理过程情形"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-多物理过程情形"}},[t._v("#")]),t._v(" 4. 多物理过程情形")]),t._v(" "),s("h3",{attrs:{id:"说明"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#说明"}},[t._v("#")]),t._v(" 说明:")]),t._v(" "),s("p",[t._v('在 Geant4 中,一粒子的轨迹(track)被分解为多个连续的 "步"(steps)。在每一步结束时,Geant4 会评估所有应用于该粒子类型的离散物理过程(例如电离、散射等)。这个评估的目的是为了决定下一步应该执行哪个过程。')]),t._v(" "),s("p",[t._v("假设我们有三个不同的物理过程 A、B 和 C。每一个都有自己的 "),s("code",[t._v("GetMeanFreePath")]),t._v(" 函数,这个函数返回一个距离值,该值表示粒子在该距离后大概会经历该过程。")]),t._v(" "),s("ol",[s("li",[t._v("计算平均自由路径: 在每一步的结束,Geant4 会调用所有过程的 "),s("code",[t._v("GetMeanFreePath")]),t._v(" 函数,获得 A、B、C 的平均自由路径,分别记作"),s("em",[t._v("λA")]),t._v(","),s("em",[t._v("λB")]),t._v(","),s("em",[t._v("λC")]),t._v("。")]),t._v(" "),s("li",[t._v("概率性决策: 基于这些平均自由路径和其他概率性因素,Geant4 会计算哪一个过程应该下一个被执行。一种简单的方式是,选择平均自由路径最小的那个过程,因为它更可能发生。但实际的算法可能更加复杂,并考虑其他因素。")]),t._v(" "),s("li",[t._v("执行过程: 选定了要执行的过程(比如说是过程 A)后,Geant4 就会调用 A 的 "),s("code",[t._v("PostStepDoIt")]),t._v(" 函数来实际模拟该过程,更新粒子的状态。")]),t._v(" "),s("li",[t._v("进入下一步: 根据 "),s("code",[t._v("PostStepDoIt")]),t._v(" 的结果,粒子的状态被更新,然后开始下一步的模拟。")])]),t._v(" "),s("p",[t._v("这样,通过在每一步结束时动态评估哪一个过程应该被执行,Geant4 能够模拟一个粒子轨迹中多种物理过程的竞争和相互作用。这是为什么需要定义 "),s("code",[t._v("GetMeanFreePath")]),t._v(" 的原因:它为这个概率性决策提供了必要的信息。")]),t._v(" "),s("h3",{attrs:{id:"示例"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#示例"}},[t._v("#")]),t._v(" 示例:")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"G4VDiscreteProcess.hh"')])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"G4Step.hh"')])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"G4ParticleChange.hh"')])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SimpleElasticScattering")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token base-clause"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("G4VDiscreteProcess")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ... Constructors, destructor, etc.")]),t._v("\n\n G4VParticleChange"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("PostStepDoIt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" G4Track"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" track"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" G4Step"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n aParticleChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Initialize")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("track"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ... Do some calculations for scattering, modify aParticleChange")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("aParticleChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n G4double "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetMeanFreePath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" G4Track"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" G4double"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" G4ForceCondition"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Just a constant mean free path for demonstration")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EnergyAbsorption")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token base-clause"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("G4VDiscreteProcess")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ... Constructors, destructor, etc.")]),t._v("\n\n G4VParticleChange"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("PostStepDoIt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" G4Track"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" track"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" G4Step"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n aParticleChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Initialize")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("track"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ... Do some calculations for energy absorption, modify aParticleChange")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("aParticleChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n G4double "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetMeanFreePath")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" G4Track"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" G4double"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" G4ForceCondition"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Another constant mean free path for demonstration")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在物理列表中添加:")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"MyPhysicsList.hh"')])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"G4ParticleDefinition.hh"')])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"G4ProcessManager.hh"')])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyPhysicsList")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ConstructProcess")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ... Other setup code")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get the process manager for ions (or whatever particle you're interested in)")]),t._v("\n G4ParticleDefinition"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" ion "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("G4Ion")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("IonDefinition")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n G4ProcessManager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" pmanager "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ion"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetProcessManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Add the custom processes")]),t._v("\n SimpleElasticScattering"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" elasticScattering "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("SimpleElasticScattering")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n EnergyAbsorption"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" energyAbsorption "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("EnergyAbsorption")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n pmanager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("AddDiscreteProcess")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("elasticScattering"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n pmanager"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("AddDiscreteProcess")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("energyAbsorption"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ... Other code for adding standard processes")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h1",{attrs:{id:"蒙特卡洛程序嵌入"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#蒙特卡洛程序嵌入"}},[t._v("#")]),t._v(" 蒙特卡洛程序嵌入")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[t._v("G4VParticleChange"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("YourProcess")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("PostStepDoIt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" G4Track"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" track"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" G4Step"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n aParticleChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Initialize")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("track"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Execute your methods")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("FreeLength")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ChoseCollisionAtom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("EleEnergyLoss")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("EmissionAngle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("IonNewCondition")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Update particle state in aParticleChange (not shown)")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Check whether the ion is still under processing")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" IonFlag "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("OutOrNot")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("IonFlag"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If IonFlag is changed by OutOrNot() to indicate the ion's journey is done,")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// you might need additional logic here to finalize the ion's record.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("aParticleChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在 Geant4 中,如果一个粒子已经不再需要进一步处理,你通常需要更新这个粒子的状态,以便 Geant4 知道不再需要追踪这个粒子。这通常是通过设置 "),s("code",[t._v("G4Track")]),t._v(" 的状态来完成的,具体来说,是通过 "),s("code",[t._v("aParticleChange")]),t._v(" 对象(这通常是 "),s("code",[t._v("G4VParticleChange")]),t._v(" 类型或其子类)。")]),t._v(" "),s("p",[t._v("一个简单的例子:")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("some_condition"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Replace this with your actual stopping condition")]),t._v("\n aParticleChange"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ProposeTrackStatus")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("fStopAndKill"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),s("p",[t._v("在这里,"),s("code",[t._v("fStopAndKill")]),t._v(" 是一个枚举值,表示该粒子应停止并被“杀死”,即不再被追踪。其他可用的状态还包括 "),s("code",[t._v("fStopButAlive")]),t._v("(停止但仍然“存活”,可能在以后的时间步重新开始)和 "),s("code",[t._v("fAlive")]),t._v("(继续运动)。")]),t._v(" "),s("p",[t._v("如果在 "),s("code",[t._v("PostStepDoIt")]),t._v(" 函数中确定粒子需要被停止,你可以通过上面的代码片段来告诉 Geant4。这样,Geant4 在执行完该步骤后就会知道不再需要对这个粒子进行后续计算。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/106.d6888e66.js b/assets/js/106.d6888e66.js new file mode 100644 index 0000000..47b9933 --- /dev/null +++ b/assets/js/106.d6888e66.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[106],{468:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2023-09-05-c-trim-程序"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2023-09-05-c-trim-程序"}},[t._v("#")]),t._v(" 2023.09.05-C++ Trim 程序")]),t._v(" "),s("h2",{attrs:{id:"每个粒子端到端的计算"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#每个粒子端到端的计算"}},[t._v("#")]),t._v(" 每个粒子端到端的计算")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PKU_MC")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("DoOneIon")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" IonFlag"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// init the orginal paramters for current ions")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("InitialIon")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tIonFlag "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("IonFlag "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// the current ion are under processing")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("FreeLength")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ChoseCollisionAtom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("EleEnergyLoss")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("EmissionAngle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("IonNewCondition")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ProcessRecorder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("OutOrNot")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("IonFlag"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// end of one ions")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("CollisionRecording")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add the results of this ion to the recording arraies")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"initialion"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialion"}},[t._v("#")]),t._v(" "),s("code",[t._v("InitialIon()")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PKU_MC")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("InitialIon")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n\tE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IonEnergyEV"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Energy")]),t._v("\n\tCOSIN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cos")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ALPHA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// direction to the normal")]),t._v("\n\tSINY "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" COSIN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\tSINE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sin")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ALPHA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tCOSY "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" SINE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\tCurrentLayer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tIonWayLength "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tIonCollisionNo "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tX "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tY "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"具体计算"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#具体计算"}},[t._v("#")]),t._v(" 具体计算")]),t._v(" "),s("h3",{attrs:{id:"_1-freelength"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-freelength"}},[t._v("#")]),t._v(" 1. "),s("code",[t._v("FreeLength()")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PKU_MC")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("FreeLength")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("float")]),t._v(" tempvalue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// when the ion energy is high")]),t._v("\n\tIonCollisionNo"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tReducedCollEnergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" E "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" F"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tEEG "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sqrt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ReducedCollEnergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" EPSDG"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tPMAX"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("EEG "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sqrt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("EEG"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.125")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("EEG"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tIonFreeLength "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("PI "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" PMAX"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" PMAX"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" ARHO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// when the ion enrgy is low")]),t._v("\n\n\ttempvalue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("PKURandom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("IonCollisionNo "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\tIonFreeLength "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tempvalue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("AMIN1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("IonFreeLength"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" channelwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" IonFreeLength"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[s("code",[t._v("ReducedCollEnergy")]),t._v(': 同样表示与被选中的原子碰撞后的"减少的"能量。')]),t._v(" "),s("li",[s("code",[t._v("E")]),t._v(": 未定义在这个函数中,但似乎是离子或粒子的能量。")]),t._v(" "),s("li",[s("code",[t._v("F[CurrentLayer]")]),t._v(": 当前层对应的一个因子,用于计算"),s("code",[t._v("ReducedCollEnergy")]),t._v("。")]),t._v(" "),s("li",[s("code",[t._v("EEG")]),t._v(": 一个与"),s("code",[t._v("ReducedCollEnergy")]),t._v("和"),s("code",[t._v("EPSDG[CurrentLayer]")]),t._v("有关的参数。")]),t._v(" "),s("li",[s("code",[t._v("EPSDG[CurrentLayer]")]),t._v(": 与当前层有关的一个常数或参数。")]),t._v(" "),s("li",[s("code",[t._v("PMAX[CurrentLayer]")]),t._v(": 当前层中的最大动量或概率。")]),t._v(" "),s("li",[s("code",[t._v("A[CurrentLayer]")]),t._v(": 当前层对应的一个参数或常数。")]),t._v(" "),s("li",[s("code",[t._v("IonFreeLength")]),t._v(": 离子的自由路径长度。")]),t._v(" "),s("li",[s("code",[t._v("ARHO[CurrentLayer]")]),t._v(": 当前层的密度或者与密度相关的一个参数。")]),t._v(" "),s("li",[s("code",[t._v("channelwidth")]),t._v(": 一个与离子自由路径长度有关的参数或者常数。")])]),t._v(" "),s("h3",{attrs:{id:"使用到的变量"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用到的变量"}},[t._v("#")]),t._v(" 使用到的变量:")]),t._v(" "),s("p",[s("code",[t._v("E")]),t._v(", "),s("code",[t._v("F")]),t._v(", "),s("code",[t._v("EPSDG")]),t._v(", "),s("code",[t._v("A")]),t._v(", "),s("code",[t._v("ARHO")])]),t._v(" "),s("h3",{attrs:{id:"输出-改变-的变量"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#输出-改变-的变量"}},[t._v("#")]),t._v(" 输出(改变)的变量:")]),t._v(" "),s("p",[s("code",[t._v("IonCollisionNo")]),t._v(", "),s("code",[t._v("ReducedCollEnergy")]),t._v(", "),s("code",[t._v("IonFreeLength")]),t._v(", "),s("code",[t._v("PMAX")])]),t._v(" "),s("h3",{attrs:{id:"_2-chosecollisionatom"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-chosecollisionatom"}},[t._v("#")]),t._v(" 2. "),s("code",[t._v("ChoseCollisionAtom()")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PKU_MC")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ChoseCollisionAtom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" MaxElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("float")]),t._v(" tempRandValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\ttempRandValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("PKURandom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tempRandValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\ttempRandValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("PKURandom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\tP "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" PMAX"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sqrt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tempRandValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tMaxElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" LayerElementNo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// decided which kinds of atoms to be knocked!")]),t._v("\n\n\ttempRandValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("PKURandom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CurrentElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" CurrentElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" MaxElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" CurrentElement"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\ttempRandValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tempRandValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" TargetAtomConc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tempRandValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tempRandValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\tCurrentElement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" LayerElementNo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\tReducedCollEnergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" FItemp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" E"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tB "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" P "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" ScreenLen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" TargetAtomNumber"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[s("code",[t._v("P")]),t._v(": 未定义在这个函数中,但在函数内部进行了计算。可能是与粒子动量或概率有关的一个参数。")]),t._v(" "),s("li",[s("code",[t._v("PMAX[CurrentLayer]")]),t._v(": 当前层中的最大动量或概率。")]),t._v(" "),s("li",[s("code",[t._v("CurrentLayer")]),t._v(": 当前所在的层编号。")]),t._v(" "),s("li",[s("code",[t._v("LayerElementNo[CurrentLayer]")]),t._v(": 当前层包含的元素(原子)种类数量。")]),t._v(" "),s("li",[s("code",[t._v("CurrentElement")]),t._v(": 当前正在考虑的元素(原子)的编号。")]),t._v(" "),s("li",[s("code",[t._v("TargetAtomConc[CurrentLayer][CurrentElement]")]),t._v(": 当前层和元素对应的原子浓度或概率。")]),t._v(" "),s("li",[s("code",[t._v("ReducedCollEnergy")]),t._v(': 表示与被选中的原子碰撞后的"减少的"能量。')]),t._v(" "),s("li",[s("code",[t._v("FItemp[CurrentLayer][CurrentElement]")]),t._v(": 与当前层和元素有关的一个因子,用于计算"),s("code",[t._v("ReducedCollEnergy")]),t._v("。")]),t._v(" "),s("li",[s("code",[t._v("E")]),t._v(": 未定义在这个函数中,但用于计算"),s("code",[t._v("ReducedCollEnergy")]),t._v(",可能是粒子的能量。")]),t._v(" "),s("li",[s("code",[t._v("B")]),t._v(": 另一个与碰撞有关的参数。")]),t._v(" "),s("li",[s("code",[t._v("ScreenLen[CurrentLayer][CurrentElement]")]),t._v(": 与当前层和元素有关的一个参数,用于计算"),s("code",[t._v("B")]),t._v("。")]),t._v(" "),s("li",[s("code",[t._v("TargetAtomNumber[CurrentLayer][CurrentElement]")]),t._v(": 返回的是当前层和元素对应的目标原子的编号。")])]),t._v(" "),s("h3",{attrs:{id:"使用到的变量-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用到的变量-2"}},[t._v("#")]),t._v(" 使用到的变量:")]),t._v(" "),s("p",[s("code",[t._v("PMAX")]),t._v(", "),s("code",[t._v("FItemp")]),t._v(", "),s("code",[t._v("E")]),t._v(", "),s("code",[t._v("ScreenLen")])]),t._v(" "),s("h3",{attrs:{id:"改变的变量"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#改变的变量"}},[t._v("#")]),t._v(" 改变的变量:")]),t._v(" "),s("p",[s("code",[t._v("P")]),t._v(", "),s("code",[t._v("ReducedCollEnergy")]),t._v(", "),s("code",[t._v("B")])]),t._v(" "),s("h2",{attrs:{id:"_3-eleenergyloss"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-eleenergyloss"}},[t._v("#")]),t._v(" 3. "),s("code",[t._v("EleEnergyLoss()")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PKU_MC")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("EleEnergyLoss")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" Ion_Se"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\tIE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("E "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" IonEnergyKeV "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v(".5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("IE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\tSEE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" SE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("IE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("E "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" IonEnergyKeV"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\tSEE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" SE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sqrt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("E "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" IonEnergyKeV"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tDEE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IonFreeLength "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" SEE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tIon_Se "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" DEE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" Ion_Se"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[s("code",[t._v("double Ion_Se")]),t._v(": 存储电子或离子的能量损失。")]),t._v(" "),s("li",[s("code",[t._v("IE")]),t._v(": 一个与离子或粒子能量"),s("code",[t._v("E")]),t._v("有关的整数变量。")]),t._v(" "),s("li",[s("code",[t._v("E")]),t._v(": 离子或粒子的能量,未在此函数内定义。")]),t._v(" "),s("li",[s("code",[t._v("IonEnergyKeV")]),t._v(": 离子能量的一个特定单位(千电子伏特,KeV)。")]),t._v(" "),s("li",[s("code",[t._v("SEE")]),t._v(": 与离子或粒子能量损失有关的一个参数。")]),t._v(" "),s("li",[s("code",[t._v("SE[CurrentLayer][IE]")]),t._v(": 当前层和能量级对应的能量损失率。")]),t._v(" "),s("li",[s("code",[t._v("DEE")]),t._v(": 实际能量损失,是"),s("code",[t._v("IonFreeLength")]),t._v("(离子的自由路径长度)和"),s("code",[t._v("SEE")]),t._v("(能量损失率)的乘积。")])]),t._v(" "),s("h3",{attrs:{id:"使用的变量"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用的变量"}},[t._v("#")]),t._v(" 使用的变量:")]),t._v(" "),s("p",[s("code",[t._v("E")]),t._v(", "),s("code",[t._v("IonEnergyKeV")]),t._v(", "),s("code",[t._v("SE")]),t._v(", "),s("code",[t._v("IonFreeLength")])]),t._v(" "),s("h3",{attrs:{id:"改变的变量-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#改变的变量-2"}},[t._v("#")]),t._v(" 改变的变量:")]),t._v(" "),s("p",[s("code",[t._v("DEE")]),t._v(",")]),t._v(" "),s("h2",{attrs:{id:"_4-emissionangle"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-emissionangle"}},[t._v("#")]),t._v(" 4. "),s("code",[t._v("EmissionAngle()")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PKU_MC")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("EmissionAngle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" AngleValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" R"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Q"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// using the magic method")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ReducedCollEnergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\tR "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tRR "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.7")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ReducedCollEnergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RR "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\tRR "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.7")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ReducedCollEnergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" RR"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RR "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t\t\tR "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RR"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("do")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\tEX1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.18175")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("exp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.1998")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" R"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\tEX2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.50986")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("exp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.94229")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" R"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\tEX3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.28022")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("exp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.4029")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" R"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\tEX4 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.028171")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("exp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.20162")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" R"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\tV "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("EX1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" EX2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" EX3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" EX4"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" R"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\tV1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("V "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.1998")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" EX1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.94229")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" EX2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.4092")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" EX3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.20162")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" EX4"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" R"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t\t\tFR "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" R "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" V "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" R "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" ReducedCollEnergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" R"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\tFR1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("R "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" R"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("V "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" V1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" R"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" ReducedCollEnergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\tQ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" FR "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" FR1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\tR "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" R "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" Q"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fabs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Q "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" R"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.001")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t\tROC "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ReducedCollEnergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" V"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" V1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tSQE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sqrt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ReducedCollEnergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tCC "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.011615")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" SQE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0071222")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" SQE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tAA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" ReducedCollEnergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.99229")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" SQE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" CC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tFF "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sqrt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("AA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" AA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" AA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9.3066")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" ReducedCollEnergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("14.813")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" ReducedCollEnergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tDELTA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("R "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" AA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" FF "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("FF "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tCO "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" DELTA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" ROC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("R "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" ROC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tC2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" CO "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" CO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tS2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" C2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("S2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t\t"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\n%d %lf\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ElapsedIonNo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tCT "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" C2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tST "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sqrt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" CT "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" CT"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// using the RusefScattering methods")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\tS2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" ReducedCollEnergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" ReducedCollEnergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("S2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t\t"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\n%d %lf\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ElapsedIonNo"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tC2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" S2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tCT "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" C2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\tST "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sqrt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" CT "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" CT"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\tAngleValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("acos")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CT"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" AngleValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"使用的变量-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用的变量-2"}},[t._v("#")]),t._v(" 使用的变量:")]),t._v(" "),s("p",[s("code",[t._v("ReducedCollEnergy")]),t._v(", "),s("code",[t._v("B")]),t._v(",")]),t._v(" "),s("h3",{attrs:{id:"改变的变量-3"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#改变的变量-3"}},[t._v("#")]),t._v(" 改变的变量:")]),t._v(" "),s("p",[s("code",[t._v("RR")]),t._v(", "),s("code",[t._v("ST")]),t._v(", "),s("code",[t._v("S2")]),t._v(", "),s("code",[t._v("CT")]),t._v(",")]),t._v(" "),s("h2",{attrs:{id:"_5-ionnewcondition"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-ionnewcondition"}},[t._v("#")]),t._v(" 5. "),s("code",[t._v("IonNewCondition()")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PKU_MC")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("IonNewCondition")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("MAX")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" X1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// MAX is not OK!!!!!!!!!!!!!!!!!!!!!!!!!")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("float")]),t._v(" tempvalue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\tDEN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" recoilfactor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" S2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" E"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" E "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" DEN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" DEE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("DEE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" MAX"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\tMAX "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" DEE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tIonWayLength "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IonWayLength "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" IonFreeLength "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" DistanceNuclear"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\tX "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" X "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("IonFreeLength "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" DistanceNuclear"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" COSIN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tY "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Y "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("IonFreeLength "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" DistanceNuclear"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" COSY"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\tI "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("AMIN1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fabs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("X "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" channelwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tJ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("AMIN1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fabs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Y "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" channelwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ALPHA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Y "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\tJ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\ttempvalue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("PKURandom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tPHI "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" PI "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" tempvalue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\tPSI "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("atan")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ST "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CT "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" M1_to_M2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentElement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("PSI "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\tPSI "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" PSI "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" PI"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tX1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("COSIN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" COSY "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("SINE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" SINY "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fabs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("X1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\tX1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" X1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fabs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("X1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tDELTA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" PHI "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("acos")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("X1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\tCOSIN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" COSIN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cos")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("PSI"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" SINE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sin")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("PSI"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cos")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("PHI"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tCOSY "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" COSY "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cos")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("PSI"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" SINY "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sin")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("PSI"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cos")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("DELTA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\tSINY "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sqrt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" COSY "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" COSY"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\tSINE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sqrt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" COSIN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" COSIN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"使用的变量-3"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用的变量-3"}},[t._v("#")]),t._v(" 使用的变量:")]),t._v(" "),s("p",[s("code",[t._v("recoilfactor")]),t._v(", "),s("code",[t._v("DistanceNuclear")]),t._v(", "),s("code",[t._v("IonFreeLength")]),t._v(", "),s("code",[t._v("channelwidth")]),t._v(", "),s("code",[t._v("ALPHA")]),t._v(", "),s("code",[t._v("M1_to_M2")]),t._v(",")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("channelwidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\tchannelwidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.01")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" LayertoSurface"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// for recording, the total sample are dividied into 100 segment")]),t._v("\n")])])]),s("h3",{attrs:{id:"改变的变量-4"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#改变的变量-4"}},[t._v("#")]),t._v(" 改变的变量:")]),t._v(" "),s("p",[s("code",[t._v("DEN")]),t._v(", "),s("code",[t._v("E")]),t._v(", "),s("code",[t._v("IonWayLength")]),t._v(", "),s("code",[t._v("COSIN")]),t._v(", "),s("code",[t._v("COSY")]),t._v(", "),s("code",[t._v("X")]),t._v(", "),s("code",[t._v("Y")]),t._v(", "),s("code",[t._v("I")]),t._v(", "),s("code",[t._v("J")]),t._v(", "),s("code",[t._v("PHI")]),t._v(", "),s("code",[t._v("PSI")]),t._v(", "),s("code",[t._v("SINE")]),t._v(", "),s("code",[t._v("SINY")]),t._v(", "),s("code",[t._v("DELTA")]),t._v(",")]),t._v(" "),s("h2",{attrs:{id:"_6-processrecorder"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-processrecorder"}},[t._v("#")]),t._v(" 6. "),s("code",[t._v("ProcessRecorder()")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PKU_MC")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ProcessRecorder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" EPSD"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" EN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// total energy")]),t._v("\n\tMTOT"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("J"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MTOT"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("J"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" DEN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" DEE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// the nuclear energy loss treamting process")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("DEN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" DisEnergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\tPhoneEDis"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" PhoneEDis"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" DEN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\tEPSD "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" DamageEFract"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" DEN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Modified Kinchin-Pease model")]),t._v("\n\t\tEN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" DEN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" ElectronEFract"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("EPSD "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.4")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("EPSD"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.75")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.4")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("EPSD"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("6.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("EN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" DisEnergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t\tPhoneEDis"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" PhoneEDis"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" DEN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n\t\t\tMVAC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("J"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MVAC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("J"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\tIVAC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IVAC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("EN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//!!!!")]),t._v("\n\t\t\t\tRPHON"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RPHON"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" EN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" DisEnergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\t\t\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Multi-defect production!")]),t._v("\n\t\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("EN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.5")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" DisEnergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t\tMVAC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("J"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MVAC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("J"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.4")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" EN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" DisEnergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\t\tRPHON"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RPHON"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" DisEnergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.4")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" EN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\t\tRVAC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RVAC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.4")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" EN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" DisEnergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n\t\t\tMION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("J"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("J"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" DEN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" EN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\tRION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" DEN "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" EN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// eletric energy loss treating process")]),t._v("\n\tIonizatinEDis"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IonizatinEDis"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" DEE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\tMION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("J"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MION"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("I "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("J"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" DEE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"使用的变量-4"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用的变量-4"}},[t._v("#")]),t._v(" 使用的变量:")]),t._v(" "),s("p",[s("code",[t._v("I")]),t._v(", "),s("code",[t._v("J")]),t._v(", "),s("code",[t._v("DEN")]),t._v(", "),s("code",[t._v("DEE")]),t._v(", "),s("code",[t._v("DisEnergy")]),t._v(", "),s("code",[t._v("DamageEFract")]),t._v(", "),s("code",[t._v("ElectronEFract")]),t._v(",")]),t._v(" "),s("h3",{attrs:{id:"改变的变量-5"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#改变的变量-5"}},[t._v("#")]),t._v(" 改变的变量:")]),t._v(" "),s("p",[s("code",[t._v("MTOT")]),t._v(", "),s("code",[t._v("PhoneEDis")]),t._v(", "),s("code",[t._v("MVAC")]),t._v(", "),s("code",[t._v("IVAC")]),t._v(", "),s("code",[t._v("RPHON")]),t._v(", "),s("code",[t._v("RVAC")]),t._v(", "),s("code",[t._v("MION")]),t._v(", "),s("code",[t._v("RION")]),t._v(", "),s("code",[t._v("IonizatinEDis")]),t._v(",")]),t._v(" "),s("h2",{attrs:{id:"_7-outornot-int-ionflag"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_7-outornot-int-ionflag"}},[t._v("#")]),t._v(" 7. "),s("code",[t._v("OutOrNot(int &Ionflag)")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PKU_MC")]),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("OutOrNot")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("Ionflag"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("X "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\tIonflag "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("X "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" LayertoSurface"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t\tCurrentLayer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("X "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" LayertoSurface"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t\tCurrentLayer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n\t\t\tCurrentLayer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("X "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" LayertoSurface"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CurrentLayer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\tIonflag "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("E "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" StoppingEnergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\tIonflag "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"使用的变量-5"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用的变量-5"}},[t._v("#")]),t._v(" 使用的变量:")]),t._v(" "),s("p",[s("code",[t._v("X")]),t._v(", "),s("code",[t._v("LayertoSurface")]),t._v(", "),s("code",[t._v("StoppingEnergy")]),t._v(", "),s("code",[t._v("E")]),t._v(",")]),t._v(" "),s("h3",{attrs:{id:"改变的变量-6"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#改变的变量-6"}},[t._v("#")]),t._v(" 改变的变量:")]),t._v(" "),s("p",[s("code",[t._v("Ionflag")]),t._v(",")]),t._v(" "),s("h1",{attrs:{id:"一些注意点"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#一些注意点"}},[t._v("#")]),t._v(" 一些注意点")]),t._v(" "),s("ol",[s("li",[t._v("while 大循环内部其实就是一个 step,那这些 step 里使用到的变量应该是继承在 event 里一直用的,但是在 event 结束后这些变量在哪里初始化的")])])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/107.96a6fc7c.js b/assets/js/107.96a6fc7c.js new file mode 100644 index 0000000..2e04f6a --- /dev/null +++ b/assets/js/107.96a6fc7c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[107],{466:function(t,s,n){"use strict";n.r(s);var a=n(14),e=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2023-12-18-geant4自动化"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2023-12-18-geant4自动化"}},[t._v("#")]),t._v(" 2023.12.18-Geant4自动化")]),t._v(" "),s("h2",{attrs:{id:"_1-cmakelists-txt与run-mac的自动创建"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-cmakelists-txt与run-mac的自动创建"}},[t._v("#")]),t._v(" 1. "),s("code",[t._v("CMakeLists.txt")]),t._v("与"),s("code",[t._v("run.mac")]),t._v("的自动创建")]),t._v(" "),s("div",{staticClass:"language-python extra-class"},[s("pre",{pre:!0,attrs:{class:"language-python"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Python script to generate CMakeLists.txt and run.mac files with customizable parameters.")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_cmake_lists")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("project_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" executable_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" files_to_copy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token triple-quoted-string string"}},[t._v('"""\n Creates a CMakeLists.txt with customizable project and executable names.\n Args:\n - project_name: Name of the project\n - executable_name: Name of the executable\n - files_to_copy: List of files to copy\n Returns:\n - A string containing the contents of the CMakeLists.txt file\n """')]),t._v("\n cmake_template "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('f"""cmake_minimum_required(VERSION 3.16)\nproject(')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("project_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(')\n\n# default build type: Debug\nif(NOT CMAKE_BUILD_TYPE)\n set(CMAKE_BUILD_TYPE Debug)\nendif()\n\n#----------------------------------------------------------------------------\n# Find Geant4 package, activating all available UI and Vis drivers by default\n# You can set WITH_GEANT4_UIVIS to OFF via the command line or ccmake/cmake-gui\n# to build a batch mode only executable\n#\noption(WITH_GEANT4_UIVIS "Build example with Geant4 UI and Vis drivers" ON)\nif(WITH_GEANT4_UIVIS)\n find_package(Geant4 REQUIRED ui_all vis_all)\nelse()\n find_package(Geant4 REQUIRED)\nendif()\n\n#----------------------------------------------------------------------------\n# Setup Geant4 include directories and compile definitions\n# Setup include directory for this project\n#\ninclude_directories(${{PROJECT_SOURCE_DIR}}/include)\ninclude(${{Geant4_USE_FILE}})\n\n#----------------------------------------------------------------------------\n# Locate sources and headers for this project\n# NB: headers are included so they will show up in IDEs\n#\nfile(GLOB sources ${{PROJECT_SOURCE_DIR}}/src/*.cc)\nfile(GLOB headers ${{PROJECT_SOURCE_DIR}}/include/*.hh)\n\n#----------------------------------------------------------------------------\n# Add the executable, and link it to the Geant4 libraries\n#\nadd_executable(')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("executable_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" main.cc ${{sources}} ${{headers}})\n# target_compile_definitions(")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("executable_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" PUBLIC G4GEOM_USE_USOLIDS)\ntarget_link_libraries(")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("executable_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" ${{Geant4_LIBRARIES}})\n\n#----------------------------------------------------------------------------\n# Copy all scripts to the build directory, i.e. the directory in which we\n# build PKU_Trim_Geant4. This is so that we can run the executable directly\n# because it relies on these scripts being in the current working directory.\n#\nset(FILES_TO_COPY")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("files_to_copy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(')\nforeach(_script ${{FILES_TO_COPY}})\n configure_file(\n ${{PROJECT_SOURCE_DIR}}/${{_script}}\n ${{PROJECT_BINARY_DIR}}/${{_script}}\n COPYONLY\n )\nendforeach()\n"""')])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" cmake_template\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_run_mac")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n numberOfThreads"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" outputFileName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" iondefinition"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ionenergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" numberOfIons\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token triple-quoted-string string"}},[t._v('"""\n Creates a run.mac file with customizable parameters.\n Args:\n - numberOfThreads: Number of threads\n - outputFileName: Name of the output file\n - iondefinition: Ion definition (Z A Q E)\n - ionenergy: Ion energy\n - numberOfIons: Number of ions\n Returns:\n - A string containing the contents of the run.mac file\n """')]),t._v("\n run_mac_content "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('f"""# Macro file for the runtime control of the example\n\n# Minimal run.mac file for testing the application\n\n# Set number of threads\n# /run/numberOfThreads ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("numberOfThreads"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\n# /tracking/verbose 2\n\n# Initialize kernel\n/run/initialize\n/myApp/setOutputFileName ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("outputFileName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\n\n# Start simulation\n/gun/particle ion\n/gun/ion ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("iondefinition"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\n/gun/energy ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("ionenergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\n/run/beamOn ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("numberOfIons"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('\n"""')])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" run_mac_content\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" __name__ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"__main__"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Default values")]),t._v("\n project_name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"PKU_Trim_Geant4"')]),t._v("\n executable_name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"PKU_Trim_Geant4"')]),t._v("\n files_to_copy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token triple-quoted-string string"}},[t._v('"""\n init_vis.mac\n vis.mac\n run.mac\n scoef.data\n scoefh.data\n thresholds.txt\n """')]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Generate CMakeLists.txt")]),t._v("\n cmake_content "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" create_cmake_lists"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("project_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" executable_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" files_to_copy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n outputFileName "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"FinFET_p_2MeV.txt"')]),t._v("\n iondefinition "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1 1 0 0"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Z A Q E")]),t._v("\n ionenergy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2 MeV"')]),t._v("\n numberOfIons "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10000")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Generate run.mac")]),t._v("\n run_mac_content "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" create_run_mac"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" outputFileName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" iondefinition"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ionenergy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" numberOfIons\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Define the paths for the output files")]),t._v("\n cmake_lists_path "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./CMakeLists.txt"')]),t._v("\n run_mac_path "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./run.mac"')]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Write the contents to the respective files")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("with")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cmake_lists_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"w"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" cmake_file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n cmake_file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("write"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cmake_content"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("with")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("run_mac_path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"w"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" run_mac_file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n run_mac_file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("write"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("run_mac_content"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h3",{attrs:{id:"cmakelists-txt中"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#cmakelists-txt中"}},[t._v("#")]),t._v(" "),s("code",[t._v("CMakeLists.txt")]),t._v("中:")]),t._v(" "),s("p",[s("code",[t._v("executable_name")]),t._v(":生成的可执行文件名")]),t._v(" "),s("p",[s("code",[t._v("files_to_copy")]),t._v(":需要复制到build文件夹中的内容")]),t._v(" "),s("h3",{attrs:{id:"run-mac中"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#run-mac中"}},[t._v("#")]),t._v(" "),s("code",[t._v("run.mac")]),t._v("中")]),t._v(" "),s("p",[s("code",[t._v("numberOfThreads")]),t._v(":Geant4运行时使用的核心数(若使用Docker可不填)")]),t._v(" "),s("p",[s("code",[t._v("outputFileName")]),t._v(":Geant4产生的数据文件名")]),t._v(" "),s("p",[s("code",[t._v("iondefinition")]),t._v(":入射离子类型 # Z A Q E")]),t._v(" "),s("p",[s("code",[t._v("ionenergy")]),t._v(":入射离子能量")]),t._v(" "),s("p",[s("code",[t._v("numberOfIons")]),t._v(":入射离子数")]),t._v(" "),s("h2",{attrs:{id:"_2-docker自动化"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-docker自动化"}},[t._v("#")]),t._v(" 2. Docker自动化")]),t._v(" "),s("h3",{attrs:{id:"dockerfile"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#dockerfile"}},[t._v("#")]),t._v(" "),s("code",[t._v("Dockerfile")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-docker extra-class"},[s("pre",{pre:!0,attrs:{class:"language-docker"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 原单Geant4镜像")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token instruction"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("FROM")]),t._v(" outispku/geant4:v1")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 指定启动脚本")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token instruction"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("COPY")]),t._v(" start.sh /")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token instruction"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("RUN")]),t._v(" chmod +x /start.sh")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token instruction"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("RUN")]),t._v(" mkdir program")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token instruction"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("ENTRYPOINT")]),t._v(" ["),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/start.sh"')]),t._v("]")]),t._v("\n")])])]),s("h3",{attrs:{id:"start-sh"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#start-sh"}},[t._v("#")]),t._v(" "),s("code",[t._v("start.sh")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token shebang important"}},[t._v("#!/bin/bash")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Source Geant4 environment scripts")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("source")]),t._v(" /geant4/bin/geant4.sh\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("source")]),t._v(" /geant4/share/Geant4/geant4make/geant4make.sh\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 获取系统的线程数")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("NUM_THREADS")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expr")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$(")]),t._v("nproc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" - "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v(")")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" /program\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 构建命令")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("CMD_TO_ADD")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/run/numberOfThreads '),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$NUM_THREADS")]),t._v('"')]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 将命令添加到 run.mac 的第一行")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 注意不要重复添加")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sed")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-i")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1i '),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$CMD_TO_ADD")]),t._v('"')]),t._v(" ./run.mac\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 定义目录路径")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("BUILD_DIR")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/program/build"')]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 检查目录是否存在")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-d")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"'),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$BUILD_DIR")]),t._v('"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("then")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 如果目录存在,删除它")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("rm")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-rf")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"'),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$BUILD_DIR")]),t._v('"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fi")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 创建新的目录")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mkdir")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-p")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"'),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$BUILD_DIR")]),t._v('"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" build\ncmake "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("make")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-j")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$NUM_THREADS")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# PKU_Trim_Geant4 为程序名称(可执行文件),由CMakeLists.txt中的add_executable(PKU_Trim_Geant4 PKU_Trim_Geant4.cc)决定")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 使用前请修改")]),t._v("\n./PKU_Trim_Geant4 run.mac "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" /dev/null "),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[t._v("2")]),t._v(">>")]),t._v("error.txt\n")])])]),s("ol",[s("li",[s("p",[t._v("默认采用处理器最大核心数减1作为使用的核心数量")])]),t._v(" "),s("li",[s("p",[t._v("默认程序名为"),s("code",[t._v("PKU_Trim_Geant4")]),t._v(",若在CMakeLists中修改,请重新使用Dockerfile创建镜像")]),t._v(" "),s("div",{staticClass:"language-docker extra-class"},[s("pre",{pre:!0,attrs:{class:"language-docker"}},[s("code",[t._v("docker build -t outispku/geant4:v2 . \n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# -t 后为新镜像名")]),t._v("\n")])])])]),t._v(" "),s("li",[s("p",[t._v("创建共享文件路径并运行容器")]),t._v(" "),s("div",{staticClass:"language-docker extra-class"},[s("pre",{pre:!0,attrs:{class:"language-docker"}},[s("code",[t._v("docker run -v D:\\FinFET:/program --name geant4_program outispku/geant4:v2\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# -v 后为映射本地路径到容器内(共享项目文件)(program为容器内路径,请不要修改)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# --name 为容器名")]),t._v("\n")])])])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/108.9a2b3df8.js b/assets/js/108.9a2b3df8.js new file mode 100644 index 0000000..405f2a2 --- /dev/null +++ b/assets/js/108.9a2b3df8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[108],{467:function(t,r,e){"use strict";e.r(r);var a=e(14),s=Object(a.a)({},(function(){var t=this,r=t._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h1",{attrs:{id:"_2023-12-12-docker"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2023-12-12-docker"}},[t._v("#")]),t._v(" 2023.12.12-Docker")]),t._v(" "),r("h2",{attrs:{id:"_01-🎉-docker-简介和安装"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_01-🎉-docker-简介和安装"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Research/Research/2023.12.12-Docker/01.Docker 简介和安装.html"}},[t._v("01. 🎉 Docker 简介和安装")])],1),t._v(" "),r("h2",{attrs:{id:"_02-💻-docker-快速安装软件"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_02-💻-docker-快速安装软件"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Research/Research/2023.12.12-Docker/02.Docker 快速安装软件.html"}},[t._v("02. 💻 Docker 快速安装软件")])],1),t._v(" "),r("h2",{attrs:{id:"_03-💽-制作自己的镜像"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_03-💽-制作自己的镜像"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Research/Research/2023.12.12-Docker/03.制作自己的镜像.html"}},[t._v("03. 💽 制作自己的镜像")])],1),t._v(" "),r("h2",{attrs:{id:"_04-🥙-目录挂载"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_04-🥙-目录挂载"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Research/Research/2023.12.12-Docker/04.目录挂载.html"}},[t._v("04. 🥙 目录挂载")])],1),t._v(" "),r("h2",{attrs:{id:"_05-👨‍👦‍👦-多容器通信"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_05-👨‍👦‍👦-多容器通信"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Research/Research/2023.12.12-Docker/05.多容器通信.html"}},[t._v("05. 👨‍👦‍👦 多容器通信")])],1),t._v(" "),r("h2",{attrs:{id:"_06-🍁-docker-compose"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_06-🍁-docker-compose"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Research/Research/2023.12.12-Docker/06.Docker-Compose.html"}},[t._v("06. 🍁 Docker-Compose")])],1),t._v(" "),r("h2",{attrs:{id:"_07-🚚-发布和部署"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_07-🚚-发布和部署"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Research/Research/2023.12.12-Docker/07.发布和部署.html"}},[t._v("07. 🚚 发布和部署")])],1),t._v(" "),r("h2",{attrs:{id:"_08-🎯-备份和迁移数据"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_08-🎯-备份和迁移数据"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Research/Research/2023.12.12-Docker/08.备份和迁移数据.html"}},[t._v("08. 🎯 备份和迁移数据")])],1),t._v(" "),r("h2",{attrs:{id:"_2023-12-12-制作定制镜像"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2023-12-12-制作定制镜像"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Research/Research/2023.12.12-Docker/2023.12.12-制作定制镜像.html"}},[t._v("2023.12.12-制作定制镜像")])],1)])}),[],!1,null,null,null);r.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/109.acce4c89.js b/assets/js/109.acce4c89.js new file mode 100644 index 0000000..c4fce14 --- /dev/null +++ b/assets/js/109.acce4c89.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[109],{471:function(e,r,s){"use strict";s.r(r);var t=s(14),o=Object(t.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("h1",{attrs:{id:"_02-💻-docker-快速安装软件"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_02-💻-docker-快速安装软件"}},[e._v("#")]),e._v(" 02. 💻 Docker 快速安装软件")]),e._v(" "),r("h3",{attrs:{id:"直接安装的缺点"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#直接安装的缺点"}},[e._v("#")]),e._v(" 直接安装的缺点")]),e._v(" "),r("ul",[r("li",[e._v("安装麻烦,可能有各种依赖,运行报错。例如:WordPress,ElasticSearch,Redis,ELK")]),e._v(" "),r("li",[e._v("可能对 Windows 并不友好,运行有各种兼容问题,软件只支持 Linux 上跑")]),e._v(" "),r("li",[e._v("不方便安装多版本软件,不能共存。")]),e._v(" "),r("li",[e._v("电脑安装了一堆软件,拖慢电脑速度。")]),e._v(" "),r("li",[e._v("不同系统和硬件,安装方式不一样")])]),e._v(" "),r("blockquote",[r("p",[e._v("本文档课件配套 视频教程")])]),e._v(" "),r("h3",{attrs:{id:"docker-安装的优点"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#docker-安装的优点"}},[e._v("#")]),e._v(" Docker 安装的优点")]),e._v(" "),r("ul",[r("li",[e._v("一个命令就可以安装好,快速方便")]),e._v(" "),r("li",[e._v("有大量的镜像,可直接使用")]),e._v(" "),r("li",[e._v("没有系统兼容问题,Linux 专享软件也照样跑")]),e._v(" "),r("li",[e._v("支持软件多版本共存")]),e._v(" "),r("li",[e._v("用完就丢,不拖慢电脑速度")]),e._v(" "),r("li",[e._v("不同系统和硬件,只要安装好 Docker 其他都一样了,一个命令搞定所有")])]),e._v(" "),r("h3",{attrs:{id:"演示-docker-安装-redis"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#演示-docker-安装-redis"}},[e._v("#")]),e._v(" 演示 Docker 安装 Redis")]),e._v(" "),r("p",[e._v("Redis 官网:"),r("a",{attrs:{href:"https://redis.io/",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://redis.io/"),r("OutboundLink")],1)]),e._v(" "),r("blockquote",[r("p",[e._v("官网下载安装教程只有源码安装方式,没有 Windows 版本。想要自己安装 windows 版本需要去找别人编译好的安装包。")])]),e._v(" "),r("p",[e._v("Docker 官方镜像仓库查找 Redis :"),r("a",{attrs:{href:"https://hub.docker.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://hub.docker.com/"),r("OutboundLink")],1)]),e._v(" "),r("p",[r("img",{attrs:{src:"https://cos.easydoc.net/46901064/files/kv8zs4qr.png",alt:"https://cos.easydoc.net/46901064/files/kv8zs4qr.png"}})]),e._v(" "),r("p",[e._v("一个命令跑起来:"),r("code",[e._v("docker run -d -p 6379:6379 --name redis redis:latest")])]),e._v(" "),r("p",[e._v("命令参考:"),r("a",{attrs:{href:"https://docs.docker.com/engine/reference/commandline/run/",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://docs.docker.com/engine/reference/commandline/run/"),r("OutboundLink")],1)]),e._v(" "),r("p",[r("img",{attrs:{src:"https://cos.easydoc.net/46901064/files/kv8zy4xn.png",alt:"https://cos.easydoc.net/46901064/files/kv8zy4xn.png"}})]),e._v(" "),r("h3",{attrs:{id:"安装-wordpress"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#安装-wordpress"}},[e._v("#")]),e._v(" 安装 Wordpress")]),e._v(" "),r("p",[e._v("docker-compose.yml")]),e._v(" "),r("div",{staticClass:"language- extra-class"},[r("pre",{pre:!0,attrs:{class:"language-text"}},[r("code",[e._v("version: '3.1'\n\nservices:\n\n wordpress:\n image: wordpress\n restart: always\n ports:\n - 8080:80\n environment:\n WORDPRESS_DB_HOST: db\n WORDPRESS_DB_USER: exampleuser\n WORDPRESS_DB_PASSWORD: examplepass\n WORDPRESS_DB_NAME: exampledb\n volumes:\n - wordpress:/var/www/html\n\n db:\n image: mysql:5.7\n restart: always\n environment:\n MYSQL_DATABASE: exampledb\n MYSQL_USER: exampleuser\n MYSQL_PASSWORD: examplepass\n MYSQL_RANDOM_ROOT_PASSWORD: '1'\n volumes:\n - db:/var/lib/mysql\n\nvolumes:\n wordpress:\n db:\n")])])]),r("h3",{attrs:{id:"安装-elk"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#安装-elk"}},[e._v("#")]),e._v(" 安装 ELK")]),e._v(" "),r("p",[r("code",[e._v("docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -it --name elk sebp/elk")])]),e._v(" "),r("p",[r("a",{attrs:{href:"https://docs.microsoft.com/en-us/windows/wsl/wsl-config#global-configuration-options-with-wslconfig",target:"_blank",rel:"noopener noreferrer"}},[e._v("内存不够解决方法"),r("OutboundLink")],1)]),e._v(" "),r("p",[e._v("转到用户目录 "),r("code",[e._v("cd ~")]),e._v(",路径类似这个:"),r("code",[e._v("C:\\Users\\")])]),e._v(" "),r("p",[e._v("创建 "),r("code",[e._v(".wslconfig")]),e._v(" 文件填入以下内容")]),e._v(" "),r("div",{staticClass:"language- extra-class"},[r("pre",{pre:!0,attrs:{class:"language-text"}},[r("code",[e._v("[wsl2]\nmemory=10GB # Limits VM memory in WSL 2 to 4 GB\nprocessors=2 # Makes the WSL 2 VM use two virtual processors\n")])])]),r("p",[e._v("生效配置,命令行运行 "),r("code",[e._v("wsl --shutdown")])]),e._v(" "),r("h3",{attrs:{id:"更多相关命令"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#更多相关命令"}},[e._v("#")]),e._v(" 更多相关命令")]),e._v(" "),r("p",[r("code",[e._v("docker ps")]),e._v(" 查看当前运行中的容器")]),e._v(" "),r("p",[r("code",[e._v("docker images")]),e._v(" 查看镜像列表")]),e._v(" "),r("p",[r("code",[e._v("docker rm container-id")]),e._v(" 删除指定 id 的容器")]),e._v(" "),r("p",[r("code",[e._v("docker stop/start container-id")]),e._v(" 停止/启动指定 id 的容器")]),e._v(" "),r("p",[r("code",[e._v("docker rmi image-id")]),e._v(" 删除指定 id 的镜像")]),e._v(" "),r("p",[r("code",[e._v("docker volume ls")]),e._v(" 查看 volume 列表")]),e._v(" "),r("p",[r("code",[e._v("docker network ls")]),e._v(" 查看网络列表")])])}),[],!1,null,null,null);r.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/11.1a662648.js b/assets/js/11.1a662648.js new file mode 100644 index 0000000..0736406 --- /dev/null +++ b/assets/js/11.1a662648.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[11,19,23],{241:function(t,e,n){"use strict";n.d(e,"d",(function(){return r})),n.d(e,"a",(function(){return a})),n.d(e,"i",(function(){return s})),n.d(e,"f",(function(){return u})),n.d(e,"g",(function(){return c})),n.d(e,"h",(function(){return l})),n.d(e,"b",(function(){return p})),n.d(e,"e",(function(){return f})),n.d(e,"k",(function(){return d})),n.d(e,"l",(function(){return h})),n.d(e,"c",(function(){return v})),n.d(e,"j",(function(){return m}));n(45);const r=/#.*$/,i=/\.(md|html)$/,a=/\/$/,s=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(r,"").replace(i,"")}function u(t){return s.test(t)}function c(t){return/^mailto:/.test(t)}function l(t){return/^tel:/.test(t)}function p(t){if(u(t))return t;const e=t.match(r),n=e?e[0]:"",i=o(t);return a.test(i)?t:i+".html"+n}function f(t,e){const n=decodeURIComponent(t.hash),i=function(t){const e=t.match(r);if(e)return e[0]}(e);if(i&&n!==i)return!1;return o(t.path)===o(e)}function d(t,e,n){if(u(e))return{type:"external",path:e};n&&(e=function(t,e,n){const r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return e+t;const i=e.split("/");n&&i[i.length-1]||i.pop();const a=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,r,i=1){if("string"==typeof e)return d(n,e,r);if(Array.isArray(e))return Object.assign(d(n,e[0],r),{title:e[1]});{const a=e.children||[];return 0===a.length&&e.path?Object.assign(d(n,e.path,r),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:a.map(e=>t(e,n,r,i+1)),collapsable:!1!==e.collapsable}}}(t,i,n)):[]}return[]}function g(t){const e=v(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function v(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function m(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},248:function(t,e){t.exports=function(t){return null==t}},250:function(t,e,n){},251:function(t,e,n){},261:function(t,e,n){"use strict";n(250)},262:function(t,e,n){var r=n(11),i=n(4),a=n(10);t.exports=function(t){return"string"==typeof t||!i(t)&&a(t)&&"[object String]"==r(t)}},263:function(t,e,n){"use strict";n(251)},264:function(t,e,n){},269:function(t,e,n){"use strict";n.r(e);var r=n(248),i=n.n(r),a=n(241),s={name:"PageEdit",computed:{lastUpdated(){return this.$page.lastUpdated},lastUpdatedText(){return"string"==typeof this.$themeLocaleConfig.lastUpdated?this.$themeLocaleConfig.lastUpdated:"string"==typeof this.$site.themeConfig.lastUpdated?this.$site.themeConfig.lastUpdated:"Last Updated"},editLink(){const t=i()(this.$page.frontmatter.editLink)?this.$site.themeConfig.editLinks:this.$page.frontmatter.editLink,{repo:e,docsDir:n="",docsBranch:r="master",docsRepo:a=e}=this.$site.themeConfig;return t&&a&&this.$page.relativePath?this.createEditLink(e,a,n,r,this.$page.relativePath):null},editLinkText(){return this.$themeLocaleConfig.editLinkText||this.$site.themeConfig.editLinkText||"Edit this page"}},methods:{createEditLink(t,e,n,r,i){if(/bitbucket.org/.test(e)){return e.replace(a.a,"")+"/src"+`/${r}/`+(n?n.replace(a.a,"")+"/":"")+i+`?mode=edit&spa=0&at=${r}&fileviewer=file-view-default`}if(/gitlab.com/.test(e)){return e.replace(a.a,"")+"/-/edit"+`/${r}/`+(n?n.replace(a.a,"")+"/":"")+i}return(a.i.test(e)?e:"https://github.com/"+e).replace(a.a,"")+"/edit"+`/${r}/`+(n?n.replace(a.a,"")+"/":"")+i}}},o=(n(261),n(14)),u=Object(o.a)(s,(function(){var t=this,e=t._self._c;return e("footer",{staticClass:"page-edit"},[t.editLink?e("div",{staticClass:"edit-link"},[e("a",{attrs:{href:t.editLink,target:"_blank",rel:"noopener noreferrer"}},[t._v(t._s(t.editLinkText))]),t._v(" "),e("OutboundLink")],1):t._e(),t._v(" "),t.lastUpdated?e("div",{staticClass:"last-updated"},[e("span",{staticClass:"prefix"},[t._v(t._s(t.lastUpdatedText)+":")]),t._v(" "),e("span",{staticClass:"time"},[t._v(t._s(t.lastUpdated))])]):t._e()])}),[],!1,null,null,null);e.default=u.exports},270:function(t,e,n){"use strict";n.r(e);n(45);var r=n(241),i=n(262),a=n.n(i),s=n(248),o=n.n(s),u={name:"PageNav",props:["sidebarItems"],computed:{prev(){return l(c.PREV,this)},next(){return l(c.NEXT,this)}}};const c={NEXT:{resolveLink:function(t,e){return p(t,e,1)},getThemeLinkConfig:({nextLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.next},PREV:{resolveLink:function(t,e){return p(t,e,-1)},getThemeLinkConfig:({prevLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.prev}};function l(t,{$themeConfig:e,$page:n,$route:i,$site:s,sidebarItems:u}){const{resolveLink:c,getThemeLinkConfig:l,getPageLinkConfig:p}=t,f=l(e),d=p(n),h=o()(d)?f:d;return!1===h?void 0:a()(h)?Object(r.k)(s.pages,h,i.path):c(n,u)}function p(t,e,n){const r=[];!function t(e,n){for(let r=0,i=e.length;rfunction t(e,n,i,r=1){if("string"==typeof e)return f(n,e,i);if(Array.isArray(e))return Object.assign(f(n,e[0],i),{title:e[1]});{const s=e.children||[];return 0===s.length&&e.path?Object.assign(f(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:s.map(e=>t(e,n,i,r+1)),collapsable:!1!==e.collapsable}}}(t,r,n)):[]}return[]}function m(t){const e=b(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function b(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function g(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},242:function(t,e,n){},243:function(t,e,n){"use strict";n.r(e);var i=n(241),r={name:"NavLink",props:{item:{required:!0}},computed:{link(){return Object(i.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link},isNonHttpURI(){return Object(i.g)(this.link)||Object(i.h)(this.link)},isBlankTarget(){return"_blank"===this.target},isInternal(){return!Object(i.f)(this.link)&&!this.isBlankTarget},target(){return this.isNonHttpURI?null:this.item.target?this.item.target:Object(i.f)(this.link)?"_blank":""},rel(){return this.isNonHttpURI||!1===this.item.rel?null:this.item.rel?this.item.rel:this.isBlankTarget?"noopener noreferrer":null}},methods:{focusoutAction(){this.$emit("focusout")}}},s=n(14),a=Object(s.a)(r,(function(){var t=this,e=t._self._c;return t.isInternal?e("RouterLink",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v("\n "+t._s(t.item.text)+"\n")]):e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.target,rel:t.rel},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),t.isBlankTarget?e("OutboundLink"):t._e()],1)}),[],!1,null,null,null);e.default=a.exports},244:function(t,e,n){"use strict";n.r(e);var i={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},r=(n(245),n(14)),s=Object(r.a)(i,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=s.exports},245:function(t,e,n){"use strict";n(242)},246:function(t,e,n){},249:function(t,e,n){},253:function(t,e,n){"use strict";n(246)},256:function(t,e,n){"use strict";n.r(e);var i=n(243),r=n(244),s=n(90),a=n.n(s),o={name:"DropdownLink",components:{NavLink:i.default,DropdownTransition:r.default},props:{item:{required:!0}},data:()=>({open:!1}),computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},watch:{$route(){this.open=!1}},methods:{setOpen(t){this.open=t},isLastItemOfArray:(t,e)=>a()(e)===t,handleDropdown(){0===event.detail&&this.setOpen(!this.open)}}},l=(n(253),n(14)),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.handleDropdown}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow down"})]),t._v(" "),e("button",{staticClass:"mobile-dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:function(e){return t.setOpen(!t.open)}}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})]),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(n,i){return e("li",{key:n.link||i,staticClass:"dropdown-item"},["links"===n.type?e("h4",[t._v("\n "+t._s(n.text)+"\n ")]):t._e(),t._v(" "),"links"===n.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(n.items,(function(i){return e("li",{key:i.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:i},on:{focusout:function(e){t.isLastItemOfArray(i,n.items)&&t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0):e("NavLink",{attrs:{item:n},on:{focusout:function(e){t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports},260:function(t,e,n){"use strict";n(249)},267:function(t,e,n){"use strict";n.r(e);var i=n(256),r=n(241),s={name:"NavLinks",components:{NavLink:n(243).default,DropdownLink:i.default},computed:{userNav(){return this.$themeLocaleConfig.nav||this.$site.themeConfig.nav||[]},nav(){const{locales:t}=this.$site;if(t&&Object.keys(t).length>1){const e=this.$page.path,n=this.$router.options.routes,i=this.$site.themeConfig.locales||{},r={text:this.$themeLocaleConfig.selectText||"Languages",ariaLabel:this.$themeLocaleConfig.ariaLabel||"Select language",items:Object.keys(t).map(r=>{const s=t[r],a=i[r]&&i[r].label||s.lang;let o;return s.lang===this.$lang?o=e:(o=e.replace(this.$localeConfig.path,r),n.some(t=>t.path===o)||(o=r)),{text:a,link:o}})};return[...this.userNav,r]}return this.userNav},userLinks(){return(this.nav||[]).map(t=>Object.assign(Object(r.j)(t),{items:(t.items||[]).map(r.j)}))},repoLink(){const{repo:t}=this.$site.themeConfig;return t?/^https?:/.test(t)?t:"https://github.com/"+t:null},repoLabel(){if(!this.repoLink)return;if(this.$site.themeConfig.repoLabel)return this.$site.themeConfig.repoLabel;const t=this.repoLink.match(/^https?:\/\/[^/]+/)[0],e=["GitHub","GitLab","Bitbucket"];for(let n=0;n")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tree"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v("\n+- foo "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tree"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" + bar.txt "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("blob, contents "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hello world"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v("\n+- baz.txt "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("blob, contents "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"git is wonderful"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("这个顶层的树包含了两个元素,一个名为 “foo” 的树(它本身包含了一个 blob 对象 “bar.txt”),以及一个 blob 对象 “baz.txt”。")]),t._v(" "),a("h3",{attrs:{id:"_1-2-历史记录建模-关联快照"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-历史记录建模-关联快照"}},[t._v("#")]),t._v(" 1.2 历史记录建模:关联快照")]),t._v(" "),a("p",[t._v("版本控制系统和快照有什么关系呢?线性历史记录是一种最简单的模型,它包含了一组按照时间顺序线性排列的快照。不过出于种种原因,Git 并没有采用这样的模型。")]),t._v(" "),a("p",[t._v("在 Git 中,历史记录是一个由快照组成的有向无环图。有向无环图,听上去似乎是什么高大上的数学名词。不过不要怕,您只需要知道这代表 Git 中的每个快照都有一系列的“父辈”,也就是其之前的一系列快照。注意,快照具有多个“父辈”而非一个,因为某个快照可能由多个父辈而来。例如,经过合并后的两条分支。")]),t._v(" "),a("p",[t._v("在 Git 中,这些快照被称为“提交”。通过可视化的方式来表示这些历史提交记录时,看起来差不多是这样的:")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[t._v("o "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("-- o "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("-- o "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("-- o\n ^\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("\\")]),t._v("\n --- o "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("-- o\n")])])]),a("p",[t._v("上面是一个 ASCII 码构成的简图,其中的  "),a("code",[t._v("o")]),t._v("  表示一次提交(快照)。")]),t._v(" "),a("p",[t._v("箭头指向了当前提交的父辈(这是一种“在…之前”,而不是“在…之后”的关系)。在第三次提交之后,历史记录分岔成了两条独立的分支。这可能因为此时需要同时开发两个不同的特性,它们之间是相互独立的。开发完成后,这些分支可能会被合并并创建一个新的提交,这个新的提交会同时包含这些特性。新的提交会创建一个新的历史记录,看上去像这样(最新的合并提交用粗体标记):")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[t._v("o "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("-- o "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("-- o "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("-- o "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("---- o\n ^ /\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("\\")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("v")]),t._v("\n --- o "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("-- o\n")])])]),a("p",[t._v("Git 中的提交是不可改变的。但这并不代表错误不能被修改,只不过这种“修改”实际上是创建了一个全新的提交记录。而引用(参见下文)则被更新为指向这些新的提交。")]),t._v(" "),a("h3",{attrs:{id:"_1-3-数据模型及其伪代码表示"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-数据模型及其伪代码表示"}},[t._v("#")]),t._v(" 1.3 数据模型及其伪代码表示")]),t._v(" "),a("p",[t._v("以伪代码的形式来学习 Git 的数据模型,可能更加清晰:")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[t._v("// 文件就是一组数据\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("type")]),t._v(" blob "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" array"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("byte"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n\n// 一个包含文件和目录的目录\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("type")]),t._v(" tree "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" map"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("string, tree "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" blob"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n\n// 每个提交都包含一个父辈,元数据和顶层树\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("type")]),t._v(" commit "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" struct "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n parent: array"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("commit"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n author: string\n message: string\n snapshot: tree\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("这是一种简洁的历史模型。")]),t._v(" "),a("h3",{attrs:{id:"_1-4-对象和内存寻址"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-4-对象和内存寻址"}},[t._v("#")]),t._v(" 1.4 对象和内存寻址")]),t._v(" "),a("p",[t._v("Git 中的对象可以是 blob、树或提交:")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("type")]),t._v(" object "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" blob "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" tree "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" commit\n")])])]),a("p",[t._v("Git 在储存数据时,所有的对象都会基于它们的  "),a("a",{attrs:{href:"https://en.wikipedia.org/wiki/SHA-1",target:"_blank",rel:"noopener noreferrer"}},[t._v("SHA-1 哈希"),a("OutboundLink")],1),t._v("  进行寻址。")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[t._v("objects "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" map"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("string, object"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n\ndef store"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("object"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(":\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("id")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" sha1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("object"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n objects"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" object\n\ndef load"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(":\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("return")]),t._v(" objects"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),a("p",[t._v("Blobs、树和提交都一样,它们都是对象。当它们引用其他对象时,它们并没有真正的在硬盘上保存这些对象,而是仅仅保存了它们的哈希值作为引用。")]),t._v(" "),a("p",[t._v("例如,"),a("a",{attrs:{href:"https://missing-semester-cn.github.io/2020/version-control/#snapshots",target:"_blank",rel:"noopener noreferrer"}},[t._v("上面"),a("OutboundLink")],1),t._v("例子中的树(可以通过  "),a("code",[t._v("git cat-file -p 698281bc680d1995c5f4caaf3359721a5a58d48d")]),t._v("  来进行可视化),看上去是这样的:")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token number"}},[t._v("100644")]),t._v(" blob 4448adbf7ecd394f42ae135bbeed9676e894af85 baz.txt\n040000 tree c68d233a33c5c06e0340e4c224f0afca87c8ce87 foo\n")])])]),a("p",[t._v("树本身会包含一些指向其他内容的指针,例如  "),a("code",[t._v("baz.txt")]),t._v(" (blob) 和  "),a("code",[t._v("foo")]),t._v(" (树)。如果我们用  "),a("code",[t._v("git cat-file -p 4448adbf7ecd394f42ae135bbeed9676e894af85")]),t._v(",即通过哈希值查看 baz.txt 的内容,会得到以下信息:")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" is wonderful\n")])])]),a("h3",{attrs:{id:"_1-5-引用"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-5-引用"}},[t._v("#")]),t._v(" 1.5 引用")]),t._v(" "),a("p",[t._v("现在,所有的快照都可以通过它们的 SHA-1 哈希值来标记了。但这也太不方便了,谁也记不住一串 40 位的十六进制字符。")]),t._v(" "),a("p",[t._v("针对这一问题,Git 的解决方法是给这些哈希值赋予人类可读的名字,也就是引用(references)。引用是指向提交的指针。与对象不同的是,它是可变的(引用可以被更新,指向新的提交)。例如,"),a("code",[t._v("master")]),t._v("  引用通常会指向主分支的最新一次提交。")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[t._v("references "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" map"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("string, string"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n\ndef update_reference"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name, "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("id")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(":\n references"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("id")]),t._v("\n\ndef read_reference"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(":\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("return")]),t._v(" references"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n\ndef load_reference"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name_or_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(":\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" name_or_id "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" references:\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("return")]),t._v(" load"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("references"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("name_or_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n else:\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("return")]),t._v(" load"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name_or_id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("这样,Git 就可以使用诸如 “master” 这样人类可读的名称来表示历史记录中某个特定的提交,而不需要在使用一长串十六进制字符了。")]),t._v(" "),a("p",[t._v("有一个细节需要我们注意, 通常情况下,我们会想要知道“我们当前所在位置”,并将其标记下来。这样当我们创建新的快照的时候,我们就可以知道它的相对位置(如何设置它的“父辈”)。在 Git 中,我们当前的位置有一个特殊的索引,它就是 “HEAD”。")]),t._v(" "),a("h3",{attrs:{id:"_1-6-仓库"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-6-仓库"}},[t._v("#")]),t._v(" 1.6 仓库")]),t._v(" "),a("p",[t._v("最后,我们可以粗略地给出 Git 仓库的定义了:"),a("code",[t._v("对象")]),t._v("  和  "),a("code",[t._v("引用")]),t._v("。")]),t._v(" "),a("p",[t._v("在硬盘上,Git 仅存储对象和引用:因为其数据模型仅包含这些东西。所有的  "),a("code",[t._v("git")]),t._v("  命令都对应着对提交树的操作,例如增加对象,增加或删除引用。")]),t._v(" "),a("p",[t._v("当您输入某个指令时,请思考一下这条命令是如何对底层的图数据结构进行操作的。另一方面,如果您希望修改提交树,例如“丢弃未提交的修改和将 ‘master’ 引用指向提交  "),a("code",[t._v("5d83f9e")]),t._v("  时,有什么命令可以完成该操作(针对这个具体问题,您可以使用  "),a("code",[t._v("git checkout master; git reset --hard 5d83f9e")]),t._v(")")]),t._v(" "),a("h2",{attrs:{id:"_2-暂存区"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-暂存区"}},[t._v("#")]),t._v(" 2. 暂存区")]),t._v(" "),a("p",[t._v("Git 中还包括一个和数据模型完全不相关的概念,但它确是创建提交的接口的一部分。")]),t._v(" "),a("p",[t._v("就上面介绍的快照系统来说,您也许会期望它的实现里包括一个 “创建快照” 的命令,该命令能够基于当前工作目录的当前状态创建一个全新的快照。有些版本控制系统确实是这样工作的,但 Git 不是。我们希望简洁的快照,而且每次从当前状态创建快照可能效果并不理想。例如,考虑如下场景,您开发了两个独立的特性,然后您希望创建两个独立的提交,其中第一个提交仅包含第一个特性,而第二个提交仅包含第二个特性。或者,假设您在调试代码时添加了很多打印语句,然后您仅仅希望提交和修复 bug 相关的代码而丢弃所有的打印语句。")]),t._v(" "),a("p",[t._v("Git 处理这些场景的方法是使用一种叫做 “暂存区(staging area)”的机制,它允许您指定下次快照中要包括那些改动。")]),t._v(" "),a("h2",{attrs:{id:"_3-git-的命令行接口"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-git-的命令行接口"}},[t._v("#")]),t._v(" 3. Git 的命令行接口")]),t._v(" "),a("h3",{attrs:{id:"_3-1-基础"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-基础"}},[t._v("#")]),t._v(" 3.1 基础")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("git help ")]),t._v(": 获取 git 命令的帮助信息")]),t._v(" "),a("li",[a("code",[t._v("git init")]),t._v(": 创建一个新的 git 仓库,其数据会存放在一个名为  "),a("code",[t._v(".git")]),t._v("  的目录下")]),t._v(" "),a("li",[a("code",[t._v("git status")]),t._v(": 显示当前的仓库状态")]),t._v(" "),a("li",[a("code",[t._v("git add ")]),t._v(": 添加文件到暂存区")]),t._v(" "),a("li",[a("code",[t._v("git commit")]),t._v(": 创建一个新的提交\n"),a("ul",[a("li",[t._v("如何编写  "),a("a",{attrs:{href:"https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("良好的提交信息"),a("OutboundLink")],1),t._v("!")]),t._v(" "),a("li",[t._v("为何要  "),a("a",{attrs:{href:"https://chris.beams.io/posts/git-commit/",target:"_blank",rel:"noopener noreferrer"}},[t._v("编写良好的提交信息"),a("OutboundLink")],1)])])]),t._v(" "),a("li",[a("code",[t._v("git log")]),t._v(": 显示历史日志")]),t._v(" "),a("li",[a("code",[t._v("git log --all --graph --decorate")]),t._v(": 可视化历史记录(有向无环图) "),a("code",[t._v("--oneline")]),t._v(" 一行")]),t._v(" "),a("li",[a("code",[t._v("git diff ")]),t._v(": 显示与暂存区文件的差异")]),t._v(" "),a("li",[a("code",[t._v("git diff ")]),t._v(": 显示某个文件两个版本之间的差异")]),t._v(" "),a("li",[a("code",[t._v("git checkout ")]),t._v(": 更新 HEAD 和目前的分支")]),t._v(" "),a("li",[a("code",[t._v("git checkout ")]),t._v(": 把文件回到之前(HEAD)版本")])]),t._v(" "),a("h3",{attrs:{id:"_3-2-分支和合并"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-分支和合并"}},[t._v("#")]),t._v(" 3.2 分支和合并")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("git branch")]),t._v(": 显示分支")]),t._v(" "),a("li",[a("code",[t._v("git branch ")]),t._v(": 创建分支")]),t._v(" "),a("li",[a("code",[t._v("git checkout -b ")]),t._v(": 创建分支并切换到该分支\n"),a("ul",[a("li",[t._v("相当于  "),a("code",[t._v("git branch ; git checkout ")])])])]),t._v(" "),a("li",[a("code",[t._v("git merge ")]),t._v(": 合并到当前分支")]),t._v(" "),a("li",[a("code",[t._v("git mergetool")]),t._v(": 使用工具来处理合并冲突")]),t._v(" "),a("li",[a("code",[t._v("git rebase")]),t._v(": 将一系列补丁变基(rebase)为新的基线")])]),t._v(" "),a("h3",{attrs:{id:"_3-3-远端操作"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-远端操作"}},[t._v("#")]),t._v(" 3.3 远端操作")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("git remote")]),t._v(": 列出远端")]),t._v(" "),a("li",[a("code",[t._v("git remote add ")]),t._v(": 添加一个远端")]),t._v(" "),a("li",[a("code",[t._v("git push :")]),t._v(": 将对象传送至远端并更新远端引用")]),t._v(" "),a("li",[a("code",[t._v("git branch --set-upstream-to=/")]),t._v(": 创建本地和远端分支的关联关系")]),t._v(" "),a("li",[a("code",[t._v("git fetch")]),t._v(": 从远端获取对象/索引")]),t._v(" "),a("li",[a("code",[t._v("git pull")]),t._v(": 相当于  "),a("code",[t._v("git fetch; git merge")])]),t._v(" "),a("li",[a("code",[t._v("git clone")]),t._v(": 从远端下载仓库")])]),t._v(" "),a("h3",{attrs:{id:"_3-4-撤销"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-撤销"}},[t._v("#")]),t._v(" 3.4 撤销")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("git commit --amend")]),t._v(": 编辑提交的内容或信息")]),t._v(" "),a("li",[a("code",[t._v("git reset HEAD ")]),t._v(": 恢复暂存的文件")]),t._v(" "),a("li",[a("code",[t._v("git checkout -- ")]),t._v(": 丢弃修改")]),t._v(" "),a("li",[a("code",[t._v("git restore")]),t._v(": git2.32 版本后取代 git reset 进行许多撤销操作")])]),t._v(" "),a("h2",{attrs:{id:"_4-git-高级操作"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_4-git-高级操作"}},[t._v("#")]),t._v(" 4. Git 高级操作")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("git config")]),t._v(": Git 是一个  "),a("a",{attrs:{href:"https://git-scm.com/docs/git-config",target:"_blank",rel:"noopener noreferrer"}},[t._v("高度可定制的"),a("OutboundLink")],1),t._v("  工具")]),t._v(" "),a("li",[a("code",[t._v("git clone --depth=1")]),t._v(": 浅克隆(shallow clone),不包括完整的版本历史信息")]),t._v(" "),a("li",[a("code",[t._v("git add -p")]),t._v(": 交互式暂存")]),t._v(" "),a("li",[a("code",[t._v("git rebase -i")]),t._v(": 交互式变基")]),t._v(" "),a("li",[a("code",[t._v("git blame")]),t._v(": 查看最后修改某行的人")]),t._v(" "),a("li",[a("code",[t._v("git stash")]),t._v(": 暂时移除工作目录下的修改内容")]),t._v(" "),a("li",[a("code",[t._v("git bisect")]),t._v(": 通过二分查找搜索历史记录")]),t._v(" "),a("li",[a("code",[t._v(".gitignore")]),t._v(": "),a("a",{attrs:{href:"https://git-scm.com/docs/gitignore",target:"_blank",rel:"noopener noreferrer"}},[t._v("指定"),a("OutboundLink")],1),t._v("  故意不追踪的文件")])]),t._v(" "),a("h2",{attrs:{id:"_5-杂项"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5-杂项"}},[t._v("#")]),t._v(" 5. 杂项")]),t._v(" "),a("ul",[a("li",[t._v("图形用户界面: Git 的  "),a("a",{attrs:{href:"https://git-scm.com/downloads/guis",target:"_blank",rel:"noopener noreferrer"}},[t._v("图形用户界面客户端"),a("OutboundLink")],1),t._v("  有很多,但是我们自己并不使用这些图形用户界面的客户端,我们选择使用命令行接口")]),t._v(" "),a("li",[t._v("Shell 集成: 将 Git 状态集成到您的 shell 中会非常方便。("),a("a",{attrs:{href:"https://github.com/olivierverdier/zsh-git-prompt",target:"_blank",rel:"noopener noreferrer"}},[t._v("zsh"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/magicmonty/bash-git-prompt",target:"_blank",rel:"noopener noreferrer"}},[t._v("bash"),a("OutboundLink")],1),t._v(")。"),a("a",{attrs:{href:"https://github.com/ohmyzsh/ohmyzsh",target:"_blank",rel:"noopener noreferrer"}},[t._v("Oh My Zsh"),a("OutboundLink")],1),t._v("这样的框架中一般以及集成了这一功能")]),t._v(" "),a("li",[t._v("编辑器集成: 和上面一条类似,将 Git 集成到编辑器中好处多多。"),a("a",{attrs:{href:"https://github.com/tpope/vim-fugitive",target:"_blank",rel:"noopener noreferrer"}},[t._v("fugitive.vim"),a("OutboundLink")],1),t._v("  是 Vim 中集成 GIt 的常用插件")]),t._v(" "),a("li",[t._v("工作流: 我们已经讲解了数据模型与一些基础命令,但还没讨论到进行大型项目时的一些惯例 ( 有"),a("a",{attrs:{href:"https://nvie.com/posts/a-successful-git-branching-model/",target:"_blank",rel:"noopener noreferrer"}},[t._v("很多"),a("OutboundLink")],1),t._v(" "),a("a",{attrs:{href:"https://www.endoflineblog.com/gitflow-considered-harmful",target:"_blank",rel:"noopener noreferrer"}},[t._v("不同的"),a("OutboundLink")],1),t._v(" "),a("a",{attrs:{href:"https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow",target:"_blank",rel:"noopener noreferrer"}},[t._v("处理方法"),a("OutboundLink")],1),t._v(")")]),t._v(" "),a("li",[t._v("GitHub: Git 并不等同于 GitHub。 在 GitHub 中您需要使用一个被称作"),a("a",{attrs:{href:"https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests",target:"_blank",rel:"noopener noreferrer"}},[t._v("拉取请求(pull request)"),a("OutboundLink")],1),t._v("的方法来向其他项目贡献代码")]),t._v(" "),a("li",[t._v("其他 Git 提供商: GitHub 并不是唯一的。还有像  "),a("a",{attrs:{href:"https://about.gitlab.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitLab"),a("OutboundLink")],1),t._v("  和  "),a("a",{attrs:{href:"https://bitbucket.org/",target:"_blank",rel:"noopener noreferrer"}},[t._v("BitBucket"),a("OutboundLink")],1),t._v("  这样的平台。")])]),t._v(" "),a("h2",{attrs:{id:"_6-资源"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_6-资源"}},[t._v("#")]),t._v(" 6. 资源")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://git-scm.com/book/en/v2",target:"_blank",rel:"noopener noreferrer"}},[t._v("Pro Git"),a("OutboundLink")],1),t._v(" ,学习前五章的内容可以教会您流畅使用 Git 的绝大多数技巧,因为您已经理解了 Git 的数据模型。后面的章节提供了很多有趣的高级主题。("),a("a",{attrs:{href:"https://git-scm.com/book/zh/v2",target:"_blank",rel:"noopener noreferrer"}},[t._v("Pro Git 中文版"),a("OutboundLink")],1),t._v(");")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://ohshitgit.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Oh Shit, Git!?!"),a("OutboundLink")],1),t._v(" ,简短的介绍了如何从 Git 错误中恢复;")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://eagain.net/articles/git-for-computer-scientists/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Git for Computer Scientists"),a("OutboundLink")],1),t._v(" ,简短的介绍了 Git 的数据模型,与本文相比包含较少量的伪代码以及大量的精美图片;")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://jwiegley.github.io/git-from-the-bottom-up/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Git from the Bottom Up"),a("OutboundLink")],1),t._v("详细的介绍了 Git 的实现细节,而不仅仅局限于数据模型。好奇的同学可以看看;")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://smusamashah.github.io/blog/2017/10/14/explain-git-in-simple-words",target:"_blank",rel:"noopener noreferrer"}},[t._v("How to explain git in simple words"),a("OutboundLink")],1),t._v(";")]),t._v(" "),a("li",[a("a",{attrs:{href:"https://learngitbranching.js.org/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Learn Git Branching"),a("OutboundLink")],1),t._v("  通过基于浏览器的游戏来学习 Git ;")])]),t._v(" "),a("h2",{attrs:{id:"_7-exercise"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_7-exercise"}},[t._v("#")]),t._v(" 7. Exercise")]),t._v(" "),a("h3",{attrs:{id:"_7-1-fork-本课程网站的仓库"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_7-1-fork-本课程网站的仓库"}},[t._v("#")]),t._v(" 7.1 Fork "),a("a",{attrs:{href:"https://github.com/missing-semester-cn/missing-semester-cn.github.io.git",target:"_blank",rel:"noopener noreferrer"}},[t._v("本课程网站的仓库"),a("OutboundLink")],1)]),t._v(" "),a("ol",[a("li",[a("p",[t._v("将版本历史可视化并进行探索")]),t._v(" "),a("p",[a("img",{attrs:{src:e(358),alt:"Untitled"}})])]),t._v(" "),a("li",[a("p",[t._v("是谁最后修改了  "),a("code",[t._v("README.md")]),t._v("文件?(提示:使用  "),a("code",[t._v("git log")]),t._v("  命令并添加合适的参数)")]),t._v(" "),a("p",[a("img",{attrs:{src:e(359),alt:"Untitled"}})])]),t._v(" "),a("li",[a("p",[t._v("最后一次修改"),a("code",[t._v("_config.yml")]),t._v("  文件中  "),a("code",[t._v("collections:")]),t._v("  行时的提交信息是什么?(提示:使用  "),a("code",[t._v("git blame")]),t._v("  和  "),a("code",[t._v("git show")]),t._v(")")]),t._v(" "),a("p",[a("img",{attrs:{src:e(360),alt:"Untitled"}})])])]),t._v(" "),a("h3",{attrs:{id:"_7-2-从-git-历史中删除"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_7-2-从-git-历史中删除"}},[t._v("#")]),t._v(" 7.2 从 Git 历史中删除")]),t._v(" "),a("p",[t._v("使用 Git 时的一个常见错误是提交本不应该由 Git 管理的大文件,或是将含有敏感信息的文件提交给 Git 。尝试向仓库中添加一个文件并添加提交信息,然后将其从历史中删除 ( "),a("a",{attrs:{href:"https://help.github.com/articles/removing-sensitive-data-from-a-repository/",target:"_blank",rel:"noopener noreferrer"}},[t._v("这篇文章也许会有帮助"),a("OutboundLink")],1),t._v(");")]),t._v(" "),a("p",[t._v("从历史记录中删除文件")]),t._v(" "),a("p",[t._v("要从历史记录中彻底删除 "),a("code",[t._v("secret.txt")]),t._v(" 文件,你可以使用 "),a("code",[t._v("git filter-branch")]),t._v(" 命令或更新的 "),a("code",[t._v("git filter-repo")]),t._v("。"),a("code",[t._v("git filter-repo")]),t._v(" 是 "),a("code",[t._v("git filter-branch")]),t._v(" 的替代品,效率更高但需要单独安装。这里我将展示使用 "),a("code",[t._v("git filter-branch")]),t._v(" 的方法,因为它不需要额外安装。")]),t._v(" "),a("ol",[a("li",[a("p",[t._v("使用 "),a("code",[t._v("git filter-branch")]),t._v(" 删除文件:")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" filter-branch "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--force")]),t._v(" --index-filter "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("\\")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"git rm --cached --ignore-unmatch secret.txt"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("\\")]),t._v("\n--prune-empty --tag-name-filter "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("cat")]),t._v(" -- "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--all")]),t._v("\n")])])]),a("ul",[a("li",[a("code",[t._v("-force")]),t._v(": 强制运行,覆盖备份。")]),t._v(" "),a("li",[a("code",[t._v("-index-filter")]),t._v(": 对每个修订版本使用的过滤器,这里用于删除 "),a("code",[t._v("secret.txt")]),t._v("。")]),t._v(" "),a("li",[a("code",[t._v("git rm --cached --ignore-unmatch secret.txt")]),t._v(": 删除指定的文件,即使它在某些修订版本中不存在。")]),t._v(" "),a("li",[a("code",[t._v("-prune-empty")]),t._v(": 删除因为文件删除而变成空的提交。")]),t._v(" "),a("li",[a("code",[t._v("-tag-name-filter cat")]),t._v(": 保留标签名称不变。")]),t._v(" "),a("li",[a("code",[t._v("-all")]),t._v(": 应用于所有分支和标签。")])]),t._v(" "),a("p",[a("img",{attrs:{src:e(361),alt:"Untitled"}})]),t._v(" "),a("p",[a("img",{attrs:{src:e(362),alt:"Untitled"}})])]),t._v(" "),a("li",[a("p",[t._v("推送更改到远程仓库:")]),t._v(" "),a("p",[t._v("删除文件后,你需要强制推送更改到远程仓库,因为这是一次重写历史的操作:")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" push origin "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--force")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--all")]),t._v("\n")])])]),a("p",[t._v("这会强制更新所有分支到远程仓库。")])]),t._v(" "),a("li",[a("p",[t._v("清理和回收空间:")]),t._v(" "),a("p",[t._v("在本地,运行以下命令来清理 Git 对象并回收空间:")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" for-each-ref "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--format")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"delete %(refname)"')]),t._v(" refs/original "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" update-ref "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--stdin")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" reflog expire "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--expire")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("now "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--all")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" gc "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--prune")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("now\n")])])]),a("p",[a("img",{attrs:{src:e(363),alt:"Untitled"}})])])]),t._v(" "),a("h3",{attrs:{id:"_7-3-git-stash"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_7-3-git-stash"}},[t._v("#")]),t._v(" 7.3 git stash")]),t._v(" "),a("p",[t._v("从 GitHub 上克隆某个仓库,修改一些文件。当您使用  "),a("code",[t._v("git stash")]),t._v("  会发生什么?当您执行  "),a("code",[t._v("git log --all --oneline")]),t._v("  时会显示什么?通过  "),a("code",[t._v("git stash pop")]),t._v("  命令来撤销  "),a("code",[t._v("git stash")]),t._v("  操作,什么时候会用到这一技巧?")]),t._v(" "),a("p",[a("img",{attrs:{src:e(364),alt:"Untitled"}})]),t._v(" "),a("p",[a("img",{attrs:{src:e(365),alt:"Untitled"}})]),t._v(" "),a("p",[t._v("执行"),a("code",[t._v("git stash")]),t._v("后,添加到暂存区的内容不会再提示需要提交(Changes to be committed)。而且,尽管执行"),a("code",[t._v("git stash")]),t._v("使得提交记录新增了两项,但是可以发现"),a("code",[t._v("HEAD")]),t._v("引用并没有变动。")]),t._v(" "),a("p",[t._v("当我们将改动添加到暂存区("),a("code",[t._v("git add")]),t._v(")后,通过执行"),a("code",[t._v("git stash")]),t._v("后,可以自由地切换到其他分支(注意:在暂存区存有改动时,切换分支("),a("code",[t._v("checkout")]),t._v(")是不被允许的)")]),t._v(" "),a("p",[t._v("另外,运用"),a("code",[t._v("stash")]),t._v("和"),a("code",[t._v("stash pop")]),t._v(",可以自由选择  "),a("em",[t._v("stash 存储的改动")]),t._v("  即将提交到的分支")]),t._v(" "),a("h3",{attrs:{id:"_7-4-gitconfig"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_7-4-gitconfig"}},[t._v("#")]),t._v(" 7.4 .gitconfig")]),t._v(" "),a("p",[t._v("与其他的命令行工具一样,Git 也提供了一个名为 ~/.gitconfig 配置文件 (或 dotfile)。请在 ~/.gitconfig 中创建一个别名,使您在运行 git graph 时,您可以得到 git log –all –graph –decorate –oneline 的输出结果;")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("alias"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n graph "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" log "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--all")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--graph")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--decorate")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--oneline")]),t._v("\n")])])]),a("p",[a("img",{attrs:{src:e(366),alt:"Untitled"}})]),t._v(" "),a("h3",{attrs:{id:"_7-5-gitignore-global"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_7-5-gitignore-global"}},[t._v("#")]),t._v(" 7.5 .gitignore_global")]),t._v(" "),a("p",[t._v("您可以通过执行 git config –global core.excludesfile ~/.gitignore_global 在 ~/.gitignore_global 中创建全局忽略规则。配置您的全局 gitignore 文件来自动忽略系统或编辑器的临时文件,例如 .DS_Store;")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" config "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--global")]),t._v(" core.excludesfile ~/.gitignore .DS_Store\n")])])])])}),[],!1,null,null,null);a.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/14.2bf74249.js b/assets/js/14.2bf74249.js new file mode 100644 index 0000000..b8cb33e --- /dev/null +++ b/assets/js/14.2bf74249.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[14],{275:function(e,t,a){"use strict";var i=TypeError;e.exports=function(e,t){if(e({placeholder:void 0}),watch:{$lang(e){this.update(this.options,e)},options(e){this.update(e,this.$lang)}},mounted(){this.initialize(this.options,this.$lang),this.placeholder=this.$site.themeConfig.searchPlaceholder||""},methods:{initialize(e,t){Promise.all([Promise.all([a.e(0),a.e(9)]).then(a.t.bind(null,378,7)),Promise.all([a.e(0),a.e(9)]).then(a.t.bind(null,379,7))]).then(([a])=>{a=a.default;const{algoliaOptions:i={}}=e;a(Object.assign({},e,{inputSelector:"#algolia-search-input",algoliaOptions:{...i,facetFilters:["lang:"+t].concat(i.facetFilters||[])},handleSelected:(e,t,a)=>{const{pathname:i,hash:n}=new URL(a.url),r=i.replace(this.$site.base,"/"),s=decodeURIComponent(n);this.$router.push(`${r}${s}`)}}))})},update(e,t){this.$el.innerHTML='',this.initialize(e,t)}}},n=(a(290),a(14)),r=Object(n.a)(i,(function(){var e=this._self._c;return e("form",{staticClass:"algolia-search-wrapper search-box",attrs:{id:"search-form",role:"search"}},[e("input",{staticClass:"search-query",attrs:{id:"algolia-search-input",placeholder:this.placeholder}})])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/15.339e7fa7.js b/assets/js/15.339e7fa7.js new file mode 100644 index 0000000..aa598c7 --- /dev/null +++ b/assets/js/15.339e7fa7.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[15,30,38],{241:function(t,e,n){"use strict";n.d(e,"d",(function(){return i})),n.d(e,"a",(function(){return s})),n.d(e,"i",(function(){return o})),n.d(e,"f",(function(){return l})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return c})),n.d(e,"b",(function(){return p})),n.d(e,"e",(function(){return f})),n.d(e,"k",(function(){return h})),n.d(e,"l",(function(){return d})),n.d(e,"c",(function(){return b})),n.d(e,"j",(function(){return g}));n(45);const i=/#.*$/,r=/\.(md|html)$/,s=/\/$/,o=/^[a-z]+:/i;function a(t){return decodeURI(t).replace(i,"").replace(r,"")}function l(t){return o.test(t)}function u(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function p(t){if(l(t))return t;const e=t.match(i),n=e?e[0]:"",r=a(t);return s.test(r)?t:r+".html"+n}function f(t,e){const n=decodeURIComponent(t.hash),r=function(t){const e=t.match(i);if(e)return e[0]}(e);if(r&&n!==r)return!1;return a(t.path)===a(e)}function h(t,e,n){if(l(e))return{type:"external",path:e};n&&(e=function(t,e,n){const i=t.charAt(0);if("/"===i)return t;if("?"===i||"#"===i)return e+t;const r=e.split("/");n&&r[r.length-1]||r.pop();const s=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,i,r=1){if("string"==typeof e)return h(n,e,i);if(Array.isArray(e))return Object.assign(h(n,e[0],i),{title:e[1]});{const s=e.children||[];return 0===s.length&&e.path?Object.assign(h(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:s.map(e=>t(e,n,i,r+1)),collapsable:!1!==e.collapsable}}}(t,r,n)):[]}return[]}function m(t){const e=b(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function b(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function g(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},242:function(t,e,n){},243:function(t,e,n){"use strict";n.r(e);var i=n(241),r={name:"NavLink",props:{item:{required:!0}},computed:{link(){return Object(i.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link},isNonHttpURI(){return Object(i.g)(this.link)||Object(i.h)(this.link)},isBlankTarget(){return"_blank"===this.target},isInternal(){return!Object(i.f)(this.link)&&!this.isBlankTarget},target(){return this.isNonHttpURI?null:this.item.target?this.item.target:Object(i.f)(this.link)?"_blank":""},rel(){return this.isNonHttpURI||!1===this.item.rel?null:this.item.rel?this.item.rel:this.isBlankTarget?"noopener noreferrer":null}},methods:{focusoutAction(){this.$emit("focusout")}}},s=n(14),o=Object(s.a)(r,(function(){var t=this,e=t._self._c;return t.isInternal?e("RouterLink",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v("\n "+t._s(t.item.text)+"\n")]):e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.target,rel:t.rel},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),t.isBlankTarget?e("OutboundLink"):t._e()],1)}),[],!1,null,null,null);e.default=o.exports},244:function(t,e,n){"use strict";n.r(e);var i={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},r=(n(245),n(14)),s=Object(r.a)(i,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=s.exports},245:function(t,e,n){"use strict";n(242)},246:function(t,e,n){},253:function(t,e,n){"use strict";n(246)},256:function(t,e,n){"use strict";n.r(e);var i=n(243),r=n(244),s=n(90),o=n.n(s),a={name:"DropdownLink",components:{NavLink:i.default,DropdownTransition:r.default},props:{item:{required:!0}},data:()=>({open:!1}),computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},watch:{$route(){this.open=!1}},methods:{setOpen(t){this.open=t},isLastItemOfArray:(t,e)=>o()(e)===t,handleDropdown(){0===event.detail&&this.setOpen(!this.open)}}},l=(n(253),n(14)),u=Object(l.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.handleDropdown}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow down"})]),t._v(" "),e("button",{staticClass:"mobile-dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:function(e){return t.setOpen(!t.open)}}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})]),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(n,i){return e("li",{key:n.link||i,staticClass:"dropdown-item"},["links"===n.type?e("h4",[t._v("\n "+t._s(n.text)+"\n ")]):t._e(),t._v(" "),"links"===n.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(n.items,(function(i){return e("li",{key:i.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:i},on:{focusout:function(e){t.isLastItemOfArray(i,n.items)&&t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0):e("NavLink",{attrs:{item:n},on:{focusout:function(e){t.isLastItemOfArray(n,t.item.items)&&t.setOpen(!1)}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports}}]); \ No newline at end of file diff --git a/assets/js/16.dcb098f8.js b/assets/js/16.dcb098f8.js new file mode 100644 index 0000000..ff93bc1 --- /dev/null +++ b/assets/js/16.dcb098f8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[16],{368:function(t,r,e){t.exports=e.p+"assets/img/0101.1b2216b4.png"},369:function(t,r,e){t.exports=e.p+"assets/img/0102.bf7542ae.png"},370:function(t,r,e){t.exports=e.p+"assets/img/0103.67b2bee9.png"},371:function(t,r){t.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAa8AAABrCAIAAABPB5pAAAAQnUlEQVR4Ae2dzaoc1xWFW++igEceeaBRCBgCAg8CAYEGxrN4kmA9gkaamTxGniJ6gEAmAT2GjeceKG5ve91Pe586XVXdVV1VvYIQ6+yz9t86dfbtnyvn9OHDhzdv3jx7/sp/rIAVsAKPrMDJ0/CRj9+9WwErIAU8Df2i2ApYAStwVsDT0M+BFbACVuCswOk///3f3//xnV4rGlgBK2AFHlMBvzb0T0UrYAWswFmBO0zDH3/46Y4/eVbLvkSijx9P8eeGAr79/X815tu3b6tx45boZuNFurxtKvDbNPzxh5/4h7UO2ckJPIlJdzk+e/6KmJwb4iXmVLO8hRJ9/HhqprvG2Bx8TeM1Wdbx3WnZ64jjLB0Fnl4b8uoKC8Sc6gQaz2yGmuTeKWPMFnON4VfO+AjjmTXLkGW1aThUQLVvagBtqpiqlS2bVWDCNOz0kO58XVZLikYCcaLdZHl9/EkRJpHHNOhp2FfJ07Cvj3eHFLgwDZuv42qs/oWPN7/JK7lwmXB975wsXKZc2mLM1JRcBFSq3KslkStTLikd7c+ev9LngDHjtNQWLeG7wjT8/bPE/Lmh7Jo4tMiYepy0VMBfPtUm7i+DGYnkleqRnfXISLKMZBofXoFPpuHQlU43v4qSZk0lVEty4VJYgAOlaQwCt+iScHMp3wqafHYkl8oMGgl0DKw5GBOQxorJqaHCost8ESgCZ8GQkRzimFPyaoKLlYiQoimRQCVwq+5GPeQIC9CraWw2ZePBFPhkGvZ761zpztZQzOTCZcJcxrjR1OYWsZIOzfFE5pKY6RSzjjzWk9wrmXECN6ehXhsO8av9GgtHgOJUY8wsEQQqU1vzQARkWI3LVAM5kYsWYQEOvsDckkXp5tVvrz0qcLdpmMYEhwhxaEoLMRUfsqdEciH/IiahBky7SlGZ3BIemoZBqO+Lq0WhZoM0ESJO05imSZ95ZT0sgJhhq50WYYGL9ZPJRMaHV+DCNOQ9J666cJc4JkKyhDuNTTze2Jw7TXdVPrQru0ANzq20yy1i5W0CDsQgcOQRj3mn3EzRNzZHQDJySdycL/10Y3Y7KbhFHGFpERZgteONYwo2Z+8KnN7/+l/00nu91I/sYy62yM0gyZiGSCwjgpgKmLLLHkwtR7rLS0COCpW2REj2WA4Vr92LoDkN4/sTjkJZ6lcrF1MMEfSWkO9ALxpTNPGT/ZolR1XESVm0DKBctMsYQ3A2k3GMj6rA6d37e/73DdOYW1nl+2ZfuVmnswJWoK/A6avv//3mzd/6JO9aAStgBQ6vwOkPr//57bd/PXyfbtAKWAEr0Ffg9O71ly/++Kc+ybtWwApYgcMrcHr//Tefff7y8H26QStgBaxAX4Ffp+HLr/sk7vJbV+Lg8HsJ7gpXwODG21GAJ8UvzZO9c+5kVrydTpeuRL0PyRiEusvCFERXjBYZFUS+ommLZNEMfvmtg9NXX3zzl2+n/X/m6fBCX+qYhBZTILkkPkMZ31EBnktgWSoYOtPE1DLx79jmaqmbvV9pjOIZhMLSPnT7Vmt/L4lO3/1r8m/YDIkbB9A8hiGXvcj0aHXyEFPvdauee7gkZlqmsMdesndhAfZOo7AAmYG5RZwmo7YEaihbnv4tyngtQlD+zYOh3BqCAumQxic1c2UFeI5MXe31SQh+YmopwLCHx1Ul6SAQtyMuC428NUko0ojpEnb+nYJ4GQosPg11KjoqHbYsPoxtKsCfYaqwntrQNUvMBz/3qlJTkEqj8klSXa7gpF0tGVNGhTWQAjeehun+NI9B5yGgagw2qEA6prSMC5nOPbpITC0FNtjsciVF1+xdWIDTjUZWlexcEtdQsZs4jGw8fxrqGoSIVFmYB5CMln4vCujg6kHzyiV8cbmX9m9VJ+9CU8lkTLKrjGTnkpj6y978oaXIBneehjonn8SmFOC5EPOORcHcJZ7E3FTvyxXT0UdbAhSwaaz6X3TxNOwf7uRpGILqeALQKCzpE6cS+iV6d30FeEbMLnsYuSSOaxmWxEw0Bj881q2hPhSEWBwB6pmMNbLErDG1ZZAUmDwNk7+XVsAKWIFjKDB2Gv784oX/WAErsBcFjjGeVu5iwjRcuTKnswJWYJ4CP794Mc/xwb08DV89+BPg9o+ngKfhvDO9zTRMn+/OK+VKr/RpcURrGpuJOi3wI+qmr43jFXhYMcc/iuPFHGJ6Gg4p07fnaTj0sEpfHmrC/UyL7rJsYYH4Aq5TgJgCJDeNJBwM61gD3La7RxMz1GPXxLfVVtF0W2UxGKPA0zSMQ+Lf9Ke+PE5hAXpNxbOD0FFYoD8NSavMJSbCVFnW51MT4vUrOUZGaki8UHe8rQulOGTYp2nI32CqrVJfHqewQPUdb1kuSCdy2uIyMC3je9k1ky0T77qpjRS/gp68rRvpehdl3HIa6h1WdM5XVcIVkMwIYmpMjxG0+ag1jYqWdrkMTIu8jg10EOq9eRwyCvCwaJRdAWUhkKrhmyJod7+A7S/XhafhPG2fpmGcE/9mROrLExUWiIc7fIeMsgtUPuMI85IIs84UsBmWfEWWUREqEOfwIHqXAtEvl8IcWH1jDRLi0ytxtHUYwdfpiLf1MNKt0MjTNEwPYspNfXmiwgKcL+ONzexN91QYl+TL3jRql9WGUXxNW154Oh4YUwS1KSNFG29M8talQlWgGnYN1NfSXfC2Lp3rSPHzNBzqjfryUIUFlr4qQxWyAHGaRu0GSJy0ZDvJ8cBLiSCQdJBdgISm8aLayYvLA0i9Zju8rQeQbrUWVpqGfHnFx4KY1yndHLo3pWEcYQFGboYSU4BZmkYSjofZsjABsdrvG4MmTl1qS0CR9w7YEfFCfXkazhN2zjSM4ZLGSiyTUUwB0WhR6dwNowIKiEwgR9I6RvqmRGlLQZL9wMvUcpWUZ6ddeQmQRlxduMvjWGFwrHOO0kS9L5rX03CevDOn4bxk9rICYxTgECQe42vOs+evPA3nPQaehv53yltUQC+m5j3WD+7laTjvAZgwDffy3zJynVbACswbBw/uNXYaPrhMbt8KWIHDK3DVNJzxkfAMl0lnMCP+DJdJJTXJd0narGRl48N+Dhgn/rDtr/yYzUt31TSMrwKnJl76gZgRf4bL1K4r/y5JaxnVonu7xMjebNdVhxta2DXxDVM41PUKeBqev0PoPKCdrSvVHxN5DOfKMpruzEvcJNt4UQFqSHzR0YQ1FfA09DRsfKfMG0u85qN51FzWc7MnO3Ma8s2UepNRFv5WrR6CAJWcLFwGZtiKxVciZie/MpslkdaJOURjRmLyZZexWmKr2mVZAqgeNc4yhCuQ5gRRoWKq4KZ7IqsAee0aHKydXZ9FLX7ONOSJCgvENYhMfWNzl+6dG6WrFUGaoWYY6VJbqLVVjuphhbz2OgPlEkjx+0t6KeatgLpgQGYUVmustmmMUHLUUpYOYBm7xupx110ctfj1pqEUjAciPRZpdiSylkOA0YQ7McWJgLFMRm4pLznCApwIciHoMFXtEF/2JlO7NwGqUyC1JrsACU1jFMYtuhCLI3CTpu4e5GDt3F3Pmxdwn2kY95nNDD0oQ3b68iIR932525kvpDE4MTnEqUi6DOHknpb0qls13WyLggswNXGT0DRGMdxinIoTc3YvG3E8WDsbUfW2Zaw3DfU0VFBvgpoUWZYmIE1YgPH7Ru5GomThUliAia6sc3z2ZqIrjc2OZOQPMxnZe9M4viO6X9nIRtzZEfFGynMZocCcaRjPvV5P6XRlobjJyGVgkbk1lELkCuTOsDKKL0uzbPqGi/g1QrUoprYqUEDmahopguIMMUW4HihFhKp1sjDtykuANOLqwl0mHaPn9f2uEEGaqPcVkjrFVAVmTsOpaY7NP8yl3cgxUU/ijZTnMo6qgKdh47ftJh22fuxP8jK5r4BV7evj3SUU8DS8dhoucSqOaQWswPoKeBp6GloBK2AFzgpcNQ1nfCQ8w2XSj4gZ8We4TCrJZCrwsJ8DxmP2sO3zGdgsvmoaxleBU3tb+oGYEX+Gy9Sud8TXvV3i58RjSs2uiXf0VDxCqZ6G51fInQe0s3Xg54NdEx+45UVbo4bEiyZ18KkKeBp6GjY+M+KNJZ76eJlfFbCeVZONWGZOQ76ZUicyysLfqtVDEKCSk4XLwAxbsfhKxOzkV2azJNI6MYdozLg7zKai+LAkLKOANCegV1WyMmVh2N1p2CyY7TcJNt5RgTnTkCcqLBCPcrTUNzZ36a5bIYHieqS/q8uY7PRSJQLMKEwXYnoR03FfOLpIvXApzIHVN4YC4mgpSwfsS71Oteqxw/HWvRRYbxqqw3gg0mNRB1zwE01BEiBNuBNTHGZJRm4pHTnCAhyRctkjUEcCqTXZBUhoGmfoyTh7lDHVfLB2UncHWN5nGvIFRYg49KAM2ZP0pAkLJHLNqLlZmSkIl8ICnAg11I4s6kggtSa7AAlNY5WdLhUzyI6kGyr1YO0Mtblr+3rTUE9DBfUmSFORZWkC0oQFGL9v5G4kShYuhQWYqFnnXozNjmTkDzMZ2XvTOE/PvSjWr7MjSN/Ru2sqMGcaxnOv11M6aVnYQDJyGVhkbg2lELkCuTOsjOLL0iybvuEifo1QLYqprT2C1DI1ERZnyBJSiNY80OZuKMatPWqYalY7AdKulxtRYOY03Ej1GynjGENwI2LyNWbC26nQlRxSAU/Dxm/bTTpp/dif5GVyXwGr2tfHu0so4Gl47TRc4lQc0wpYgfUV8DT0NLQCVsAKnBW4wzS876dsq2VfLdH6P0Kd0QocUoHfpqE+pqnfeXGrL8EkJkPJkd88knBbvNqcWi3RbfVxNCvwmAo8vTbk1RUWuPjt3nhmM9Qk9yuPirnmhRofYTxzXiX2sgJW4FYKTJiGnZTpztdltaRoJBAn2k2W18efFGES+SYNOogVsAIzFLgwDZuv42qa/oWv775rWEZImO+jI3WycJlyaYsxU3a5CKhBuVdLIlemXFI62o2tgBXYjgKfTMOhK51ufq0+zZpKqJbkwqWwAAdK0xgEbtEl4eZSvhU0+exILpUZNBLoaGwFrMB2FPhkGvbL6lzpztZQzOTCZcJcxrjR1OYWsZIOzfFE5pKY6RSzjjzWk9wrmXGMrYAV2I4Cd5uGaUxwiBCHUrQQU8che0okF/IvYhJqwLSrFJXJLWMrYAU2pcCFach7Tlx74C5xTIRkCXcam3i8sTl3mu6qfGhXdoEanFtpl1vEymtgBazANhX4bRrqvV6qUvYxF1vkZpBkTEMklhFBTAVM2WUPppYj3eUlIEeFSlsiJHssh4rXroEVsALbV+DpteFdak1jbuUa7pt95WadzgpYgb4Cd56G/eK8awWsgBVYTQFPQ/97dStgBazAWQFPQz8HVsAKWIGzAp6Gfg6sgBWwAmcFPA39HFgBK2AFzgp4Gvo5sAJWwAqcFfA09HNgBayAFTgr4Gno58AKWAErcFbA09DPgRWwAlbgrICnoZ8DK2AFrMBZAU9DPwdWwApYgbMCp3evv/zz129W+7cvTmQFrIAV2KYC52n42edfbLM4V2UFrIAVWE2BX6fhy69Xy+dEVsAKWIFtKuB3yv7ExApYAStwVsDT0M+BFbACVuCsgKehnwMrYAWswFkBT0M/B1bACliBswL+fUM/B1bACliBswKehn4OrIAVsAJnBf4PdhL3mynxRv8AAAAASUVORK5CYII="},372:function(t,r,e){t.exports=e.p+"assets/img/0105.51a5549d.png"},373:function(t,r,e){t.exports=e.p+"assets/img/0106.a9dd398c.png"},374:function(t,r,e){t.exports=e.p+"assets/img/0107.21b3e1d2.png"},469:function(t,r,e){"use strict";e.r(r);var v=e(14),s=Object(v.a)({},(function(){var t=this,r=t._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h1",{attrs:{id:"_01-🎉-docker-简介和安装"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_01-🎉-docker-简介和安装"}},[t._v("#")]),t._v(" 01. 🎉 Docker 简介和安装")]),t._v(" "),r("h2",{attrs:{id:"docker-是什么"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#docker-是什么"}},[t._v("#")]),t._v(" Docker 是什么")]),t._v(" "),r("p",[t._v("Docker 是一个应用打包、分发、部署的工具")]),t._v(" "),r("p",[t._v("你也可以把它理解为一个轻量的虚拟机,它只虚拟你软件需要的运行环境,多余的一点都不要,")]),t._v(" "),r("p",[t._v("而普通虚拟机则是一个完整而庞大的系统,包含各种不管你要不要的软件。")]),t._v(" "),r("h2",{attrs:{id:"跟普通虚拟机的对比"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#跟普通虚拟机的对比"}},[t._v("#")]),t._v(" 跟普通虚拟机的对比")]),t._v(" "),r("table",[r("thead",[r("tr",[r("th",[t._v("特性")]),t._v(" "),r("th",[t._v("普通虚拟机")]),t._v(" "),r("th",[t._v("Docker")])])]),t._v(" "),r("tbody",[r("tr",[r("td",[t._v("跨平台")]),t._v(" "),r("td",[t._v("通常只能在桌面级系统运行,例如 Windows/Mac,无法在不带图形界面的服务器上运行")]),t._v(" "),r("td",[t._v("支持的系统非常多,各类 windows 和 Linux 都支持")])]),t._v(" "),r("tr",[r("td",[t._v("性能")]),t._v(" "),r("td",[t._v("性能损耗大,内存占用高,因为是把整个完整系统都虚拟出来了")]),t._v(" "),r("td",[t._v("性能好,只虚拟软件所需运行环境,最大化减少没用的配置")])]),t._v(" "),r("tr",[r("td",[t._v("自动化")]),t._v(" "),r("td",[t._v("需要手动安装所有东西")]),t._v(" "),r("td",[t._v("一个命令就可以自动部署好所需环境")])]),t._v(" "),r("tr",[r("td",[t._v("稳定性")]),t._v(" "),r("td",[t._v("稳定性不高,不同系统差异大")]),t._v(" "),r("td",[t._v("稳定性好,不同系统都一样部署方式")])])])]),t._v(" "),r("h2",{attrs:{id:"打包、分发、部署"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#打包、分发、部署"}},[t._v("#")]),t._v(" 打包、分发、部署")]),t._v(" "),r("p",[r("strong",[t._v("打包")]),t._v(":就是把你软件运行所需的依赖、第三方库、软件打包到一起,变成一个安装包")]),t._v(" "),r("p",[r("strong",[t._v("分发")]),t._v(":你可以把你打包好的“安装包”上传到一个镜像仓库,其他人可以非常方便的获取和安装")]),t._v(" "),r("p",[r("strong",[t._v("部署")]),t._v(":拿着“安装包”就可以一个命令运行起来你的应用,自动模拟出一摸一样的运行环境,不管是在 Windows/Mac/Linux。")]),t._v(" "),r("p",[r("img",{attrs:{src:e(368),alt:"Untitled"}})]),t._v(" "),r("h2",{attrs:{id:"docker-部署的优势"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#docker-部署的优势"}},[t._v("#")]),t._v(" Docker 部署的优势")]),t._v(" "),r("p",[t._v("常规应用开发部署方式:自己在 Windows 上开发、测试 --\x3e 到 Linux 服务器配置运行环境部署。")]),t._v(" "),r("blockquote",[r("p",[t._v("问题:我机器上跑都没问题,怎么到服务器就各种问题了")])]),t._v(" "),r("p",[t._v("用 Docker 开发部署流程:自己在 Windows 上开发、测试 --\x3e 打包为 Docker 镜像(可以理解为软件安装包) --\x3e 各种服务器上只需要一个命令部署好")]),t._v(" "),r("blockquote",[r("p",[t._v("优点:确保了不同机器上跑都是一致的运行环境,不会出现我机器上跑正常,你机器跑就有问题的情况。")])]),t._v(" "),r("p",[t._v("例如 "),r("a",{attrs:{href:"https://easydoc.net/",target:"_blank",rel:"noopener noreferrer"}},[t._v("易文档"),r("OutboundLink")],1),t._v(","),r("a",{attrs:{href:"https://svnbucket.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("SVNBucket"),r("OutboundLink")],1),t._v(" 的私有化部署就是用 Docker,轻松应对客户的各种服务器。")]),t._v(" "),r("h2",{attrs:{id:"docker-通常用来做什么"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#docker-通常用来做什么"}},[t._v("#")]),t._v(" Docker 通常用来做什么")]),t._v(" "),r("ul",[r("li",[t._v("应用分发、部署,方便传播给他人安装。特别是开源软件和提供私有部署的应用")]),t._v(" "),r("li",[t._v("快速安装测试/学习软件,用完就丢(类似小程序),不把时间浪费在安装软件上。例如 Redis / MongoDB / ElasticSearch / ELK")]),t._v(" "),r("li",[t._v("多个版本软件共存,不污染系统,例如 Python2、Python3,Redis4.0,Redis5.0")]),t._v(" "),r("li",[t._v("Windows 上体验/学习各种 Linux 系统")])]),t._v(" "),r("h2",{attrs:{id:"重要概念-镜像、容器"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#重要概念-镜像、容器"}},[t._v("#")]),t._v(" 重要概念:镜像、容器")]),t._v(" "),r("p",[r("strong",[t._v("镜像")]),t._v(":可以理解为软件安装包,可以方便的进行传播和安装。")]),t._v(" "),r("p",[r("strong",[t._v("容器")]),t._v(":软件安装后的状态,每个软件运行环境都是独立的、隔离的,称之为容器。")]),t._v(" "),r("h2",{attrs:{id:"安装"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#安装"}},[t._v("#")]),t._v(" 安装")]),t._v(" "),r("p",[t._v("桌面版:"),r("a",{attrs:{href:"https://www.docker.com/products/docker-desktop",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://www.docker.com/products/docker-desktop"),r("OutboundLink")],1)]),t._v(" "),r("p",[t._v("服务器版:"),r("a",{attrs:{href:"https://docs.docker.com/engine/install/#server",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://docs.docker.com/engine/install/#server"),r("OutboundLink")],1)]),t._v(" "),r("h2",{attrs:{id:"启动报错解决"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#启动报错解决"}},[t._v("#")]),t._v(" 启动报错解决")]),t._v(" "),r("p",[t._v("报错截图")]),t._v(" "),r("p",[r("img",{attrs:{src:e(369),alt:"Untitled"}})]),t._v(" "),r("p",[r("strong",[t._v("解决方法")]),t._v(":")]),t._v(" "),r("p",[t._v("控制面板->程序->启用或关闭 windows 功能,开启 Windows 虚拟化和 Linux 子系统(WSL2)")]),t._v(" "),r("p",[r("img",{attrs:{src:e(370),alt:"Untitled"}})]),t._v(" "),r("p",[r("strong",[t._v("命令行安装 Linux 内核")])]),t._v(" "),r("p",[r("code",[t._v("wsl.exe --install -d Ubuntu")])]),t._v(" "),r("blockquote",[r("p",[t._v("你也可以打开微软商店 Microsoft Store 搜索 Linux 进行安装,选择一个最新版本的 Ubuntu 或者 Debian 都可以")])]),t._v(" "),r("blockquote",[r("p",[t._v("上面命令很可能你安装不了,微软商店你也可能打不开,如果遇到这个问题,参考:https://blog.csdn.net/qq_42220935/article/details/104714114")])]),t._v(" "),r("p",[r("strong",[t._v("设置开机启动 Hypervisor")])]),t._v(" "),r("p",[r("code",[t._v("bcdedit /set hypervisorlaunchtype auto")])]),t._v(" "),r("blockquote",[r("p",[t._v("注意要用管理员权限打开 PowerShell")])]),t._v(" "),r("p",[r("strong",[t._v("设置默认使用版本2")])]),t._v(" "),r("p",[r("code",[t._v("wsl.exe --set-default-version 2")])]),t._v(" "),r("p",[r("strong",[t._v("查看 WSL 是否安装正确")])]),t._v(" "),r("p",[r("code",[t._v("wsl.exe --list --verbose")])]),t._v(" "),r("p",[t._v("应该如下图,可以看到一个 Linux 系统,名字你的不一定跟我的一样,看你安装的是什么版本。")]),t._v(" "),r("p",[t._v("并且 VERSION 是 2")]),t._v(" "),r("p",[r("img",{attrs:{src:e(371),alt:"Untitled"}})]),t._v(" "),r("p",[r("strong",[t._v("确保 BIOS 已开启虚拟化,下图检查是否已开启好")])]),t._v(" "),r("blockquote",[r("p",[t._v("如果是已禁用,请在开机时按 F2 进入 BIOS 开启一下,不会设置的可以网上搜索下自己主板的设置方法,Intel 和 AMD 的设置可能稍有不同")])]),t._v(" "),r("p",[r("img",{attrs:{src:e(372),alt:"Untitled"}})]),t._v(" "),r("p",[r("strong",[t._v("出现下图错误,点击链接安装最新版本的 WSL2")])]),t._v(" "),r("p",[r("a",{attrs:{href:"https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi"),r("OutboundLink")],1)]),t._v(" "),r("p",[r("img",{attrs:{src:e(373),alt:"Untitled"}})]),t._v(" "),r("h2",{attrs:{id:"镜像加速源"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#镜像加速源"}},[t._v("#")]),t._v(" 镜像加速源")]),t._v(" "),r("table",[r("thead",[r("tr",[r("th",[t._v("镜像加速器")]),t._v(" "),r("th",[t._v("镜像加速器地址")])])]),t._v(" "),r("tbody",[r("tr",[r("td",[t._v("Docker 中国官方镜像")]),t._v(" "),r("td",[t._v("https://registry.docker-cn.com")])]),t._v(" "),r("tr",[r("td",[t._v("DaoCloud 镜像站")]),t._v(" "),r("td",[t._v("http://f1361db2.m.daocloud.io")])]),t._v(" "),r("tr",[r("td",[t._v("Azure 中国镜像")]),t._v(" "),r("td",[t._v("https://dockerhub.azk8s.cn")])]),t._v(" "),r("tr",[r("td",[t._v("科大镜像站")]),t._v(" "),r("td",[t._v("https://docker.mirrors.ustc.edu.cn")])]),t._v(" "),r("tr",[r("td",[t._v("阿里云")]),t._v(" "),r("td",[t._v("https://ud6340vz.mirror.aliyuncs.com")])]),t._v(" "),r("tr",[r("td",[t._v("七牛云")]),t._v(" "),r("td",[t._v("https://reg-mirror.qiniu.com")])]),t._v(" "),r("tr",[r("td",[t._v("网易云")]),t._v(" "),r("td",[t._v("https://hub-mirror.c.163.com")])]),t._v(" "),r("tr",[r("td",[t._v("腾讯云")]),t._v(" "),r("td",[t._v("https://mirror.ccs.tencentyun.com")])])])]),t._v(" "),r("p",[r("code",[t._v('"registry-mirrors": ["https://registry.docker-cn.com"]')])]),t._v(" "),r("p",[r("img",{attrs:{src:e(374),alt:"Untitled"}})])])}),[],!1,null,null,null);r.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/17.d39e6028.js b/assets/js/17.d39e6028.js new file mode 100644 index 0000000..a7bcda9 --- /dev/null +++ b/assets/js/17.d39e6028.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{312:function(t,s,a){t.exports=a.p+"assets/img/80.45baf6aa.png"},313:function(t,s,a){t.exports=a.p+"assets/img/81.91d115e8.png"},314:function(t,s,a){t.exports=a.p+"assets/img/82.ee29aaa1.png"},315:function(t,s,a){t.exports=a.p+"assets/img/83.1991b8e8.png"},316:function(t,s,a){t.exports=a.p+"assets/img/84.e8508045.png"},317:function(t,s,a){t.exports=a.p+"assets/img/85.92a58c83.png"},419:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-03-练习8-大小和数组"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-03-练习8-大小和数组"}},[t._v("#")]),t._v(" 2024.04.03-练习8:大小和数组")]),t._v(" "),s("h2",{attrs:{id:"_1-sizeof和数组"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-sizeof和数组"}},[t._v("#")]),t._v(" 1. "),s("code",[t._v("sizeof")]),t._v("和数组")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" areas"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("13")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("14")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Zed"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" full_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'Z'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'e'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'d'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("' '")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'A'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'.'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("' '")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'S'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'h'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'a'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'w'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\0'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// WARNING: On some systems you may have to change the")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// %ld in this code to a %u since it will use unsigned ints")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The size of an int: %ld\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The size of areas (int[]): %ld\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("areas"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The number of ints in areas: %ld\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("areas"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The first area is %d, the 2nd %d.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n areas"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" areas"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The size of a char: %ld\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The size of name (char[]): %ld\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The number of chars: %ld\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The size of full_name (char[]): %ld\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("full_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The number of chars: %ld\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("full_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name=\\"%s\\" and full_name=\\"%s\\"\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" full_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"_2-如何使它崩溃"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-如何使它崩溃"}},[t._v("#")]),t._v(" 2. 如何使它崩溃")]),t._v(" "),s("h3",{attrs:{id:"_2-1-将full-name最后的-0-去掉"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-将full-name最后的-0-去掉"}},[t._v("#")]),t._v(" 2.1 将"),s("code",[t._v("full_name")]),t._v("最后的"),s("code",[t._v("'\\0'")]),t._v("去掉")]),t._v(" "),s("p",[s("img",{attrs:{src:a(312),alt:"Untitled"}})]),t._v(" "),s("p",[s("img",{attrs:{src:a(313),alt:"Untitled"}})]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("无"),s("code",[t._v("\\0")]),t._v("终止符的后果")]),t._v(":标准的字符串处理函数(如"),s("code",[t._v("printf")]),t._v("的"),s("code",[t._v("%s")]),t._v("格式化输出、"),s("code",[t._v("strcpy")]),t._v("、"),s("code",[t._v("strlen")]),t._v("等)期望字符串以"),s("code",[t._v("\\0")]),t._v("终止。如果省略了"),s("code",[t._v("\\0")]),t._v(",这些函数会继续读取内存,直到偶然遇到一个"),s("code",[t._v("\\0")]),t._v("字节。这可能导致读取数组后面的内存,结果是不可预测的,可能会导致错误的输出、内存访问违规、甚至是程序崩溃。")]),t._v(" "),s("li",[s("strong",[t._v("为什么没有立即出错")]),t._v(':在实际使用中,如果紧接在字符数组后面的内存恰好是零(可能由于内存的初始状态或者其他变量的影响),那么使用字符串相关函数时可能看起来"运行正常"。但这是纯粹偶然的,并不可靠。随着程序的运行,内存布局的变化可能会改变这一状况,从而引发难以预测的错误。')])]),t._v(" "),s("h3",{attrs:{id:"_2-2-将areas-0-改为areas-10"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-将areas-0-改为areas-10"}},[t._v("#")]),t._v(" 2.2 将"),s("code",[t._v("areas[0]")]),t._v("改为"),s("code",[t._v("areas[10]")])]),t._v(" "),s("p",[s("img",{attrs:{src:a(314),alt:"Untitled"}})]),t._v(" "),s("p",[t._v("会打印出一个随机数")]),t._v(" "),s("h2",{attrs:{id:"_3-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-附加题"}},[t._v("#")]),t._v(" 3. 附加题")]),t._v(" "),s("h3",{attrs:{id:"_3-1-对areas的元素赋值"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-对areas的元素赋值"}},[t._v("#")]),t._v(" 3.1 对"),s("code",[t._v("areas")]),t._v("的元素赋值")]),t._v(" "),s("p",[s("img",{attrs:{src:a(315),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_3-2-对name的元素赋值"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-对name的元素赋值"}},[t._v("#")]),t._v(" 3.2 对"),s("code",[t._v("name")]),t._v("的元素赋值")]),t._v(" "),s("p",[s("img",{attrs:{src:a(316),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_3-3-将areas的一个元素赋值为name中的字符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-将areas的一个元素赋值为name中的字符"}},[t._v("#")]),t._v(" 3.3 将"),s("code",[t._v("areas")]),t._v("的一个元素赋值为"),s("code",[t._v("name")]),t._v("中的字符")]),t._v(" "),s("p",[s("img",{attrs:{src:a(317),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_3-4-c语言中不同的cpu上整数所占的不同大小"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-c语言中不同的cpu上整数所占的不同大小"}},[t._v("#")]),t._v(" 3.4 C语言中不同的CPU上整数所占的不同大小")]),t._v(" "),s("p",[s("strong",[t._v("1. 32位系统(如x86)")])]),t._v(" "),s("p",[t._v("在32位系统上,通常遵循ILP32数据模型,其中:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("int")]),t._v(" 通常是32位(4字节)。")]),t._v(" "),s("li",[s("code",[t._v("short")]),t._v(" 通常是16位(2字节)。")]),t._v(" "),s("li",[s("code",[t._v("long")]),t._v(" 也通常是32位(4字节)。")]),t._v(" "),s("li",[s("code",[t._v("long long")]),t._v(" 保证至少是64位(8字节)。")]),t._v(" "),s("li",[t._v("指针大小是32位(4字节)。")])]),t._v(" "),s("p",[s("strong",[t._v("2. 64位系统(如x86_64或AMD64)")])]),t._v(" "),s("p",[t._v("在64位系统上,最常见的数据模型是LP64,其中:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("int")]),t._v(" 保持32位(4字节)。")]),t._v(" "),s("li",[s("code",[t._v("short")]),t._v(" 仍然是16位(2字节)。")]),t._v(" "),s("li",[s("code",[t._v("long")]),t._v(" 和指针的大小增加到64位(8字节)。")]),t._v(" "),s("li",[s("code",[t._v("long long")]),t._v(" 保证至少是64位(8字节)。")])]),t._v(" "),s("p",[t._v("另一个在某些64位系统(如Windows的64位版本)上使用的数据模型是LLP64,它保持"),s("code",[t._v("long")]),t._v("为32位,而只有指针和"),s("code",[t._v("long long")]),t._v("是64位。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/18.3d9ea382.js b/assets/js/18.3d9ea382.js new file mode 100644 index 0000000..cabcf50 --- /dev/null +++ b/assets/js/18.3d9ea382.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[18],{347:function(s,a,t){s.exports=t.p+"assets/img/2Untitled.a0446167.png"},348:function(s,a,t){s.exports=t.p+"assets/img/2Untitled1.27be85d1.png"},349:function(s,a,t){s.exports=t.p+"assets/img/22.d7d4f076.png"},350:function(s,a,t){s.exports=t.p+"assets/img/23.5d2a18d3.png"},351:function(s,a,t){s.exports=t.p+"assets/img/24.ef298398.png"},352:function(s,a,t){s.exports=t.p+"assets/img/25.292bd7a3.png"},437:function(s,a,t){"use strict";t.r(a);var e=t(14),n=Object(e.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h1",{attrs:{id:"_2024-03-19-2-script"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-19-2-script"}},[s._v("#")]),s._v(" 2024.03.19-2. Script")]),s._v(" "),a("h1",{attrs:{id:"_1-shell"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-shell"}},[s._v("#")]),s._v(" 1. Shell")]),s._v(" "),a("h2",{attrs:{id:"_1-1-变量赋值"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-变量赋值"}},[s._v("#")]),s._v(" 1.1 变量赋值")]),s._v(" "),a("p",[s._v("在 bash 中为变量赋值的语法是 "),a("code",[s._v("foo=bar")]),s._v(" ,访问变量中存储的数值,其语法为  "),a("code",[s._v("$foo")]),s._v("。 需要注意的是,"),a("code",[s._v("foo = bar")]),s._v(" (使用空格隔开)是不能正确工作的,因为解释器会调用程序"),a("code",[s._v("foo")]),s._v("  并将  "),a("code",[s._v("=")]),s._v("  和  "),a("code",[s._v("bar")]),s._v("作为参数。 总的来说,在 shell 脚本中使用空格会起到分割参数的作用,有时候可能会造成混淆,请务必多加检查。")]),s._v(" "),a("p",[s._v("Bash 中的字符串通过"),a("code",[s._v("'")]),s._v("  和  "),a("code",[s._v('"')]),s._v("分隔符来定义,但是它们的含义并不相同。以"),a("code",[s._v("'")]),s._v("定义的字符串为原义字符串,其中的变量不会被转义,而  "),a("code",[s._v('"')]),s._v("定义的字符串会将变量值进行替换。")]),s._v(" "),a("p",[a("img",{attrs:{src:t(347),alt:"Untitled"}})]),s._v(" "),a("h2",{attrs:{id:"_1-2-函数"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-函数"}},[s._v("#")]),s._v(" 1.2 函数")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("// mcd.sh\n// 创建一个文件夹并使用cd进入该文件夹。\n"),a("span",{pre:!0,attrs:{class:"token function-name function"}},[s._v("mcd")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("mkdir")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-p")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$1")]),s._v('"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("cd")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$1")]),s._v('"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("这里  "),a("code",[s._v("$1")]),s._v("  是脚本的第一个参数。与其他脚本语言不同的是,bash 使用了很多特殊的变量来表示参数、错误代码和相关变量。下面列举了其中一些变量,更完整的列表可以参考  "),a("a",{attrs:{href:"https://www.tldp.org/LDP/abs/html/special-chars.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("这里"),a("OutboundLink")],1),s._v("。")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("$0")]),s._v(" - 脚本名")]),s._v(" "),a("li",[a("code",[s._v("$1")]),s._v("  到  "),a("code",[s._v("$9")]),s._v(" - 脚本的参数。 "),a("code",[s._v("$1")]),s._v("  是第一个参数,依此类推。")]),s._v(" "),a("li",[a("code",[s._v("$@")]),s._v(" - 所有参数")]),s._v(" "),a("li",[a("code",[s._v("$#")]),s._v(" - 参数个数")]),s._v(" "),a("li",[a("code",[s._v("$?")]),s._v(" - 前一个命令的返回值")]),s._v(" "),a("li",[a("code",[s._v("$$")]),s._v(" - 当前脚本的进程识别码")]),s._v(" "),a("li",[a("code",[s._v("!!")]),s._v(" - 完整的上一条命令,包括参数。常见应用:当你因为权限不足执行命令失败时,可以使用  "),a("code",[s._v("sudo !!")]),s._v("再尝试一次。")]),s._v(" "),a("li",[a("code",[s._v("$_")]),s._v(" - 上一条命令的最后一个参数。如果你正在使用的是交互式 shell,你可以通过按下  "),a("code",[s._v("Esc")]),s._v("  之后键入 . 来获取这个值。")])]),s._v(" "),a("p",[s._v("使用 "),a("code",[s._v("source mcd.sh")]),s._v(" 会将 mcd 函数加载进来,后面可以直接调用")]),s._v(" "),a("h2",{attrs:{id:"_1-3-返回码"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-返回码"}},[s._v("#")]),s._v(" 1.3 返回码")]),s._v(" "),a("p",[s._v("命令通常使用  "),a("code",[s._v("STDOUT")]),s._v("来返回输出值,使用"),a("code",[s._v("STDERR")]),s._v("  来返回错误及错误码,便于脚本以更加友好的方式报告错误。 返回码或退出状态是脚本/命令之间交流执行状态的方式。返回值 0 表示正常执行,其他所有非 0 的返回值都表示有错误发生。")]),s._v(" "),a("p",[s._v("退出码可以搭配  "),a("code",[s._v("&&")]),s._v("(与操作符)和  "),a("code",[s._v("||")]),s._v("(或操作符)使用,用来进行条件判断,决定是否执行其他程序。它们都属于短路"),a("a",{attrs:{href:"https://en.wikipedia.org/wiki/Short-circuit_evaluation",target:"_blank",rel:"noopener noreferrer"}},[s._v("运算符"),a("OutboundLink")],1),s._v("(short-circuiting) 同一行的多个命令可以用  "),a("code",[s._v(";")]),s._v("  分隔。程序  "),a("code",[s._v("true")]),s._v("  的返回码永远是"),a("code",[s._v("0")]),s._v(","),a("code",[s._v("false")]),s._v("  的返回码永远是"),a("code",[s._v("1")]),s._v("。")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("false")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("||")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Oops, fail"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# Oops, fail")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("||")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Will not be printed"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("#")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("&&")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Things went well"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# Things went well")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("false")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("&&")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Will not be printed"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("#")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("false")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"This will always run"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# This will always run")]),s._v("\n")])])]),a("p",[s._v("另一个常见的模式是以变量的形式获取一个命令的输出,这可以通过  "),a("em",[s._v("命令替换")]),s._v("("),a("em",[s._v("command substitution")]),s._v(")实现。")]),s._v(" "),a("p",[s._v("当您通过  "),a("code",[s._v("$( CMD )")]),s._v("  这样的方式来执行"),a("code",[s._v("CMD")]),s._v("  这个命令时,它的输出结果会替换掉  "),a("code",[s._v("$( CMD )")]),s._v(" 。例如,如果执行  "),a("code",[s._v("for file in $(ls)")]),s._v(" ,shell 首先将调用"),a("code",[s._v("ls")]),s._v(" ,然后遍历得到的这些返回值。还有一个冷门的类似特性是  "),a("em",[s._v("进程替换")]),s._v("("),a("em",[s._v("process substitution")]),s._v("), "),a("code",[s._v("<( CMD )")]),s._v("  会执行  "),a("code",[s._v("CMD")]),s._v("  并将结果输出到一个临时文件中,并将  "),a("code",[s._v("<( CMD )")]),s._v("  替换成临时文件名。这在我们希望返回值通过文件而不是 STDIN 传递时很有用。例如, "),a("code",[s._v("diff <(ls foo) <(ls bar)")]),s._v("  会显示文件夹  "),a("code",[s._v("foo")]),s._v("  和  "),a("code",[s._v("bar")]),s._v("  中文件的区别。")]),s._v(" "),a("p",[s._v("说了很多,现在该看例子了,下面这个例子展示了一部分上面提到的特性。这段脚本会遍历我们提供的参数,使用"),a("code",[s._v("grep")]),s._v("  搜索字符串  "),a("code",[s._v("foobar")]),s._v(",如果没有找到,则将其作为注释追加到文件中。")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#!/bin/bash")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Starting program at '),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("date")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# date会被替换成日期和时间")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Running program '),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$0")]),s._v(" with "),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$#")]),s._v(" arguments with pid "),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$$")]),s._v('"')]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("for")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token for-or-select variable"}},[s._v("file")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$@")]),s._v('"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("do")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" foobar "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$file")]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" /dev/null "),a("span",{pre:!0,attrs:{class:"token operator"}},[a("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[s._v("2")]),s._v(">")]),s._v(" /dev/null\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 如果模式没有找到,则grep退出状态为 1")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 我们将标准输出流和标准错误流重定向到Null,因为我们并不关心这些信息")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$?")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-ne")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("then")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"File '),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$file")]),s._v(' does not have any foobar, adding one"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"# foobar"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">>")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$file")]),s._v('"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("fi")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("done")]),s._v("\n")])])]),a("p",[s._v("在条件语句中,我们比较  "),a("code",[s._v("$?")]),s._v("  是否等于 0。 Bash 实现了许多类似的比较操作,您可以查看  "),a("code",[s._v("[test 手册](https://man7.org/linux/man-pages/man1/test.1.html)")]),s._v("。 在 bash 中进行比较时,尽量使用双方括号  "),a("code",[s._v("[[ ]]")]),s._v("  而不是单方括号  "),a("code",[s._v("[ ]")]),s._v(",这样会降低犯错的几率,尽管这样并不能兼容  "),a("code",[s._v("sh")]),s._v("。 更详细的说明参见"),a("a",{attrs:{href:"http://mywiki.wooledge.org/BashFAQ/031",target:"_blank",rel:"noopener noreferrer"}},[s._v("这里"),a("OutboundLink")],1),s._v("。")]),s._v(" "),a("h2",{attrs:{id:"_1-4-通配"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-4-通配"}},[s._v("#")]),s._v(" 1.4 通配")]),s._v(" "),a("p",[s._v("当执行脚本时,我们经常需要提供形式类似的参数。bash 使我们可以轻松的实现这一操作,它可以基于文件扩展名展开表达式。这一技术被称为 shell 的  "),a("em",[s._v("通配")]),s._v("("),a("em",[s._v("globbing")]),s._v(")")]),s._v(" "),a("ul",[a("li",[s._v("通配符 - 当你想要利用通配符进行匹配时,你可以分别使用  "),a("code",[s._v("?")]),s._v("  和  "),a("code",[s._v("*")]),s._v(" 来匹配一个或任意个字符。例如,对于文件"),a("code",[s._v("foo")]),s._v(", "),a("code",[s._v("foo1")]),s._v(", "),a("code",[s._v("foo2")]),s._v(", "),a("code",[s._v("foo10")]),s._v("  和  "),a("code",[s._v("bar")]),s._v(", "),a("code",[s._v("rm foo?")]),s._v("这条命令会删除"),a("code",[s._v("foo1")]),s._v("  和  "),a("code",[s._v("foo2")]),s._v(" ,而"),a("code",[s._v("rm foo*")]),s._v("  则会删除除了"),a("code",[s._v("bar")]),s._v("之外的所有文件。")]),s._v(" "),a("li",[s._v("花括号"),a("code",[s._v("{}")]),s._v(" - 当你有一系列的指令,其中包含一段公共子串时,可以用花括号来自动展开这些命令。这在批量移动或转换文件时非常方便。")])]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("convert image."),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("png,jpg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 会展开为")]),s._v("\nconvert image.png image.jpg\n\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cp")]),s._v(" /path/to/project/"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("foo,bar,baz"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(".sh /newpath\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 会展开为")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cp")]),s._v(" /path/to/project/foo.sh /path/to/project/bar.sh /path/to/project/baz.sh /newpath\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 也可以结合通配使用")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("mv")]),s._v(" *"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(".py,.sh"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" folder\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 会移动所有 *.py 和 *.sh 文件")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("mkdir")]),s._v(" foo bar\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 下面命令会创建foo/a, foo/b, ... foo/h, bar/a, bar/b, ... bar/h这些文件")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("touch")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("foo,bar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("/"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("..")]),s._v("h"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("touch")]),s._v(" foo/x bar/y\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 比较文件夹 foo 和 bar 中包含文件的不同")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("diff")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ls")]),s._v(" foo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ls")]),s._v(" bar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 输出")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# < x")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# ---")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# > y")]),s._v("\n")])])]),a("h2",{attrs:{id:"_1-5-shebang"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-5-shebang"}},[s._v("#")]),s._v(" 1.5 shebang")]),s._v(" "),a("p",[s._v("脚本并不一定只有用 bash 写才能在终端里调用。比如说,这是一段 Python 脚本,作用是将输入的参数倒序输出:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("*"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("#!/usr/local/bin/python //* #!/usr/bin/env python")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("import")]),s._v(" sys\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("for")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token for-or-select variable"}},[s._v("arg")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" reversed"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("sys.argv"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(":"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(":\n print"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("arg"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])])]),a("p",[s._v("内核知道去用 python 解释器而不是 shell 命令来运行这段脚本,是因为脚本的开头第一行的  "),a("a",{attrs:{href:"https://en.wikipedia.org/wiki/Shebang_(Unix)",target:"_blank",rel:"noopener noreferrer"}},[s._v("shebang"),a("OutboundLink")],1),s._v("。")]),s._v(" "),a("p",[s._v("在  "),a("code",[s._v("shebang")]),s._v("  行中使用  "),a("code",[s._v("[env](https://man7.org/linux/man-pages/man1/env.1.html)")]),s._v("  命令是一种好的实践,它会利用环境变量中的程序来解析该脚本,这样就提高了您的脚本的可移植性。"),a("code",[s._v("env")]),s._v("  会利用我们第一节讲座中介绍过的"),a("code",[s._v("PATH")]),s._v("  环境变量来进行定位。 例如,使用了"),a("code",[s._v("env")]),s._v("的 shebang 看上去是这样的"),a("code",[s._v("#!/usr/bin/env python")]),s._v("。")]),s._v(" "),a("h2",{attrs:{id:"_1-6-shell-函数和脚本"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-6-shell-函数和脚本"}},[s._v("#")]),s._v(" 1.6 shell 函数和脚本")]),s._v(" "),a("p",[s._v("shell 函数和脚本有如下一些不同点:")]),s._v(" "),a("ul",[a("li",[s._v("函数只能与 shell 使用相同的语言,脚本可以使用任意语言。因此在脚本中包含  "),a("code",[s._v("shebang")]),s._v("  是很重要的。")]),s._v(" "),a("li",[s._v("函数仅在定义时被加载,脚本会在每次被执行时加载。这让函数的加载比脚本略快一些,但每次修改函数定义,都要重新加载一次。")]),s._v(" "),a("li",[s._v("函数会在当前的 shell 环境中执行,脚本会在单独的进程中执行。因此,函数可以对环境变量进行更改,比如改变当前工作目录,脚本则不行。脚本需要使用  "),a("code",[s._v("[export](https://man7.org/linux/man-pages/man1/export.1p.html)")]),s._v("  将环境变量导出,并将值传递给环境变量。")]),s._v(" "),a("li",[s._v("与其他程序语言一样,函数可以提高代码模块性、代码复用性并创建清晰性的结构。shell 脚本中往往也会包含它们自己的函数定义。")])]),s._v(" "),a("h2",{attrs:{id:"_1-7-shellcheck"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-7-shellcheck"}},[s._v("#")]),s._v(" 1.7  shellcheck")]),s._v(" "),a("p",[s._v("编写  "),a("code",[s._v("bash")]),s._v("  脚本有时候会很别扭和反直觉。例如  "),a("a",{attrs:{href:"https://github.com/koalaman/shellcheck",target:"_blank",rel:"noopener noreferrer"}},[s._v("shellcheck"),a("OutboundLink")],1),s._v("  这样的工具可以帮助你定位 sh/bash 脚本中的错误。")]),s._v(" "),a("h1",{attrs:{id:"_2-shell-工具"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-shell-工具"}},[s._v("#")]),s._v(" 2. Shell 工具")]),s._v(" "),a("h2",{attrs:{id:"_2-1-查看命令如何使用"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-查看命令如何使用"}},[s._v("#")]),s._v(" 2.1 查看命令如何使用")]),s._v(" "),a("p",[s._v("看到这里,您可能会有疑问,我们应该如何为特定的命令找到合适的标记呢?例如  "),a("code",[s._v("ls -l")]),s._v(", "),a("code",[s._v("mv -i")]),s._v("  和  "),a("code",[s._v("mkdir -p")]),s._v("。更普遍的是,给您一个命令行,您应该怎样了解如何使用这个命令行并找出它的不同的选项呢? 一般来说,您可能会先去网上搜索答案,但是,UNIX 可比 StackOverflow 出现的早,因此我们的系统里其实早就包含了可以获取相关信息的方法。")]),s._v(" "),a("p",[s._v("在上一节中我们介绍过,最常用的方法是为对应的命令行添加"),a("code",[s._v("-h")]),s._v("  或  "),a("code",[s._v("--help")]),s._v("  标记。另外一个更详细的方法则是使用"),a("code",[s._v("man")]),s._v("  命令。"),a("code",[s._v("[man](https://man7.org/linux/man-pages/man1/man.1.html)")]),s._v("  命令是手册(manual)的缩写,它提供了命令的用户手册。")]),s._v(" "),a("p",[s._v("例如,"),a("code",[s._v("man rm")]),s._v("  会输出命令  "),a("code",[s._v("rm")]),s._v("  的说明,同时还有其标记列表,包括之前我们介绍过的"),a("code",[s._v("-i")]),s._v("。 事实上,目前我们给出的所有命令的说明链接,都是网页版的 Linux 命令手册。即使是您安装的第三方命令,前提是开发者编写了手册并将其包含在了安装包中。在交互式的、基于字符处理的终端窗口中,一般也可以通过  "),a("code",[s._v(":help")]),s._v("  命令或键入  "),a("code",[s._v("?")]),s._v("  来获取帮助。")]),s._v(" "),a("p",[s._v("有时候手册内容太过详实,让我们难以在其中查找哪些最常用的标记和语法。 "),a("a",{attrs:{href:"https://tldr.sh/",target:"_blank",rel:"noopener noreferrer"}},[s._v("TLDR pages"),a("OutboundLink")],1),s._v("  是一个很不错的替代品,它提供了一些案例,可以帮助您快速找到正确的选项。")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("snap "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("install")]),s._v(" tldr "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# in Ubuntu")]),s._v("\n")])])]),a("h2",{attrs:{id:"_2-2-查找文件"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-查找文件"}},[s._v("#")]),s._v(" 2.2 查找文件")]),s._v(" "),a("p",[s._v("程序员们面对的最常见的重复任务就是查找文件或目录。所有的类 UNIX 系统都包含一个名为  "),a("code",[s._v("[find](https://man7.org/linux/man-pages/man1/find.1.html)")]),s._v("  的工具,它是 shell 上用于查找文件的绝佳工具。"),a("code",[s._v("find")]),s._v("命令会递归地搜索符合条件的文件,例如:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 查找所有名称为src的文件夹")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("find")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v(".")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-name")]),s._v(" src "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-type")]),s._v(" d\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 查找前一天修改的所有文件")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("find")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v(".")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-mtime")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-1")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 查找所有大小在500k至10M的tar.gz文件")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("find")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v(".")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-size")]),s._v(" +500k "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-size")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-10M")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-name")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'*.tar.gz'")]),s._v("\n")])])]),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 查找所有文件夹路径中包含test的python文件")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("find")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v(".")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-path")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'/test/*.py'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-type")]),s._v(" f\n")])])]),a("ol",[a("li",[a("code",[s._v("find .")]),s._v(":这个命令从当前目录("),a("code",[s._v(".")]),s._v("代表当前目录)开始递归搜索。")]),s._v(" "),a("li",[a("code",[s._v("path '/test/*.py'")]),s._v(":这部分指定了搜索的路径模式:\n"),a("ul",[a("li",[s._v("``:这个模式匹配零个或多个目录;在"),a("code",[s._v("/test/\\*.py")]),s._v("中,它表示可以匹配任何深度的目录层级,直到遇到"),a("code",[s._v("test")]),s._v("目录。")]),s._v(" "),a("li",[a("code",[s._v("test")]),s._v("是一个具体的目录名,表示在任何可能的位置中寻找名为"),a("code",[s._v("test")]),s._v("的目录。")]),s._v(" "),a("li",[a("code",[s._v(".py")]),s._v(":这个模式匹配所有以"),a("code",[s._v(".py")]),s._v("结尾的文件,即 Python 脚本文件。")])])]),s._v(" "),a("li",[a("code",[s._v("type f")]),s._v(":这个参数告诉"),a("code",[s._v("find")]),s._v("命令只关心文件("),a("code",[s._v("f")]),s._v("代表文件),不要在结果中包括目录或其他类型的文件系统对象。")])]),s._v(" "),a("p",[s._v("除了列出所寻找的文件之外,find 还能对所有查找到的文件进行操作。这能极大地简化一些单调的任务。")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("*"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 删除全部扩展名为.tmp 的文件*")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("find")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v(".")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-name")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'*.tmp'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-exec")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("rm")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("\\")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n*"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 查找全部的 PNG 文件并将其转换为 JPG*")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("find")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v(".")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-name")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'*.png'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-exec")]),s._v(" convert "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(".jpg "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("\\")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("p",[s._v("这段代码是一个在 Unix 或类 Unix 系统中使用的 shell 命令,用于查找当前目录及其子目录中所有的"),a("code",[s._v(".png")]),s._v("文件,并将每个找到的文件转换为"),a("code",[s._v(".jpg")]),s._v("格式。这里一步一步解释这个命令:")]),s._v(" "),a("ol",[a("li",[a("code",[s._v("find . -name '*.png'")]),s._v(":这个命令从当前目录("),a("code",[s._v(".")]),s._v("代表当前目录)开始递归搜索所有扩展名为"),a("code",[s._v(".png")]),s._v("的文件。"),a("code",[s._v("name '*.png'")]),s._v("指定了要匹配的文件名模式,星号``是一个通配符,表示任意数量的任意字符。")]),s._v(" "),a("li",[a("code",[s._v("exec convert {} {}.jpg \\;")]),s._v(":这部分指定了"),a("code",[s._v("find")]),s._v("命令找到每个文件后要执行的操作。"),a("code",[s._v("exec")]),s._v("后面跟的是要执行的命令,这里使用"),a("code",[s._v("convert")]),s._v("命令来转换图像格式。\n"),a("ul",[a("li",[a("code",[s._v("convert")]),s._v(":这是 ImageMagick 工具集中的一个命令,用于转换图像格式。")]),s._v(" "),a("li",[a("code",[s._v("{}")]),s._v(":这是一个特殊的占位符,对于每个匹配的文件,"),a("code",[s._v("find")]),s._v("命令都会在这个位置插入文件的路径。")]),s._v(" "),a("li",[a("code",[s._v("{}.jpg")]),s._v(":这指定了输出文件的名称。对于每个输入文件,这会在原文件名(即"),a("code",[s._v("{}")]),s._v(")后添加"),a("code",[s._v(".jpg")]),s._v("扩展名,创建一个新的文件名。")]),s._v(" "),a("li",[a("code",[s._v("\\;")]),s._v(":这个分号表示"),a("code",[s._v("exec")]),s._v("参数的结束,并且需要转义("),a("code",[s._v("\\;")]),s._v(")来避免被 shell 解释。")])])])]),s._v(" "),a("p",[s._v("尽管  "),a("code",[s._v("find")]),s._v("  用途广泛,它的语法却比较难以记忆。例如,为了查找满足模式  "),a("code",[s._v("PATTERN")]),s._v("  的文件,您需要执行  "),a("code",[s._v("find -name '*PATTERN*'")]),s._v(" (如果您希望模式匹配时是不区分大小写,可以使用"),a("code",[s._v("-iname")]),s._v("选项)")]),s._v(" "),a("p",[s._v("您当然可以使用 alias 设置别名来简化上述操作,但 shell 的哲学之一便是寻找(更好用的)替代方案。 记住,shell 最好的特性就是您只是在调用程序,因此您只要找到合适的替代程序即可(甚至自己编写)。")]),s._v(" "),a("p",[s._v("例如,"),a("code",[s._v("[fd](https://github.com/sharkdp/fd)")]),s._v("  就是一个更简单、更快速、更友好的程序,它可以用来作为"),a("code",[s._v("find")]),s._v("的替代品。它有很多不错的默认设置,例如输出着色、默认支持正则匹配、支持 unicode 并且我认为它的语法更符合直觉。以模式"),a("code",[s._v("PATTERN")]),s._v("  搜索的语法是  "),a("code",[s._v("fd PATTERN")]),s._v("。")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sudo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("apt")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("install")]),s._v(" fdfind\n")])])]),a("p",[s._v("下面是关于如何使用 "),a("code",[s._v("fd")]),s._v(" 以及一些实际的例子:")]),s._v(" "),a("h3",{attrs:{id:"fd-基本用法"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#fd-基本用法"}},[s._v("#")]),s._v(" "),a("code",[s._v("fd")]),s._v(" 基本用法")]),s._v(" "),a("ul",[a("li",[s._v("查找文件:输入 "),a("code",[s._v("fd")]),s._v(" 后跟你要搜索的文件名或模式,它会在当前目录及其子目录下查找匹配的文件。例如,要查找所有的 "),a("code",[s._v(".txt")]),s._v(" 文件,你可以使用:"),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("fd "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'\\.txt$'")]),s._v("\n")])])])]),s._v(" "),a("li",[s._v("指定搜索目录:你可以在命令中指定一个特定的目录来让 "),a("code",[s._v("fd")]),s._v(" 在其中搜索。例如,要在 "),a("code",[s._v("~/Documents")]),s._v(" 目录中搜索 "),a("code",[s._v(".pdf")]),s._v(" 文件:"),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("fd "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'\\.pdf$'")]),s._v(" ~/Documents\n")])])])])]),s._v(" "),a("h3",{attrs:{id:"fd-高级用法"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#fd-高级用法"}},[s._v("#")]),s._v(" "),a("code",[s._v("fd")]),s._v(" 高级用法")]),s._v(" "),a("ul",[a("li",[s._v("忽略大小写:"),a("code",[s._v("fd")]),s._v(" 默认使用智能大小写搜索。如果你想强制执行不区分大小写的搜索,可以使用 "),a("code",[s._v("i")]),s._v(" 选项。例如,查找所有的 "),a("code",[s._v("README")]),s._v(" 文件(不区分大小写):"),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("fd "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-i")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'readme'")]),s._v("\n")])])])]),s._v(" "),a("li",[s._v("使用正则表达式:"),a("code",[s._v("fd")]),s._v(" 支持正则表达式,让你可以进行更复杂的搜索。例如,查找所有以 "),a("code",[s._v("a")]),s._v(" 开头,以 "),a("code",[s._v("z")]),s._v(" 结尾的文件:"),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("fd "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'^a.*z$'")]),s._v("\n")])])])]),s._v(" "),a("li",[s._v("排除特定目录:如果你想在搜索中排除特定的目录,可以使用 "),a("code",[s._v("E")]),s._v(" 选项。例如,搜索所有 "),a("code",[s._v(".js")]),s._v(" 文件,但排除掉 "),a("code",[s._v("node_modules")]),s._v(" 目录:"),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("fd "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'\\.js$'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-E")]),s._v(" node_modules\n")])])])]),s._v(" "),a("li",[s._v("输出搜索结果到其他命令:"),a("code",[s._v("fd")]),s._v(" 的输出可以通过管道传递给其他命令。例如,你可以使用 "),a("code",[s._v("xargs")]),s._v(" 结合 "),a("code",[s._v("fd")]),s._v(" 来对找到的文件执行操作。下面的命令将找到所有 "),a("code",[s._v(".tmp")]),s._v(" 文件并删除它们:"),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("fd "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'\\.tmp$'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("xargs")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("rm")]),s._v("\n")])])])])]),s._v(" "),a("h3",{attrs:{id:"fd-实用示例"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#fd-实用示例"}},[s._v("#")]),s._v(" "),a("code",[s._v("fd")]),s._v(" 实用示例")]),s._v(" "),a("ol",[a("li",[a("p",[s._v("快速查找特定文件:如果你想找到所有的 JPEG 图片文件,可以使用如下命令:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("fd "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'\\.jpg$'")]),s._v("\n")])])])]),s._v(" "),a("li",[a("p",[s._v("在特定目录下搜索:如果你需要在 "),a("code",[s._v("/var/log")]),s._v(" 目录下查找扩展名为 "),a("code",[s._v(".log")]),s._v(" 的文件,可以使用:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("fd "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'\\.log$'")]),s._v(" /var/lo\n")])])])])]),s._v(" "),a("p",[s._v("大多数人都认为  "),a("code",[s._v("find")]),s._v("  和  "),a("code",[s._v("fd")]),s._v("  已经很好用了,但是有的人可能想知道,我们是不是可以有更高效的方法,例如不要每次都搜索文件而是通过编译索引或建立数据库的方式来实现更加快速地搜索。")]),s._v(" "),a("p",[s._v("这就要靠  "),a("code",[s._v("[locate](https://man7.org/linux/man-pages/man1/locate.1.html)")]),s._v("  了。 "),a("code",[s._v("locate")]),s._v("  使用一个由  "),a("code",[s._v("[updatedb](https://man7.org/linux/man-pages/man1/updatedb.1.html)")]),s._v("负责更新的数据库,在大多数系统中  "),a("code",[s._v("updatedb")]),s._v("  都会通过  "),a("code",[s._v("[cron](https://man7.org/linux/man-pages/man8/cron.8.html)")]),s._v("  每日更新。这便需要我们在速度和时效性之间作出权衡。而且,"),a("code",[s._v("find")]),s._v("  和类似的工具可以通过别的属性比如文件大小、修改时间或是权限来查找文件,"),a("code",[s._v("locate")]),s._v("则只能通过文件名。 "),a("a",{attrs:{href:"https://unix.stackexchange.com/questions/60205/locate-vs-find-usage-pros-and-cons-of-each-other",target:"_blank",rel:"noopener noreferrer"}},[s._v("这里"),a("OutboundLink")],1),s._v("有一个更详细的对比。")]),s._v(" "),a("h2",{attrs:{id:"_2-3-查找代码"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-查找代码"}},[s._v("#")]),s._v(" 2.3 查找代码")]),s._v(" "),a("p",[s._v("查找文件是很有用的技能,但是很多时候您的目标其实是查看文件的内容。一个最常见的场景是您希望查找具有某种模式的全部文件,并找它们的位置。")]),s._v(" "),a("p",[s._v("为了实现这一点,很多类 UNIX 的系统都提供了"),a("code",[s._v("[grep](https://man7.org/linux/man-pages/man1/grep.1.html)")]),s._v("命令,它是用于对输入文本进行匹配的通用工具。它是一个非常重要的 shell 工具,我们会在后续的数据清理课程中深入的探讨它。")]),s._v(" "),a("p",[a("code",[s._v("grep")]),s._v("  有很多选项,这也使它成为一个非常全能的工具。其中我经常使用的有  "),a("code",[s._v("-C")]),s._v(" :获取查找结果的上下文(Context);"),a("code",[s._v("-v")]),s._v("  将对结果进行反选(Invert),也就是输出不匹配的结果。举例来说, "),a("code",[s._v("grep -C 5")]),s._v("  会输出匹配结果前后五行。当需要搜索大量文件的时候,使用  "),a("code",[s._v("-R")]),s._v("  会递归地进入子目录并搜索所有的文本文件。")]),s._v(" "),a("p",[s._v("但是,我们有很多办法可以对  "),a("code",[s._v("grep -R")]),s._v("  进行改进,例如使其忽略"),a("code",[s._v(".git")]),s._v("  文件夹,使用多 CPU 等等。")]),s._v(" "),a("p",[s._v("因此也出现了很多它的替代品,包括  "),a("a",{attrs:{href:"https://beyondgrep.com/",target:"_blank",rel:"noopener noreferrer"}},[s._v("ack"),a("OutboundLink")],1),s._v(", "),a("a",{attrs:{href:"https://github.com/ggreer/the_silver_searcher",target:"_blank",rel:"noopener noreferrer"}},[s._v("ag"),a("OutboundLink")],1),s._v("  和  "),a("a",{attrs:{href:"https://github.com/BurntSushi/ripgrep",target:"_blank",rel:"noopener noreferrer"}},[s._v("rg"),a("OutboundLink")],1),s._v("。它们都特别好用,但是功能也都差不多,我比较常用的是 ripgrep ("),a("code",[s._v("rg")]),s._v(") ,因为它速度快,而且用法非常符合直觉。例子如下:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 查找所有使用了 requests 库的文件")]),s._v("\nrg "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-t")]),s._v(" py "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'import requests'")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 查找所有没有写 shebang 的文件(包含隐藏文件)")]),s._v("\nrg "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-u")]),s._v(" --files-without-match "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"^#!"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 查找所有的foo字符串,并打印其之后的5行")]),s._v("\nrg foo "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-A")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("5")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 打印匹配的统计信息(匹配的行和文件的数量)")]),s._v("\nrg "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("--stats")]),s._v(" PATTERN\n")])])]),a("h2",{attrs:{id:"_2-4-查找-shell-命令"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-4-查找-shell-命令"}},[s._v("#")]),s._v(" 2.4 查找 shell 命令")]),s._v(" "),a("p",[s._v("首先,按向上的方向键会显示你使用过的上一条命令,继续按上键则会遍历整个历史记录。")]),s._v(" "),a("p",[a("code",[s._v("history")]),s._v("  命令允许您以程序员的方式来访问 shell 中输入的历史命令。这个命令会在标准输出中打印 shell 中的历史命令。如果我们要搜索历史记录,则可以利用管道将输出结果传递给  "),a("code",[s._v("grep")]),s._v("  进行模式搜索。 "),a("code",[s._v("history | grep find")]),s._v("  会打印包含 find 子串的命令。")]),s._v(" "),a("p",[s._v("对于大多数的 shell 来说,您可以使用  "),a("code",[s._v("Ctrl+R")]),s._v("  对命令历史记录进行回溯搜索。敲  "),a("code",[s._v("Ctrl+R")]),s._v("  后您可以输入子串来进行匹配,查找历史命令行。")]),s._v(" "),a("p",[s._v("反复按下就会在所有搜索结果中循环。在  "),a("a",{attrs:{href:"https://github.com/zsh-users/zsh-history-substring-search",target:"_blank",rel:"noopener noreferrer"}},[s._v("zsh"),a("OutboundLink")],1),s._v("  中,使用方向键上或下也可以完成这项工作。")]),s._v(" "),a("p",[a("code",[s._v("Ctrl+R")]),s._v("  可以配合  "),a("a",{attrs:{href:"https://github.com/junegunn/fzf/wiki/Configuring-shell-key-bindings#ctrl-r",target:"_blank",rel:"noopener noreferrer"}},[s._v("fzf"),a("OutboundLink")],1),s._v("  使用。"),a("code",[s._v("fzf")]),s._v("  是一个通用的模糊查找工具,它可以和很多命令一起使用。这里我们可以对历史命令进行模糊查找并将结果以赏心悦目的格式输出。")]),s._v(" "),a("ol",[a("li",[a("p",[s._v("搜索历史命令:")]),s._v(" "),a("p",[s._v("你可以通过管道将 "),a("code",[s._v("history")]),s._v(" 命令的输出送入 "),a("code",[s._v("fzf")]),s._v(",然后 "),a("code",[s._v("fzf")]),s._v(" 会提供一个交互式界面让你模糊搜索历史命令:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("history")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" fzf\n")])])]),a("p",[s._v("这将展示一个交互式列表,你可以开始输入来过滤历史命令。当你找到需要的命令时,按 Enter 键,"),a("code",[s._v("fzf")]),s._v(" 将把这个命令输出到标准输出。")])]),s._v(" "),a("li",[a("p",[s._v("执行选中的历史命令:")]),s._v(" "),a("p",[s._v("如果你想直接执行选择的命令,可以使用以下技巧结合 "),a("code",[s._v("xargs")]),s._v(":")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("history")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" fzf "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("awk")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'{print $2}'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("xargs")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-I")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("bash")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-c")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"{}"')]),s._v("\n")])])]),a("p",[s._v("这条命令的工作流程是:")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("history | fzf")]),s._v(":从历史中选择一个命令。")]),s._v(" "),a("li",[a("code",[s._v("awk '{print $2}'")]),s._v(":假设你的历史格式是编号后跟命令,这将抽取命令部分(根据你的 shell 历史格式可能需要调整)。")]),s._v(" "),a("li",[a("code",[s._v('xargs -I {} bash -c "{}"')]),s._v(":执行选中的命令。")])])])]),s._v(" "),a("p",[s._v("你可以修改 shell history 的行为,例如,如果在命令的开头加上一个空格,它就不会被加进 shell 记录中。当你输入包含密码或是其他敏感信息的命令时会用到这一特性。 为此你需要在"),a("code",[s._v(".bashrc")]),s._v("中添加"),a("code",[s._v("HISTCONTROL=ignorespace")]),s._v("或者向"),a("code",[s._v(".zshrc")]),s._v("  添加  "),a("code",[s._v("setopt HIST_IGNORE_SPACE")]),s._v("。 如果你不小心忘了在前面加空格,可以通过编辑  "),a("code",[s._v(".bash_history")]),s._v("或  "),a("code",[s._v(".zhistory")]),s._v("  来手动地从历史记录中移除那一项。")]),s._v(" "),a("h2",{attrs:{id:"_2-5-文件夹导航"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-文件夹导航"}},[s._v("#")]),s._v(" 2.5 文件夹导航")]),s._v(" "),a("p",[s._v("之前对所有操作我们都默认一个前提,即您已经位于想要执行命令的目录下,但是如何才能高效地在目录间随意切换呢?有很多简便的方法可以做到,比如设置 alias,使用  "),a("a",{attrs:{href:"https://man7.org/linux/man-pages/man1/ln.1.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("ln -s"),a("OutboundLink")],1),s._v("  创建符号连接等。而开发者们已经想到了很多更为精妙的解决方案。")]),s._v(" "),a("p",[s._v("由于本课程的目的是尽可能对你的日常习惯进行优化。因此,我们可以使用"),a("code",[s._v("[fasd](https://github.com/clvv/fasd)")]),s._v("和  "),a("a",{attrs:{href:"https://github.com/wting/autojump",target:"_blank",rel:"noopener noreferrer"}},[a("code",[s._v("autojump")]),a("OutboundLink")],1),s._v("  这两个工具来查找最常用或最近使用的文件和目录。")]),s._v(" "),a("p",[s._v("Fasd 基于  *"),a("a",{attrs:{href:"https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Places/Frecency_algorithm",target:"_blank",rel:"noopener noreferrer"}},[s._v("frecency*"),a("OutboundLink")],1),s._v("  对文件和文件排序,也就是说它会同时针对频率("),a("em",[s._v("frequency")]),s._v(")和时效("),a("em",[s._v("recency")]),s._v(")进行排序。默认情况下,"),a("code",[s._v("fasd")]),s._v("使用命令  "),a("code",[s._v("z")]),s._v("  帮助我们快速切换到最常访问的目录。例如, 如果您经常访问"),a("code",[s._v("/home/user/files/cool_project")]),s._v("  目录,那么可以直接使用  "),a("code",[s._v("z cool")]),s._v("  跳转到该目录。对于 autojump,则使用"),a("code",[s._v("j cool")]),s._v("代替即可。")]),s._v(" "),a("p",[s._v("还有一些更复杂的工具可以用来概览目录结构,例如  "),a("code",[s._v("[tree](https://linux.die.net/man/1/tree)")]),s._v(", "),a("code",[s._v("[broot](https://github.com/Canop/broot)")]),s._v("  或更加完整的文件管理器,例如  "),a("code",[s._v("[nnn](https://github.com/jarun/nnn)")]),s._v("  或  "),a("code",[s._v("[ranger](https://github.com/ranger/ranger)")]),s._v("。")]),s._v(" "),a("h1",{attrs:{id:"_3-exercise"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-exercise"}},[s._v("#")]),s._v(" 3. Exercise")]),s._v(" "),a("h2",{attrs:{id:"_3-1-ls"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-ls"}},[s._v("#")]),s._v(" 3.1 ls")]),s._v(" "),a("p",[s._v("阅读  "),a("code",[s._v("[man ls](https://man7.org/linux/man-pages/man1/ls.1.html)")]),s._v(" ,然后使用"),a("code",[s._v("ls")]),s._v("  命令进行如下操作:")]),s._v(" "),a("ul",[a("li",[s._v("所有文件(包括隐藏文件)")]),s._v(" "),a("li",[s._v("文件打印以人类可以理解的格式输出 (例如,使用 454M 而不是 454279954)")]),s._v(" "),a("li",[s._v("文件以最近访问顺序排序")]),s._v(" "),a("li",[s._v("以彩色文本显示输出结果")])]),s._v(" "),a("p",[s._v("典型输出如下:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v(" -rw-r--r-- "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" user group "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(".1M Jan "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("14")]),s._v(" 09:53 baz\n drwxr-xr-x "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("5")]),s._v(" user group "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("160")]),s._v(" Jan "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("14")]),s._v(" 09:53 "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v(".")]),s._v("\n -rw-r--r-- "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" user group "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("514")]),s._v(" Jan "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("14")]),s._v(" 06:42 bar\n -rw-r--r-- "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" user group 106M Jan "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("13")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("12")]),s._v(":12 foo\n drwx------+ "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("47")]),s._v(" user group "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(".5K Jan "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("12")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("18")]),s._v(":08 "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("..")]),s._v("\n")])])]),a("p",[a("img",{attrs:{src:t(348),alt:"Untitled"}})]),s._v(" "),a("h2",{attrs:{id:"_3-2-函数"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-函数"}},[s._v("#")]),s._v(" 3.2 函数")]),s._v(" "),a("p",[s._v("编写两个 bash 函数  "),a("code",[s._v("marco")]),s._v("  和  "),a("code",[s._v("polo")]),s._v("  执行下面的操作。 每当你执行  "),a("code",[s._v("marco")]),s._v("  时,当前的工作目录应当以某种形式保存,当执行  "),a("code",[s._v("polo")]),s._v("  时,无论现在处在什么目录下,都应当  "),a("code",[s._v("cd")]),s._v("  回到当时执行  "),a("code",[s._v("marco")]),s._v("  的目录。 为了方便 debug,你可以把代码写在单独的文件  "),a("code",[s._v("marco.sh")]),s._v("  中,并通过  "),a("code",[s._v("source marco.sh")]),s._v("命令,(重新)加载函数。")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#!/usr/bin/env zsh")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token function-name function"}},[s._v("marco")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("pwd")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token environment constant"}},[s._v("$HOME")]),s._v("/marco_history.log\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"save pwd '),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("pwd")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token function-name function"}},[s._v("polo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("cd")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token environment constant"}},[s._v("$HOME")]),s._v('/marco_history.log"')]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#!/usr/bin/env zsh")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function-name function"}},[s._v("marco")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("export")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("MARCO")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("pwd")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function-name function"}},[s._v("polo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("cd")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$MARCO")]),s._v('"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[s._v("Answer:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function-name function"}},[s._v("marco")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("current_dir")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("pwd")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function-name function"}},[s._v("polo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("cd")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$current_dir")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[a("img",{attrs:{src:t(349),alt:"Untitled"}})]),s._v(" "),a("h2",{attrs:{id:"_3-3-返回码"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-返回码"}},[s._v("#")]),s._v(" 3.3 返回码")]),s._v(" "),a("p",[s._v("假设您有一个命令,它很少出错。因此为了在出错时能够对其进行调试,需要花费大量的时间重现错误并捕获输出。 编写一段 bash 脚本,运行如下的脚本直到它出错,将它的标准输出和标准错误流记录到文件,并在最后输出所有内容。")]),s._v(" "),a("p",[s._v("加分项:报告脚本在失败前共运行了多少次。")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#!/usr/bin/env zsh")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("n")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$((")]),s._v(" RANDOM "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("%")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("100")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("))")])]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" n "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-eq")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("42")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("then")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Something went wrong"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),a("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[s._v("&2")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"The error was using magic numbers"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("exit")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("fi")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Everything went according to plan"')]),s._v("\n")])])]),a("p",[s._v("Answer:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#!/usr/bin/env zsh")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("chmod")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("777")]),s._v(" 3script.sh\n"),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("normCnt")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("while")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("do")]),s._v("\n ./3script.sh "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">>")]),s._v(" 3log.txt "),a("span",{pre:!0,attrs:{class:"token operator"}},[a("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[s._v("2")]),s._v(">")]),s._v(" 3err.txt\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$?")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-eq")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("then")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"The script failed"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"The script succeeded '),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$normCnt")]),s._v(' times before failed"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("break")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("fi")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("((")]),s._v("normCnt"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("++")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("))")])]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("done")]),s._v("\n")])])]),a("p",[a("img",{attrs:{src:t(350),alt:"Untitled"}})]),s._v(" "),a("h2",{attrs:{id:"_3-4-find"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-find"}},[s._v("#")]),s._v(" 3.4 find")]),s._v(" "),a("p",[s._v("本节课我们讲解的  "),a("code",[s._v("find")]),s._v("  命令中的  "),a("code",[s._v("exec")]),s._v("  参数非常强大,它可以对我们查找的文件进行操作。但是,如果我们要对所有文件进行操作呢?例如创建一个 zip 压缩文件?我们已经知道,命令行可以从参数或标准输入接受输入。在用管道连接命令时,我们将标准输出和标准输入连接起来,但是有些命令,例如"),a("code",[s._v("tar")]),s._v("  则需要从参数接受输入。这里我们可以使用"),a("code",[s._v("[xargs](https://man7.org/linux/man-pages/man1/xargs.1.html)")]),s._v("  命令,它可以使用标准输入中的内容作为参数。 例如  "),a("code",[s._v("ls | xargs rm")]),s._v("  会删除当前目录中的所有文件。")]),s._v(" "),a("p",[s._v("您的任务是编写一个命令,它可以递归地查找文件夹中所有的 HTML 文件,并将它们压缩成 zip 文件。注意,即使文件名中包含空格,您的命令也应该能够正确执行(提示:查看  "),a("code",[s._v("xargs")]),s._v("的参数"),a("code",[s._v("-d")]),s._v(",译注:MacOS 上的  "),a("code",[s._v("xargs")]),s._v("没有"),a("code",[s._v("-d")]),s._v(","),a("a",{attrs:{href:"https://github.com/missing-semester/missing-semester/issues/93",target:"_blank",rel:"noopener noreferrer"}},[s._v("查看这个 issue"),a("OutboundLink")],1),s._v(")")]),s._v(" "),a("p",[s._v("如果您使用的是 MacOS,请注意默认的 BSD "),a("code",[s._v("find")]),s._v("  与  "),a("a",{attrs:{href:"https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands",target:"_blank",rel:"noopener noreferrer"}},[s._v("GNU coreutils"),a("OutboundLink")],1),s._v("  中的是不一样的。你可以为"),a("code",[s._v("find")]),s._v("添加"),a("code",[s._v("-print0")]),s._v("选项,并为"),a("code",[s._v("xargs")]),s._v("添加"),a("code",[s._v("-0")]),s._v("选项。作为 Mac 用户,您需要注意 mac 系统自带的命令行工具和 GNU 中对应的工具是有区别的;如果你想使用 GNU 版本的工具,也可以使用  "),a("a",{attrs:{href:"https://formulae.brew.sh/formula/coreutils",target:"_blank",rel:"noopener noreferrer"}},[s._v("brew 来安装"),a("OutboundLink")],1),s._v("。")]),s._v(" "),a("p",[a("img",{attrs:{src:t(351),alt:"Untitled"}})]),s._v(" "),a("h2",{attrs:{id:"_3-5-lru"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-lru"}},[s._v("#")]),s._v(" 3.5 LRU")]),s._v(" "),a("p",[s._v("(进阶)编写一个命令或脚本递归的查找文件夹中最近使用的文件。更通用的做法,你可以按照最近的使用时间列出文件吗?")]),s._v(" "),a("p",[a("img",{attrs:{src:t(352),alt:"Untitled"}})]),s._v(" "),a("p",[s._v("管道实现的是将前面的输出"),a("code",[s._v("stdout")]),s._v("作为后面的输入"),a("code",[s._v("stdin")]),s._v(",但是有些命令不接受管道的传递方式。例如:"),a("code",[s._v("ls")]),s._v(",这是为什么呢?")]),s._v(" "),a("p",[s._v("因为有些命令希望管道传递过来的是参数,但是直接使用管道有时无法传递到命令的参数位。这时候就需要"),a("code",[s._v("xargs")]),s._v(","),a("code",[s._v("xargs")]),s._v("实现的是将管道传递过来的"),a("code",[s._v("stdin")]),s._v("进行处理然后传递到命令的参数位置上。")]),s._v(" "),a("p",[a("code",[s._v("xargs -0")]),s._v("  可以处理接收到的"),a("code",[s._v("stdin")]),s._v("中的 null 字符"),a("code",[s._v("(\\0)")]),s._v("。如果不使用"),a("code",[s._v("-0")]),s._v("选项或"),a("code",[s._v("-null")]),s._v("选项,检测到"),a("code",[s._v("\\0")]),s._v("后会给出警告提醒,并只向命令传递非"),a("code",[s._v("\\0")]),s._v("段。")])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/19.831e14a0.js b/assets/js/19.831e14a0.js new file mode 100644 index 0000000..1b0321b --- /dev/null +++ b/assets/js/19.831e14a0.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{241:function(t,n,e){"use strict";e.d(n,"d",(function(){return r})),e.d(n,"a",(function(){return o})),e.d(n,"i",(function(){return a})),e.d(n,"f",(function(){return u})),e.d(n,"g",(function(){return c})),e.d(n,"h",(function(){return p})),e.d(n,"b",(function(){return l})),e.d(n,"e",(function(){return f})),e.d(n,"k",(function(){return h})),e.d(n,"l",(function(){return d})),e.d(n,"c",(function(){return v})),e.d(n,"j",(function(){return b}));e(45);const r=/#.*$/,i=/\.(md|html)$/,o=/\/$/,a=/^[a-z]+:/i;function s(t){return decodeURI(t).replace(r,"").replace(i,"")}function u(t){return a.test(t)}function c(t){return/^mailto:/.test(t)}function p(t){return/^tel:/.test(t)}function l(t){if(u(t))return t;const n=t.match(r),e=n?n[0]:"",i=s(t);return o.test(i)?t:i+".html"+e}function f(t,n){const e=decodeURIComponent(t.hash),i=function(t){const n=t.match(r);if(n)return n[0]}(n);if(i&&e!==i)return!1;return s(t.path)===s(n)}function h(t,n,e){if(u(n))return{type:"external",path:n};e&&(n=function(t,n,e){const r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return n+t;const i=n.split("/");e&&i[i.length-1]||i.pop();const o=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(n,e,r,i=1){if("string"==typeof n)return h(e,n,r);if(Array.isArray(n))return Object.assign(h(e,n[0],r),{title:n[1]});{const o=n.children||[];return 0===o.length&&n.path?Object.assign(h(e,n.path,r),{title:n.title}):{type:"group",path:n.path,title:n.title,sidebarDepth:n.sidebarDepth,initialOpenGroupIndex:n.initialOpenGroupIndex,children:o.map(n=>t(n,e,r,i+1)),collapsable:!1!==n.collapsable}}}(t,i,e)):[]}return[]}function g(t){const n=v(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:n.map(n=>({type:"auto",title:n.title,basePath:t.path,path:t.path+"#"+n.slug,children:n.children||[]}))}]}function v(t){let n;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?n=t:n&&(n.children||(n.children=[])).push(t)}),t.filter(t=>2===t.level)}function b(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},248:function(t,n){t.exports=function(t){return null==t}},251:function(t,n,e){},262:function(t,n,e){var r=e(11),i=e(4),o=e(10);t.exports=function(t){return"string"==typeof t||!i(t)&&o(t)&&"[object String]"==r(t)}},263:function(t,n,e){"use strict";e(251)},270:function(t,n,e){"use strict";e.r(n);e(45);var r=e(241),i=e(262),o=e.n(i),a=e(248),s=e.n(a),u={name:"PageNav",props:["sidebarItems"],computed:{prev(){return p(c.PREV,this)},next(){return p(c.NEXT,this)}}};const c={NEXT:{resolveLink:function(t,n){return l(t,n,1)},getThemeLinkConfig:({nextLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.next},PREV:{resolveLink:function(t,n){return l(t,n,-1)},getThemeLinkConfig:({prevLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.prev}};function p(t,{$themeConfig:n,$page:e,$route:i,$site:a,sidebarItems:u}){const{resolveLink:c,getThemeLinkConfig:p,getPageLinkConfig:l}=t,f=p(n),h=l(e),d=s()(h)?f:h;return!1===d?void 0:o()(d)?Object(r.k)(a.pages,d,i.path):c(e,u)}function l(t,n,e){const r=[];!function t(n,e){for(let r=0,i=n.length;r"group"===e.type?r(t,e):"page"===e.type&&Object(i.e)(t,e.path));return a||n}return!1}var o={name:"SidebarLinks",components:{SidebarGroup:n.default,SidebarLink:s.default},props:["items","depth","sidebarDepth","initialOpenGroupIndex"],data(){return{openGroupIndex:this.initialOpenGroupIndex||0}},watch:{$route(){this.refreshIndex()}},created(){this.refreshIndex()},methods:{refreshIndex(){const t=function(t,e){for(let a=0;a-1&&(this.openGroupIndex=t)},toggleGroup(t){this.openGroupIndex=t===this.openGroupIndex?-1:t},isActive(t){return Object(i.e)(this.$route,t.regularPath)}}},l=a(14),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return t.items.length?e("ul",{staticClass:"sidebar-links"},t._l(t.items,(function(a,n){return e("li",{key:n},["group"===a.type?e("SidebarGroup",{attrs:{item:a,open:n===t.openGroupIndex,collapsable:a.collapsable||a.collapsible,depth:t.depth},on:{toggle:function(e){return t.toggleGroup(n)}}}):e("SidebarLink",{attrs:{"sidebar-depth":t.sidebarDepth,item:a}})],1)})),0):t._e()}),[],!1,null,null,null);e.default=u.exports},257:function(t,e,a){"use strict";a.r(e);var n=a(241);function s(t,e,a,n,s){const i={props:{to:e,activeClass:"",exactActiveClass:""},class:{active:n,"sidebar-link":!0}};return s>2&&(i.style={"padding-left":s+"rem"}),t("RouterLink",i,a)}function i(t,e,a,r,o,l=1){return!e||l>o?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const u=Object(n.e)(r,a+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[s(t,a+"#"+e.slug,e.title,u,e.level-1),i(t,e.children,a,r,o,l+1)])}))}var r={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:a,$route:r,$themeConfig:o,$themeLocaleConfig:l},props:{item:u,sidebarDepth:c}}){const p=Object(n.e)(r,u.path),d="auto"===u.type?p||u.children.some(t=>Object(n.e)(r,u.basePath+"#"+t.slug)):p,h="external"===u.type?function(t,e,a){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[a,t("OutboundLink")])}(t,u.path,u.title||u.path):s(t,u.path,u.title||u.path,d),f=[e.frontmatter.sidebarDepth,c,l.sidebarDepth,o.sidebarDepth,1].find(t=>void 0!==t),b=l.displayAllHeaders||o.displayAllHeaders;if("auto"===u.type)return[h,i(t,u.children,u.basePath,r,f)];if((d||b)&&u.headers&&!n.d.test(u.path)){return[h,i(t,Object(n.c)(u.headers),u.path,r,f)]}return h}},o=(a(254),a(14)),l=Object(o.a)(r,void 0,void 0,!1,null,null,null);e.default=l.exports},258:function(t,e,a){},261:function(t,e,a){"use strict";a(250)},262:function(t,e,a){var n=a(11),s=a(4),i=a(10);t.exports=function(t){return"string"==typeof t||!s(t)&&i(t)&&"[object String]"==n(t)}},263:function(t,e,a){"use strict";a(251)},264:function(t,e,a){},265:function(t,e,a){"use strict";a(252)},266:function(t,e,a){},268:function(t,e,a){"use strict";a.r(e);var n=a(241),s={name:"SidebarGroup",components:{DropdownTransition:a(244).default},props:["item","open","collapsable","depth"],beforeCreate(){this.$options.components.SidebarLinks=a(255).default},methods:{isActive:n.e}},i=(a(265),a(14)),r=Object(i.a)(s,(function(){var t=this,e=t._self._c;return e("section",{staticClass:"sidebar-group",class:[{collapsable:t.collapsable,"is-sub-group":0!==t.depth},"depth-"+t.depth]},[t.item.path?e("RouterLink",{staticClass:"sidebar-heading clickable",class:{open:t.open,active:t.isActive(t.$route,t.item.path)},attrs:{to:t.item.path},nativeOn:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"down":"right"}):t._e()]):e("p",{staticClass:"sidebar-heading",class:{open:t.open},on:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"down":"right"}):t._e()]),t._v(" "),e("DropdownTransition",[t.open||!t.collapsable?e("SidebarLinks",{staticClass:"sidebar-group-items",attrs:{items:t.item.children,"sidebar-depth":t.item.sidebarDepth,"initial-open-group-index":t.item.initialOpenGroupIndex,depth:t.depth+1}}):t._e()],1)],1)}),[],!1,null,null,null);e.default=r.exports},269:function(t,e,a){"use strict";a.r(e);var n=a(248),s=a.n(n),i=a(241),r={name:"PageEdit",computed:{lastUpdated(){return this.$page.lastUpdated},lastUpdatedText(){return"string"==typeof this.$themeLocaleConfig.lastUpdated?this.$themeLocaleConfig.lastUpdated:"string"==typeof this.$site.themeConfig.lastUpdated?this.$site.themeConfig.lastUpdated:"Last Updated"},editLink(){const t=s()(this.$page.frontmatter.editLink)?this.$site.themeConfig.editLinks:this.$page.frontmatter.editLink,{repo:e,docsDir:a="",docsBranch:n="master",docsRepo:i=e}=this.$site.themeConfig;return t&&i&&this.$page.relativePath?this.createEditLink(e,i,a,n,this.$page.relativePath):null},editLinkText(){return this.$themeLocaleConfig.editLinkText||this.$site.themeConfig.editLinkText||"Edit this page"}},methods:{createEditLink(t,e,a,n,s){if(/bitbucket.org/.test(e)){return e.replace(i.a,"")+"/src"+`/${n}/`+(a?a.replace(i.a,"")+"/":"")+s+`?mode=edit&spa=0&at=${n}&fileviewer=file-view-default`}if(/gitlab.com/.test(e)){return e.replace(i.a,"")+"/-/edit"+`/${n}/`+(a?a.replace(i.a,"")+"/":"")+s}return(i.i.test(e)?e:"https://github.com/"+e).replace(i.a,"")+"/edit"+`/${n}/`+(a?a.replace(i.a,"")+"/":"")+s}}},o=(a(261),a(14)),l=Object(o.a)(r,(function(){var t=this,e=t._self._c;return e("footer",{staticClass:"page-edit"},[t.editLink?e("div",{staticClass:"edit-link"},[e("a",{attrs:{href:t.editLink,target:"_blank",rel:"noopener noreferrer"}},[t._v(t._s(t.editLinkText))]),t._v(" "),e("OutboundLink")],1):t._e(),t._v(" "),t.lastUpdated?e("div",{staticClass:"last-updated"},[e("span",{staticClass:"prefix"},[t._v(t._s(t.lastUpdatedText)+":")]),t._v(" "),e("span",{staticClass:"time"},[t._v(t._s(t.lastUpdated))])]):t._e()])}),[],!1,null,null,null);e.default=l.exports},270:function(t,e,a){"use strict";a.r(e);a(45);var n=a(241),s=a(262),i=a.n(s),r=a(248),o=a.n(r),l={name:"PageNav",props:["sidebarItems"],computed:{prev(){return c(u.PREV,this)},next(){return c(u.NEXT,this)}}};const u={NEXT:{resolveLink:function(t,e){return p(t,e,1)},getThemeLinkConfig:({nextLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.next},PREV:{resolveLink:function(t,e){return p(t,e,-1)},getThemeLinkConfig:({prevLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.prev}};function c(t,{$themeConfig:e,$page:a,$route:s,$site:r,sidebarItems:l}){const{resolveLink:u,getThemeLinkConfig:c,getPageLinkConfig:p}=t,d=c(e),h=p(a),f=o()(h)?d:h;return!1===f?void 0:i()(f)?Object(n.k)(r.pages,f,s.path):u(a,l)}function p(t,e,a){const n=[];!function t(e,a){for(let n=0,s=e.length;n({isSidebarOpen:!1}),computed:{shouldShowNavbar(){const{themeConfig:t}=this.$site,{frontmatter:e}=this.$page;return!1!==e.navbar&&!1!==t.navbar&&(this.$title||t.logo||t.repo||t.nav||this.$themeLocaleConfig.nav)},shouldShowSidebar(){const{frontmatter:t}=this.$page;return!t.home&&!1!==t.sidebar&&this.sidebarItems.length},sidebarItems(){return Object(o.l)(this.$page,this.$page.regularPath,this.$site,this.$localePath)},pageClasses(){const t=this.$page.frontmatter.pageClass;return[{"no-navbar":!this.shouldShowNavbar,"sidebar-open":this.isSidebarOpen,"no-sidebar":!this.shouldShowSidebar},t]}},mounted(){this.$router.afterEach(()=>{this.isSidebarOpen=!1})},methods:{toggleSidebar(t){this.isSidebarOpen="boolean"==typeof t?t:!this.isSidebarOpen,this.$emit("toggle-sidebar",this.isSidebarOpen)},onTouchStart(t){this.touchStart={x:t.changedTouches[0].clientX,y:t.changedTouches[0].clientY}},onTouchEnd(t){const e=t.changedTouches[0].clientX-this.touchStart.x,a=t.changedTouches[0].clientY-this.touchStart.y;Math.abs(e)>Math.abs(a)&&Math.abs(e)>40&&(e>0&&this.touchStart.x<=80?this.toggleSidebar(!0):this.toggleSidebar(!1))}}},u=a(14),c=Object(u.a)(l,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"theme-container",class:t.pageClasses,on:{touchstart:t.onTouchStart,touchend:t.onTouchEnd}},[t.shouldShowNavbar?e("Navbar",{on:{"toggle-sidebar":t.toggleSidebar}}):t._e(),t._v(" "),e("div",{staticClass:"sidebar-mask",on:{click:function(e){return t.toggleSidebar(!1)}}}),t._v(" "),e("Sidebar",{attrs:{items:t.sidebarItems},on:{"toggle-sidebar":t.toggleSidebar},scopedSlots:t._u([{key:"top",fn:function(){return[t._t("sidebar-top")]},proxy:!0},{key:"bottom",fn:function(){return[t._t("sidebar-bottom")]},proxy:!0}],null,!0)}),t._v(" "),t.$page.frontmatter.home?e("Home"):e("Page",{attrs:{"sidebar-items":t.sidebarItems},scopedSlots:t._u([{key:"top",fn:function(){return[t._t("page-top")]},proxy:!0},{key:"bottom",fn:function(){return[t._t("page-bottom")]},proxy:!0}],null,!0)})],1)}),[],!1,null,null,null);e.default=c.exports}}]); \ No newline at end of file diff --git a/assets/js/20.03221997.js b/assets/js/20.03221997.js new file mode 100644 index 0000000..c0d678e --- /dev/null +++ b/assets/js/20.03221997.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[20],{329:function(t,s,a){t.exports=a.p+"assets/img/160.f3a7ce3c.png"},330:function(t,s,a){t.exports=a.p+"assets/img/161.17ec9311.png"},331:function(t,s,a){t.exports=a.p+"assets/img/162.638197d7.png"},332:function(t,s,a){t.exports=a.p+"assets/img/163.7b78786e.png"},333:function(t,s,a){t.exports=a.p+"assets/img/164.d8ddcf2a.png"},428:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-05-练习16-结构体和指向它们的指针"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-05-练习16-结构体和指向它们的指针"}},[t._v("#")]),t._v(" 2024.04.05-练习16:结构体和指向它们的指针")]),t._v(" "),s("h2",{attrs:{id:"_1-struct"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-struct"}},[t._v("#")]),t._v(" 1. struct")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Person")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" weight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Person")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Person_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" weight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Person")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("who "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Person")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("who "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n who"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strdup")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n who"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("age "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n who"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("height "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n who"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("weight "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" weight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" who"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Person_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Person")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("who"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("who "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("who"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("who"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Person_print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Person")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("who"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Name: %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" who"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tAge: %d\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" who"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tHeight: %d\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" who"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("height"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tWeight: %d\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" who"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("weight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// make two people structures")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Person")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("joe "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Person_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Joe Alex"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("64")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("140")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Person")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("frank "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Person_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Frank Blank"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("72")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("180")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// print them out and where they are in memory")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Joe is at memory location %p:\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" joe"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Person_print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("joe"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Frank is at memory location %p:\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" frank"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Person_print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("frank"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// make everyone age 20 years and print them again")]),t._v("\n joe"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("age "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n joe"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("height "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n joe"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("weight "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("40")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Person_print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("joe"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n frank"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("age "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n frank"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("weight "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Person_print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("frank"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// destroy them both so we clean up")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Person_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("joe"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Person_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("frank"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("使用"),s("code",[t._v("strdup")]),t._v("来复制字符串"),s("code",[t._v("name")]),t._v(",是为了确保结构体真正拥有它。"),s("code",[t._v("strdup")]),t._v("的行为实际上类似"),s("code",[t._v("malloc")]),t._v("但是它同时会将原来的字符串复制到新创建的内存。")]),t._v(" "),s("p",[t._v("!!!如果结构体有指针类型成员,同时结构体在堆中创建的,那么释放堆中结构体之前需要提前释放结构体中的指针成员指向的内存,然后再释放结构体自身的。")]),t._v(" "),s("h2",{attrs:{id:"_2-使它崩溃"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-使它崩溃"}},[t._v("#")]),t._v(" 2. 使它崩溃")]),t._v(" "),s("h3",{attrs:{id:"_2-1-assert-who-null"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-assert-who-null"}},[t._v("#")]),t._v(" 2.1 "),s("code",[t._v("assert(who != NULL);")])]),t._v(" "),s("p",[t._v("试着传递"),s("code",[t._v("NULL")]),t._v("给"),s("code",[t._v("Person_destroy")]),t._v("来看看会发生什么。如果它没有崩溃,你必须移除Makefile的"),s("code",[t._v("CFLAGS")]),t._v("中的"),s("code",[t._v("g")]),t._v("选项。")]),t._v(" "),s("p",[s("img",{attrs:{src:a(329),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_2-2-内存泄漏"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-内存泄漏"}},[t._v("#")]),t._v(" 2.2 内存泄漏")]),t._v(" "),s("p",[t._v("在结尾处忘记调用"),s("code",[t._v("Person_destroy")]),t._v(",在"),s("code",[t._v("Valgrind")]),t._v("下运行程序,你会看到它报告出你忘记释放内存。弄清楚你应该向"),s("code",[t._v("valgrind")]),t._v("传递什么参数来让它向你报告内存如何泄露。")]),t._v(" "),s("p",[s("img",{attrs:{src:a(330),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_2-3-单独释放结构体中的指针"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-单独释放结构体中的指针"}},[t._v("#")]),t._v(" 2.3 单独释放结构体中的指针")]),t._v(" "),s("p",[t._v("忘记在"),s("code",[t._v("Person_destroy")]),t._v("中释放"),s("code",[t._v("who->name")]),t._v(",并且对比两次的输出。同时,使用正确的选项来让"),s("code",[t._v("Valgrind")]),t._v("告诉你哪里错了。")]),t._v(" "),s("p",[s("img",{attrs:{src:a(331),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_2-4-获取null"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-4-获取null"}},[t._v("#")]),t._v(" 2.4 获取NULL")]),t._v(" "),s("p",[t._v("这一次,向"),s("code",[t._v("Person_print")]),t._v("传递"),s("code",[t._v("NULL")]),t._v(",并且观察"),s("code",[t._v("Valgrind")]),t._v("会输出什么。")]),t._v(" "),s("p",[s("img",{attrs:{src:a(332),alt:"Untitled"}})]),t._v(" "),s("h2",{attrs:{id:"_3-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-附加题"}},[t._v("#")]),t._v(" 3. 附加题")]),t._v(" "),s("h3",{attrs:{id:"_3-1-在栈上创建结构体"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-在栈上创建结构体"}},[t._v("#")]),t._v(" 3.1 在栈上创建结构体")]),t._v(" "),s("p",[s("img",{attrs:{src:a(333),alt:"Untitled"}})])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/21.1ec03a46.js b/assets/js/21.1ec03a46.js new file mode 100644 index 0000000..ddd8b77 --- /dev/null +++ b/assets/js/21.1ec03a46.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[21],{334:function(t,s,a){t.exports=a.p+"assets/img/180.4124ca07.png"},335:function(t,s,a){t.exports=a.p+"assets/img/181.614e612d.png"},336:function(t,s,a){t.exports=a.p+"assets/img/182.907e9a86.png"},337:function(t,s,a){t.exports=a.p+"assets/img/183.aeedd703.png"},338:function(t,s,a){t.exports=a.p+"assets/img/184.e236f620.png"},429:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-10-练习18-函数指针"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-10-练习18-函数指针"}},[t._v("#")]),t._v(" 2024.04.10-练习18:函数指针")]),t._v(" "),s("h2",{attrs:{id:"_1-函数指针"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-函数指针"}},[t._v("#")]),t._v(" 1. 函数指针")]),t._v(" "),s("p",[t._v("函数在C中实际上只是指向程序中某一个代码存在位置的指针。就像你创建过的结构体指针、字符串和数组那样,你也可以创建指向函数的指针。函数指针的主要用途是向其他函数传递“回调”,或者模拟类和对象。在这个练习中我们会创建一些回调,并且下一节我们会制作一个简单的对象系统。")]),t._v(" "),s("p",[t._v("函数指针的格式类似这样:")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("POINTER_NAME"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("记住如何编写它的一个方法是:")]),t._v(" "),s("ul",[s("li",[t._v("编写一个普通的函数声明:"),s("code",[t._v("int callme(int a, int b)")])]),t._v(" "),s("li",[t._v("将函数用指针语法包装:"),s("code",[t._v("int (*callme)(int a, int b)")])]),t._v(" "),s("li",[t._v("将名称改成指针名称:"),s("code",[t._v("int (*compare_cb)(int a, int b)")])])]),t._v(" "),s("p",[t._v("这个方法的关键是,当你完成这些之后,指针的变量名称为"),s("code",[t._v("compare_cb")]),t._v(",而你可以将它用作函数。这类似于指向数组的指针可以表示所指向的数组。指向函数的指针也可以用作表示所指向的函数,只不过是不同的名字。")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("tester"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" sorted_order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"TEST: %d is same as %d\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tester")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sorted_order")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("即使是对于返回指针的函数指针,上述方法依然有效:")]),t._v(" "),s("ul",[s("li",[t._v("编写:"),s("code",[t._v("char *make_coolness(int awesome_levels)")])]),t._v(" "),s("li",[t._v("包装:"),s("code",[t._v("char *(*make_coolness)(int awesome_levels)")])]),t._v(" "),s("li",[t._v("重命名:"),s("code",[t._v("char *(*coolness_cb)(int awesome_levels)")])])]),t._v(" "),s("p",[t._v("需要解决的下一个问题是使用函数指针向其它函数提供参数比较困难,比如当你打算向其它函数传递回调函数的时候。解决方法是使用"),s("code",[t._v("typedef")]),t._v(",它是C的一个关键字,可以给其它更复杂的类型起个新的名字。你需要记住的事情是,将"),s("code",[t._v("typedef")]),t._v("添加到相同的指针语法之前,然后你就可以将那个名字用作类型了。")]),t._v(" "),s("h2",{attrs:{id:"_2-program"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-program"}},[t._v("#")]),t._v(" 2. program")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/** Our old friend die from ex17. */")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("errno"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("perror")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("exit")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// a typedef creates a fake type, in this")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// case for a function pointer")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typedef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("compare_cb"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/**\n * A classic bubble sort function that uses the\n * compare_cb to do the sorting.\n */")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bubble_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" compare_cb cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" temp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" j "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("target "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Memory error."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("memcpy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("j "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" j "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cmp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n temp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" temp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sorted_order")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reverse_order")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strange_order")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/**\n * Used to test that we are sorting things correctly\n * by doing the sort and printing it out.\n */")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_sorting")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" compare_cb cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("sorted "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bubble_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("sorted"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to sort as requested."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%d "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sorted"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sorted"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"USAGE: ex18 4 3 1 5 6"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("inputs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" argv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("numbers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Memory error."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("atoi")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("inputs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_sorting")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sorted_order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_sorting")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" reverse_order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_sorting")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" strange_order"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"_3-函数指针汇编字节码"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-函数指针汇编字节码"}},[t._v("#")]),t._v(" 3. 函数指针汇编字节码")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typedef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("compare_cb"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ncompare_cb cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("unsigned")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("unsigned")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%02x:"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// output:")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("55")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("48")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("89")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("e5"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("89")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),t._v("d"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("fc"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("89")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("75")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("f8"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("55")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("fc"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("45")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("f8"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("29")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("d0"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("c9"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("c3"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("55")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("48")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("89")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("e5"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("89")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n")])])]),s("p",[t._v("这段代码试图以十六进制的形式打印出一个函数指针("),s("code",[t._v("cmp")]),t._v(")所指向的函数的前25个字节。"),s("code",[t._v("compare_cb")]),t._v("是一个函数指针的类型定义,指向一个接受两个"),s("code",[t._v("int")]),t._v("类型参数并返回"),s("code",[t._v("int")]),t._v("类型结果的函数。"),s("code",[t._v("unsigned char *data = (unsigned char *)cmp;")]),t._v("这行代码将函数指针"),s("code",[t._v("cmp")]),t._v("转换为一个"),s("code",[t._v("unsigned char")]),t._v("类型的指针,这样就可以逐字节地访问函数指针所指向的函数的机器代码。")]),t._v(" "),s("p",[t._v("在循环中,程序逐个字节地访问并打印出这个函数的机器代码,直到打印了25个字节。每个字节以两位十六进制数的形式打印,后面跟着一个冒号。")]),t._v(" "),s("p",[t._v("输出的具体内容取决于"),s("code",[t._v("cmp")]),t._v("所指向的函数的机器代码,这又依赖于具体的函数实现、编译器以及目标平台的架构。不同的编译器优化设置可能产生不同的机器代码。此外,不同的处理器架构(如x86、ARM等)有其独特的指令集,导致即使是相同的高级语言函数,其编译成的机器代码也会不同。")]),t._v(" "),s("p",[t._v("由于这段代码直接访问和解释函数的机器码,它涉及到底层的、平台特定的行为。在大多数现代操作系统和处理器架构中,试图访问函数的机器码是不推荐的,因为:")]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("可移植性差")]),t._v(":这段代码的行为在不同的系统和编译器下可能会有很大差异。")]),t._v(" "),s("li",[s("strong",[t._v("安全性")]),t._v(":现代操作系统通常实施某种形式的代码和数据分离(如DEP/NX),这可能阻止程序以这种方式访问函数的代码。")]),t._v(" "),s("li",[s("strong",[t._v("实用性")]),t._v(":除了特定的底层编程或逆向工程场景外,直接处理函数的机器码通常是不必要的。")])]),t._v(" "),s("p",[t._v("总之,这段代码的目的是展示如何以字节为单位访问和打印出一个函数的机器码,但实际应用场景有限,且在不同环境中的行为可能会有很大差异。")]),t._v(" "),s("h2",{attrs:{id:"_4-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-附加题"}},[t._v("#")]),t._v(" 4. 附加题")]),t._v(" "),s("h3",{attrs:{id:"_4-1-十六进制编辑器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-1-十六进制编辑器"}},[t._v("#")]),t._v(" 4.1 十六进制编辑器")]),t._v(" "),s("p",[t._v("用十六进制编辑器打开"),s("code",[t._v("ex18")]),t._v(",接着找到函数起始处的十六进制代码序列,看看是否能在原始程序中找到函数。")]),t._v(" "),s("p",[s("img",{attrs:{src:a(334),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_4-2-修改十六进制文件"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-修改十六进制文件"}},[t._v("#")]),t._v(" 4.2 修改十六进制文件")]),t._v(" "),s("p",[s("img",{attrs:{src:a(335),alt:"Untitled"}})]),t._v(" "),s("p",[t._v("修改了上述函数的汇编机器码,结果就提示不合法的硬件指令")]),t._v(" "),s("h3",{attrs:{id:"_4-3-传递错误函数"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-3-传递错误函数"}},[t._v("#")]),t._v(" 4.3 传递错误函数")]),t._v(" "),s("p",[s("img",{attrs:{src:a(336),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_4-4-传递null到原函数指针位置"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-4-传递null到原函数指针位置"}},[t._v("#")]),t._v(" 4.4 传递NULL到原函数指针位置")]),t._v(" "),s("p",[s("img",{attrs:{src:a(337),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_4-5-快速排序"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-5-快速排序"}},[t._v("#")]),t._v(" 4.5 快速排序")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("swap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" temp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("b "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" temp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("partition")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" low"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" high"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" compare_cb cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" pivot "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("high"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("low "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" j "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" low"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" j "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" high "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cmp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" pivot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("swap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("swap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("high"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("quick_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" low"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" high"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" compare_cb cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("low "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" high"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" pi "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("partition")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" low"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" high"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("quick_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" low"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" pi "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("quick_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" pi "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" high"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("quick_sort_wrapper")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" compare_cb cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("target "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Memory error."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("memcpy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("quick_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("img",{attrs:{src:a(338),alt:"Untitled"}})])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/22.a17f69b5.js b/assets/js/22.a17f69b5.js new file mode 100644 index 0000000..a007b21 --- /dev/null +++ b/assets/js/22.a17f69b5.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[22,38],{241:function(t,e,n){"use strict";n.d(e,"d",(function(){return i})),n.d(e,"a",(function(){return a})),n.d(e,"i",(function(){return s})),n.d(e,"f",(function(){return l})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return c})),n.d(e,"b",(function(){return f})),n.d(e,"e",(function(){return h})),n.d(e,"k",(function(){return d})),n.d(e,"l",(function(){return p})),n.d(e,"c",(function(){return g})),n.d(e,"j",(function(){return b}));n(45);const i=/#.*$/,r=/\.(md|html)$/,a=/\/$/,s=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(i,"").replace(r,"")}function l(t){return s.test(t)}function u(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function f(t){if(l(t))return t;const e=t.match(i),n=e?e[0]:"",r=o(t);return a.test(r)?t:r+".html"+n}function h(t,e){const n=decodeURIComponent(t.hash),r=function(t){const e=t.match(i);if(e)return e[0]}(e);if(r&&n!==r)return!1;return o(t.path)===o(e)}function d(t,e,n){if(l(e))return{type:"external",path:e};n&&(e=function(t,e,n){const i=t.charAt(0);if("/"===i)return t;if("?"===i||"#"===i)return e+t;const r=e.split("/");n&&r[r.length-1]||r.pop();const a=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,i,r=1){if("string"==typeof e)return d(n,e,i);if(Array.isArray(e))return Object.assign(d(n,e[0],i),{title:e[1]});{const a=e.children||[];return 0===a.length&&e.path?Object.assign(d(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:a.map(e=>t(e,n,i,r+1)),collapsable:!1!==e.collapsable}}}(t,r,n)):[]}return[]}function m(t){const e=g(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function g(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function b(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},243:function(t,e,n){"use strict";n.r(e);var i=n(241),r={name:"NavLink",props:{item:{required:!0}},computed:{link(){return Object(i.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link},isNonHttpURI(){return Object(i.g)(this.link)||Object(i.h)(this.link)},isBlankTarget(){return"_blank"===this.target},isInternal(){return!Object(i.f)(this.link)&&!this.isBlankTarget},target(){return this.isNonHttpURI?null:this.item.target?this.item.target:Object(i.f)(this.link)?"_blank":""},rel(){return this.isNonHttpURI||!1===this.item.rel?null:this.item.rel?this.item.rel:this.isBlankTarget?"noopener noreferrer":null}},methods:{focusoutAction(){this.$emit("focusout")}}},a=n(14),s=Object(a.a)(r,(function(){var t=this,e=t._self._c;return t.isInternal?e("RouterLink",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v("\n "+t._s(t.item.text)+"\n")]):e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.target,rel:t.rel},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),t.isBlankTarget?e("OutboundLink"):t._e()],1)}),[],!1,null,null,null);e.default=s.exports},258:function(t,e,n){},271:function(t,e,n){"use strict";n(258)},282:function(t,e,n){"use strict";n.r(e);var i={name:"Home",components:{NavLink:n(243).default},computed:{data(){return this.$page.frontmatter},actionLink(){return{link:this.data.actionLink,text:this.data.actionText}}}},r=(n(271),n(14)),a=Object(r.a)(i,(function(){var t=this,e=t._self._c;return e("main",{staticClass:"home",attrs:{"aria-labelledby":null!==t.data.heroText?"main-title":null}},[e("header",{staticClass:"hero"},[t.data.heroImage?e("img",{attrs:{src:t.$withBase(t.data.heroImage),alt:t.data.heroAlt||"hero"}}):t._e(),t._v(" "),null!==t.data.heroText?e("h1",{attrs:{id:"main-title"}},[t._v("\n "+t._s(t.data.heroText||t.$title||"Hello")+"\n ")]):t._e(),t._v(" "),null!==t.data.tagline?e("p",{staticClass:"description"},[t._v("\n "+t._s(t.data.tagline||t.$description||"Welcome to your VuePress site")+"\n ")]):t._e(),t._v(" "),t.data.actionText&&t.data.actionLink?e("p",{staticClass:"action"},[e("NavLink",{staticClass:"action-button",attrs:{item:t.actionLink}})],1):t._e()]),t._v(" "),t.data.features&&t.data.features.length?e("div",{staticClass:"features"},t._l(t.data.features,(function(n,i){return e("div",{key:i,staticClass:"feature"},[e("h2",[t._v(t._s(n.title))]),t._v(" "),e("p",[t._v(t._s(n.details))])])})),0):t._e(),t._v(" "),e("Content",{staticClass:"theme-default-content custom"}),t._v(" "),t.data.footer?e("div",{staticClass:"footer"},[t._v("\n "+t._s(t.data.footer)+"\n ")]):e("Content",{staticClass:"footer",attrs:{"slot-key":"footer"}})],1)}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/23.883f4d72.js b/assets/js/23.883f4d72.js new file mode 100644 index 0000000..2b49902 --- /dev/null +++ b/assets/js/23.883f4d72.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[23],{241:function(t,e,n){"use strict";n.d(e,"d",(function(){return i})),n.d(e,"a",(function(){return a})),n.d(e,"i",(function(){return s})),n.d(e,"f",(function(){return c})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return l})),n.d(e,"b",(function(){return d})),n.d(e,"e",(function(){return p})),n.d(e,"k",(function(){return f})),n.d(e,"l",(function(){return h})),n.d(e,"c",(function(){return m})),n.d(e,"j",(function(){return b}));n(45);const i=/#.*$/,r=/\.(md|html)$/,a=/\/$/,s=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(i,"").replace(r,"")}function c(t){return s.test(t)}function u(t){return/^mailto:/.test(t)}function l(t){return/^tel:/.test(t)}function d(t){if(c(t))return t;const e=t.match(i),n=e?e[0]:"",r=o(t);return a.test(r)?t:r+".html"+n}function p(t,e){const n=decodeURIComponent(t.hash),r=function(t){const e=t.match(i);if(e)return e[0]}(e);if(r&&n!==r)return!1;return o(t.path)===o(e)}function f(t,e,n){if(c(e))return{type:"external",path:e};n&&(e=function(t,e,n){const i=t.charAt(0);if("/"===i)return t;if("?"===i||"#"===i)return e+t;const r=e.split("/");n&&r[r.length-1]||r.pop();const a=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,i,r=1){if("string"==typeof e)return f(n,e,i);if(Array.isArray(e))return Object.assign(f(n,e[0],i),{title:e[1]});{const a=e.children||[];return 0===a.length&&e.path?Object.assign(f(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:a.map(e=>t(e,n,i,r+1)),collapsable:!1!==e.collapsable}}}(t,r,n)):[]}return[]}function g(t){const e=m(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function m(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function b(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},248:function(t,e){t.exports=function(t){return null==t}},250:function(t,e,n){},261:function(t,e,n){"use strict";n(250)},269:function(t,e,n){"use strict";n.r(e);var i=n(248),r=n.n(i),a=n(241),s={name:"PageEdit",computed:{lastUpdated(){return this.$page.lastUpdated},lastUpdatedText(){return"string"==typeof this.$themeLocaleConfig.lastUpdated?this.$themeLocaleConfig.lastUpdated:"string"==typeof this.$site.themeConfig.lastUpdated?this.$site.themeConfig.lastUpdated:"Last Updated"},editLink(){const t=r()(this.$page.frontmatter.editLink)?this.$site.themeConfig.editLinks:this.$page.frontmatter.editLink,{repo:e,docsDir:n="",docsBranch:i="master",docsRepo:a=e}=this.$site.themeConfig;return t&&a&&this.$page.relativePath?this.createEditLink(e,a,n,i,this.$page.relativePath):null},editLinkText(){return this.$themeLocaleConfig.editLinkText||this.$site.themeConfig.editLinkText||"Edit this page"}},methods:{createEditLink(t,e,n,i,r){if(/bitbucket.org/.test(e)){return e.replace(a.a,"")+"/src"+`/${i}/`+(n?n.replace(a.a,"")+"/":"")+r+`?mode=edit&spa=0&at=${i}&fileviewer=file-view-default`}if(/gitlab.com/.test(e)){return e.replace(a.a,"")+"/-/edit"+`/${i}/`+(n?n.replace(a.a,"")+"/":"")+r}return(a.i.test(e)?e:"https://github.com/"+e).replace(a.a,"")+"/edit"+`/${i}/`+(n?n.replace(a.a,"")+"/":"")+r}}},o=(n(261),n(14)),c=Object(o.a)(s,(function(){var t=this,e=t._self._c;return e("footer",{staticClass:"page-edit"},[t.editLink?e("div",{staticClass:"edit-link"},[e("a",{attrs:{href:t.editLink,target:"_blank",rel:"noopener noreferrer"}},[t._v(t._s(t.editLinkText))]),t._v(" "),e("OutboundLink")],1):t._e(),t._v(" "),t.lastUpdated?e("div",{staticClass:"last-updated"},[e("span",{staticClass:"prefix"},[t._v(t._s(t.lastUpdatedText)+":")]),t._v(" "),e("span",{staticClass:"time"},[t._v(t._s(t.lastUpdated))])]):t._e()])}),[],!1,null,null,null);e.default=c.exports}}]); \ No newline at end of file diff --git a/assets/js/24.3e49c207.js b/assets/js/24.3e49c207.js new file mode 100644 index 0000000..fb51187 --- /dev/null +++ b/assets/js/24.3e49c207.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[24],{307:function(a,v,t){a.exports=t.p+"assets/img/10.3fdd2e73.png"},308:function(a,v,t){a.exports=t.p+"assets/img/11.8de292dd.png"},309:function(a,v,t){a.exports=t.p+"assets/img/12.738b1aa1.png"},310:function(a,v,t){a.exports=t.p+"assets/img/13.aeaf6857.png"},413:function(a,v,t){"use strict";t.r(v);var s=t(14),_=Object(s.a)({},(function(){var a=this,v=a._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[v("h1",{attrs:{id:"_2024-04-02-练习-1-启用编译器"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-02-练习-1-启用编译器"}},[a._v("#")]),a._v(" 2024.04.02-练习 1:启用编译器")]),a._v(" "),v("h2",{attrs:{id:"_1-make"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_1-make"}},[a._v("#")]),a._v(" 1. make")]),a._v(" "),v("div",{staticClass:"language-cpp extra-class"},[v("pre",{pre:!0,attrs:{class:"language-cpp"}},[v("code",[v("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("int")]),a._v(" "),v("span",{pre:!0,attrs:{class:"token function"}},[a._v("main")]),v("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),v("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("int")]),a._v(" argc"),v("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" "),v("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("char")]),a._v(" "),v("span",{pre:!0,attrs:{class:"token operator"}},[a._v("*")]),a._v("argv"),v("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),v("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),v("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),v("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),v("span",{pre:!0,attrs:{class:"token function"}},[a._v("puts")]),v("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),v("span",{pre:!0,attrs:{class:"token string"}},[a._v('"Hello world."')]),v("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),v("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n\n "),v("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("return")]),a._v(" "),v("span",{pre:!0,attrs:{class:"token number"}},[a._v("0")]),v("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n"),v("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),v("p",[a._v("代码段没有显式包含"),v("code",[a._v("#include ")]),a._v(",但是仍然能够运行,并成功调用"),v("code",[a._v("puts")]),a._v('函数输出"Hello world."。这是因为,在某些编译器和开发环境中,即使没有显式地包含标准输入输出头文件'),v("code",[a._v("stdio.h")]),a._v(",编译器也可能会隐式地包含或者提前编译了这些基本的库函数。")]),a._v(" "),v("p",[a._v("具体来说,"),v("code",[a._v("puts")]),a._v("函数是 C 语言标准库中负责输出字符串到标准输出的函数,它定义在"),v("code",[a._v("stdio.h")]),a._v("中。按照 C 语言标准,使用"),v("code",[a._v("puts")]),a._v("或者其他标准库函数时,应该包含相应的头文件。不这样做是不符合标准的,可能导致编译器警告或错误。")]),a._v(" "),v("p",[a._v("然而,一些编译器为了方便开发者,可能会有以下行为:")]),a._v(" "),v("ul",[v("li",[a._v("隐式包含:编译器可能会默认包含一些常用的头文件。这意味着即使开发者没有显式包含"),v("code",[a._v("stdio.h")]),a._v(",编译器也会处理像"),v("code",[a._v("puts")]),a._v("这样的标准库函数调用。")]),a._v(" "),v("li",[a._v("预编译头文件:在某些开发环境中,常用的头文件可能被预编译并隐式地包含在每个编译单元中,以提高编译效率。")]),a._v(" "),v("li",[a._v("特定编译器扩展:一些编译器可能会提供非标准的扩展,允许在没有包含对应头文件的情况下使用某些库函数。")])]),a._v(" "),v("p",[a._v("不过,依赖这种非标准的行为是不推荐的。为了确保代码的可移植性和避免潜在的问题,最佳实践是始终显式包含你在代码中用到的所有标准库头文件。这样做可以保证代码在不同的编译器和环境中都能正常工作。")]),a._v(" "),v("h2",{attrs:{id:"_2-如何使它崩溃"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_2-如何使它崩溃"}},[a._v("#")]),a._v(" 2. 如何使它崩溃?")]),a._v(" "),v("p",[a._v("对于这个程序,打开所有编译警告重新构建它:")]),a._v(" "),v("div",{staticClass:"language-bash extra-class"},[v("pre",{pre:!0,attrs:{class:"language-bash"}},[v("code",[a._v("$ "),v("span",{pre:!0,attrs:{class:"token function"}},[a._v("rm")]),a._v(" ex1\n$ "),v("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("CFLAGS")]),v("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),v("span",{pre:!0,attrs:{class:"token string"}},[a._v('"-Wall"')]),a._v(" "),v("span",{pre:!0,attrs:{class:"token function"}},[a._v("make")]),a._v(" ex1\ncc "),v("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-Wall")]),a._v(" ex1.c "),v("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-o")]),a._v(" ex1\nex1.c: Infunction "),v("span",{pre:!0,attrs:{class:"token string"}},[a._v("'main'")]),v("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v("\nex1.c:3: warning: implicit declaration offunction "),v("span",{pre:!0,attrs:{class:"token string"}},[a._v("'puts'")]),a._v("\n$ ./ex1\nHello world.\n")])])]),v("p",[v("code",[a._v('CFLAGS="-Wall"')]),a._v(":这部分设置了一个环境变量"),v("code",[a._v("CFLAGS")]),a._v(",它是用于 C 编译器的标志(flags)集合。在这个特定的例子中,"),v("code",[a._v("-Wall")]),a._v("选项被设置给"),v("code",[a._v("CFLAGS")]),a._v("。"),v("code",[a._v("-Wall")]),a._v("是一个编译器标志,告诉编译器生成所有警告信息,帮助开发者发现代码中的潜在问题。这个标志对于提高代码质量和发现潜在的错误非常有用。")]),a._v(" "),v("p",[a._v("现在你会得到一个警告,说"),v("code",[a._v("puts")]),a._v("函数是隐式声明的。C 语言的编译器很智能,它能够理解你想要什么。但是如果可以的话,你应该去除所有编译器警告。把下面一行添加到"),v("code",[a._v("ex1.c")]),a._v("文件的最上面,之后重新编译来去除它:")]),a._v(" "),v("div",{staticClass:"language-c extra-class"},[v("pre",{pre:!0,attrs:{class:"language-c"}},[v("code",[v("span",{pre:!0,attrs:{class:"token macro property"}},[v("span",{pre:!0,attrs:{class:"token directive-hash"}},[a._v("#")]),v("span",{pre:!0,attrs:{class:"token directive keyword"}},[a._v("include")]),a._v(" "),v("span",{pre:!0,attrs:{class:"token string"}},[a._v("")])]),a._v("\n")])])]),v("h2",{attrs:{id:"_3-附加题-1"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_3-附加题-1"}},[a._v("#")]),a._v(" 3. 附加题 1")]),a._v(" "),v("p",[a._v("在你的文本编辑器中打开"),v("code",[a._v("ex1")]),a._v("文件,随机修改或删除一部分,之后运行它看看发生了什么。")]),a._v(" "),v("p",[v("img",{attrs:{src:t(307),alt:"Untitled"}})]),a._v(" "),v("p",[v("img",{attrs:{src:t(308),alt:"Untitled"}})]),a._v(" "),v("h2",{attrs:{id:"_4-附加题-2"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_4-附加题-2"}},[a._v("#")]),a._v(" 4. 附加题 2")]),a._v(" "),v("p",[a._v("再多打印 5 行文本或者其它比"),v("code",[a._v('"Hello world."')]),a._v("更复杂的东西。")]),a._v(" "),v("p",[a._v("在 C 语言中,"),v("code",[a._v("char *argv[]")]),a._v("是"),v("code",[a._v("main")]),a._v("函数的一个参数,它表示传递给程序的命令行参数的数组。让我们分解一下这个声明,以便更好地理解它:")]),a._v(" "),v("ul",[v("li",[v("code",[a._v("char")]),a._v(":表示数组中的元素是字符类型。")]),a._v(" "),v("li",[v("code",[a._v("*")]),a._v(":这是一个指针符号,表明这个变量是一个指针。")]),a._v(" "),v("li",[v("code",[a._v("argv[]")]),a._v(":这是一个数组符号,表明这个变量是一个数组。结合前面的指针符号,这意味着"),v("code",[a._v("argv")]),a._v("是一个指向指针的数组,或者更准确地说,是一个指向字符指针的数组。")])]),a._v(" "),v("p",[a._v("所以,"),v("code",[a._v("char *argv[]")]),a._v("是一个指向字符指针数组的指针,每个字符指针指向一个字符串。这些字符串是命令行参数,即在命令行中执行程序时输入的参数。")]),a._v(" "),v("p",[a._v("在"),v("code",[a._v("main")]),a._v("函数的上下文中,"),v("code",[a._v("argc")]),a._v("(argument count)是一个整型("),v("code",[a._v("int")]),a._v(")变量,它表示命令行参数的数量,包括程序名本身。"),v("code",[a._v("argv")]),a._v("(argument vector)是一个指向字符串数组的指针,存储了所有的命令行参数。"),v("code",[a._v("argv[0]")]),a._v("通常是程序的名称,"),v("code",[a._v("argv[1]")]),a._v("是传递给程序的第一个参数,依此类推。"),v("code",[a._v("argv[argc]")]),a._v("是"),v("code",[a._v("NULL")]),a._v(",标记数组的结束。")]),a._v(" "),v("p",[a._v("举例来说,如果你在命令行中运行程序如下:")]),a._v(" "),v("div",{staticClass:"language-bash extra-class"},[v("pre",{pre:!0,attrs:{class:"language-bash"}},[v("code",[a._v("./myprogram arg1 arg2\n")])])]),v("p",[a._v("这里,"),v("code",[a._v("argc")]),a._v("将是"),v("code",[a._v("3")]),a._v("(因为有三个命令行参数:"),v("code",[a._v("./myprogram")]),a._v(", "),v("code",[a._v("arg1")]),a._v(", 和 "),v("code",[a._v("arg2")]),a._v("),而"),v("code",[a._v("argv")]),a._v("数组将包含以下内容:")]),a._v(" "),v("ul",[v("li",[v("code",[a._v("argv[0]")]),a._v(" 将是字符串 "),v("code",[a._v('"./myprogram"')]),a._v(",指向程序的名称。")]),a._v(" "),v("li",[v("code",[a._v("argv[1]")]),a._v(" 将是字符串 "),v("code",[a._v('"arg1"')]),a._v(",指向第一个命令行参数。")]),a._v(" "),v("li",[v("code",[a._v("argv[2]")]),a._v(" 将是字符串 "),v("code",[a._v('"arg2"')]),a._v(",指向第二个命令行参数。")]),a._v(" "),v("li",[v("code",[a._v("argv[3]")]),a._v(" 将是"),v("code",[a._v("NULL")]),a._v(",标记数组的结束。")])]),a._v(" "),v("p",[a._v("通过使用"),v("code",[a._v("argc")]),a._v("和"),v("code",[a._v("argv")]),a._v(",C 程序可以接收和处理用户在命令行中输入的参数。")]),a._v(" "),v("p",[v("img",{attrs:{src:t(309),alt:"Untitled"}})]),a._v(" "),v("h2",{attrs:{id:"_5-附加题-3"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_5-附加题-3"}},[a._v("#")]),a._v(" 5. 附加题 3")]),a._v(" "),v("p",[a._v("执行"),v("code",[a._v("man 3 puts")]),a._v("来阅读这个函数和其它函数的文档。")]),a._v(" "),v("p",[a._v("在 UNIX 或类 UNIX 系统中,"),v("code",[a._v("man")]),a._v("命令用于查看手册页(manual pages),它是系统文档的一个重要组成部分。手册页按照不同的部分组织,每个部分涵盖了特定类型的命令或信息。当你在命令行中输入"),v("code",[a._v("man 3 puts")]),a._v("时,"),v("code",[a._v("3")]),a._v("指的是你想要查看第三部分中"),v("code",[a._v("puts")]),a._v("函数的手册页。")]),a._v(" "),v("p",[a._v("手册页的部分主要包括:")]),a._v(" "),v("ol",[v("li",[v("strong",[a._v("用户命令")]),a._v(":可执行程序或 shell 命令。")]),a._v(" "),v("li",[v("strong",[a._v("系统调用")]),a._v(":由内核提供的函数。")]),a._v(" "),v("li",[v("strong",[a._v("库调用")]),a._v(":标准库函数,如 C 库(libc)中的函数。")]),a._v(" "),v("li",[v("strong",[a._v("特殊文件")]),a._v(":通常指/dev 目录下的文件。")]),a._v(" "),v("li",[v("strong",[a._v("文件格式和约定")]),a._v(":例如/etc/passwd。")]),a._v(" "),v("li",[v("strong",[a._v("游戏和屏保")]),a._v(":已经很少使用。")]),a._v(" "),v("li",[v("strong",[a._v("杂项")]),a._v(":包括宏包和约定,如 man 文档自身的格式。")]),a._v(" "),v("li",[v("strong",[a._v("系统管理命令")]),a._v(":通常只能由 root 用户执行的命令。")]),a._v(" "),v("li",[v("strong",[a._v("内核例程")]),a._v(":内核的接口。")])]),a._v(" "),v("p",[a._v("所以,"),v("code",[a._v("man 3 puts")]),a._v("命令表示你请求查看第三部分(库调用)中关于"),v("code",[a._v("puts")]),a._v("函数的文档。"),v("code",[a._v("puts")]),a._v("是标准 C 库的一部分,用于向标准输出写入一个字符串,这就是为什么它位于第三部分。这种组织方法让用户可以快速找到关于不同类型命令和函数的文档,即使它们的名字相同(例如,一个是用户命令,另一个是系统调用)。")]),a._v(" "),v("p",[v("img",{attrs:{src:t(310),alt:"Untitled"}})])])}),[],!1,null,null,null);v.default=_.exports}}]); \ No newline at end of file diff --git a/assets/js/25.fa27d43f.js b/assets/js/25.fa27d43f.js new file mode 100644 index 0000000..165c1fc --- /dev/null +++ b/assets/js/25.fa27d43f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[25],{322:function(t,s,a){t.exports=a.p+"assets/img/74.35cba8aa.png"},323:function(t,s,a){t.exports=a.p+"assets/img/71.7cb849c0.png"},324:function(t,s,a){t.exports=a.p+"assets/img/72.921c6bb2.png"},325:function(t,s,a){t.exports=a.p+"assets/img/73.4dfb177b.png"},421:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-03-练习7-更多变量和一些算术"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-03-练习7-更多变量和一些算术"}},[t._v("#")]),t._v(" 2024.04.03-练习7:更多变量和一些算术")]),t._v(" "),s("h2",{attrs:{id:"_1-基本算术操作"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-基本算术操作"}},[t._v("#")]),t._v(" 1. 基本算术操作")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" bugs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" bug_rate "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"You have %d bugs at the imaginary rate of %f.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n bugs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bug_rate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("long")]),t._v(" universe_of_defects "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1L")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1024L")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1024L")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1024L")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The entire universe has %ld bugs.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n universe_of_defects"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" expected_bugs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" bugs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" bug_rate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"You are expected to have %f bugs.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n expected_bugs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" part_of_universe "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" expected_bugs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" universe_of_defects"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"That is only a %e portion of the universe.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n part_of_universe"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this makes no sense, just a demo of something weird")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" nul_byte "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" care_percentage "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" bugs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" nul_byte"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Which means you should care %d%%.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n care_percentage"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("以特殊的语法"),s("code",[t._v("'\\0'")]),t._v("声明了一个字符。这样创建了一个“空字节”字符,实际上是数字0。")]),t._v(" "),s("h2",{attrs:{id:"_2-用-s打印-0"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-用-s打印-0"}},[t._v("#")]),t._v(" 2. 用%s打印\\0")]),t._v(" "),s("p",[s("img",{attrs:{src:a(322),alt:"Untitled"}})]),t._v(" "),s("h2",{attrs:{id:"_3-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-附加题"}},[t._v("#")]),t._v(" 3. 附加题")]),t._v(" "),s("h3",{attrs:{id:"_3-1-long-max"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-long-max"}},[t._v("#")]),t._v(" 3.1 LONG_MAX")]),t._v(" "),s("p",[s("img",{attrs:{src:a(323),alt:"Untitled"}})]),t._v(" "),s("p",[t._v("会发生溢出,到负的那边循环")]),t._v(" "),s("h3",{attrs:{id:"_3-2-ulong-max"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-ulong-max"}},[t._v("#")]),t._v(" 3.2 ULONG_MAX")]),t._v(" "),s("p",[s("img",{attrs:{src:a(324),alt:"Untitled"}})]),t._v(" "),s("p",[t._v("unsigned的范围是signed的最大值的两倍加一")]),t._v(" "),s("h3",{attrs:{id:"_3-3-char-int"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-char-int"}},[t._v("#")]),t._v(" 3.3 char & int")]),t._v(" "),s("p",[s("img",{attrs:{src:a(325),alt:"Untitled"}})]),t._v(" "),s("p",[t._v("因为char字符都有ASCII编码,所以可以被认为是int")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/26.65784971.js b/assets/js/26.65784971.js new file mode 100644 index 0000000..9c68020 --- /dev/null +++ b/assets/js/26.65784971.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[26],{318:function(t,s,a){t.exports=a.p+"assets/img/90.1771be5f.png"},319:function(t,s,a){t.exports=a.p+"assets/img/91.c7cffbcc.png"},320:function(t,s,a){t.exports=a.p+"assets/img/92.e9c4a47f.png"},321:function(t,s,a){t.exports=a.p+"assets/img/93.b74ca16a.png"},420:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-03-练习9-数组和字符串"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-03-练习9-数组和字符串"}},[t._v("#")]),t._v(" 2024.04.03-练习9:数组和字符串")]),t._v(" "),s("h2",{attrs:{id:"_1-字符数组"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-字符数组"}},[t._v("#")]),t._v(" 1. 字符数组")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'a'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// first, print them out raw")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"numbers: %d %d %d %d\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name each: %c %c %c %c\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name: %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// setup the numbers")]),t._v("\n numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// setup the name")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'Z'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'e'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'d'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// then print them out initialized")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"numbers: %d %d %d %d\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" numbers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name each: %c %c %c %c\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// print the name like a string")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name: %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// another way to use name")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("another "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Zed"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"another: %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" another"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"another each: %c %c %c %c\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n another"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" another"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n another"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" another"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"_2-使其崩溃"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-使其崩溃"}},[t._v("#")]),t._v(" 2. 使其崩溃")]),t._v(" "),s("h3",{attrs:{id:"_2-1-删掉name的初始化表达式"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-删掉name的初始化表达式"}},[t._v("#")]),t._v(" 2.1 删掉"),s("code",[t._v("name")]),t._v("的初始化表达式")]),t._v(" "),s("p",[t._v("error")]),t._v(" "),s("h3",{attrs:{id:"_2-2-设置name-3-a"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-设置name-3-a"}},[t._v("#")]),t._v(" 2.2 设置"),s("code",[t._v("name[3] = 'A'")])]),t._v(" "),s("p",[s("img",{attrs:{src:a(318),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_2-3-初始化表达式设置为-a-a-a-a"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-初始化表达式设置为-a-a-a-a"}},[t._v("#")]),t._v(" 2.3 初始化表达式设置为"),s("code",[t._v("{'a','a','a','a'}")])]),t._v(" "),s("p",[s("img",{attrs:{src:a(319),alt:"Untitled"}})]),t._v(" "),s("p",[s("img",{attrs:{src:a(320),alt:"Untitled"}})]),t._v(" "),s("h2",{attrs:{id:"_3-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-附加题"}},[t._v("#")]),t._v(" 3. 附加题")]),t._v(" "),s("h3",{attrs:{id:"_3-1-字符赋给numbers的元素"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-字符赋给numbers的元素"}},[t._v("#")]),t._v(" 3.1 字符赋给"),s("code",[t._v("numbers")]),t._v("的元素")]),t._v(" "),s("p",[t._v("当用"),s("code",[t._v("%c")]),t._v("格式化字符串来打印一个"),s("code",[t._v("int")]),t._v("值时,编译器通常不会发出警告,因为"),s("code",[t._v("%c")]),t._v("期望一个"),s("code",[t._v("int")]),t._v("类型的参数(在大多数情况下,字符在传递给函数时会被提升为"),s("code",[t._v("int")]),t._v(")。然而,如果数组中的整数值不对应于有效的ASCII字符编码,则打印的结果可能是乱码或不可预测的字符。")]),t._v(" "),s("h3",{attrs:{id:"_3-2-把names当成int数组"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-把names当成int数组"}},[t._v("#")]),t._v(" 3.2 把"),s("code",[t._v("names")]),t._v("当成"),s("code",[t._v("int")]),t._v("数组")]),t._v(" "),s("p",[t._v("使用"),s("code",[t._v("%d")]),t._v("格式化字符串来打印时,如果直接传递"),s("code",[t._v("char")]),t._v("类型的值给"),s("code",[t._v("printf")]),t._v(",由于"),s("code",[t._v("char")]),t._v("到"),s("code",[t._v("int")]),t._v("的隐式类型提升,这种类型不匹配通常不会导致编译器警告。但是,如果尝试直接以"),s("code",[t._v("int")]),t._v("数组的方式访问"),s("code",[t._v("char")]),t._v("数组(如通过类型转换或指针操作),并尝试打印,这将导致未定义的行为,特别是当"),s("code",[t._v("char")]),t._v("数组的大小小于"),s("code",[t._v("int")]),t._v("时。")]),t._v(" "),s("h3",{attrs:{id:"_3-3"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-3"}},[t._v("#")]),t._v(" 3.3")]),t._v(" "),s("p",[t._v("如果一个字符数组占四个字节,一个整数也占4个字节,你可以像整数一样使用整个name吗?你如何用黑魔法实现它?")]),t._v(" "),s("p",[s("img",{attrs:{src:a(321),alt:"Untitled"}})]),t._v(" "),s("p",[s("code",[t._v("Zed\\0")]),t._v(" 的ASCII码对应的十六进制分别是5a,65,64,0.然后考虑到计算机是小端序,所以name存储时最低位存的是Z,所以综合起来存储的就是0064655a,十进制就是6579546")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/27.48df2183.js b/assets/js/27.48df2183.js new file mode 100644 index 0000000..2907a6c --- /dev/null +++ b/assets/js/27.48df2183.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[27],{241:function(t,e,n){"use strict";n.d(e,"d",(function(){return r})),n.d(e,"a",(function(){return a})),n.d(e,"i",(function(){return s})),n.d(e,"f",(function(){return o})),n.d(e,"g",(function(){return c})),n.d(e,"h",(function(){return l})),n.d(e,"b",(function(){return p})),n.d(e,"e",(function(){return f})),n.d(e,"k",(function(){return d})),n.d(e,"l",(function(){return h})),n.d(e,"c",(function(){return g})),n.d(e,"j",(function(){return m}));n(45);const r=/#.*$/,i=/\.(md|html)$/,a=/\/$/,s=/^[a-z]+:/i;function u(t){return decodeURI(t).replace(r,"").replace(i,"")}function o(t){return s.test(t)}function c(t){return/^mailto:/.test(t)}function l(t){return/^tel:/.test(t)}function p(t){if(o(t))return t;const e=t.match(r),n=e?e[0]:"",i=u(t);return a.test(i)?t:i+".html"+n}function f(t,e){const n=decodeURIComponent(t.hash),i=function(t){const e=t.match(r);if(e)return e[0]}(e);if(i&&n!==i)return!1;return u(t.path)===u(e)}function d(t,e,n){if(o(e))return{type:"external",path:e};n&&(e=function(t,e,n){const r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return e+t;const i=e.split("/");n&&i[i.length-1]||i.pop();const a=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,r,i=1){if("string"==typeof e)return d(n,e,r);if(Array.isArray(e))return Object.assign(d(n,e[0],r),{title:e[1]});{const a=e.children||[];return 0===a.length&&e.path?Object.assign(d(n,e.path,r),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:a.map(e=>t(e,n,r,i+1)),collapsable:!1!==e.collapsable}}}(t,i,n)):[]}return[]}function b(t){const e=g(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function g(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function m(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},247:function(t,e,n){},254:function(t,e,n){"use strict";n(247)},257:function(t,e,n){"use strict";n.r(e);var r=n(241);function i(t,e,n,r,i){const a={props:{to:e,activeClass:"",exactActiveClass:""},class:{active:r,"sidebar-link":!0}};return i>2&&(a.style={"padding-left":i+"rem"}),t("RouterLink",a,n)}function a(t,e,n,s,u,o=1){return!e||o>u?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const c=Object(r.e)(s,n+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[i(t,n+"#"+e.slug,e.title,c,e.level-1),a(t,e.children,n,s,u,o+1)])}))}var s={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:n,$route:s,$themeConfig:u,$themeLocaleConfig:o},props:{item:c,sidebarDepth:l}}){const p=Object(r.e)(s,c.path),f="auto"===c.type?p||c.children.some(t=>Object(r.e)(s,c.basePath+"#"+t.slug)):p,d="external"===c.type?function(t,e,n){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[n,t("OutboundLink")])}(t,c.path,c.title||c.path):i(t,c.path,c.title||c.path,f),h=[e.frontmatter.sidebarDepth,l,o.sidebarDepth,u.sidebarDepth,1].find(t=>void 0!==t),b=o.displayAllHeaders||u.displayAllHeaders;if("auto"===c.type)return[d,a(t,c.children,c.basePath,s,h)];if((f||b)&&c.headers&&!r.d.test(c.path)){return[d,a(t,Object(r.c)(c.headers),c.path,s,h)]}return d}},u=(n(254),n(14)),o=Object(u.a)(s,void 0,void 0,!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/28.a6546003.js b/assets/js/28.a6546003.js new file mode 100644 index 0000000..ffe01cf --- /dev/null +++ b/assets/js/28.a6546003.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[28],{341:function(t,s,a){t.exports=a.p+"assets/img/330.d5f6b243.png"},342:function(t,s,a){t.exports=a.p+"assets/img/331.87f2f64d.png"},343:function(t,s,a){t.exports=a.p+"assets/img/332.055be097.png"},432:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-11-练习33-链表算法"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-11-练习33-链表算法"}},[t._v("#")]),t._v(" 2024.04.11-练习33:链表算法")]),t._v(" "),s("h2",{attrs:{id:"_1-归并排序"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-归并排序"}},[t._v("#")]),t._v(" 1. 归并排序")]),t._v(" "),s("p",[t._v("归并排序是一种高效、稳定的排序算法,使用分治法(Divide and Conquer)的一个非常典型的应用。它的基本思想是将两个或两个以上的有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。")]),t._v(" "),s("p",[t._v("归并排序的过程可以分为两个主要部分:")]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("拆分")]),t._v(":从中间将待排序数组拆分成两个子数组,递归地对这两个子数组进行归并排序,直到子数组长度为1或0。")]),t._v(" "),s("li",[s("strong",[t._v("合并")]),t._v(":将两个有序的子数组合并成一个有序数组。合并过程需要额外的空间来暂存数据。")])]),t._v(" "),s("p",[t._v("归并排序的时间复杂度为"),s("mjx-container",{staticClass:"MathJax",attrs:{jax:"CHTML"}},[s("mjx-math",{staticClass:"MJX-TEX"},[s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"O"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"("}})],1),s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"n"}})],1),s("mjx-mi",{staticClass:"mjx-n",attrs:{space:"2"}},[s("mjx-c",{attrs:{c:"l"}}),s("mjx-c",{attrs:{c:"o"}}),s("mjx-c",{attrs:{c:"g"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"2061"}})],1),s("mjx-mi",{staticClass:"mjx-i",attrs:{space:"2"}},[s("mjx-c",{attrs:{c:"n"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:")"}})],1)],1)],1),t._v(",不管最坏情况还是平均情况都是这个时间复杂度,其中 "),s("mjx-container",{staticClass:"MathJax",attrs:{jax:"CHTML"}},[s("mjx-math",{staticClass:"MJX-TEX"},[s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"n"}})],1)],1)],1),t._v(" 是数组或列表的长度。这是因为归并排序总是把列表分成两半,然后进行合并,所以拆分的层数(递归深度)是 "),s("mjx-container",{staticClass:"MathJax",attrs:{jax:"CHTML"}},[s("mjx-math",{staticClass:"MJX-TEX"},[s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"n"}})],1),s("mjx-mi",{staticClass:"mjx-n",attrs:{space:"2"}},[s("mjx-c",{attrs:{c:"l"}}),s("mjx-c",{attrs:{c:"o"}}),s("mjx-c",{attrs:{c:"g"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"2061"}})],1),s("mjx-mi",{staticClass:"mjx-i",attrs:{space:"2"}},[s("mjx-c",{attrs:{c:"n"}})],1)],1)],1),t._v(" ,每层需要的比较和合并操作是 "),s("mjx-container",{staticClass:"MathJax",attrs:{jax:"CHTML"}},[s("mjx-math",{staticClass:"MJX-TEX"},[s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"n"}})],1)],1)],1),t._v(" 次,所以总的操作次数是 "),s("mjx-container",{staticClass:"MathJax",attrs:{jax:"CHTML"}},[s("mjx-math",{staticClass:"MJX-TEX"},[s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"n"}})],1),s("mjx-mi",{staticClass:"mjx-n",attrs:{space:"2"}},[s("mjx-c",{attrs:{c:"l"}}),s("mjx-c",{attrs:{c:"o"}}),s("mjx-c",{attrs:{c:"g"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"2061"}})],1),s("mjx-mi",{staticClass:"mjx-i",attrs:{space:"2"}},[s("mjx-c",{attrs:{c:"n"}})],1)],1)],1),t._v("。")],1),t._v(" "),s("p",[t._v("归并排序的稳定性来源于合并过程中,相等的元素会保持原有的先后顺序。这使得归并排序非常适合用于需要稳定排序算法的场景,比如数据库的排序等。")]),t._v(" "),s("p",[t._v("这个算法的空间复杂度是 "),s("mjx-container",{staticClass:"MathJax",attrs:{jax:"CHTML"}},[s("mjx-math",{staticClass:"MJX-TEX"},[s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"O"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"("}})],1),s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"n"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:")"}})],1)],1)],1),t._v(",因为合并过程需要与原始数组相等大小的空间来暂时存储合并后的数组。")],1),t._v(" "),s("p",[t._v("归并排序虽然在时间复杂度上表现良好,但由于其空间复杂度较高,因此在对空间使用有严格要求的环境下需要慎用。")]),t._v(" "),s("h2",{attrs:{id:"_2-代码"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-代码"}},[t._v("#")]),t._v(" 2. 代码")]),t._v(" "),s("h3",{attrs:{id:"_2-1-头文件"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-头文件"}},[t._v("#")]),t._v(" 2.1 头文件")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("ifndef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("lcthw_List_algos_h")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name"}},[t._v("lcthw_List_algos_h")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typedef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("List_compare"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_bubble_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List_compare cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List_compare cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("inline")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ListNode_swap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("temp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" temp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List_compare cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("endif")])]),t._v("\n")])])]),s("h3",{attrs:{id:"_2-2-实现"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-实现"}},[t._v("#")]),t._v(" 2.2 实现")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_bubble_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List_compare cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" sorted "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// already sorted")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("do")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n sorted "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("LIST_FOREACH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cmp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("ListNode_swap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n sorted "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("sorted"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List_compare cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("val "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cmp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_first")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_first")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n val "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_shift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n val "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_shift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n val "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_shift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n val "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_shift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List_compare cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" middle "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("LIST_FOREACH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("middle "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n middle"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("sort_left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("sort_right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sort_left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sort_right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sort_left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort_right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"_2-3-单元测试"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-单元测试"}},[t._v("#")]),t._v(" 2.3 单元测试")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"minunit.h"')])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("values"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"XXXX"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1234"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"abcd"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"xjvef"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"NDSS"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name"}},[t._v("NUM_VALUES")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")])])]),t._v("\n\nList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_words")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("words "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" NUM_VALUES"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" values"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("is_sorted")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("LIST_FOREACH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strcmp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("debug")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%s %s"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_bubble_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("words "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_words")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// should work on a list that needs sorting")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" rc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_bubble_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List_compare"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("strcmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bubble sort failed."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("is_sorted")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Words are not sorted after bubble sort."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// should work on an already sorted list")]),t._v("\n rc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_bubble_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List_compare"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("strcmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bubble sort of already sorted failed."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("is_sorted")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Words should be sort if already bubble sorted."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// should work on an empty list")]),t._v("\n words "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n rc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_bubble_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List_compare"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("strcmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bubble sort failed on empty list."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("is_sorted")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Words should be sorted if empty."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_merge_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("words "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_words")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// should work on a list that needs sorting")]),t._v("\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List_compare"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("strcmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("is_sorted")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Words are not sorted after merge sort."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("res2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List_compare"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("strcmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("is_sorted")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Should still be sorted after merge sort."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("words"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("all_tests")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_suite_start")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_run_test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("test_bubble_sort"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_run_test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("test_merge_sort"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RUN_TESTS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("all_tests"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"_2-4-inline"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-4-inline"}},[t._v("#")]),t._v(" 2.4 inline")]),t._v(" "),s("h3",{attrs:{id:"标准inline函数的使用"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#标准inline函数的使用"}},[t._v("#")]),t._v(" 标准"),s("code",[t._v("inline")]),t._v("函数的使用")]),t._v(" "),s("p",[t._v("当你在头文件中使用"),s("code",[t._v("inline")]),t._v("关键字声明和定义一个函数时,你告诉编译器这个函数的调用可以被替换为其函数体,即内联展开。这可以减少函数调用的开销,特别是对于那些非常小且频繁调用的函数。")]),t._v(" "),s("h3",{attrs:{id:"使用static-inline"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用static-inline"}},[t._v("#")]),t._v(" 使用"),s("code",[t._v("static inline")])]),t._v(" "),s("p",[t._v("通过在头文件中将函数定义为"),s("code",[t._v("static inline")]),t._v(",你可以避免链接问题。这样做的结果是,每个包含此头文件的"),s("code",[t._v(".c")]),t._v("文件都会得到函数的一个私有副本。这种方法很简单,适用于大多数情况,特别是当函数非常短小时。")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("ifndef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("EXAMPLE_H")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name"}},[t._v("EXAMPLE_H")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Inline function declaration")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("inline")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("myFunction")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Function implementation")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("endif")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// EXAMPLE_H")])]),t._v("\n")])])]),s("p",[t._v("这种方式不需要在源文件中额外定义函数。")]),t._v(" "),s("p",[t._v("如果你的目的是确保有一个非内联的版本可用,你可能不需要在源文件中使用"),s("code",[t._v("inline")]),s("strong",[t._v("或")]),s("code",[t._v("extern")]),s("strong",[t._v("关键字,因为")]),s("code",[t._v("static inline")]),s("strong",[t._v("的使用通常已经足够。我之前的建议在这方面可能不完全准确,因为在C中使用")]),s("code",[t._v("inline")]),s("strong",[t._v("函数的最佳实践可能因编译器和具体情况而异。如果确实需要在某个地方提供一个明确的外部定义,那么你应该在源文件中提供一个普通的函数定义(无")]),s("code",[t._v("inline")]),s("strong",[t._v("关键字),但这在使用了")]),s("code",[t._v("static inline")]),t._v("定义的情况下通常是不必要的。")]),t._v(" "),s("h2",{attrs:{id:"_3-改进"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-改进"}},[t._v("#")]),t._v(" 3. 改进")]),t._v(" "),s("p",[t._v("归并排序做了大量的链表复制和创建操作,寻找减少它们的办法。")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List_compare cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" right"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cmp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" right"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_shift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_shift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_shift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_shift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List_compare cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("secondHalf "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_split_mid")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("sort_left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("sort_right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge_sort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("secondHalf"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sort_left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sort_right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" secondHalf"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("secondHalf"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_merge")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sort_left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sort_right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_split_mid")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" cnt "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" c1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" c2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("slow "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("fast "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("fast "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" fast"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n slow "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" slow"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n fast "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" fast"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n c1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n c2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" cnt "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" c1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("listsecond "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n listsecond"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" slow"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n listsecond"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n listsecond"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n listsecond"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" c2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" slow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n slow"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" c1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" listsecond"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("img",{attrs:{src:a(341),alt:"Untitled"}})]),t._v(" "),s("h2",{attrs:{id:"_4-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-附加题"}},[t._v("#")]),t._v(" 4. 附加题")]),t._v(" "),s("h3",{attrs:{id:"_4-1-程序运行时间"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-1-程序运行时间"}},[t._v("#")]),t._v(" 4.1 程序运行时间")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" start "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clock")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_run_test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("test_bubble_sort"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clock")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),t._v(" cpu_time_used "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" start"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" CLOCKS_PER_SEC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test_bubble_sort took %f seconds to execute \\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cpu_time_used"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nstart "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clock")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_run_test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("test_merge_sort"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nend "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clock")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ncpu_time_used "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("double")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" start"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" CLOCKS_PER_SEC"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test_merge_sort took %f seconds to execute \\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cpu_time_used"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("img",{attrs:{src:a(342),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_4-2-list-insert-sorted"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-list-insert-sorted"}},[t._v("#")]),t._v(" 4.2 "),s("code",[t._v("List_insert_sorted")])]),t._v(" "),s("p",[t._v("实现"),s("code",[t._v("List_insert_sorted")]),t._v("(有序链表),它使用"),s("code",[t._v("List_compare")]),t._v(",接收一个值,将其插入到正确的位置,使链表有序。")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_insert_sorted")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List_compare cmp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ListNode"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cmp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 插入到链表头部")]),t._v("\n node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在链表中找到正确的插入位置")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("current "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cmp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" current"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n current "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" current"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 插入到current节点之后")]),t._v("\n node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" current"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n current"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("current"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("img",{attrs:{src:a(343),alt:"Untitled"}})])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/29.05cb5e16.js b/assets/js/29.05cb5e16.js new file mode 100644 index 0000000..4e17111 --- /dev/null +++ b/assets/js/29.05cb5e16.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[29],{353:function(s,a,t){s.exports=t.p+"assets/img/40.64b5a4ec.png"},354:function(s,a,t){s.exports=t.p+"assets/img/41.6f90f7f4.png"},355:function(s,a,t){s.exports=t.p+"assets/img/42.17353efa.png"},438:function(s,a,t){"use strict";t.r(a);var e=t(14),n=Object(e.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h1",{attrs:{id:"_2024-03-21-4-data-wrangling"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-21-4-data-wrangling"}},[s._v("#")]),s._v(" 2024.03.21-4. Data Wrangling")]),s._v(" "),a("h2",{attrs:{id:"_1-journalctl"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-journalctl"}},[s._v("#")]),s._v(" 1. journalctl")]),s._v(" "),a("p",[s._v("查看所有日志(默认情况下 ,只保存本次启动的日志)")]),s._v(" "),a("p",[s._v("journalctl")]),s._v(" "),a("p",[s._v("查看内核日志(不显示应用日志)")]),s._v(" "),a("p",[s._v("journalctl -k")]),s._v(" "),a("p",[s._v("查看系统本次启动的日志")]),s._v(" "),a("p",[s._v("journalctl -b")]),s._v(" "),a("p",[s._v("journalctl -b -0")]),s._v(" "),a("p",[s._v("查看上一次启动的日志(需更改设置)")]),s._v(" "),a("p",[s._v("journalctl -b -1")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ssh")]),s._v(" myserver journalctl "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" sshd\n")])])]),a("p",[s._v("这里我们使用管道将一个远程服务器上的文件传递给本机的  "),a("code",[s._v("grep")]),s._v("  程序! "),a("code",[s._v("ssh")]),s._v("  太牛了,下一节课我们会讲授命令行环境,届时我们会详细讨论  "),a("code",[s._v("ssh")]),s._v("  的相关内容。此时我们打印出的内容,仍然比我们需要的要多得多,读起来也非常费劲。我们来改进一下:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ssh")]),s._v(" myserver "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'journalctl | grep sshd | grep \"Disconnected from\"'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("less")]),s._v("\n")])])]),a("p",[s._v("多出来的引号是什么作用呢?这么说吧,我们的日志是一个非常大的文件,把这么大的文件流直接传输到我们本地的电脑上再进行过滤是对流量的一种浪费。因此我们采取另外一种方式,我们先在远端机器上过滤文本内容,然后再将结果传输到本机。 "),a("code",[s._v("less")]),s._v("  为我们创建来一个文件分页器,使我们可以通过翻页的方式浏览较长的文本。")]),s._v(" "),a("p",[s._v("为了进一步节省流量,我们甚至可以将当前过滤出的日志保存到文件中,这样后续就不需要再次通过网络访问该文件了:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ssh")]),s._v(" myserver "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'journalctl | grep sshd | grep \"Disconnected from\"'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" ssh.log\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("less")]),s._v(" ssh.log\n")])])]),a("p",[s._v("过滤结果中仍然包含不少没用的数据。我们有很多办法可以删除这些无用的数据,但是让我们先研究一下  "),a("code",[s._v("sed")]),s._v("  这个非常强大的工具。")]),s._v(" "),a("p",[a("code",[s._v("sed")]),s._v("  是一个基于文本编辑器"),a("code",[s._v("ed")]),s._v("构建的”流编辑器” 。在  "),a("code",[s._v("sed")]),s._v("  中,您基本上是利用一些简短的命令来修改文件,而不是直接操作文件的内容(尽管您也可以选择这样做)。相关的命令行非常多,但是最常用的是  "),a("code",[s._v("s")]),s._v(",即"),a("em",[s._v("替换")]),s._v("命令,例如我们可以这样写:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ssh")]),s._v(" myserver journalctl\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" sshd\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Disconnected from"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sed")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'s/.*Disconnected from //'")]),s._v("\n")])])]),a("p",[s._v("上面这段命令中,我们使用了一段简单的"),a("em",[s._v("正则表达式")]),s._v("。正则表达式是一种非常强大的工具,可以让我们基于某种模式来对字符串进行匹配。"),a("code",[s._v("s")]),s._v("  命令的语法如下:"),a("code",[s._v("s/REGEX/SUBSTITUTION/")]),s._v(", 其中  "),a("code",[s._v("REGEX")]),s._v("  部分是我们需要使用的正则表达式,而  "),a("code",[s._v("SUBSTITUTION")]),s._v("  是用于替换匹配结果的文本。")]),s._v(" "),a("h2",{attrs:{id:"_2-正则表达式"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-正则表达式"}},[s._v("#")]),s._v(" 2. 正则表达式")]),s._v(" "),a("p",[s._v("正则表达式通常以(尽管并不总是) "),a("code",[s._v("/")]),s._v(" 开始和结束。大多数的 ASCII 字符都表示它们本来的含义,但是有一些字符确实具有表示匹配行为的“特殊”含义。不同字符所表示的含义,根据正则表达式的实现方式不同,也会有所变化,这一点确实令人沮丧。常见的模式有:")]),s._v(" "),a("ul",[a("li",[a("code",[s._v(".")]),s._v("  除换行符之外的”任意单个字符”")]),s._v(" "),a("li",[s._v("``  匹配前面字符零次或多次")]),s._v(" "),a("li",[a("code",[s._v("+")]),s._v("  匹配前面字符一次或多次")]),s._v(" "),a("li",[a("code",[s._v("[abc]")]),s._v("  匹配  "),a("code",[s._v("a")]),s._v(", "),a("code",[s._v("b")]),s._v("  和  "),a("code",[s._v("c")]),s._v("  中的任意一个")]),s._v(" "),a("li",[a("code",[s._v("(RX1|RX2)")]),s._v("  任何能够匹配"),a("code",[s._v("RX1")]),s._v("  或  "),a("code",[s._v("RX2")]),s._v("的结果")]),s._v(" "),a("li",[a("code",[s._v("^")]),s._v("  行首")]),s._v(" "),a("li",[a("code",[s._v("$")]),s._v("  行尾")])]),s._v(" "),a("p",[s._v("正则表达式会如何匹配?"),a("code",[s._v("*")]),s._v("  和  "),a("code",[s._v("+")]),s._v("  在默认情况下是贪婪模式,也就是说,它们会尽可能多的匹配文本。对于某些正则表达式的实现来说,您可以给  "),a("code",[s._v("*")]),s._v("  或  "),a("code",[s._v("+")]),s._v("  增加一个"),a("code",[s._v("?")]),s._v("  后缀使其变成非贪婪模式")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sed")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-E")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'s/.*Disconnected from (invalid |authenticating )?user .* [^ ]+ port [0-9]+( \\[preauth\\])?$//'")]),s._v("\n")])])]),a("p",[s._v("IP 地址正则表达式:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("?:"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("?:1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-9"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-9"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("\\")]),s._v("."),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("?:2"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-4"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-9"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("\\")]),s._v("."),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("?:25"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-5"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("\\")]),s._v("."),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("?:"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v("-9"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-9"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("\\")]),s._v("."),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("?:"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-9"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("\\")]),s._v("."),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("))")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("3")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("?:"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("?:1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-9"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-9"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("?:2"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-4"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-9"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("?:25"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-5"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("?:"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v("-9"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-9"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("?:"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("-9"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("))")]),s._v("\n")])])]),a("p",[s._v("我们实际上希望能够将用户名"),a("em",[s._v("保留")]),s._v("下来。对此,我们可以使用“捕获组(capture groups)”来完成。被圆括号内的正则表达式匹配到的文本,都会被存入一系列以编号区分的捕获组中。捕获组的内容可以在替换字符串时使用(有些正则表达式的引擎甚至支持替换表达式本身),例如"),a("code",[s._v("\\1")]),s._v("、 "),a("code",[s._v("\\2")]),s._v("、"),a("code",[s._v("\\3")]),s._v("等等,因此可以使用如下命令:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sed")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-E")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'s/.*Disconnected from (invalid |authenticating )?user (.*) [^ ]+ port [0-9]+( \\[preauth\\])?$/\\2/'")]),s._v("\n")])])]),a("h3",{attrs:{id:"_2-1-正则匹配基本知识及概念"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-正则匹配基本知识及概念"}},[s._v("#")]),s._v(" 2.1 正则匹配基本知识及概念")]),s._v(" "),a("p",[s._v("在练习之前,需要大家知道一些基本知识,如果有一定基础的可以跳过该步骤,直接往下看。")]),s._v(" "),a("h3",{attrs:{id:"_2-2-正则表达式-字符类"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-正则表达式-字符类"}},[s._v("#")]),s._v(" 2.2 正则表达式-字符类")]),s._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[s._v("[abc]:代表a或者b,或者c字符中的一个。\n[^abc]:代表除a,b,c以外的任何字符。\n[a-z]:代表a-z的所有小写字符中的一个。\n[A-Z]:代表A-Z的所有大写字符中的一个。\n[0-9]:代表0-9之间的某一个数字字符。\n[a-zA-Z0-9]:代表a-z或者A-Z或者0-9之间的任意一个字符。\n[a-dm-p]:a 到 d 或 m 到 p之间的任意一个字符。\n")])])]),a("h3",{attrs:{id:"_2-3-正则表达式-逻辑运算符"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-正则表达式-逻辑运算符"}},[s._v("#")]),s._v(" 2.3 正则表达式-逻辑运算符")]),s._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[s._v("&&:并且\n| :或者(可以省略)\n")])])]),a("h3",{attrs:{id:"_2-4-正则表达式-预定义字符"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-4-正则表达式-预定义字符"}},[s._v("#")]),s._v(" 2.4 正则表达式-预定义字符")]),s._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[s._v("“.” : 匹配任何字符。\n“\\d”:任何数字[0-9]的简写;\n“\\D”:任何非数字[^0-9]的简写;\n“\\s”: 空白字符:[ \\t\\n\\x0B\\f\\r] 的简写\n“\\S”: 非空白字符:[^\\s] 的简写\n“\\w”:单词字符:[a-zA-Z_0-9]的简写\n“\\W”:非单词字符:[^\\w]\n")])])]),a("h3",{attrs:{id:"_2-5-正则表达式-数量词"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-正则表达式-数量词"}},[s._v("#")]),s._v(" 2.5 正则表达式-数量词")]),s._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[s._v("x? : 0次或1次\nx* : 0次到多次\nx+ : 1次或多次\nX{n} : 恰好n次\nX{n,} : 至少n次\nX{n,m}: n到m次(n和m都是包含的,最少n次,最多m次。\n")])])]),a("h2",{attrs:{id:"_3-数据整理"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-数据整理"}},[s._v("#")]),s._v(" 3. 数据整理")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ssh")]),s._v(" myserver journalctl\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" sshd\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Disconnected from"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sed")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-E")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'s/.*Disconnected from (invalid |authenticating )?user (.*) [^ ]+ port [0-9]+( \\[preauth\\])?$/\\2/'")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("uniq")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-c")]),s._v("\n")])])]),a("p",[a("code",[s._v("sort")]),s._v("  会对其输入数据进行排序。"),a("code",[s._v("uniq -c")]),s._v("  会把连续出现的行折叠为一行并使用出现次数作为前缀。我们希望按照出现次数排序,过滤出最常出现的用户名:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ssh")]),s._v(" myserver journalctl\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" sshd\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Disconnected from"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sed")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-E")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'s/.*Disconnected from (invalid |authenticating )?user (.*) [^ ]+ port [0-9]+( \\[preauth\\])?$/\\2/'")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("uniq")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-c")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" -nk1,1 "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("tail")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-n10")]),s._v("\n")])])]),a("p",[a("code",[s._v("sort -n")]),s._v("  会按照数字顺序对输入进行排序(默认情况下是按照字典序排序) "),a("code",[s._v("-k1,1")]),s._v("  则表示“仅基于以空格分割的第一列进行排序”。"),a("code",[s._v(",n")]),s._v("  部分表示“仅排序到第 n 个部分”,默认情况是到行尾。就本例来说,针对整个行进行排序也没有任何问题,我们这里主要是为了学习这一用法!")]),s._v(" "),a("p",[s._v("如果我们希望得到登录次数最少的用户,我们可以使用  "),a("code",[s._v("head")]),s._v("  来代替"),a("code",[s._v("tail")]),s._v("。或者使用"),a("code",[s._v("sort -r")]),s._v("来进行倒序排序。")]),s._v(" "),a("p",[s._v("相当不错。但我们只想获取用户名,而且不要一行一个地显示:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ssh")]),s._v(" myserver journalctl\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" sshd\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Disconnected from"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sed")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-E")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'s/.*Disconnected from (invalid |authenticating )?user (.*) [^ ]+ port [0-9]+( \\[preauth\\])?$/\\2/'")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("uniq")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-c")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" -nk1,1 "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("tail")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-n10")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("awk")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'{print $2}'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("paste")]),s._v(" -sd,\n")])])]),a("h2",{attrs:{id:"_4-awk-另外一种编辑器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_4-awk-另外一种编辑器"}},[s._v("#")]),s._v(" 4. awk – 另外一种编辑器")]),s._v(" "),a("p",[a("code",[s._v("awk")]),s._v("  其实是一种编程语言,只不过它碰巧非常善于处理文本。")]),s._v(" "),a("p",[s._v("首先, "),a("code",[s._v("{print $2}")]),s._v("  的作用是什么? "),a("code",[s._v("awk")]),s._v("  程序接受一个模式串(可选),以及一个代码块,指定当模式匹配时应该做何种操作。默认当模式串即匹配所有行(上面命令中当用法)。 在代码块中,"),a("code",[s._v("$0")]),s._v("  表示整行的内容,"),a("code",[s._v("$1")]),s._v("  到  "),a("code",[s._v("$n")]),s._v("  为一行中的 n 个区域,区域的分割基于  "),a("code",[s._v("awk")]),s._v("  的域分隔符(默认是空格,可以通过"),a("code",[s._v("-F")]),s._v("来修改)。在这个例子中,我们的代码意思是:对于每一行文本,打印其第二个部分,也就是用户名。")]),s._v(" "),a("p",[s._v("让我们康康,还有什么炫酷的操作可以做。让我们统计一下所有以"),a("code",[s._v("c")]),s._v("  开头,以  "),a("code",[s._v("e")]),s._v("  结尾,并且仅尝试过一次登录的用户。")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("awk")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'$1 == 1 && $2 ~ /^c[^ ]*e$/ { print $2 }'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("wc")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-l")]),s._v("\n")])])]),a("p",[s._v("让我们好好分析一下。首先,注意这次我们为  "),a("code",[s._v("awk")]),s._v("指定了一个匹配模式串(也就是"),a("code",[s._v("{...}")]),s._v("前面的那部分内容)。该匹配要求文本的第一部分需要等于 1(这部分刚好是"),a("code",[s._v("uniq -c")]),s._v("得到的计数值),然后其第二部分必须满足给定的一个正则表达式。代码块中的内容则表示打印用户名。然后我们使用  "),a("code",[s._v("wc -l")]),s._v("  统计输出结果的行数。")]),s._v(" "),a("p",[s._v("不过,既然  "),a("code",[s._v("awk")]),s._v("  是一种编程语言,那么则可以这样:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("BEGIN "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" rows "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$1")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("&&")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$2")]),s._v(" ~ /^c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("^ "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("*e$/ "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" rows "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("+=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$1")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\nEND "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" print rows "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[a("code",[s._v("BEGIN")]),s._v("  也是一种模式,它会匹配输入的开头( "),a("code",[s._v("END")]),s._v("  则匹配结尾)。然后,对每一行第一个部分进行累加,最后将结果输出。事实上,我们完全可以抛弃  "),a("code",[s._v("grep")]),s._v("  和  "),a("code",[s._v("sed")]),s._v(" ,因为  "),a("code",[s._v("awk")]),s._v("  就可以"),a("a",{attrs:{href:"https://backreference.org/2010/02/10/idiomatic-awk",target:"_blank",rel:"noopener noreferrer"}},[s._v("解决所有问题"),a("OutboundLink")],1),s._v("。至于怎么做,就留给读者们做课后练习吧。")]),s._v(" "),a("h2",{attrs:{id:"_5-分析数据"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5-分析数据"}},[s._v("#")]),s._v(" 5. 分析数据")]),s._v(" "),a("p",[s._v("想做数学计算也是可以的!例如这样,您可以将每行的数字加起来:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("paste")]),s._v(" -sd+ "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("bc")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-l")]),s._v("\n")])])]),a("p",[s._v("下面这种更加复杂的表达式也可以:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"2*('),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),s._v("data "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("paste")]),s._v(" -sd+"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v(')"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("bc")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-l")]),s._v("\n")])])]),a("p",[s._v("如果您希望绘制一些简单的图表, "),a("code",[s._v("gnuplot")]),s._v("  可以帮助到您:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ssh")]),s._v(" myserver journalctl\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" sshd\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Disconnected from"')]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sed")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-E")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'s/.*Disconnected from (invalid |authenticating )?user (.*) [^ ]+ port [0-9]+( \\[preauth\\])?$/\\2/'")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("uniq")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-c")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" -nk1,1 "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("tail")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-n10")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" gnuplot "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-p")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-e")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'set boxwidth 0.5; plot \"-\" using 1:xtic(2) with boxes'")]),s._v("\n")])])]),a("h2",{attrs:{id:"_6-exercise"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_6-exercise"}},[s._v("#")]),s._v(" 6. Exercise")]),s._v(" "),a("h3",{attrs:{id:"_6-1-学习这篇简短的-交互式正则表达式教程"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-学习这篇简短的-交互式正则表达式教程"}},[s._v("#")]),s._v(" 6.1 学习这篇简短的  "),a("a",{attrs:{href:"https://regexone.com/",target:"_blank",rel:"noopener noreferrer"}},[s._v("交互式正则表达式教程"),a("OutboundLink")],1)]),s._v(" "),a("h3",{attrs:{id:"_6-2-sed"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_6-2-sed"}},[s._v("#")]),s._v(" 6.2 sed")]),s._v(" "),a("p",[s._v("统计 words 文件 ("),a("code",[s._v("/usr/share/dict/words")]),s._v(") 中包含至少三个"),a("code",[s._v("a")]),s._v("  且不以"),a("code",[s._v("'s")]),s._v("  结尾的单词个数。这些单词中,出现频率前三的末尾两个字母是什么? "),a("code",[s._v("sed")]),s._v("的  "),a("code",[s._v("y")]),s._v("命令,或者  "),a("code",[s._v("tr")]),s._v("  程序也许可以帮你解决大小写的问题。共存在多少种词尾两字母组合?还有一个很 有挑战性的问题:哪个组合从未出现过?")]),s._v(" "),a("p",[a("img",{attrs:{src:t(353),alt:"Untitled"}})]),s._v(" "),a("p",[a("img",{attrs:{src:t(354),alt:"Untitled"}})]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#! /usr/bin/env zsh")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 2.sh")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("for")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token for-or-select variable"}},[s._v("i")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("..")]),s._v("z"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("do")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("for")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token for-or-select variable"}},[s._v("j")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("..")]),s._v("z"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("do")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$i")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$j")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("done")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("done")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" allcomb.txt\n\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" words.txt "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-P")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'(?:a.*){3,}'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sed")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-E")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"/\'s$/d"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sed")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-E")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'s/.*(..)$/\\1/'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("tr")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'[:upper:]'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'[:lower:]'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-u")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" appcomb.txt\n\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-vxFf")]),s._v(" appcomb.txt allcomb.txt "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("uniq")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" notappcomb.txt\n")])])]),a("h3",{attrs:{id:"_6-3-in-place"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_6-3-in-place"}},[s._v("#")]),s._v(" 6.3 in-place")]),s._v(" "),a("p",[s._v("进行原地替换听上去很有诱惑力,例如: "),a("code",[s._v("sed s/REGEX/SUBSTITUTION/ input.txt > input.txt")]),s._v("。但是这并不是一个明智的做法,为什么呢?还是说只有  "),a("code",[s._v("sed")]),s._v("是这样的? 查看  "),a("code",[s._v("man sed")]),s._v("  来完成这个问题")]),s._v(" "),a("p",[s._v("Answer:")]),s._v(" "),a("p",[s._v("当你尝试使用 "),a("code",[s._v("sed")]),s._v(" 命令进行原地替换,如使用命令 "),a("code",[s._v("sed s/REGEX/SUBSTITUTION/ input.txt > input.txt")]),s._v(",看似想要直接在源文件上执行替换操作,实际上这样做是有问题的。这个命令的问题在于它试图将输出重定向回输入文件,这并不是 "),a("code",[s._v("sed")]),s._v(" 命令或其他文本处理命令特有的问题,而是 Unix/Linux shell 处理重定向的方式所导致的。")]),s._v(" "),a("p",[s._v("当你执行上述命令时,shell 会先处理重定向("),a("code",[s._v(">")]),s._v("),这导致 "),a("code",[s._v("input.txt")]),s._v(" 被打开用于写入并且立即被截断(即文件内容被清空),然后 "),a("code",[s._v("sed")]),s._v(" 才开始从这个现在已经是空的文件读取数据。结果是,"),a("code",[s._v("sed")]),s._v(" 没有数据可供处理,因此也就没有任何数据写回到 "),a("code",[s._v("input.txt")]),s._v(" 中,导致文件内容丢失。")]),s._v(" "),a("p",[s._v("对于 "),a("code",[s._v("sed")]),s._v(",如果你想进行原地编辑,应该使用 "),a("code",[s._v("-i")]),s._v(" 选项(或 "),a("code",[s._v("--in-place")]),s._v("),这样可以直接在文件上执行修改操作而不需要重定向输出到新文件:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sed")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-i")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'s/REGEX/SUBSTITUTION/'")]),s._v(" input.txt\n")])])]),a("p",[s._v("这个 "),a("code",[s._v("-i")]),s._v(" 选项告诉 "),a("code",[s._v("sed")]),s._v(" 直接修改文件内容,而不是输出到标准输出。注意,"),a("code",[s._v("-i")]),s._v(" 选项在不同的系统中可能稍有不同,某些系统可能要求为 "),a("code",[s._v("-i")]),s._v(" 指定一个扩展名,用于在修改前保存原文件的备份。")]),s._v(" "),a("p",[s._v("例如,如果你希望备份原文件,可以这样做:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sed")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-i.bak")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'s/REGEX/SUBSTITUTION/'")]),s._v(" input.txt\n")])])]),a("p",[s._v("这会将原始的 "),a("code",[s._v("input.txt")]),s._v(" 保存为 "),a("code",[s._v("input.txt.bak")]),s._v(",并直接修改 "),a("code",[s._v("input.txt")]),s._v("。")]),s._v(" "),a("p",[s._v("总结,这并不是只有 "),a("code",[s._v("sed")]),s._v(" 会遇到的问题,任何尝试将输出重定向回输入文件的操作都可能遇到同样的问题,因为 Unix/Linux shell 会先处理重定向,导致输入文件被清空。所以,当需要原地编辑文件时,应该使用工具提供的原地编辑功能(比如 "),a("code",[s._v("sed")]),s._v(" 的 "),a("code",[s._v("-i")]),s._v(" 选项),而不是使用重定向。")]),s._v(" "),a("h3",{attrs:{id:"_6-4-开机时间"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_6-4-开机时间"}},[s._v("#")]),s._v(" 6.4 开机时间")]),s._v(" "),a("p",[s._v("找出您最近十次开机的开机时间平均数、中位数和最长时间。在 Linux 上需要用到  "),a("code",[s._v("journalctl")]),s._v(" ,而在 macOS 上使用  "),a("code",[s._v("log show")]),s._v("。找到每次起到开始和结束时的时间戳。")]),s._v(" "),a("p",[s._v("在 Linux 上类似这样:"),a("code",[s._v("Logs begin at ...")]),s._v(" 和 "),a("code",[s._v("systemd[577]: Startup finished in ...")])]),s._v(" "),a("p",[s._v("在 macOS 上, "),a("a",{attrs:{href:"https://eclecticlight.co/2018/03/21/macos-unified-log-3-finding-your-way/",target:"_blank",rel:"noopener noreferrer"}},[s._v("查找"),a("OutboundLink")],1),s._v(": "),a("code",[s._v("=== system boot:")]),s._v(" 和 "),a("code",[s._v("Previous shutdown cause: 5")])]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#! /usr/bin/env zsh")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 4.sh")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("for")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token for-or-select variable"}},[s._v("i")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("..")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("9")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("do")]),s._v("\n journalctl "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-b")]),s._v(" -"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$i")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Startup finished"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"kernel"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sed")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-E")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'s/.*= (.*)s\\.$/\\1/'")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("done")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" ./startTime.txt\n\n"),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("minTime")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" startTime.txt "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-n")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("head")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-1")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Minimum time: '),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("${minTime}")]),s._v('s"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("maxTime")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" startTime.txt "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-n")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("tail")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-1")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Maximum time: '),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("${maxTime}")]),s._v('s"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("avgTime")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" startTime.txt "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("paste")]),s._v(" -sd+ "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("bc")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-l")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("awk")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'{print $1/10}'")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Average time: '),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("${avgTime}")]),s._v('s"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("midTime")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" startTime.txt "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-n")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("paste")]),s._v(" -sd"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("\\")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("awk")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'{print ($5+$6)/2}'")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Median time: '),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("${midTime}")]),s._v('s"')]),s._v("\n")])])]),a("p",[a("img",{attrs:{src:t(355),alt:"Untitled"}})]),s._v(" "),a("h3",{attrs:{id:"_6-5-awk"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_6-5-awk"}},[s._v("#")]),s._v(" 6.5 awk")]),s._v(" "),a("p",[s._v("查看之前三次重启启动信息中不同的部分(参见  "),a("code",[s._v("journalctl")]),s._v("的"),a("code",[s._v("-b")]),s._v("  选项)。将这一任务分为几个步骤,首先获取之前三次启动的启动日志,也许获取启动日志的命令就有合适的选项可以帮助您提取前三次启动的日志,亦或者您可以使用"),a("code",[s._v("sed '0,/STRING/d'")]),s._v("  来删除"),a("code",[s._v("STRING")]),s._v("匹配到的字符串前面的全部内容。然后,过滤掉每次都不相同的部分,例如时间戳。下一步,重复记录输入行并对其计数(可以使用"),a("code",[s._v("uniq")]),s._v(" )。最后,删除所有出现过 3 次的内容(因为这些内容是三次启动日志中的重复部分)。")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#! /usr/bin/env zsh")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 5.sh")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("for")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token for-or-select variable"}},[s._v("i")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("..")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("do")]),s._v("\n journalctl "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-b")]),s._v(" -"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$i")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">>")]),s._v(" ./last3.txt\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("done")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" last3.txt "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sed")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-E")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"s/.*pi\\ (.*)/'),a("span",{pre:!0,attrs:{class:"token entity",title:"\\1"}},[s._v("\\1")]),s._v('/"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("uniq")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-c")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sort")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-n")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("awk")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'$1!=3 {print}'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2.5")]),s._v(".txt\n")])])])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/3.2e411533.js b/assets/js/3.2e411533.js new file mode 100644 index 0000000..4459dcc --- /dev/null +++ b/assets/js/3.2e411533.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[3,27,30],{241:function(t,e,n){"use strict";n.d(e,"d",(function(){return r})),n.d(e,"a",(function(){return s})),n.d(e,"i",(function(){return a})),n.d(e,"f",(function(){return l})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return c})),n.d(e,"b",(function(){return p})),n.d(e,"e",(function(){return d})),n.d(e,"k",(function(){return h})),n.d(e,"l",(function(){return f})),n.d(e,"c",(function(){return g})),n.d(e,"j",(function(){return m}));n(45);const r=/#.*$/,i=/\.(md|html)$/,s=/\/$/,a=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(r,"").replace(i,"")}function l(t){return a.test(t)}function u(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function p(t){if(l(t))return t;const e=t.match(r),n=e?e[0]:"",i=o(t);return s.test(i)?t:i+".html"+n}function d(t,e){const n=decodeURIComponent(t.hash),i=function(t){const e=t.match(r);if(e)return e[0]}(e);if(i&&n!==i)return!1;return o(t.path)===o(e)}function h(t,e,n){if(l(e))return{type:"external",path:e};n&&(e=function(t,e,n){const r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return e+t;const i=e.split("/");n&&i[i.length-1]||i.pop();const s=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(e,n,r,i=1){if("string"==typeof e)return h(n,e,r);if(Array.isArray(e))return Object.assign(h(n,e[0],r),{title:e[1]});{const s=e.children||[];return 0===s.length&&e.path?Object.assign(h(n,e.path,r),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,initialOpenGroupIndex:e.initialOpenGroupIndex,children:s.map(e=>t(e,n,r,i+1)),collapsable:!1!==e.collapsable}}}(t,i,n)):[]}return[]}function b(t){const e=g(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:e.map(e=>({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}function g(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function m(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},242:function(t,e,n){},244:function(t,e,n){"use strict";n.r(e);var r={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},i=(n(245),n(14)),s=Object(i.a)(r,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=s.exports},245:function(t,e,n){"use strict";n(242)},247:function(t,e,n){},252:function(t,e,n){},254:function(t,e,n){"use strict";n(247)},255:function(t,e,n){"use strict";n.r(e);var r=n(268),i=n(257),s=n(241);function a(t,e){if("group"===e.type){const n=e.path&&Object(s.e)(t,e.path),r=e.children.some(e=>"group"===e.type?a(t,e):"page"===e.type&&Object(s.e)(t,e.path));return n||r}return!1}var o={name:"SidebarLinks",components:{SidebarGroup:r.default,SidebarLink:i.default},props:["items","depth","sidebarDepth","initialOpenGroupIndex"],data(){return{openGroupIndex:this.initialOpenGroupIndex||0}},watch:{$route(){this.refreshIndex()}},created(){this.refreshIndex()},methods:{refreshIndex(){const t=function(t,e){for(let n=0;n-1&&(this.openGroupIndex=t)},toggleGroup(t){this.openGroupIndex=t===this.openGroupIndex?-1:t},isActive(t){return Object(s.e)(this.$route,t.regularPath)}}},l=n(14),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return t.items.length?e("ul",{staticClass:"sidebar-links"},t._l(t.items,(function(n,r){return e("li",{key:r},["group"===n.type?e("SidebarGroup",{attrs:{item:n,open:r===t.openGroupIndex,collapsable:n.collapsable||n.collapsible,depth:t.depth},on:{toggle:function(e){return t.toggleGroup(r)}}}):e("SidebarLink",{attrs:{"sidebar-depth":t.sidebarDepth,item:n}})],1)})),0):t._e()}),[],!1,null,null,null);e.default=u.exports},257:function(t,e,n){"use strict";n.r(e);var r=n(241);function i(t,e,n,r,i){const s={props:{to:e,activeClass:"",exactActiveClass:""},class:{active:r,"sidebar-link":!0}};return i>2&&(s.style={"padding-left":i+"rem"}),t("RouterLink",s,n)}function s(t,e,n,a,o,l=1){return!e||l>o?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const u=Object(r.e)(a,n+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[i(t,n+"#"+e.slug,e.title,u,e.level-1),s(t,e.children,n,a,o,l+1)])}))}var a={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:n,$route:a,$themeConfig:o,$themeLocaleConfig:l},props:{item:u,sidebarDepth:c}}){const p=Object(r.e)(a,u.path),d="auto"===u.type?p||u.children.some(t=>Object(r.e)(a,u.basePath+"#"+t.slug)):p,h="external"===u.type?function(t,e,n){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[n,t("OutboundLink")])}(t,u.path,u.title||u.path):i(t,u.path,u.title||u.path,d),f=[e.frontmatter.sidebarDepth,c,l.sidebarDepth,o.sidebarDepth,1].find(t=>void 0!==t),b=l.displayAllHeaders||o.displayAllHeaders;if("auto"===u.type)return[h,s(t,u.children,u.basePath,a,f)];if((d||b)&&u.headers&&!r.d.test(u.path)){return[h,s(t,Object(r.c)(u.headers),u.path,a,f)]}return h}},o=(n(254),n(14)),l=Object(o.a)(a,void 0,void 0,!1,null,null,null);e.default=l.exports},265:function(t,e,n){"use strict";n(252)},268:function(t,e,n){"use strict";n.r(e);var r=n(241),i={name:"SidebarGroup",components:{DropdownTransition:n(244).default},props:["item","open","collapsable","depth"],beforeCreate(){this.$options.components.SidebarLinks=n(255).default},methods:{isActive:r.e}},s=(n(265),n(14)),a=Object(s.a)(i,(function(){var t=this,e=t._self._c;return e("section",{staticClass:"sidebar-group",class:[{collapsable:t.collapsable,"is-sub-group":0!==t.depth},"depth-"+t.depth]},[t.item.path?e("RouterLink",{staticClass:"sidebar-heading clickable",class:{open:t.open,active:t.isActive(t.$route,t.item.path)},attrs:{to:t.item.path},nativeOn:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"down":"right"}):t._e()]):e("p",{staticClass:"sidebar-heading",class:{open:t.open},on:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"down":"right"}):t._e()]),t._v(" "),e("DropdownTransition",[t.open||!t.collapsable?e("SidebarLinks",{staticClass:"sidebar-group-items",attrs:{items:t.item.children,"sidebar-depth":t.item.sidebarDepth,"initial-open-group-index":t.item.initialOpenGroupIndex,depth:t.depth+1}}):t._e()],1)],1)}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/30.399eb7e0.js b/assets/js/30.399eb7e0.js new file mode 100644 index 0000000..bebd3df --- /dev/null +++ b/assets/js/30.399eb7e0.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[30],{242:function(t,e,n){},244:function(t,e,n){"use strict";n.r(e);var s={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},i=(n(245),n(14)),o=Object(i.a)(s,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=o.exports},245:function(t,e,n){"use strict";n(242)}}]); \ No newline at end of file diff --git a/assets/js/31.b3883f92.js b/assets/js/31.b3883f92.js new file mode 100644 index 0000000..93bcad6 --- /dev/null +++ b/assets/js/31.b3883f92.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[31],{259:function(t,c,n){},272:function(t,c,n){"use strict";n(259)},285:function(t,c,n){"use strict";n.r(c);n(272);var i=n(14),s=Object(i.a)({},(function(){var t=this,c=t._self._c;return c("div",{staticClass:"sidebar-button",on:{click:function(c){return t.$emit("toggle-sidebar")}}},[c("svg",{staticClass:"icon",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",viewBox:"0 0 448 512"}},[c("path",{attrs:{fill:"currentColor",d:"M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"}})])])}),[],!1,null,null,null);c.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/32.c40c2118.js b/assets/js/32.c40c2118.js new file mode 100644 index 0000000..7b3f4d0 --- /dev/null +++ b/assets/js/32.c40c2118.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[32],{296:function(l,v,_){l.exports=_.p+"assets/img/Vivado.3cc10be4.png"},297:function(l,v,_){l.exports=_.p+"assets/img/Vivado1.ffa29b16.png"},392:function(l,v,_){"use strict";_.r(v);var i=_(14),s=Object(i.a)({},(function(){var l=this,v=l._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":l.$parent.slotKey}},[v("h1",{attrs:{id:"_2023-11-15-vivado"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_2023-11-15-vivado"}},[l._v("#")]),l._v(" 2023.11.15-Vivado")]),l._v(" "),v("h2",{attrs:{id:"_1-rtl-schematic-synthesis-schematic"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_1-rtl-schematic-synthesis-schematic"}},[l._v("#")]),l._v(" 1. RTL Schematic & Synthesis Schematic")]),l._v(" "),v("p",[l._v("在 Vivado 或类似的 FPGA 开发环境中,您会遇到 RTL (Register Transfer Level) 分析中的 Schematic 和 Synthesis 过程中的 Schematic。它们虽然看起来相似,但代表了不同阶段的电路设计和功能。")]),l._v(" "),v("ol",[v("li",[v("p",[l._v("RTL Analysis Schematic:")]),l._v(" "),v("ul",[v("li",[l._v("这个 Schematic 是您用硬件描述语言(如 Verilog)编写的代码的直接可视化表示。")]),l._v(" "),v("li",[l._v("它展示了代码中定义的模块、它们的互联以及信号流。")]),l._v(" "),v("li",[l._v("RTL Schematic 重点在于逻辑功能的实现,而不是实际硬件如何实现这些功能。它更多地表示逻辑结构而非物理结构。")]),l._v(" "),v("li",[l._v("这是设计验证的早期阶段,您可以在这里检查逻辑错误或结构问题。")])]),l._v(" "),v("p",[v("img",{attrs:{src:_(296),alt:"Untitled"}})])]),l._v(" "),v("li",[v("p",[l._v("Synthesis Schematic:")]),l._v(" "),v("ul",[v("li",[l._v("经过综合后的 Schematic 是将 RTL 设计转换为实际 FPGA 内部资源(如查找表(LUTs)、寄存器和逻辑单元)的表示。")]),l._v(" "),v("li",[l._v("这个过程涉及优化、逻辑最小化、资源分配和时序分析。")]),l._v(" "),v("li",[l._v("Synthesis Schematic 展示了设计如何映射到 FPGA 的实际硬件上,包括使用的具体资源和连接。")]),l._v(" "),v("li",[l._v("这是设计流程的后期阶段,您可以在这里优化性能、资源使用和满足时序要求。")])]),l._v(" "),v("p",[v("img",{attrs:{src:_(297),alt:"Untitled"}})])])]),l._v(" "),v("p",[l._v("总结来说,RTL Schematic 关注于逻辑设计的表示,而 Synthesis Schematic 则关注于该设计在 FPGA 上的物理实现。理解两者的区别对于 FPGA 开发至关重要,因为这影响着您如何优化设计以及解决可能出现的问题。")]),l._v(" "),v("h2",{attrs:{id:"_2-project-汇总中的-lut-ff-io-bufg"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_2-project-汇总中的-lut-ff-io-bufg"}},[l._v("#")]),l._v(" 2. Project 汇总中的 LUT,FF,IO,BUFG")]),l._v(" "),v("p",[l._v("在 Vivado 或类似的 FPGA 设计项目中,您会遇到几个关键的资源指标,如 LUT、FF、IO 和 BUFG。这些指标是 FPGA 设计和资源利用的重要部分。下面是每个术语的简要解释:")]),l._v(" "),v("ol",[v("li",[l._v("LUT (Look-Up Table):\n"),v("ul",[v("li",[l._v("LUT 是 FPGA 中实现逻辑功能的基本单元。")]),l._v(" "),v("li",[l._v("它本质上是一个可编程的真值表,可以配置为执行各种逻辑操作(如 AND、OR、NOT、XOR 等)。")]),l._v(" "),v("li",[l._v("LUT 的大小和数量是 FPGA 性能和复杂性的关键决定因素。在设计中,LUT 的使用量通常是衡量设计复杂度的一个重要指标。")])])]),l._v(" "),v("li",[l._v("FF (Flip-Flop):\n"),v("ul",[v("li",[l._v("FF 是用于存储数据的基本存储元件,通常用于实现寄存器、计数器等。")]),l._v(" "),v("li",[l._v("在 FPGA 中,FF 通常与 LUT 配对使用,以实现存储和逻辑功能的组合。")]),l._v(" "),v("li",[l._v("FF 的数量通常表明了设计中的数据存储需求和时序复杂度。")])])]),l._v(" "),v("li",[l._v("IO (Input/Output Ports):\n"),v("ul",[v("li",[l._v("这些是 FPGA 与外界通信的端口,包括输入端口和输出端口。")]),l._v(" "),v("li",[l._v("IO 的数量和类型(如单端或差分)取决于 FPGA 的物理特性和您的设计需求。")]),l._v(" "),v("li",[l._v("在设计中,您需要确保 FPGA 有足够的 IO 端口来满足您的外部连接需求。")])])]),l._v(" "),v("li",[l._v("BUFG (Buffered Global Clock):\n"),v("ul",[v("li",[l._v("BUFG 是一种专用的时钟缓冲器,用于分配全局时钟信号。")]),l._v(" "),v("li",[l._v("在复杂的 FPGA 设计中,确保时钟信号的稳定和同步是非常重要的。BUFG 能够在整个芯片上稳定地分配时钟信号。")]),l._v(" "),v("li",[l._v("BUFG 的使用和配置对于实现有效的时钟管理和避免时钟偏移非常关键。")])])])]),l._v(" "),v("p",[l._v("理解这些资源对于 FPGA 设计至关重要,因为它们直接影响您的设计能否在特定的 FPGA 上实现,以及该设计的性能和效率。在 Vivado 的项目汇总中,这些参数帮助您评估设计对 FPGA 资源的利用情况。")]),l._v(" "),v("h2",{attrs:{id:"_3-fpga-的组成构造"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_3-fpga-的组成构造"}},[l._v("#")]),l._v(" 3. FPGA 的组成构造")]),l._v(" "),v("p",[l._v("FPGA (Field-Programmable Gate Array) 是一种高度灵活的可编程硬件,它由多个不同的元件构成,共同实现复杂的数字逻辑功能。以下是 FPGA 内部主要组成部分的概述:")]),l._v(" "),v("ol",[v("li",[l._v("查找表 (LUTs):\n"),v("ul",[v("li",[l._v("如您所述,LUTs 是 FPGA 的核心,用于实现基本的逻辑功能。它们通过存储预定义的输出值来模拟逻辑门的行为。")]),l._v(" "),v("li",[l._v("LUTs 可以通过编程来实现简单的逻辑操作(如 AND、OR、NOT)或更复杂的组合逻辑。")])])]),l._v(" "),v("li",[l._v("多路选择器 (MUXes):\n"),v("ul",[v("li",[l._v("虽然在传统的逻辑电路中,MUXes 是通过逻辑门实现的,但在 FPGA 中,它们通常与 LUTs 结合或独立实现。")]),l._v(" "),v("li",[l._v("MUXes 在 FPGA 设计中用于根据控制信号选择不同的输入路径,这对于创建复杂的数据路径和逻辑结构至关重要。")])])]),l._v(" "),v("li",[l._v("触发器 (Flip-Flops):\n"),v("ul",[v("li",[l._v("Flip-Flops 用于存储信息,是实现时序逻辑的关键元件。它们通常与 LUTs 配对,以构成可存储状态的逻辑单元。")])])]),l._v(" "),v("li",[l._v("编程互联资源 (Programmable Interconnects):\n"),v("ul",[v("li",[l._v("这些是连接 FPGA 内部不同部件的路径。它们可以被编程以形成任何所需的逻辑网络,从而将 LUTs、Flip-Flops 和其他资源连接起来。")])])]),l._v(" "),v("li",[l._v("输入/输出块 (I/O Blocks):\n"),v("ul",[v("li",[l._v("这些块连接 FPGA 和外部世界,提供数据输入和输出功能。它们可以配置为不同类型的接口(如单端或差分)。")])])]),l._v(" "),v("li",[l._v("专用硬件资源:\n"),v("ul",[v("li",[l._v("许多 FPGA 还包含专用的硬件资源,如 DSP (数字信号处理) 块、内存控制器、时钟管理模块(如 PLLs 和 BUFGs),以及其他特定功能块。")])])]),l._v(" "),v("li",[l._v("存储资源:\n"),v("ul",[v("li",[l._v("包括 RAM 块 (Block RAM) 或更小的存储单元,用于数据存储和缓冲。")])])])]),l._v(" "),v("p",[l._v("FPGA 的关键优势在于其高度可编程性和灵活性。设计师可以通过编程定义 LUTs、MUXes、Flip-Flops 以及互连的配置和组合方式,从而在没有物理改动硬件的情况下实现几乎任何数字逻辑设计。这种灵活性使得 FPGA 在快速原型制作、定制硬件加速和可重配置系统中非常有价值。")]),l._v(" "),v("p",[l._v("FPGA (Field-Programmable Gate Array) 是一种高度灵活的可编程硬件,它由多个不同的元件构成,共同实现复杂的数字逻辑功能。以下是 FPGA 内部主要组成部分的概述:")]),l._v(" "),v("ol",[v("li",[l._v("查找表 (LUTs):\n"),v("ul",[v("li",[l._v("如您所述,LUTs 是 FPGA 的核心,用于实现基本的逻辑功能。它们通过存储预定义的输出值来模拟逻辑门的行为。")]),l._v(" "),v("li",[l._v("LUTs 可以通过编程来实现简单的逻辑操作(如 AND、OR、NOT)或更复杂的组合逻辑。")])])]),l._v(" "),v("li",[l._v("多路选择器 (MUXes):\n"),v("ul",[v("li",[l._v("虽然在传统的逻辑电路中,MUXes 是通过逻辑门实现的,但在 FPGA 中,它们通常与 LUTs 结合或独立实现。")]),l._v(" "),v("li",[l._v("MUXes 在 FPGA 设计中用于根据控制信号选择不同的输入路径,这对于创建复杂的数据路径和逻辑结构至关重要。")])])]),l._v(" "),v("li",[l._v("触发器 (Flip-Flops):\n"),v("ul",[v("li",[l._v("Flip-Flops 用于存储信息,是实现时序逻辑的关键元件。它们通常与 LUTs 配对,以构成可存储状态的逻辑单元。")])])]),l._v(" "),v("li",[l._v("编程互联资源 (Programmable Interconnects):\n"),v("ul",[v("li",[l._v("这些是连接 FPGA 内部不同部件的路径。它们可以被编程以形成任何所需的逻辑网络,从而将 LUTs、Flip-Flops 和其他资源连接起来。")])])]),l._v(" "),v("li",[l._v("输入/输出块 (I/O Blocks):\n"),v("ul",[v("li",[l._v("这些块连接 FPGA 和外部世界,提供数据输入和输出功能。它们可以配置为不同类型的接口(如单端或差分)。")])])]),l._v(" "),v("li",[l._v("专用硬件资源:\n"),v("ul",[v("li",[l._v("许多 FPGA 还包含专用的硬件资源,如 DSP (数字信号处理) 块、内存控制器、时钟管理模块(如 PLLs 和 BUFGs),以及其他特定功能块。")])])]),l._v(" "),v("li",[l._v("存储资源:\n"),v("ul",[v("li",[l._v("包括 RAM 块 (Block RAM) 或更小的存储单元,用于数据存储和缓冲。")])])])]),l._v(" "),v("p",[l._v("FPGA 的关键优势在于其高度可编程性和灵活性。设计师可以通过编程定义 LUTs、MUXes、Flip-Flops 以及互连的配置和组合方式,从而在没有物理改动硬件的情况下实现几乎任何数字逻辑设计。这种灵活性使得 FPGA 在快速原型制作、定制硬件加速和可重配置系统中非常有价值。")])])}),[],!1,null,null,null);v.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/33.bf753b45.js b/assets/js/33.bf753b45.js new file mode 100644 index 0000000..fb1f049 --- /dev/null +++ b/assets/js/33.bf753b45.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[33],{302:function(t,s,a){t.exports=a.p+"assets/img/block.b5292fb2.png"},303:function(t,s,a){t.exports=a.p+"assets/img/block1.bbc37b84.png"},400:function(t,s,a){"use strict";a.r(s);var n=a(14),v=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2023-11-16-阻塞与非阻塞赋值"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2023-11-16-阻塞与非阻塞赋值"}},[t._v("#")]),t._v(" 2023.11.16-阻塞与非阻塞赋值")]),t._v(" "),s("p",[s("img",{attrs:{src:a(302),alt:"Untitled"}})]),t._v(" "),s("p",[s("img",{attrs:{src:a(303),alt:"Untitled"}})]),t._v(" "),s("p",[t._v("组合逻辑电路使用阻塞赋值")]),t._v(" "),s("p",[t._v("时序逻辑电路使用非阻塞赋值")]),t._v(" "),s("p",[t._v("在 Verilog 中,阻塞赋值(Blocking Assignment)和非阻塞赋值(Non-Blocking Assignment)是两种不同的信号赋值方法,它们在时序逻辑的模拟和硬件描述语言(HDL)代码的编写中有着重要的区别。")]),t._v(" "),s("h3",{attrs:{id:"阻塞赋值-blocking-assignment"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#阻塞赋值-blocking-assignment"}},[t._v("#")]),t._v(" 阻塞赋值(Blocking Assignment)")]),t._v(" "),s("ul",[s("li",[t._v("使用符号 "),s("code",[t._v("=")]),t._v(" 进行赋值。")]),t._v(" "),s("li",[t._v("阻塞赋值在执行时会“阻塞”代码的进一步执行,直到赋值完成。")]),t._v(" "),s("li",[t._v("在执行下一条语句之前,当前语句必须完成其操作。")]),t._v(" "),s("li",[t._v("在组合逻辑设计中常用,但在时序逻辑中使用可能会导致问题,因为它们可能会引起模拟时序和硬件时序的不一致。")])]),t._v(" "),s("p",[t._v("举例:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在这个例子中,"),s("code",[t._v("c = a;")]),t._v(" 会等待 "),s("code",[t._v("a = b;")]),t._v(" 完成后才执行。")]),t._v(" "),s("h3",{attrs:{id:"非阻塞赋值-non-blocking-assignment"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#非阻塞赋值-non-blocking-assignment"}},[t._v("#")]),t._v(" 非阻塞赋值(Non-Blocking Assignment)")]),t._v(" "),s("ul",[s("li",[t._v("使用符号 "),s("code",[t._v("<=")]),t._v(" 进行赋值。")]),t._v(" "),s("li",[t._v("非阻塞赋值允许代码的后续部分在赋值完成之前继续执行。")]),t._v(" "),s("li",[t._v("这意味着所有非阻塞赋值都是并行发生的(或看起来如此),这更接近于硬件的实际行为。")]),t._v(" "),s("li",[t._v("在时序逻辑,特别是在描述触发器(如寄存器)的行为时非常重要和常用。")])]),t._v(" "),s("p",[t._v("举例:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("在这个例子中,"),s("code",[t._v("c <= a;")]),t._v(" 不会等待 "),s("code",[t._v("a <= b;")]),t._v(" 的完成。"),s("code",[t._v("a")]),t._v(" 和 "),s("code",[t._v("c")]),t._v(" 的赋值看似同时发生。")]),t._v(" "),s("p",[t._v("在一个 always 块中,不同地方对同一个变量的赋值会被同时执行,最终结果是变量变成最后一次赋值的结果(前面的操作被覆盖)")])])}),[],!1,null,null,null);s.default=v.exports}}]); \ No newline at end of file diff --git a/assets/js/34.9d29de34.js b/assets/js/34.9d29de34.js new file mode 100644 index 0000000..ea3e463 --- /dev/null +++ b/assets/js/34.9d29de34.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[34],{327:function(t,s,a){t.exports=a.p+"assets/img/150.02b9f277.png"},328:function(t,s,a){t.exports=a.p+"assets/img/151.c440b711.png"},427:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-05-练习15-指针-可怕的指针"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-05-练习15-指针-可怕的指针"}},[t._v("#")]),t._v(" 2024.04.05-练习15:指针,可怕的指针")]),t._v(" "),s("h2",{attrs:{id:"_1-指针"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-指针"}},[t._v("#")]),t._v(" 1. 指针")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create two arrays we care about")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" ages"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("23")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("43")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("89")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("names"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Alan"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Frank"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Mary"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"John"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Lisa"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// safely get the size of ages")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ages"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// first way using indexing")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%s has %d years alive.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n names"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ages"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"---\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// setup the pointers to the start of the arrays")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("cur_age "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ages"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("cur_name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" names"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// second way using pointers")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%s is %d years old.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur_name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur_age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"---\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// third way, pointers are just arrays")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%s is %d years old again.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n cur_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur_age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"---\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// fourth way with pointers in a stupid complex way")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur_name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" names"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur_age "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" ages"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur_age "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" ages"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n cur_name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur_age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%s lived %d years so far.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("cur_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("cur_age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("code",[t._v("char ** list;")]),t._v(" 那么"),s("code",[t._v("list")]),t._v("是指向第一个字符串指针的指针。访问第一个字符串的第二个字符,可以使用表达式 "),s("code",[t._v("*(*(list) + 1)")]),t._v("。")]),t._v(" "),s("h2",{attrs:{id:"_2-实用的指针用法"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-实用的指针用法"}},[t._v("#")]),t._v(" 2. 实用的指针用法")]),t._v(" "),s("p",[t._v("你可以用指针做下面四个最基本的操作:")]),t._v(" "),s("ul",[s("li",[t._v("向OS申请一块内存,并且用指针处理它。这包括字符串,和一些你从来没见过的东西,比如结构体。")]),t._v(" "),s("li",[t._v("通过指针向函数传递大块的内存(比如很大的结构体),这样不必把全部数据都传递进去。")]),t._v(" "),s("li",[t._v("获取函数的地址用于动态调用。")]),t._v(" "),s("li",[t._v("对一块内存做复杂的搜索,比如,转换网络套接字中的字节,或者解析文件。")])]),t._v(" "),s("p",[t._v("对于你看到的其它所有情况,实际上应当使用数组。在早期,由于编译器不擅长优化数组,人们使用指针来加速它们的程序。然而,现在访问数组和指针的语法都会翻译成相同的机器码,并且表现一致。由此,你应该每次尽可能使用数组,并且按需将指针用作提升性能的手段。")]),t._v(" "),s("h2",{attrs:{id:"_3-指针词库"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-指针词库"}},[t._v("#")]),t._v(" 3. 指针词库")]),t._v(" "),s("p",[t._v("现在我打算向你提供一个词库,用于读写指针。当你遇到复杂的指针语句时,试着参考它并且逐字拆分语句(或者不要使用这个语句,因为有可能并不好):")]),t._v(" "),s("p",[s("code",[t._v("type *ptr")]),t._v(" : "),s("code",[t._v("type")]),t._v("类型的指针,名为"),s("code",[t._v("ptr")]),t._v("。")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("*ptr")]),t._v(" : "),s("code",[t._v("ptr")]),t._v("所指向位置的值。")]),t._v(" "),s("li",[s("code",[t._v("*(ptr + i)")]),t._v(" : ("),s("code",[t._v("ptr")]),t._v("所指向位置加上"),s("code",[t._v("i")]),t._v(")的值。")])]),t._v(" "),s("blockquote",[s("p",[t._v("译者注:以字节为单位的话,应该是ptr所指向的位置再加上"),s("code",[t._v("sizeof(type) * i")]),t._v("。")])]),t._v(" "),s("p",[s("code",[t._v("&thing")]),t._v(" : "),s("code",[t._v("thing")]),t._v("的地址。")]),t._v(" "),s("p",[s("code",[t._v("type *ptr = &thing")]),t._v(" : 名为"),s("code",[t._v("ptr")]),t._v(","),s("code",[t._v("type")]),t._v("类型的指针,值设置为"),s("code",[t._v("thing")]),t._v("的地址。 "),s("code",[t._v("ptr++")]),t._v(" 自增"),s("code",[t._v("ptr")]),t._v("指向的位置。")]),t._v(" "),s("h2",{attrs:{id:"_4-指针并不是数组"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-指针并不是数组"}},[t._v("#")]),t._v(" 4. 指针并不是数组")]),t._v(" "),s("p",[t._v("无论怎么样,你都不应该把指针和数组混为一谈。它们并不是相同的东西,即使C让你以一些相同的方法来使用它们。例如,如果你访问上面代码中的"),s("code",[t._v("sizeof(cur_age)")]),t._v(",你会得到指针的大小,而不是它指向数组的大小。如果你想得到整个数组的大小,你应该使用数组的名称"),s("code",[t._v("age")]),t._v(",就像第12行那样。")]),t._v(" "),s("p",[t._v("译者注,除了"),s("code",[t._v("sizeof")]),t._v("、"),s("code",[t._v("&")]),t._v("操作和声明之外,数组名称都会被编译器推导为指向其首个元素的指针。对于这些情况,不要用“是”这个词,而是要用“推导”。")]),t._v(" "),s("h2",{attrs:{id:"_5-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-附加题"}},[t._v("#")]),t._v(" 5. 附加题")]),t._v(" "),s("h2",{attrs:{id:"_5-1-获取地址"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-获取地址"}},[t._v("#")]),t._v(" 5.1 获取地址")]),t._v(" "),s("p",[s("img",{attrs:{src:a(327),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_5-2-倒序遍历"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-2-倒序遍历"}},[t._v("#")]),t._v(" 5.2 倒序遍历")]),t._v(" "),s("p",[s("img",{attrs:{src:a(328),alt:"Untitled"}})])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/35.3c50b78d.js b/assets/js/35.3c50b78d.js new file mode 100644 index 0000000..5b6ce44 --- /dev/null +++ b/assets/js/35.3c50b78d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[35],{344:function(t,s,a){t.exports=a.p+"assets/img/170.3b319b11.png"},345:function(t,s,a){t.exports=a.p+"assets/img/171.5368cde2.png"},433:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-08-练习17-堆和栈的内存分配"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-08-练习17-堆和栈的内存分配"}},[t._v("#")]),t._v(" 2024.04.08-练习17:堆和栈的内存分配")]),t._v(" "),s("h2",{attrs:{id:"_1-program"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-program"}},[t._v("#")]),t._v(" 1. Program")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name"}},[t._v("MAX_DATA")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token number"}},[t._v("512")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name"}},[t._v("MAX_ROWS")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Database")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n FILE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Database")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("errno"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("perror")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("exit")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Address_print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%d %s %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_load")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" rc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fread")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Database")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to load database."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("filename"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" mode"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Memory error"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Database")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Memory error"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'c'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fopen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("filename"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"w"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fopen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("filename"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"r+"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_load")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to open the file"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_close")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fclose")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("rewind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" rc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fwrite")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Database")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to write database."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n rc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fflush")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Cannot flush database."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// make a prototype to initialize it")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("set "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// then just assign it")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Already set, delete it first"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// WARNING: bug, read the "How To Break It" and fix this')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strncpy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// demonstrate the strncpy bug")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Name copy failed"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strncpy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Email copy failed"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Address_print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ID is not set"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_delete")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("set "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_list")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Database")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("db "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("cur "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Address_print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"USAGE: ex17 [action params]"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("filename "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" action "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("filename"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("atoi")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"There\'s not that many records."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("switch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'c'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'g'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Need an id to get"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'s'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Need id, name, email to set"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'d'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Need id to delete"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_delete")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'l'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_list")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Invalid action, only: c=create, g=get, s=set, d=del, l=list"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_close")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("code",[t._v("#define")]),t._v(" "),s("strong",[t._v("常量")])]),t._v(" "),s("p",[t._v("我使用了“C预处理器”的另外一部分,来创建"),s("code",[t._v("MAX_DATA")]),t._v("和"),s("code",[t._v("MAX_ROWS")]),t._v("的设置常量。我之后会更多地讲解预处理器的功能,不过这是一个创建可靠的常量的简易方法。除此之外还有另一种方法,但是在特定场景下并不适用。")]),t._v(" "),s("p",[s("strong",[t._v("定长结构体")])]),t._v(" "),s("p",[s("code",[t._v("Address")]),t._v("结构体接着使用这些常量来创建数据,这些数据是定长的,它们并不高效,但是便于存储和读取。"),s("code",[t._v("Database")]),t._v("结构体也是定长的,因为它有一个定长的"),s("code",[t._v("Address")]),t._v("结构体数组。这样你就可以稍后把整个数据一步写到磁盘。")]),t._v(" "),s("p",[t._v("出现错误时终止的"),s("code",[t._v("die")]),t._v("函数")]),t._v(" "),s("p",[t._v("在像这样的小型程序中,你可以编写一个单个函数在出现错误时杀掉程序。我把它叫做"),s("code",[t._v("die")]),t._v("。而且在任何失败的函数调用,或错误输出之后,它会调用"),s("code",[t._v("exit")]),t._v("带着错误退出程序。")]),t._v(" "),s("p",[t._v("用于错误报告的 "),s("code",[t._v("errno")]),t._v("和"),s("code",[t._v("perror")])]),t._v(" "),s("p",[t._v("当函数返回了一个错误时,它通常设置一个叫做"),s("code",[t._v("errno")]),t._v("的“外部”变量,来描述发生了什么错误。它们只是数字,所以你可以使用"),s("code",[t._v("perror")]),t._v("来“打印出错误信息”。")]),t._v(" "),s("p",[s("strong",[t._v("文件函数")])]),t._v(" "),s("p",[t._v("我使用了一些新的函数,比如"),s("code",[t._v("fopen")]),t._v(","),s("code",[t._v("fread")]),t._v(","),s("code",[t._v("fclose")]),t._v(",和"),s("code",[t._v("rewind")]),t._v("来处理文件。这些函数中每个都作用于"),s("code",[t._v("FILE")]),t._v("结构体上,就像你的结构体似的,但是它由C标准库定义。")]),t._v(" "),s("p",[s("strong",[t._v("嵌套结构体指针")])]),t._v(" "),s("p",[t._v("你应该学习这里的嵌套结构器和获取数组元素地址的用法,它读作“读取"),s("code",[t._v("db")]),t._v("中的"),s("code",[t._v("conn")]),t._v("中的"),s("code",[t._v("rows")]),t._v("的第"),s("code",[t._v("i")]),t._v("个元素,并返回地址("),s("code",[t._v("&")]),t._v(")”。")]),t._v(" "),s("blockquote",[s("p",[t._v("译者注:这里有个更简便的写法是db->conn->row + i。")])]),t._v(" "),s("p",[s("strong",[t._v("结构体原型的复制")])]),t._v(" "),s("p",[t._v("它在"),s("code",[t._v("Database_delete")]),t._v("中体现得最清楚,你可以看到我是用了临时的局部"),s("code",[t._v("Address")]),t._v("变量,初始化了它的"),s("code",[t._v("id")]),t._v("和"),s("code",[t._v("set")]),t._v("字段,接着通过把它赋值给"),s("code",[t._v("rows")]),t._v("数组中的元素,简单地复制到数组中。这个小技巧确保了所有除了"),s("code",[t._v("set")]),t._v("和"),s("code",[t._v("id")]),t._v("的字段都初始化为0,而且很容易编写。顺便说一句,你不应该在这种数组复制操作中使用"),s("code",[t._v("memcpy")]),t._v("。现代C语言中你可以只是将一个赋值给另一个,它会自动帮你处理复制。")]),t._v(" "),s("p",[s("strong",[t._v("处理复杂参数")])]),t._v(" "),s("p",[t._v("我执行了一些更复杂的参数解析,但是这不是处理它们的最好方法。在这本书的后面我们将会了解一些用于解析的更好方法。")]),t._v(" "),s("p",[s("strong",[t._v("将字符串转换为整数")])]),t._v(" "),s("p",[t._v("我使用了"),s("code",[t._v("atoi")]),t._v("函数在命令行中接受作为id的字符串并把它转换为"),s("code",[t._v("int id")]),t._v("变量。去查询这个函数以及相似的函数。")]),t._v(" "),s("p",[s("strong",[t._v("在堆上分配大块数据")])]),t._v(" "),s("p",[t._v("这个程序的要点就是在我创建"),s("code",[t._v("Database")]),t._v("的时候,我使用了"),s("code",[t._v("malloc")]),t._v("来向OS请求一块大容量的内存。稍后我会讲得更细致一些。")]),t._v(" "),s("p",[s("code",[t._v("NULL")]),s("strong",[t._v("就是0,所以可转成布尔值")])]),t._v(" "),s("p",[t._v("在许多检查中,我简单地通过"),s("code",[t._v('if(!ptr) die("fail!")')]),t._v("检测了一个指针是不是"),s("code",[t._v("NULL")]),t._v("。这是有效的,因为"),s("code",[t._v("NULL")]),t._v("会被计算成假。在一些少见的系统中,"),s("code",[t._v("NULL")]),t._v("会储存在计算机中,并且表示为一些不是0的东西。但在C标准中,你可以把它当成0来编写代码。到目前为止,当我说“"),s("code",[t._v("NULL")]),t._v("就是0”的时候,我都是对一些迂腐的人说的。")]),t._v(" "),s("h2",{attrs:{id:"_2-堆和栈的内存分配"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-堆和栈的内存分配"}},[t._v("#")]),t._v(" 2. 堆和栈的内存分配")]),t._v(" "),s("p",[t._v("C使用了CPU真实的机制来完成工作,这涉及到RAM中的一块叫做栈的区域,以及另外一块叫做堆的区域。它们的差异取决于取得储存空间的位置。")]),t._v(" "),s("p",[t._v("堆更容易解释,因为它就是你电脑中的剩余内存,你可以通过"),s("code",[t._v("malloc")]),t._v("访问它来获取更多内存,OS会使用内部函数为你注册一块内存区域,并且返回指向它的指针。当你使用完这片区域时,你应该使用"),s("code",[t._v("free")]),t._v("把它交还给OS,使之能被其它程序复用。如果你不这样做就会导致程序“泄露”内存,但是"),s("code",[t._v("Valgrind")]),t._v("会帮你监测这些内存泄露。")]),t._v(" "),s("p",[t._v("栈是一个特殊的内存区域,它储存了每个函数的创建的临时变量,它们对于该函数为局部变量。它的工作机制是,函数的每个c参数都会“压入”栈中,并且可在函数内部使用。它是一个真正的栈数据结构,所以是后进先出的。这对于"),s("code",[t._v("main")]),t._v("中所有类似"),s("code",[t._v("char section")]),t._v("和"),s("code",[t._v("int id")]),t._v("的局部变量也是相同的。使用栈的优点是,当函数退出时C编译器会从栈中“弹出”所有变量来清理。这非常简单,也防止了栈上变量的内存泄露。")]),t._v(" "),s("p",[t._v("理清内存的最简单的方式是遵守这条原则:如果你的变量并不是从"),s("code",[t._v("malloc")]),t._v("中获取的,也不是从一个从"),s("code",[t._v("malloc")]),t._v("获取的函数中获取的,那么它在栈上。")]),t._v(" "),s("p",[t._v("下面是三个值得关注的关于栈和堆的主要问题:")]),t._v(" "),s("ul",[s("li",[t._v("如果你从"),s("code",[t._v("malloc")]),t._v("获取了一块内存,并且把指针放在了栈上,那么当函数退出时,指针会被弹出而丢失。")]),t._v(" "),s("li",[t._v("如果你在栈上存放了大量数据(比如大结构体和数组),那么会产生“栈溢出”并且程序会中止。这种情况下应该通过"),s("code",[t._v("malloc")]),t._v("放在堆上。")]),t._v(" "),s("li",[t._v("如果你获取了指向栈上变量的指针,并且将它用于传参或从函数返回,接收它的函数会产生“段错误”。因为实际的数据被弹出而消失,指针也会指向被释放的内存。")])]),t._v(" "),s("p",[t._v("这就是我在程序中使用"),s("code",[t._v("Database_open")]),t._v("来分配内存或退出的原因,相应的"),s("code",[t._v("Database_close")]),t._v("用于释放内存。如果你创建了一个“创建”函数,它创建了一些东西,那么一个“销毁”函数可以安全地清理这些东西。这样会更容易理清内存。")]),t._v(" "),s("p",[t._v("最后,当一个程序退出时,OS会为你清理所有的资源,但是有时不会立即执行。一个惯用法(也是本次练习中用到的)是立即终止并且让OS清理错误。")]),t._v(" "),s("h2",{attrs:{id:"_3-如何使它崩溃"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-如何使它崩溃"}},[t._v("#")]),t._v(" 3. 如何使它崩溃")]),t._v(" "),s("h3",{attrs:{id:"_3-1-strncpy"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-strncpy"}},[t._v("#")]),t._v(" 3.1 strncpy")]),t._v(" "),s("p",[s("code",[t._v("strncpy")]),t._v("可能不会在字符串的末尾自动添加空字符("),s("code",[t._v("\\0")]),t._v("),如果源字符串的长度等于或超过目标缓冲区的大小。这可能会导致字符串没有正确终止,从而引发安全漏洞或程序错误。为了修复这个问题,确保在"),s("code",[t._v("strncpy")]),t._v("后手动将目标字符串的最后一个字符设置为"),s("code",[t._v("\\\\0")]),t._v(",以确保字符串总是被正确终止。例如,修改代码为:")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strncpy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\naddr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\\\0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strncpy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\naddr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\\\0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("这样可以保证即使源字符串长度达到或超过"),s("code",[t._v("MAX_DATA")]),t._v(","),s("code",[t._v("addr->name")]),t._v("和"),s("code",[t._v("addr->email")]),t._v("也会被正确终止。")]),t._v(" "),s("h2",{attrs:{id:"_4-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-附加题"}},[t._v("#")]),t._v(" 4. 附加题")]),t._v(" "),s("h3",{attrs:{id:"_4-1-报错时清理内存"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-1-报错时清理内存"}},[t._v("#")]),t._v(" 4.1 报错时清理内存")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("errno"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("perror")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_close")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 清理内存")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("exit")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"_4-2-创建任意大小的数据库"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-2-创建任意大小的数据库"}},[t._v("#")]),t._v(" 4.2 创建任意大小的数据库")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// #define MAX_DATA 512")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// #define MAX_ROWS 100")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Database")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n FILE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Database")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_close")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("errno"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("perror")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_close")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 清理内存")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("exit")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Address_print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%d %s %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_load")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 确保文件指针在首个Address记录的开始位置")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fseek")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("SEEK_SET")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Address_print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fread")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fread")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fread")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fread")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("Database loaded.\\n");')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("filename"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" mode"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Memory error"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'c'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Database")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Memory error"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fopen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("filename"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"w"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to open the file"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 将MAX_DATA和MAX_ROWS写入文件")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fwrite")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fwrite")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 初始化Database结构体")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_ROWS "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("email "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fopen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("filename"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"r+"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to open the file"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 从文件读取MAX_DATA和MAX_ROWS")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fread")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fread")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Database")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Memory error"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_ROWS "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("email "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("conn->db->MAX_DATA: %d, conn->db->MAX_ROWS: %d\\n", conn->db->MAX_DATA, conn->db->MAX_ROWS);')]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_load")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_close")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fclose")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("rewind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 首先写入MAX_DATA和MAX_ROWS")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fwrite")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to write MAX_DATA."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fwrite")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to write MAX_ROWS."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 然后逐个写入Address项")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 写入Address的id和set")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fwrite")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to write id."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fwrite")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to write set."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("addr->id: %d\\n", addr->id);')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("addr->set: %d\\n", addr->set);')]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 只有当set为真时才写入name和email")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 确保字符串不超过MAX_DATA长度,最后一个字符保留为'\\0'")]),t._v("\n addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用memset填充剩余的空间")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("memset")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strlen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strlen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("memset")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strlen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strlen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 写入name和email到文件")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("size_t")]),t._v(" written "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fwrite")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("written "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to write name."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n written "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fwrite")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("written "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to write email."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 刷新文件以确保写入完成")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fflush")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Cannot flush database."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// make a prototype to initialize it")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("set "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// then just assign it")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("id: %d\\n", id);')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("addr->set: %d\\n", addr->set);')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Already set, delete it first"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strncpy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("addr->name: %s\\n", addr->name);')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Name copy failed"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strncpy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Email copy failed"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Address_print(addr);")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Address_print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ID is not set"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_delete")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// struct Address addr = {.id = id, .set = 0};")]),t._v("\n conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("set "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("id: %d\\n", id);')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("addr->set: %d\\n", conn->db->rows[id].set);')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_list")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("conn->db->rows[3].set: %d\\n", conn->db->rows[3].set);')]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("cur "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("cur->id: %d\\n", cur->id);')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("cur->set: %d\\n", cur->set);')]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("i: %d\\n", i);')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Address_print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("search_term"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("cur "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("set"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strcmp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" search_term"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strcmp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" search_term"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Address_print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Search term not found.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 至少需要文件名和操作类型")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"USAGE: ex17 [action params]"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("filename "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" action "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("conn "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 如果是创建操作,确保有足够的参数")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("action "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'c'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"USAGE: ex17 c "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" _MAX_DATA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("atoi")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" _MAX_ROWS "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("atoi")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n conn "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("filename"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _MAX_DATA"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 对于其他操作,不需要MAX_DATA和MAX_ROWS,但需要检查数据库文件是否存在")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("filename: %s\\n", filename);')]),t._v("\n conn "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("filename"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 0s表示这些值将被忽略")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"Database not found. Use 'c' option to create one.\"")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" action "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'c'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("atoi")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("db"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("MAX_ROWS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"There\'s not that many records."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("action "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'c'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("switch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("action"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'f'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Need a search term to find"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'g'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Need an id to get"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'s'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Need id, name, email to set"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_set")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'d'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Need id to delete"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_delete")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'l'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_list")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("die")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Invalid action, only: c=create, g=get, s=set, d=del, l=list"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Database_close")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("conn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),s("p",[s("img",{attrs:{src:a(344),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_4-3-添加find操作"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-3-添加find操作"}},[t._v("#")]),t._v(" 4.3 添加find操作")]),t._v(" "),s("p",[s("img",{attrs:{src:a(345),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"_4-4-c结构体存储方式"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-4-c结构体存储方式"}},[t._v("#")]),t._v(" 4.4 C结构体存储方式")]),t._v(" "),s("p",[t._v("在结构体中,为了提高访问速度,编译器可能会按照特定的对齐规则(alignment rules)来安排成员的存储。这通常依赖于目标平台(如处理器架构)和编译器的具体实现。")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("自然对齐")]),t._v(":大多数编译器采用所谓的“自然对齐”原则,要求结构体的每个成员相对于结构体开始的偏移量是该成员类型大小的整数倍。例如,如果一个结构体中有一个"),s("code",[t._v("int")]),t._v("(假设为4字节)紧跟着一个"),s("code",[t._v("char")]),t._v("(1字节),那么为了使下一个"),s("code",[t._v("int")]),t._v("成员对齐,编译器可能会在"),s("code",[t._v("char")]),t._v("后面插入3字节的填充。")]),t._v(" "),s("li",[s("strong",[t._v("结构体整体对齐")]),t._v(":结构体本身也会被对齐到它的最大成员的对齐要求。这意味着整个结构体在内存中的起始地址将是其最大成员大小的整数倍,并且可能在结构体末尾添加填充,以确保整个结构体的大小是其最大成员大小的整数倍。")])]),t._v(" "),s("p",[t._v("注:成员的排列顺序可能导致更多或更少的填充字节被插入。例如,将较小的数据类型(如"),s("code",[t._v("char")]),t._v(")放在较大的数据类型(如"),s("code",[t._v("int")]),t._v(")之间可能会导致额外的填充,以保持较大类型的对齐。")]),t._v(" "),s("h3",{attrs:{id:"_4-5-栈数据结构"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-5-栈数据结构"}},[t._v("#")]),t._v(" 4.5 栈数据结构")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name"}},[t._v("MAX_SIZE")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typedef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" items"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("MAX_SIZE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" top"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" Stack"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 栈的初始化")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("initializeStack")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Stack "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("top "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 检查栈是否为空")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isEmpty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Stack "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("top "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 检查栈是否已满")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isFull")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Stack "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("top "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" MAX_SIZE "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 入栈")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Stack "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isFull")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Stack is full!\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("items"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("top"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 出栈")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pop")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Stack "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isEmpty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Stack is empty!\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返回一个标识值,表示栈空")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("items"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("top"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 查看栈顶元素")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("peek")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Stack "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isEmpty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Stack is empty!\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 返回一个标识值,表示栈空")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("items"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("top"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 主函数,演示栈操作")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n Stack s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("initializeStack")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 入栈操作")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 查看栈顶元素")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Top element is %d\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("peek")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 出栈操作,并打印出栈元素")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Popped %d from the stack\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pop")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Popped %d from the stack\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pop")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 再次查看栈顶元素")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isEmpty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Top element is %d\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("peek")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 清空栈")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isEmpty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pop")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isEmpty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Stack is empty now.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"_5-文件操作"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-文件操作"}},[t._v("#")]),t._v(" 5. 文件操作")]),t._v(" "),s("h3",{attrs:{id:"_5-1-c"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-c"}},[t._v("#")]),t._v(" 5.1 C")]),t._v(" "),s("p",[t._v("在C中,文件操作主要通过以下几个函数实现:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("fopen(const char *filename, const char *mode)")]),t._v(":打开文件,"),s("code",[t._v("filename")]),t._v("是文件名,"),s("code",[t._v("mode")]),t._v("是打开模式,如"),s("code",[t._v('"r"')]),t._v("(只读)、"),s("code",[t._v('"w"')]),t._v("(只写)、"),s("code",[t._v('"a"')]),t._v("(追加)等。")]),t._v(" "),s("li",[s("code",[t._v("fclose(FILE *stream)")]),t._v(":关闭一个已打开的文件。")]),t._v(" "),s("li",[s("code",[t._v("fread(void *ptr, size_t size, size_t nmemb, FILE *stream)")]),t._v("和"),s("code",[t._v("fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)")]),t._v(":分别用于从文件读取数据和向文件写入数据,"),s("code",[t._v("ptr")]),t._v("是数据存储的内存地址,"),s("code",[t._v("size")]),t._v("是每个数据项的大小,"),s("code",[t._v("nmemb")]),t._v("是数据项的数量。")]),t._v(" "),s("li",[s("code",[t._v("fprintf(FILE *stream, const char *format, ...)")]),t._v("和"),s("code",[t._v("fscanf(FILE *stream, const char *format, ...)")]),t._v(":分别用于向文件写入格式化文本和从文件读取格式化文本。")]),t._v(" "),s("li",[s("code",[t._v("fseek(FILE *stream, long int offset, int whence)")]),t._v(":移动文件指针到指定位置,"),s("code",[t._v("offset")]),t._v("是相对于"),s("code",[t._v("whence")]),t._v("指定的位置偏移量,"),s("code",[t._v("whence")]),t._v("可以是"),s("code",[t._v("SEEK_SET")]),t._v("(文件开头)、"),s("code",[t._v("SEEK_CUR")]),t._v("(当前位置)、"),s("code",[t._v("SEEK_END")]),t._v("(文件末尾)。")])]),t._v(" "),s("p",[t._v("这些函数提供了基础的文件打开、读写、关闭等操作,是进行文件处理的基石。")]),t._v(" "),s("h3",{attrs:{id:"_5-2-c"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-2-c"}},[t._v("#")]),t._v(" 5.2 C++")]),t._v(" "),s("p",[t._v("在C++中,文件操作是通过标准库中的fstream库进行的,它提供了读取、写入文件的能力。fstream库中包含了三个主要的类:ifstream、ofstream和fstream,分别用于文件输入(读取)、文件输出(写入)和同时支持文件输入输出。")]),t._v(" "),s("h3",{attrs:{id:"ifstream-输入文件流"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#ifstream-输入文件流"}},[t._v("#")]),t._v(" ifstream(输入文件流)")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("用途")]),t._v(":用于从文件读取数据。")]),t._v(" "),s("li",[s("strong",[t._v("常用函数")]),t._v(":"),s("code",[t._v("open()")]),t._v(", "),s("code",[t._v("close()")]),t._v(", "),s("code",[t._v("read()")]),t._v(", "),s("code",[t._v("getline()")]),t._v(", "),s("code",[t._v("eof()")]),t._v("等。")]),t._v(" "),s("li",[s("strong",[t._v("示例代码")]),t._v(":")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("using")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("namespace")]),t._v(" std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ifstream "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("file")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"example.txt"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("is_open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n string line"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getline")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" line"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n cout "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<")]),t._v(" line "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\\\n'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("close")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" cout "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Unable to open file"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"ofstream-输出文件流"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#ofstream-输出文件流"}},[t._v("#")]),t._v(" ofstream(输出文件流)")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("用途")]),t._v(":用于向文件写入数据。")]),t._v(" "),s("li",[s("strong",[t._v("常用函数")]),t._v(":"),s("code",[t._v("open()")]),t._v(", "),s("code",[t._v("close()")]),t._v(", "),s("code",[t._v("write()")]),t._v(", "),s("code",[t._v("<<")]),t._v(" 操作符等。")]),t._v(" "),s("li",[s("strong",[t._v("示例代码")]),t._v(":")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("using")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("namespace")]),t._v(" std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ofstream "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("file")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"example.txt"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("is_open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n file "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello, World!\\\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("close")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" cout "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Unable to open file"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"fstream-文件流"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#fstream-文件流"}},[t._v("#")]),t._v(" fstream(文件流)")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("用途")]),t._v(":同时支持读取和写入操作。")]),t._v(" "),s("li",[s("strong",[t._v("常用函数")]),t._v(":继承了ifstream和ofstream的所有函数。")]),t._v(" "),s("li",[s("strong",[t._v("示例代码")]),t._v(":")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("using")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("namespace")]),t._v(" std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 打开文件,同时用于读写")]),t._v("\n fstream "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("file")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"example.txt"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ios"),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" ios"),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" ios"),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),t._v("app"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("is_open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 写入文件")]),t._v("\n file "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello, file!\\\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 设置读取位置到文件开头")]),t._v("\n file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seekg")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ios"),s("span",{pre:!0,attrs:{class:"token double-colon punctuation"}},[t._v("::")]),t._v("beg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 读取文件")]),t._v("\n string line"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getline")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" line"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n cout "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<")]),t._v(" line "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\\\n'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("close")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" cout "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Unable to open file"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"文件打开模式"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#文件打开模式"}},[t._v("#")]),t._v(" 文件打开模式")]),t._v(" "),s("p",[t._v("在使用fstream、ifstream或ofstream打开文件时,可以指定文件的打开模式。这是通过在构造函数或"),s("code",[t._v("open()")]),t._v("方法中使用特定的标志完成的,如下所示:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("ios::in")]),t._v(":打开文件进行读取。")]),t._v(" "),s("li",[s("code",[t._v("ios::out")]),t._v(":打开文件进行写入。")]),t._v(" "),s("li",[s("code",[t._v("ios::binary")]),t._v(":以二进制方式打开文件。")]),t._v(" "),s("li",[s("code",[t._v("ios::app")]),t._v(":写入数据时追加到文件末尾。")]),t._v(" "),s("li",[s("code",[t._v("ios::ate")]),t._v(":打开文件后立即移动到文件末尾。")]),t._v(" "),s("li",[s("code",[t._v("ios::trunc")]),t._v(":如果文件已存在,先删除文件再创建。")]),t._v(" "),s("li",[s("code",[t._v("ios::nocreate")]),t._v(":打开文件时,如果文件不存在,则打开失败。(在某些编译器中不可用)")]),t._v(" "),s("li",[s("code",[t._v("ios::noreplace")]),t._v(":打开文件时,如果文件已存在,则打开失败。(在某些编译器中不可用)")])]),t._v(" "),s("p",[t._v("可以组合使用这些模式,例如,"),s("code",[t._v("ios::in | ios::out")]),t._v(" 会打开文件以进行读写操作。")]),t._v(" "),s("p",[t._v("通过这种方式,C++提供了强大且灵活的文件操作能力,支持多种文件处理场景。")])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/36.2dda1970.js b/assets/js/36.2dda1970.js new file mode 100644 index 0000000..9aa2bab --- /dev/null +++ b/assets/js/36.2dda1970.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[36],{339:function(t,s,a){t.exports=a.p+"assets/img/420.6fdcd694.png"},340:function(t,s,a){t.exports=a.p+"assets/img/421.bf08c958.png"},430:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-11-练习42-栈和队列"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-11-练习42-栈和队列"}},[t._v("#")]),t._v(" 2024.04.11-练习42:栈和队列")]),t._v(" "),s("h2",{attrs:{id:"_1-栈"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-栈"}},[t._v("#")]),t._v(" 1. 栈")]),t._v(" "),s("h3",{attrs:{id:"_1-1-头文件"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-头文件"}},[t._v("#")]),t._v(" 1.1 头文件")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("ifndef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("STACK_H")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name"}},[t._v("STACK_H")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"list.h"')])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typedef")]),t._v(" List Stack"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("Stack_create")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("Stack_destroy")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("Stack_push")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("Stack_peek")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" A"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("Stack_count")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("STACK_FOREACH")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("S"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" V"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("LIST_FOREACH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("S"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" prev"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" V"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("Stack_pop")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_remove")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" A"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("endif")])]),t._v("\n")])])]),s("h3",{attrs:{id:"_1-2-单元测试"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-单元测试"}},[t._v("#")]),t._v(" 1.2 单元测试")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"minunit.h"')])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" Stack "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("stack "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("tests"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test1 data"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test2 data"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test3 data"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name"}},[t._v("NUM_TESTS")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n stack "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Stack_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("stack "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to create stack."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("stack "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to make stack #2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Stack_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("stack"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_push_pop")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" NUM_TESTS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Stack_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("stack"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" tests"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Stack_peek")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("stack"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" tests"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Wrong next value."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Stack_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("stack"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" NUM_TESTS"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Wrong count on push."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("STACK_FOREACH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("stack"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("debug")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"VAL: %s"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" NUM_TESTS "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("val "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Stack_pop")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("stack"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("val "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" tests"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Wrong value on pop."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Stack_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("stack"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Wrong count after pop."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("all_tests")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_suite_start")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_run_test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("test_create"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_run_test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("test_push_pop"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_run_test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("test_destroy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RUN_TESTS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("all_tests"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("img",{attrs:{src:a(339),alt:"Untitled"}})]),t._v(" "),s("h2",{attrs:{id:"_2-队列"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-队列"}},[t._v("#")]),t._v(" 2. 队列")]),t._v(" "),s("h3",{attrs:{id:"_2-1-头文件"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-头文件"}},[t._v("#")]),t._v(" 2.1 头文件")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("ifndef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("QUEUE_H")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name"}},[t._v("QUEUE_H")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"list.h"')])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typedef")]),t._v(" List Queue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("Queue_create")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("Queue_destroy")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("Queue_send")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("Queue_peek")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" A"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("Queue_count")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("QUEUE_FOREACH")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("S"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" V"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("LIST_FOREACH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("S"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" V"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("Queue_recv")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_remove")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" A"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("endif")])]),t._v("\n")])])]),s("h3",{attrs:{id:"_2-2-单元测试"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-单元测试"}},[t._v("#")]),t._v(" 2.2 单元测试")]),t._v(" "),s("p",[s("img",{attrs:{src:a(340),alt:"Untitled"}})])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/37.d4f91b60.js b/assets/js/37.d4f91b60.js new file mode 100644 index 0000000..ef0d8f1 --- /dev/null +++ b/assets/js/37.d4f91b60.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[37],{356:function(s,a,t){s.exports=t.p+"assets/img/50.9f171ce6.png"},357:function(s,a,t){s.exports=t.p+"assets/img/51.5a54b6e7.png"},442:function(s,a,t){"use strict";t.r(a);var e=t(14),n=Object(e.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h1",{attrs:{id:"_2024-03-21-5-command-line-interface"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-21-5-command-line-interface"}},[s._v("#")]),s._v(" 2024.03.21-5. Command Line Interface")]),s._v(" "),a("h1",{attrs:{id:"_1-任务控制"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-任务控制"}},[s._v("#")]),s._v(" 1. 任务控制")]),s._v(" "),a("h2",{attrs:{id:"_1-1-结束进程"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-结束进程"}},[s._v("#")]),s._v(" 1.1 结束进程")]),s._v(" "),a("p",[s._v("您的 shell 会使用 UNIX 提供的信号机制执行进程间通信。当一个进程接收到信号时,它会停止执行、处理该信号并基于信号传递的信息来改变其执行。就这一点而言,信号是一种"),a("em",[s._v("软件中断")]),s._v("。")]),s._v(" "),a("p",[s._v("在上面的例子中,当我们输入  "),a("code",[s._v("Ctrl-C")]),s._v("  时,shell 会发送一个"),a("code",[s._v("SIGINT")]),s._v("  信号到进程。")]),s._v(" "),a("p",[s._v("下面这个 Python 程序向您展示了捕获信号"),a("code",[s._v("SIGINT")]),s._v("  并忽略它的基本操作,它并不会让程序停止。为了停止这个程序,我们需要使用"),a("code",[s._v("SIGQUIT")]),s._v("  信号,通过输入"),a("code",[s._v("Ctrl-\\")]),s._v("可以发送该信号。")]),s._v(" "),a("div",{staticClass:"language-python extra-class"},[a("pre",{pre:!0,attrs:{class:"language-python"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("#!/usr/bin/env python")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("import")]),s._v(" signal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" time\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("def")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("handler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("signum"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" time"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("print")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"\\nI got a SIGINT, but I am not stopping"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n\nsignal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("signal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("signal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("SIGINT"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" handler"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\ni "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("while")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("True")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("\n time"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("sleep"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v(".1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("print")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"\\r{}"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[s._v("format")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("i"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" end"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('""')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n i "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("+=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v("\n")])])]),a("p",[s._v("如果我们向这个程序发送两次  "),a("code",[s._v("SIGINT")]),s._v(" ,然后再发送一次  "),a("code",[s._v("SIGQUIT")]),s._v(",程序会有什么反应?注意  "),a("code",[s._v("^")]),s._v("  是我们在终端输入"),a("code",[s._v("Ctrl")]),s._v("  时的表示形式:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("$ python sigint.py\n"),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("24")]),s._v("^C\nI got a SIGINT, but I am not stopping\n"),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("26")]),s._v("^C\nI got a SIGINT, but I am not stopping\n"),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("30")]),s._v("^"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("\\")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("39913")]),s._v(" quit python sigint.pyƒ\n")])])]),a("p",[s._v("尽管  "),a("code",[s._v("SIGINT")]),s._v("  和  "),a("code",[s._v("SIGQUIT")]),s._v("  都常常用来发出和终止程序相关的请求。"),a("code",[s._v("SIGTERM")]),s._v("  则是一个更加通用的、也更加优雅地退出信号。为了发出这个信号我们需要使用  "),a("code",[s._v("[kill](https://www.man7.org/linux/man-pages/man1/kill.1.html)")]),s._v("  命令, 它的语法是: "),a("code",[s._v("kill -TERM ")]),s._v("。")]),s._v(" "),a("h2",{attrs:{id:"_1-2-暂停和后台执行进程"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-暂停和后台执行进程"}},[s._v("#")]),s._v(" 1.2 暂停和后台执行进程")]),s._v(" "),a("p",[s._v("信号可以让进程做其他的事情,而不仅仅是终止它们。例如,"),a("code",[s._v("SIGSTOP")]),s._v("  会让进程暂停。在终端中,键入  "),a("code",[s._v("Ctrl-Z")]),s._v("  会让 shell 发送  "),a("code",[s._v("SIGTSTP")]),s._v("  信号,"),a("code",[s._v("SIGTSTP")]),s._v("是 Terminal Stop 的缩写(即"),a("code",[s._v("terminal")]),s._v("版本的 SIGSTOP)。")]),s._v(" "),a("p",[s._v("我们可以使用  "),a("code",[s._v("[fg](https://www.man7.org/linux/man-pages/man1/fg.1p.html)")]),s._v("  或  "),a("code",[s._v("[bg](http://man7.org/linux/man-pages/man1/bg.1p.html)")]),s._v("  命令恢复暂停的工作。它们分别表示在前台继续或在后台继续。")]),s._v(" "),a("p",[a("code",[s._v("[jobs](http://man7.org/linux/man-pages/man1/jobs.1p.html)")]),s._v("  命令会列出当前终端会话中尚未完成的全部任务。您可以使用 pid 引用这些任务(也可以用  "),a("code",[s._v("[pgrep](https://www.man7.org/linux/man-pages/man1/pgrep.1.html)")]),s._v("  找出 pid)。更加符合直觉的操作是您可以使用百分号 + 任务编号("),a("code",[s._v("jobs")]),s._v("  会打印任务编号)来选取该任务。如果要选择最近的一个任务,可以使用  "),a("code",[s._v("$!")]),s._v("  这一特殊参数。")]),s._v(" "),a("p",[s._v("还有一件事情需要掌握,那就是命令中的  "),a("code",[s._v("&")]),s._v("  后缀可以让命令在直接在后台运行,这使得您可以直接在 shell 中继续做其他操作,不过它此时还是会使用 shell 的标准输出,这一点有时会比较恼人(这种情况可以使用 shell 重定向处理)。")]),s._v(" "),a("p",[s._v("让已经在运行的进程转到后台运行,您可以键入"),a("code",[s._v("Ctrl-Z")]),s._v(" ,然后紧接着再输入"),a("code",[s._v("bg")]),s._v("。注意,后台的进程仍然是您的终端进程的子进程,一旦您关闭终端(会发送另外一个信号"),a("code",[s._v("SIGHUP")]),s._v("),这些后台的进程也会终止。为了防止这种情况发生,您可以使用  "),a("code",[s._v("[nohup](https://www.man7.org/linux/man-pages/man1/nohup.1.html)")]),s._v(" (一个用来忽略  "),a("code",[s._v("SIGHUP")]),s._v("  的封装) 来运行程序。针对已经运行的程序,可以使用"),a("code",[s._v("disown")]),s._v(" 。除此之外,您可以使用终端多路复用器来实现,下一章节我们会进行详细地探讨。")]),s._v(" "),a("p",[s._v("下面这个简单的会话中展示来了些概念的应用:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1000")]),s._v("\n^Z\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" + "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("18653")]),s._v(" suspended "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1000")]),s._v("\n\n$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("nohup")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2000")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("&")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("18745")]),s._v("\nappending output to nohup.out\n\n$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("jobs")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" + suspended "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1000")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" - running "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("nohup")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2000")]),s._v("\n\n$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("bg")]),s._v(" %1\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" - "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("18653")]),s._v(" continued "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1000")]),s._v("\n\n$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("jobs")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" - running "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1000")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" + running "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("nohup")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2000")]),s._v("\n\n$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("kill")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-STOP")]),s._v(" %1\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" + "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("18653")]),s._v(" suspended "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("signal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1000")]),s._v("\n\n$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("jobs")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" + suspended "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("signal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1000")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" - running "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("nohup")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2000")]),s._v("\n\n$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("kill")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-SIGHUP")]),s._v(" %1\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" + "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("18653")]),s._v(" hangup "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1000")]),s._v("\n\n$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("jobs")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" + running "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("nohup")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2000")]),s._v("\n\n$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("kill")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-SIGHUP")]),s._v(" %2\n\n$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("jobs")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" + running "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("nohup")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2000")]),s._v("\n\n$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("kill")]),s._v(" %2\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" + "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("18745")]),s._v(" terminated "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("nohup")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2000")]),s._v("\n\n$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("jobs")]),s._v("\n")])])]),a("p",[a("code",[s._v("SIGKILL")]),s._v("  是一个特殊的信号,它不能被进程捕获并且它会马上结束该进程。不过这样做会有一些副作用,例如留下孤儿进程。")]),s._v(" "),a("p",[s._v("您可以在  "),a("a",{attrs:{href:"https://en.wikipedia.org/wiki/Signal_(IPC)",target:"_blank",rel:"noopener noreferrer"}},[s._v("这里"),a("OutboundLink")],1),s._v("  或输入  "),a("code",[s._v("[man signal](https://www.man7.org/linux/man-pages/man7/signal.7.html)")]),s._v("  或使用  "),a("code",[s._v("kill -l")]),s._v("  来获取更多关于信号的信息。")]),s._v(" "),a("h1",{attrs:{id:"_2-终端多路复用"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-终端多路复用"}},[s._v("#")]),s._v(" 2. 终端多路复用")]),s._v(" "),a("p",[s._v("当您在使用命令行时,您通常会希望同时执行多个任务。举例来说,您可以想要同时运行您的编辑器,并在终端的另外一侧执行程序。尽管再打开一个新的终端窗口也能达到目的,使用终端多路复用器则是一种更好的办法。")]),s._v(" "),a("p",[s._v("像  "),a("code",[s._v("[tmux](https://www.man7.org/linux/man-pages/man1/tmux.1.html)")]),s._v("  这类的终端多路复用器可以允许我们基于面板和标签分割出多个终端窗口,这样您便可以同时与多个 shell 会话进行交互。")]),s._v(" "),a("p",[s._v("不仅如此,终端多路复用使我们可以分离当前终端会话并在将来重新连接。")]),s._v(" "),a("p",[s._v("这让您操作远端设备时的工作流大大改善,避免了  "),a("code",[s._v("nohup")]),s._v("  和其他类似技巧的使用。")]),s._v(" "),a("p",[s._v("现在最流行的终端多路器是  "),a("code",[s._v("[tmux](https://www.man7.org/linux/man-pages/man1/tmux.1.html)")]),s._v("。"),a("code",[s._v("tmux")]),s._v("  是一个高度可定制的工具,您可以使用相关快捷键创建多个标签页并在它们间导航。")]),s._v(" "),a("p",[a("code",[s._v("tmux")]),s._v("  的快捷键需要我们掌握,它们都是类似  "),a("code",[s._v(" x")]),s._v("  这样的组合,即需要先按下"),a("code",[s._v("Ctrl+b")]),s._v(",松开后再按下  "),a("code",[s._v("x")]),s._v("。"),a("code",[s._v("tmux")]),s._v("  中对象的继承结构如下:")]),s._v(" "),a("ul",[a("li",[s._v("会话  - 每个会话都是一个独立的工作区,其中包含一个或多个窗口\n"),a("ul",[a("li",[a("code",[s._v("tmux")]),s._v("  开始一个新的会话")]),s._v(" "),a("li",[a("code",[s._v("tmux new -s NAME")]),s._v("  以指定名称开始一个新的会话")]),s._v(" "),a("li",[a("code",[s._v("tmux ls")]),s._v("  列出当前所有会话")]),s._v(" "),a("li",[s._v("在  "),a("code",[s._v("tmux")]),s._v("  中输入  "),a("code",[s._v(" d")]),s._v(" ,将当前会话分离")]),s._v(" "),a("li",[a("code",[s._v("tmux a")]),s._v("  重新连接最后一个会话。您也可以通过  "),a("code",[s._v("t")]),s._v("  来指定具体的会话")])])]),s._v(" "),a("li",[s._v("窗口  - 相当于编辑器或是浏览器中的标签页,从视觉上将一个会话分割为多个部分\n"),a("ul",[a("li",[a("code",[s._v(" c")]),s._v("  创建一个新的窗口,使用  "),a("code",[s._v("")]),s._v("关闭")]),s._v(" "),a("li",[a("code",[s._v(" N")]),s._v("  跳转到第  "),a("em",[s._v("N")]),s._v("  个窗口,注意每个窗口都是有编号的")]),s._v(" "),a("li",[a("code",[s._v(" p")]),s._v("  切换到前一个窗口")]),s._v(" "),a("li",[a("code",[s._v(" n")]),s._v("  切换到下一个窗口")]),s._v(" "),a("li",[a("code",[s._v(" ,")]),s._v("  重命名当前窗口")]),s._v(" "),a("li",[a("code",[s._v(" w")]),s._v("  列出当前所有窗口")])])]),s._v(" "),a("li",[s._v("面板  - 像 vim 中的分屏一样,面板使我们可以在一个屏幕里显示多个 shell\n"),a("ul",[a("li",[a("code",[s._v(' "')]),s._v("  水平分割")]),s._v(" "),a("li",[a("code",[s._v(" %")]),s._v("  垂直分割")]),s._v(" "),a("li",[a("code",[s._v(" <方向>")]),s._v("  切换到指定方向的面板,<方向> 指的是键盘上的方向键")]),s._v(" "),a("li",[a("code",[s._v(" z")]),s._v("  切换当前面板的缩放")]),s._v(" "),a("li",[a("code",[s._v(" [")]),s._v("  开始往回卷动屏幕。您可以按下空格键来开始选择,回车键复制选中的部分")]),s._v(" "),a("li",[a("code",[s._v(" <空格>")]),s._v("  在不同的面板排布间切换")])])])]),s._v(" "),a("p",[s._v("扩展阅读: "),a("a",{attrs:{href:"https://www.hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/",target:"_blank",rel:"noopener noreferrer"}},[s._v("这里"),a("OutboundLink")],1),s._v("  是一份  "),a("code",[s._v("tmux")]),s._v("  快速入门教程, "),a("a",{attrs:{href:"http://linuxcommand.org/lc3_adv_termmux.php",target:"_blank",rel:"noopener noreferrer"}},[s._v("而这一篇"),a("OutboundLink")],1),s._v("  文章则更加详细,它包含了  "),a("code",[s._v("screen")]),s._v("  命令。您也许想要掌握  "),a("code",[s._v("[screen](https://www.man7.org/linux/man-pages/man1/screen.1.html)")]),s._v("  命令,因为在大多数 UNIX 系统中都默认安装有该程序。")]),s._v(" "),a("h1",{attrs:{id:"_3-别名"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-别名"}},[s._v("#")]),s._v(" 3. 别名")]),s._v(" "),a("p",[s._v("输入一长串包含许多选项的命令会非常麻烦。因此,大多数 shell 都支持设置别名。shell 的别名相当于一个长命令的缩写,shell 会自动将其替换成原本的命令。例如,bash 中的别名语法如下:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("alias")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("alias_name")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"command_to_alias arg1 arg2"')]),s._v("\n")])])]),a("p",[s._v("注意, "),a("code",[s._v("=")]),s._v("两边是没有空格的,因为  "),a("code",[s._v("[alias](https://www.man7.org/linux/man-pages/man1/alias.1p.html)")]),s._v("  是一个 shell 命令,它只接受一个参数。")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 创建常用命令的缩写")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("alias")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("ll")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"ls -lh"')]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 能够少输入很多")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("alias")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("gs")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"git status"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("alias")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("gc")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"git commit"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("alias")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("v")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"vim"')]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 手误打错命令也没关系")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("alias")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("sl")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v("ls\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 重新定义一些命令行的默认行为")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("alias")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("mv")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"mv -i"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# -i prompts before overwrite")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("alias")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("mkdir")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"mkdir -p"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# -p make parent dirs as needed")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("alias")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("df")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"df -h"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# -h prints human readable format")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 别名可以组合使用")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("alias")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("la")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"ls -A"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("alias")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("lla")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"la -l"')]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 在忽略某个别名: 命令前加上反斜杠 \\")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("\\")]),s._v("ls\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 或者禁用别名")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("unalias")]),s._v(" la\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 获取别名的定义")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("alias")]),s._v(" ll\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 会打印 ll='ls -lh'")]),s._v("\n")])])]),a("p",[s._v("值得注意的是,在默认情况下 shell 并不会保存别名。为了让别名持续生效,您需要将配置放进 shell 的启动文件里,像是"),a("code",[s._v(".bashrc")]),s._v("  或  "),a("code",[s._v(".zshrc")]),s._v("。")]),s._v(" "),a("h1",{attrs:{id:"_4-配置文件-dotfiles"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_4-配置文件-dotfiles"}},[s._v("#")]),s._v(" 4. 配置文件(Dotfiles)")]),s._v(" "),a("p",[s._v("很多程序的配置都是通过纯文本格式的被称作"),a("em",[s._v("点文件")]),s._v("的配置文件来完成的(之所以称为点文件,是因为它们的文件名以  "),a("code",[s._v(".")]),s._v("  开头,例如  "),a("code",[s._v("~/.vimrc")]),s._v("。也正因为此,它们默认是隐藏文件,"),a("code",[s._v("ls")]),s._v("并不会显示它们)。")]),s._v(" "),a("p",[s._v("shell 的配置也是通过这类文件完成的。在启动时,您的 shell 程序会读取很多文件以加载其配置项。根据 shell 本身的不同,您从登录开始还是以交互的方式完成这一过程可能会有很大的不同。关于这一话题,"),a("a",{attrs:{href:"https://blog.flowblok.id.au/2013-02/shell-startup-scripts.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("这里"),a("OutboundLink")],1),s._v("  有非常好的资源")]),s._v(" "),a("p",[s._v("对于  "),a("code",[s._v("bash")]),s._v("来说,在大多数系统下,您可以通过编辑  "),a("code",[s._v(".bashrc")]),s._v("  或  "),a("code",[s._v(".bash_profile")]),s._v("  来进行配置。在文件中您可以添加需要在启动时执行的命令,例如上文我们讲到过的别名,或者是您的环境变量。")]),s._v(" "),a("p",[s._v("实际上,很多程序都要求您在 shell 的配置文件中包含一行类似  "),a("code",[s._v('export PATH="$PATH:/path/to/program/bin"')]),s._v("  的命令,这样才能确保这些程序能够被 shell 找到。")]),s._v(" "),a("p",[s._v("还有一些其他的工具也可以通过"),a("em",[s._v("点文件")]),s._v("进行配置:")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("bash")]),s._v(" - "),a("code",[s._v("~/.bashrc")]),s._v(", "),a("code",[s._v("~/.bash_profile")])]),s._v(" "),a("li",[a("code",[s._v("git")]),s._v(" - "),a("code",[s._v("~/.gitconfig")])]),s._v(" "),a("li",[a("code",[s._v("vim")]),s._v(" - "),a("code",[s._v("~/.vimrc")]),s._v("  和  "),a("code",[s._v("~/.vim")]),s._v("  目录")]),s._v(" "),a("li",[a("code",[s._v("ssh")]),s._v(" - "),a("code",[s._v("~/.ssh/config")])]),s._v(" "),a("li",[a("code",[s._v("tmux")]),s._v(" - "),a("code",[s._v("~/.tmux.conf")])])]),s._v(" "),a("p",[s._v("我们应该如何管理这些配置文件呢,它们应该在它们的文件夹下,并使用版本控制系统进行管理,然后通过脚本将其   符号链接   到需要的地方。这么做有如下好处:")]),s._v(" "),a("ul",[a("li",[s._v("安装简单: 如果您登录了一台新的设备,在这台设备上应用您的配置只需要几分钟的时间;")]),s._v(" "),a("li",[s._v("可移植性: 您的工具在任何地方都以相同的配置工作")]),s._v(" "),a("li",[s._v("同步: 在一处更新配置文件,可以同步到其他所有地方")]),s._v(" "),a("li",[s._v("变更追踪: 您可能要在整个程序员生涯中持续维护这些配置文件,而对于长期项目而言,版本历史是非常重要的")])]),s._v(" "),a("p",[s._v("配置文件中需要放些什么?您可以通过在线文档和"),a("a",{attrs:{href:"https://en.wikipedia.org/wiki/Man_page",target:"_blank",rel:"noopener noreferrer"}},[s._v("帮助手册"),a("OutboundLink")],1),s._v("了解所使用工具的设置项。另一个方法是在网上搜索有关特定程序的文章,作者们在文章中会分享他们的配置。还有一种方法就是直接浏览其他人的配置文件:您可以在这里找到无数的"),a("a",{attrs:{href:"https://github.com/search?o=desc&q=dotfiles&s=stars&type=Repositories",target:"_blank",rel:"noopener noreferrer"}},[s._v("dotfiles 仓库"),a("OutboundLink")],1),s._v(" —— 其中最受欢迎的那些可以在"),a("a",{attrs:{href:"https://github.com/mathiasbynens/dotfiles",target:"_blank",rel:"noopener noreferrer"}},[s._v("这里"),a("OutboundLink")],1),s._v("找到(我们建议您不要直接复制别人的配置)。"),a("a",{attrs:{href:"https://dotfiles.github.io/",target:"_blank",rel:"noopener noreferrer"}},[s._v("这里"),a("OutboundLink")],1),s._v("  也有一些非常有用的资源。")]),s._v(" "),a("p",[s._v("本课程的老师们也在 GitHub 上开源了他们的配置文件: "),a("a",{attrs:{href:"https://github.com/anishathalye/dotfiles",target:"_blank",rel:"noopener noreferrer"}},[s._v("Anish"),a("OutboundLink")],1),s._v(", "),a("a",{attrs:{href:"https://github.com/jonhoo/configs",target:"_blank",rel:"noopener noreferrer"}},[s._v("Jon"),a("OutboundLink")],1),s._v(", "),a("a",{attrs:{href:"https://github.com/jjgo/dotfiles",target:"_blank",rel:"noopener noreferrer"}},[s._v("Jose"),a("OutboundLink")],1),s._v(".")]),s._v(" "),a("h2",{attrs:{id:"_4-1-可移植性"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_4-1-可移植性"}},[s._v("#")]),s._v(" 4.1 可移植性")]),s._v(" "),a("p",[s._v("配置文件的一个常见的痛点是它可能并不能在多种设备上生效。例如,如果您在不同设备上使用的操作系统或者 shell 是不同的,则配置文件是无法生效的。或者,有时您仅希望特定的配置只在某些设备上生效。")]),s._v(" "),a("p",[s._v("有一些技巧可以轻松达成这些目的。如果配置文件 if 语句,则您可以借助它针对不同的设备编写不同的配置。例如,您的 shell 可以这样做:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("uname")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Linux"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("then")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("do_something"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("fi")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 使用和 shell 相关的配置时先检查当前 shell 类型")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token environment constant"}},[s._v("$SHELL")]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"zsh"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("then")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("do_something"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("fi")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 您也可以针对特定的设备进行配置")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"'),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("hostname")]),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v('"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"myServer"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("then")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("do_something"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("fi")]),s._v("\n")])])]),a("p",[s._v("如果配置文件支持 include 功能,您也可以多加利用。例如:"),a("code",[s._v("~/.gitconfig")]),s._v("  可以这样编写:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("include"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n path "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" ~/.gitconfig_local\n")])])]),a("p",[s._v("然后我们可以在日常使用的设备上创建配置文件  "),a("code",[s._v("~/.gitconfig_local")]),s._v("  来包含与该设备相关的特定配置。您甚至应该创建一个单独的代码仓库来管理这些与设备相关的配置。")]),s._v(" "),a("p",[s._v("如果您希望在不同的程序之间共享某些配置,该方法也适用。例如,如果您想要在  "),a("code",[s._v("bash")]),s._v("  和  "),a("code",[s._v("zsh")]),s._v("  中同时启用一些别名,您可以把它们写在  "),a("code",[s._v(".aliases")]),s._v("  里,然后在这两个 shell 里应用:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# Test if ~/.aliases exists and source it")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-f")]),s._v(" ~/.aliases "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("then")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("source")]),s._v(" ~/.aliases\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("fi")]),s._v("\n")])])]),a("h1",{attrs:{id:"_5-远端设备"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5-远端设备"}},[s._v("#")]),s._v(" 5. 远端设备")]),s._v(" "),a("p",[s._v("对于程序员来说,在他们的日常工作中使用远程服务器已经非常普遍了。如果您需要使用远程服务器来部署后端软件或您需要一些计算能力强大的服务器,您就会用到安全 shell(SSH)。和其他工具一样,SSH 也是可以高度定制的,也值得我们花时间学习它。")]),s._v(" "),a("p",[s._v("通过如下命令,您可以使用  "),a("code",[s._v("ssh")]),s._v("  连接到其他服务器:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ssh")]),s._v(" foo@bar.mit.edu\n")])])]),a("p",[s._v("这里我们尝试以用户名  "),a("code",[s._v("foo")]),s._v("  登录服务器  "),a("code",[s._v("bar.mit.edu")]),s._v("。服务器可以通过 URL 指定(例如"),a("code",[s._v("bar.mit.edu")]),s._v("),也可以使用 IP 指定(例如"),a("code",[s._v("foobar@192.168.1.42")]),s._v(")。后面我们会介绍如何修改 ssh 配置文件使我们可以用类似  "),a("code",[s._v("ssh bar")]),s._v("  这样的命令来登录服务器。")]),s._v(" "),a("h2",{attrs:{id:"_5-1-执行命令"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5-1-执行命令"}},[s._v("#")]),s._v(" 5.1 执行命令")]),s._v(" "),a("p",[a("code",[s._v("ssh")]),s._v("  的一个经常被忽视的特性是它可以直接远程执行命令。 "),a("code",[s._v("ssh foobar@server ls")]),s._v("  可以直接在用 foobar 的命令下执行  "),a("code",[s._v("ls")]),s._v("  命令。 想要配合管道来使用也可以, "),a("code",[s._v("ssh foobar@server ls | grep PATTERN")]),s._v("  会在本地查询远端  "),a("code",[s._v("ls")]),s._v("  的输出而  "),a("code",[s._v("ls | ssh foobar@server grep PATTERN")]),s._v("  会在远端对本地  "),a("code",[s._v("ls")]),s._v("  输出的结果进行查询。")]),s._v(" "),a("h2",{attrs:{id:"_5-2-ssh-密钥"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5-2-ssh-密钥"}},[s._v("#")]),s._v(" 5.2 SSH 密钥")]),s._v(" "),a("p",[s._v("基于密钥的验证机制使用了密码学中的公钥,我们只需要向服务器证明客户端持有对应的私钥,而不需要公开其私钥。这样您就可以避免每次登录都输入密码的麻烦了秘密就可以登录。不过,私钥(通常是  "),a("code",[s._v("~/.ssh/id_rsa")]),s._v("  或者  "),a("code",[s._v("~/.ssh/id_ed25519")]),s._v(") 等效于您的密码,所以一定要好好保存它。")]),s._v(" "),a("h3",{attrs:{id:"_5-2-1-密钥生成"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5-2-1-密钥生成"}},[s._v("#")]),s._v(" 5.2.1 密钥生成")]),s._v(" "),a("p",[s._v("使用  "),a("code",[s._v("[ssh-keygen](http://man7.org/linux/man-pages/man1/ssh-keygen.1.html)")]),s._v("  命令可以生成一对密钥:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("ssh-keygen "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-o")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-a")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("100")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-t")]),s._v(" ed25519 "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-f")]),s._v(" ~/.ssh/id_ed25519\n")])])]),a("p",[s._v("您可以为密钥设置密码,防止有人持有您的私钥并使用它访问您的服务器。您可以使用  "),a("code",[s._v("[ssh-agent](https://www.man7.org/linux/man-pages/man1/ssh-agent.1.html)")]),s._v("  或  "),a("code",[s._v("[gpg-agent](https://linux.die.net/man/1/gpg-agent)")]),s._v(" ,这样就不需要每次都输入该密码了。")]),s._v(" "),a("p",[s._v("如果您曾经配置过使用 SSH 密钥推送到 GitHub,那么可能您已经完成了"),a("a",{attrs:{href:"https://help.github.com/articles/connecting-to-github-with-ssh/",target:"_blank",rel:"noopener noreferrer"}},[s._v("这里"),a("OutboundLink")],1),s._v("  介绍的这些步骤,并且已经有了一个可用的密钥对。要检查您是否持有密码并验证它,您可以运行  "),a("code",[s._v("ssh-keygen -y -f /path/to/key")]),s._v(".")]),s._v(" "),a("h3",{attrs:{id:"_5-2-2-基于密钥的认证机制"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5-2-2-基于密钥的认证机制"}},[s._v("#")]),s._v(" 5.2.2 基于密钥的认证机制")]),s._v(" "),a("p",[a("code",[s._v("ssh")]),s._v("  会查询  "),a("code",[s._v(".ssh/authorized_keys")]),s._v("  来确认那些用户可以被允许登录。您可以通过下面的命令将一个公钥拷贝到这里:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" .ssh/id_ed25519.pub "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ssh")]),s._v(" foobar@remote "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'cat >> ~/.ssh/authorized_keys'")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 如果支持 ssh-copy-id 的话,可以使用下面这种更简单的解决方案:")]),s._v("\nssh-copy-id "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-i")]),s._v(" .ssh/id_ed25519.pub foobar@remote\n")])])]),a("p",[s._v("在 GitHub(或其他类似的服务)上使用 SSH 密钥时,邮箱地址作为一个注释或标识附加到公钥的末尾。这并不是 SSH 密钥本身所必需的,而是为了帮助识别公钥的所有者。当你在多个设备上生成不同的 SSH 密钥并将它们添加到 GitHub 时,邮箱地址可以帮助你区分每个密钥对应的设备或用途。")]),s._v(" "),a("p",[s._v("在使用 "),a("code",[s._v("ssh-keygen")]),s._v(" 生成密钥时,通常在命令行最后提示你输入一个文件名来保存新的密钥时,你可以附加一个注释,如你的电子邮箱。例如:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("ssh-keygen "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-t")]),s._v(" rsa "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-b")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("4096")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-C")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"your_email@example.com"')]),s._v("\n")])])]),a("p",[s._v("这里 "),a("code",[s._v('-C "your_email@example.com"')]),s._v(" 就是为生成的公钥添加一个标签或注释,通常是你的电子邮件地址。当你将公钥添加到 GitHub 时,这个邮箱地址会一同显示,但它不影响密钥的功能。这个注释在公钥的末尾,不参与密钥认证过程,仅仅是为了方便用户识别。")]),s._v(" "),a("p",[s._v("一个电脑可以拥有多个 SSH 密钥对,而不仅限于一个。SSH 密钥对通常包括两部分:一个私钥和一个公钥。私钥应该保密不外泄,而公钥可以安全地分享给任何人或任何服务。")]),s._v(" "),a("p",[s._v("在同一台电脑上生成多个 SSH 密钥对可以用于不同目的,比如你可能想为不同的服务器或服务使用不同的密钥对,或者你可能需要不同类型或不同加密强度的密钥对。生成不同的密钥对可以提高安全性,因为即使一个密钥对被破解或泄露,其他密钥对仍然是安全的。")]),s._v(" "),a("p",[s._v("使用 "),a("code",[s._v("ssh-keygen")]),s._v(" 命令生成密钥对时,如果不指定输出文件(使用 "),a("code",[s._v("-f")]),s._v(" 选项),默认会在 "),a("code",[s._v("~/.ssh")]),s._v(" 目录下生成名为 "),a("code",[s._v("id_rsa")]),s._v(" 的私钥和名为 "),a("code",[s._v("id_rsa.pub")]),s._v(" 的公钥。如果该文件已经存在,"),a("code",[s._v("ssh-keygen")]),s._v(" 会提示是否覆盖。为了生成多个密钥对,你可以指定不同的文件名来保存新的密钥对,例如:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("ssh-keygen "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-t")]),s._v(" rsa "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-b")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("4096")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-f")]),s._v(" ~/.ssh/id_rsa_github\nssh-keygen "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-t")]),s._v(" ed25519 "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-f")]),s._v(" ~/.ssh/id_ed25519_gitlab\n")])])]),a("p",[s._v("这样,你就可以为不同的服务创建专用的密钥对。在连接时,你可以在 SSH 客户端配置文件("),a("code",[s._v("~/.ssh/config")]),s._v(")中指定使用哪个密钥对,或者在使用 "),a("code",[s._v("ssh")]),s._v(" 命令时通过 "),a("code",[s._v("-i")]),s._v(" 选项指定私钥的路径。")]),s._v(" "),a("p",[s._v("记得,每个生成的公钥(例如 "),a("code",[s._v("id_rsa_github.pub")]),s._v(" 和 "),a("code",[s._v("id_ed25519_gitlab.pub")]),s._v(")可以上传到相应的服务上(如 GitHub 或 GitLab),而对应的私钥则应该安全地存储在你的设备上,不应该泄露或被无关人员访问。")]),s._v(" "),a("h2",{attrs:{id:"_5-3-通过-ssh-复制文件"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5-3-通过-ssh-复制文件"}},[s._v("#")]),s._v(" 5.3 通过 SSH 复制文件")]),s._v(" "),a("p",[s._v("使用 ssh 复制文件有很多方法:")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("ssh+tee")]),s._v(", 最简单的方法是执行  "),a("code",[s._v("ssh")]),s._v("  命令,然后通过这样的方法利用标准输入实现  "),a("code",[s._v("cat localfile | ssh remote_server tee serverfile")]),s._v("。回忆一下,"),a("code",[s._v("[tee](https://www.man7.org/linux/man-pages/man1/tee.1.html)")]),s._v("  命令会将标准输出写入到一个文件;")]),s._v(" "),a("li",[a("code",[s._v("[scp](https://www.man7.org/linux/man-pages/man1/scp.1.html)")]),s._v(" :当需要拷贝大量的文件或目录时,使用"),a("code",[s._v("scp")]),s._v("  命令则更加方便,因为它可以方便的遍历相关路径。语法如下:"),a("code",[s._v("scp path/to/local_file remote_host:path/to/remote_file")]),s._v(";")]),s._v(" "),a("li",[a("code",[s._v("[rsync](https://www.man7.org/linux/man-pages/man1/rsync.1.html)")]),s._v("  对  "),a("code",[s._v("scp")]),s._v("  进行了改进,它可以检测本地和远端的文件以防止重复拷贝。它还可以提供一些诸如符号连接、权限管理等精心打磨的功能。甚至还可以基于  "),a("code",[s._v("-partial")]),s._v("标记实现断点续传。"),a("code",[s._v("rsync")]),s._v("  的语法和"),a("code",[s._v("scp")]),s._v("类似;")])]),s._v(" "),a("h2",{attrs:{id:"_5-4-端口转发"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5-4-端口转发"}},[s._v("#")]),s._v(" 5.4 端口转发")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("LocalForward "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("9999")]),s._v(" localhost:8888\n")])])]),a("p",[a("code",[s._v("LocalForward 9999 localhost:8888")]),s._v(" 是 SSH 配置文件中的一个指令,用于设置本地端口转发。这一行指令的出现在 SSH 配置文件(通常是 "),a("code",[s._v("~/.ssh/config")]),s._v(")中表示以下行为:")]),s._v(" "),a("ul",[a("li",[s._v("当你通过 SSH 连接到指定的主机时,SSH 客户端会创建一个本地监听端口(在这个例子中是 9999)。")]),s._v(" "),a("li",[s._v("任何发送到你本地机器上的 9999 端口的数据都会被转发到通过 SSH 连接的远程机器上的 "),a("code",[s._v("localhost:8888")]),s._v(" 地址和端口上。")]),s._v(" "),a("li",[s._v("在这个上下文中,"),a("code",[s._v("localhost")]),s._v(" 是指远程机器的本地回环接口,而不是你的本地机器。所以,实际上数据是从本地机器的 9999 端口转发到远程机器的 8888 端口。")])]),s._v(" "),a("p",[s._v("在实际应用中,这种端口转发可以用于多种情况,例如:")]),s._v(" "),a("ul",[a("li",[s._v("访问在远程主机上运行的 web 应用或服务,就像它们在本地主机上一样。")]),s._v(" "),a("li",[s._v("通过 SSH 保护未加密的网络通信,因为数据传输会在 SSH 的加密隧道中进行。")]),s._v(" "),a("li",[s._v("绕过防火墙或网络限制,访问仅在远程网络上可访问的资源。")])]),s._v(" "),a("p",[s._v("在你提供的配置中,如果有服务在远程主机的 "),a("code",[s._v("localhost:8888")]),s._v(" 上监听,你可以简单地通过访问你本地机器上的 "),a("code",[s._v("localhost:9999")]),s._v(" 来访问它,所有通信都会安全地通过 SSH 隧道转发。")]),s._v(" "),a("h2",{attrs:{id:"_5-5-ssh-配置"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5-5-ssh-配置"}},[s._v("#")]),s._v(" 5.5 SSH 配置")]),s._v(" "),a("p",[s._v("使用  "),a("code",[s._v("~/.ssh/config")])]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("Host vm\n User foobar\n HostName "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("172.16")]),s._v(".174.141\n Port "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2222")]),s._v("\n IdentityFile ~/.ssh/id_ed25519\n LocalForward "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("9999")]),s._v(" localhost:8888\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 在配置文件中也可以使用通配符")]),s._v("\nHost *.mit.edu\n User foobaz\n")])])]),a("p",[s._v("这么做的好处是,使用  "),a("code",[s._v("~/.ssh/config")]),s._v("  文件来创建别名,类似  "),a("code",[s._v("scp")]),s._v("、"),a("code",[s._v("rsync")]),s._v("和"),a("code",[s._v("mosh")]),s._v("的这些命令都可以读取这个配置并将设置转换为对应的命令行选项。")]),s._v(" "),a("p",[s._v("注意,"),a("code",[s._v("~/.ssh/config")]),s._v("  文件也可以被当作配置文件,而且一般情况下也是可以被导入其他配置文件的。不过,如果您将其公开到互联网上,那么其他人都将会看到您的服务器地址、用户名、开放端口等等。这些信息可能会帮助到那些企图攻击您系统的黑客,所以请务必三思。")]),s._v(" "),a("p",[s._v("服务器侧的配置通常放在  "),a("code",[s._v("/etc/ssh/sshd_config")]),s._v("。您可以在这里配置免密认证、修改 ssh 端口、开启 X11 转发等等。 您也可以为每个用户单独指定配置。")]),s._v(" "),a("h1",{attrs:{id:"_6-exercise"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_6-exercise"}},[s._v("#")]),s._v(" 6. Exercise")]),s._v(" "),a("h2",{attrs:{id:"_6-1-任务控制"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-任务控制"}},[s._v("#")]),s._v(" 6.1 任务控制")]),s._v(" "),a("h3",{attrs:{id:"_6-1-1-pgrep-pkill"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-1-pgrep-pkill"}},[s._v("#")]),s._v(" 6.1.1 pgrep & pkill")]),s._v(" "),a("p",[s._v("我们可以使用类似  "),a("code",[s._v("ps aux | grep")]),s._v("  这样的命令来获取任务的 pid ,然后您可以基于 pid 来结束这些进程。但我们其实有更好的方法来做这件事。在终端中执行  "),a("code",[s._v("sleep 10000")]),s._v("  这个任务。然后用  "),a("code",[s._v("Ctrl-Z")]),s._v("  将其切换到后台并使用  "),a("code",[s._v("bg")]),s._v("来继续允许它。现在,使用  "),a("code",[s._v("[pgrep](https://www.man7.org/linux/man-pages/man1/pgrep.1.html)")]),s._v("  来查找 pid 并使用  "),a("code",[s._v("[pkill](https://www.man7.org/linux/man-pages/man1/pgrep.1.html)")]),s._v("  结束进程而不需要手动输入 pid。(提示:: 使用  "),a("code",[s._v("-af")]),s._v("  标记)。")]),s._v(" "),a("p",[a("img",{attrs:{src:t(356),alt:"Untitled"}})]),s._v(" "),a("h3",{attrs:{id:"_6-1-2-pidwait"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-2-pidwait"}},[s._v("#")]),s._v(" 6.1.2 pidwait")]),s._v(" "),a("p",[s._v("如果您希望某个进程结束后再开始另外一个进程, 应该如何实现呢?在这个练习中,我们使用  "),a("code",[s._v("sleep 60 &")]),s._v("  作为先执行的程序。一种方法是使用  "),a("code",[s._v("[wait](http://man7.org/linux/man-pages/man1/wait.1p.html)")]),s._v("  命令。尝试启动这个休眠命令,然后待其结束后再执行  "),a("code",[s._v("ls")]),s._v("  命令。")]),s._v(" "),a("p",[s._v("但是,如果我们在不同的 bash 会话中进行操作,则上述方法就不起作用了。因为  "),a("code",[s._v("wait")]),s._v("  只能对子进程起作用。之前我们没有提过的一个特性是,"),a("code",[s._v("kill")]),s._v("  命令成功退出时其状态码为 0 ,其他状态则是非 0。"),a("code",[s._v("kill -0")]),s._v("  则不会发送信号,但是会在进程不存在时返回一个不为 0 的状态码。请编写一个 bash 函数  "),a("code",[s._v("pidwait")]),s._v(" ,它接受一个 pid 作为输入参数,然后一直等待直到该进程结束。您需要使用  "),a("code",[s._v("sleep")]),s._v("  来避免浪费 CPU 性能。")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#! /usr/bin/env zsh")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function-name function"}},[s._v("pidwait")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# here while loop will keep checking if the process is still running")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# if the process is still running, it will sleep for 1 second and then check again")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# if the process is not running, it will list the files in the current directory")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# kill -0 returns 0 if the process is running, 1 if the process is not running")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# while 0 is returned, the loop will keep running")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("while")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("kill")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-0")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("do")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sleep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("done")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ls")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),a("p",[a("img",{attrs:{src:t(357),alt:"Untitled"}})]),s._v(" "),a("h2",{attrs:{id:"_6-2-配置文件"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_6-2-配置文件"}},[s._v("#")]),s._v(" 6.2 配置文件")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#!/usr/bin/env zsh")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# copy.sh")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# copy all dotfiles to ./dotfiles")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# mkdir ./dotfiles if it doesn't exist")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-d")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"./dotfiles"')]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("then")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("mkdir")]),s._v(" ./dotfiles\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("fi")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cp")]),s._v(" ~/.zshrc ./dotfiles\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cp")]),s._v(" ~/.vimrc ./dotfiles\n\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Copied dotfiles to ./dotfiles"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ls")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-lah")]),s._v(" ./dotfiles\n")])])]),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#!/bin/bash")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# autoconfig.sh")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("files")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$(")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ls")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-a")]),s._v(" $1 "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-E")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'.[^.]+'")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-v")]),s._v(" .git"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v(")")])]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v('# 去掉 ls -a 返回结果中的 ". .. .git"')]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("for")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token for-or-select variable"}},[s._v("file")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("`")]),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" $files"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("`")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("do")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ln")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-s")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$1")]),s._v("/"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$file")]),s._v(" ~/"),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$file")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 创建软链接")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("done")]),s._v("\n")])])])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/38.8ed5cb63.js b/assets/js/38.8ed5cb63.js new file mode 100644 index 0000000..9f67625 --- /dev/null +++ b/assets/js/38.8ed5cb63.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[38],{241:function(t,n,e){"use strict";e.d(n,"d",(function(){return r})),e.d(n,"a",(function(){return s})),e.d(n,"i",(function(){return u})),e.d(n,"f",(function(){return a})),e.d(n,"g",(function(){return l})),e.d(n,"h",(function(){return c})),e.d(n,"b",(function(){return f})),e.d(n,"e",(function(){return h})),e.d(n,"k",(function(){return p})),e.d(n,"l",(function(){return d})),e.d(n,"c",(function(){return b})),e.d(n,"j",(function(){return m}));e(45);const r=/#.*$/,i=/\.(md|html)$/,s=/\/$/,u=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(r,"").replace(i,"")}function a(t){return u.test(t)}function l(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function f(t){if(a(t))return t;const n=t.match(r),e=n?n[0]:"",i=o(t);return s.test(i)?t:i+".html"+e}function h(t,n){const e=decodeURIComponent(t.hash),i=function(t){const n=t.match(r);if(n)return n[0]}(n);if(i&&e!==i)return!1;return o(t.path)===o(n)}function p(t,n,e){if(a(n))return{type:"external",path:n};e&&(n=function(t,n,e){const r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return n+t;const i=n.split("/");e&&i[i.length-1]||i.pop();const s=t.replace(/^\//,"").split("/");for(let t=0;tfunction t(n,e,r,i=1){if("string"==typeof n)return p(e,n,r);if(Array.isArray(n))return Object.assign(p(e,n[0],r),{title:n[1]});{const s=n.children||[];return 0===s.length&&n.path?Object.assign(p(e,n.path,r),{title:n.title}):{type:"group",path:n.path,title:n.title,sidebarDepth:n.sidebarDepth,initialOpenGroupIndex:n.initialOpenGroupIndex,children:s.map(n=>t(n,e,r,i+1)),collapsable:!1!==n.collapsable}}}(t,i,e)):[]}return[]}function g(t){const n=b(t.headers||[]);return[{type:"group",collapsable:!1,title:t.title,path:null,children:n.map(n=>({type:"auto",title:n.title,basePath:t.path,path:t.path+"#"+n.slug,children:n.children||[]}))}]}function b(t){let n;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?n=t:n&&(n.children||(n.children=[])).push(t)}),t.filter(t=>2===t.level)}function m(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},243:function(t,n,e){"use strict";e.r(n);var r=e(241),i={name:"NavLink",props:{item:{required:!0}},computed:{link(){return Object(r.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link},isNonHttpURI(){return Object(r.g)(this.link)||Object(r.h)(this.link)},isBlankTarget(){return"_blank"===this.target},isInternal(){return!Object(r.f)(this.link)&&!this.isBlankTarget},target(){return this.isNonHttpURI?null:this.item.target?this.item.target:Object(r.f)(this.link)?"_blank":""},rel(){return this.isNonHttpURI||!1===this.item.rel?null:this.item.rel?this.item.rel:this.isBlankTarget?"noopener noreferrer":null}},methods:{focusoutAction(){this.$emit("focusout")}}},s=e(14),u=Object(s.a)(i,(function(){var t=this,n=t._self._c;return t.isInternal?n("RouterLink",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(n){return t.focusoutAction.apply(null,arguments)}}},[t._v("\n "+t._s(t.item.text)+"\n")]):n("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.target,rel:t.rel},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),t.isBlankTarget?n("OutboundLink"):t._e()],1)}),[],!1,null,null,null);n.default=u.exports}}]); \ No newline at end of file diff --git a/assets/js/39.f19539b2.js b/assets/js/39.f19539b2.js new file mode 100644 index 0000000..e9ee4bd --- /dev/null +++ b/assets/js/39.f19539b2.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[39],{298:function(t,s,a){t.exports=a.p+"assets/img/mpb.b14b24ec.png"},393:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_10-verilog-多路分支语句"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_10-verilog-多路分支语句"}},[t._v("#")]),t._v(" 10. Verilog 多路分支语句")]),t._v(" "),s("h3",{attrs:{id:"关键词-case-选择器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#关键词-case-选择器"}},[t._v("#")]),t._v(" 关键词:case,选择器")]),t._v(" "),s("p",[t._v("case 语句是一种多路条件分支的形式,可以解决 if 语句中有多个条件选项时使用不方便的问题。")]),t._v(" "),s("h2",{attrs:{id:"case-语句"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#case-语句"}},[t._v("#")]),t._v(" case 语句")]),t._v(" "),s("p",[t._v("case 语句格式如下:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("case")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("case_expr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n condition1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" true_statement1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n condition2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" true_statement2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n ……\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" default_statement "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("endcase")]),t._v("\n")])])]),s("p",[t._v("case 语句执行时,如果 condition1 为真,则执行 true_statement1 ; 如果 condition1 为假,condition2 为真,则执行 true_statement2;依次类推。如果各个 condition 都不为真,则执行 default_statement 语句。")]),t._v(" "),s("p",[t._v("default 语句是可选的,且在一个 case 语句中不能有多个 default 语句。")]),t._v(" "),s("p",[t._v("条件选项可以有多个,不仅限于 condition1、condition2 等,而且这些条件选项不要求互斥。虽然这些条件选项是并发比较的,但执行效果是谁在前且条件为真谁被执行。")]),t._v(" "),s("p",[t._v("ture_statement1 等执行语句可以是一条语句,也可以是多条。如果是多条执行语句,则需要用 begin 与 end 关键字进行说明。")]),t._v(" "),s("h3",{attrs:{id:"case-语句支持嵌套使用。"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#case-语句支持嵌套使用。"}},[t._v("#")]),t._v(" case 语句支持嵌套使用。")]),t._v(" "),s("p",[t._v("下面用 case 语句代替 if 语句实现了一个 4 路选择器的功能。仿真结果与 testbench 可参考"),s("a",{attrs:{href:"https://www.runoob.com/w3cnote/verilog-condition-statement.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("条件语句"),s("OutboundLink")],1),t._v("一章,两者完全一致。")]),t._v(" "),s("h3",{attrs:{id:"实例"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("module")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mux4to1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" sel "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" p0 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" p1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" p2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" p3 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("output")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" sout"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token important"}},[t._v("always @")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("case")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b00")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("begin")]),t._v(" \n sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" p0 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("end")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b01")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" p1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" p2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" p3 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("endcase")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("assign")]),t._v(" sout "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("endmodule")]),t._v("\n")])])]),s("p",[t._v("case 语句中的条件选项表单式不必都是常量,也可以是 x 值或 z 值。")]),t._v(" "),s("p",[t._v("当多个条件选项下需要执行相同的语句时,多个条件选项可以用逗号分开,放在同一个语句块的候选项中。")]),t._v(" "),s("h3",{attrs:{id:"例如-对-4-路选择器的-case-语句进行扩展-举例如下"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#例如-对-4-路选择器的-case-语句进行扩展-举例如下"}},[t._v("#")]),t._v(" 例如,对 4 路选择器的 case 语句进行扩展,举例如下:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("case")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b00")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" p0 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b01")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" p1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" p2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b11")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" p3 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'bx0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'bx1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'bxz")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'bxx")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b0x")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b1x")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'bzx")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'bxx")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'bz0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'bz1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'bzz")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b0z")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b1z")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'bzz")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token kernel-function property"}},[t._v("$display")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Unexpected input control!!!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("endcase")]),t._v("\n")])])]),s("h2",{attrs:{id:"casex-casez-语句"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#casex-casez-语句"}},[t._v("#")]),t._v(" "),s("code",[t._v("casex")]),t._v("/"),s("code",[t._v("casez")]),t._v(" 语句")]),t._v(" "),s("p",[t._v("casex、 casez 语句是 case 语句的变形,用来表示条件选项中的无关项。")]),t._v(" "),s("p",[t._v('casex 用 "x" 来表示无关值,casez 用问号 "?" 来表示无关值。')]),t._v(" "),s("p",[t._v("两者的实现的功能是完全一致的,语法与 case 语句也完全一致。")]),t._v(" "),s("ol",[s("li",[t._v("在 case 语句中,敏感表达式中与各项值之间的比较是一种全等比较,每一位都相同才认为匹配。")]),t._v(" "),s("li",[t._v("在 casez 语句中,如果分支表达式某些位的值为高阻 z,那么对这些位的比较就会忽略,不予考虑,而只关注其他位的比较结果。")]),t._v(" "),s("li",[t._v("在 casex 语句中,则把这种处理方式进一步扩展到对 x 的处理,即如果比较双方有一方的某些位的值是 z 或 x,那么这些位的比较就不予考虑。")])]),t._v(" "),s("p",[s("img",{attrs:{src:a(298),alt:"Untitled"}})]),t._v(" "),s("h3",{attrs:{id:"例如用-casez-语句来实现一个-4bit-控制端的-4-路选择选择器。"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#例如用-casez-语句来实现一个-4bit-控制端的-4-路选择选择器。"}},[t._v("#")]),t._v(" 例如用 casez 语句来实现一个 4bit 控制端的 4 路选择选择器。")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("module")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mux4to1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" sel "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" p0 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" p1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" p2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" p3 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("output")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" sout"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token important"}},[t._v("always @")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("casez")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'b???1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" p0 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'b??1?")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" p1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'b?1??")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" p2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'b1???")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" p3 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("endcase")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("assign")]),t._v(" sout "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" sout_t "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("endmodule")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/4.fb4fd8cb.js b/assets/js/4.fb4fd8cb.js new file mode 100644 index 0000000..122d706 --- /dev/null +++ b/assets/js/4.fb4fd8cb.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{279:function(t,e,n){},293:function(t,e,n){"use strict";n(279)},385:function(t,e,n){"use strict";n.r(e);var i={functional:!0,props:{type:{type:String,default:"tip"},text:String,vertical:{type:String,default:"top"}},render:(t,{props:e,slots:n})=>t("span",{class:["badge",e.type],style:{verticalAlign:e.vertical}},e.text||n().default)},p=(n(293),n(14)),l=Object(p.a)(i,void 0,void 0,!1,null,"15b7b770",null);e.default=l.exports}}]); \ No newline at end of file diff --git a/assets/js/40.d3bb046d.js b/assets/js/40.d3bb046d.js new file mode 100644 index 0000000..387688a --- /dev/null +++ b/assets/js/40.d3bb046d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{299:function(t,a,s){t.exports=s.p+"assets/img/Arbiter.0f715328.png"},396:function(t,a,s){"use strict";s.r(a);var n=s(14),p=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"_2024-02-24-2-2-combinational-logic"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-24-2-2-combinational-logic"}},[t._v("#")]),t._v(" 2024.02.24-2.2 Combinational Logic")]),t._v(" "),a("h2",{attrs:{id:"common-operators"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#common-operators"}},[t._v("#")]),t._v(" Common Operators")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" MyModule "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Scala expression")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" two "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n println"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("two"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Chisel expression")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" utwo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U\n println"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("utwo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// incorrect")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" twotwo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" MyOperators "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out_add "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out_sub "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out_mul "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out_add "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("U\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out_sub "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("U "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out_mul "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("U "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("U\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 没有参数时可以省略小括号")]),t._v("\ntest"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" MyOperators"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("c "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out_add"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out_sub"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out_mul"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h2",{attrs:{id:"mux-and-concatenation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mux-and-concatenation"}},[t._v("#")]),t._v(" Mux and Concatenation")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" MyOperatorsTwo "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out_mux "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out_cat "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" s "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out_mux "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Mux"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// should return 3.U, since s is true")]),t._v("\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out_cat "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Cat"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// concatenates 2 (b10) with 1 (b1) to give 5 (101)")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nprintln"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getVerilog"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" MyOperatorsTwo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\ntest"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" MyOperatorsTwo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out_mux"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out_cat"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("The "),a("code",[t._v("Mux")]),t._v(" operates like a traditional ternary operator, with the order (select, value if true, value if false)")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("Cat")]),t._v(" ordering is MSB then LSB (where B refers to bit or bits), and only takes two arguments.")]),t._v(" "),a("h2",{attrs:{id:"mac-multiply-accumulate-function"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mac-multiply-accumulate-function"}},[t._v("#")]),t._v(" MAC: multiply accumulate function")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" MAC "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_b "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_c "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_b"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_c\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\ntest"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" MAC"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" cycles "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("scala"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("util"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("Random\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until cycles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Random"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("16")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_b "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Random"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("16")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_c "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Random"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("16")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in_a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_b"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in_b"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in_c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in_a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" in_b "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" in_c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h2",{attrs:{id:"arbiter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#arbiter"}},[t._v("#")]),t._v(" Arbiter")]),t._v(" "),a("p",[t._v("The following circuit arbitrates data coming from a FIFO into two parallel processing units. The FIFO and processing elements (PEs) communicate with ready-valid interfaces. Construct the arbiter to send data to whichever PE is ready to receive data, prioritizing PE0 if both are ready to receive data. Remember that the arbiter should tell the FIFO that it's ready to receive data when at least one of the PEs can receive data. Also, wait for a PE to assert that it's ready before asserting that the data are valid. You will likely need binary operators to complete this exercise.")]),t._v(" "),a("p",[a("img",{attrs:{src:s(299),alt:"Untitled"}})]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Arbiter "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// FIFO")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" fifo_valid "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" fifo_ready "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" fifo_data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// PE0")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" pe0_valid "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" pe0_ready "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" pe0_data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// PE1")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" pe1_valid "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" pe1_ready "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" pe1_data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fifo_ready "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe0_ready "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe1_ready\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe0_valid "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fifo_valid "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe0_ready\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe1_valid "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fifo_valid "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe0_ready "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe1_ready\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe0_data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fifo_data\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe1_data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fifo_data\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\ntest"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Arbiter"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("scala"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("util"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("Random\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Random"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("65536")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fifo_data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fifo_valid"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe0_ready"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe1_ready"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fifo_ready"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe0_valid"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" i "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe1_valid"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" i "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe0_data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pe1_data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nprintln"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SUCCESS!!"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("数据线(如"),a("code",[t._v("io.pe0_data")]),t._v(" 和 "),a("code",[t._v("io.pe1_data")]),t._v(")通常会持续地带有它们可能需要使用的数据信号(本例中为"),a("code",[t._v("io.fifo_data")]),t._v(")。但是,这些数据是否被“接收”或“采用”通常由"),a("code",[t._v("valid")]),t._v("信号来控制。")]),t._v(" "),a("p",[t._v("测试代码设计用来验证"),a("code",[t._v("Arbiter")]),t._v("模块的行为。测试通过随机生成一个数据,然后使用不同的组合的"),a("code",[t._v("fifo_valid")]),t._v(","),a("code",[t._v("pe0_ready")]),t._v("和"),a("code",[t._v("pe1_ready")]),t._v("信号来模拟不同的工作情况。")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("c.io.fifo_data.poke(data.U)")]),t._v("模拟从 FIFO 发送的数据。")]),t._v(" "),a("li",[t._v("循环"),a("code",[t._v("for (i <- 0 until 8)")]),t._v("遍历 8 种不同的信号组合状态。")]),t._v(" "),a("li",[a("code",[t._v("c.io.fifo_valid.poke")]),t._v(","),a("code",[t._v("c.io.pe0_ready.poke")]),t._v("和"),a("code",[t._v("c.io.pe1_ready.poke")]),t._v("根据"),a("code",[t._v("i")]),t._v("的不同值模拟不同的信号状态,使用位操作来确定每个信号是否应该被激活。")]),t._v(" "),a("li",[a("code",[t._v("c.io.fifo_ready.expect")]),t._v(","),a("code",[t._v("c.io.pe0_valid.expect")]),t._v("和"),a("code",[t._v("c.io.pe1_valid.expect")]),t._v("是对仲裁器预期行为的断言检查。")]),t._v(" "),a("li",[t._v("如果"),a("code",[t._v("i")]),t._v("的值表示 PE0 或 PE1 应该接收数据(如"),a("code",[t._v("i == 3 || i == 7")]),t._v("是 PE0,"),a("code",[t._v("i == 5")]),t._v("是 PE1),则使用"),a("code",[t._v("expect")]),t._v("断言来检查"),a("code",[t._v("io.pe0_data")]),t._v("或"),a("code",[t._v("io.pe1_data")]),t._v("与 FIFO 的数据相同。")])]),t._v(" "),a("h2",{attrs:{id:"parameterized-adder"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#parameterized-adder"}},[t._v("#")]),t._v(" Parameterized Adder")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" ParameterizedAdder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("saturate"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_b "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" sum "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_b\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("saturate"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Mux"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sum"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("15.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("15.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("sum"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" sum\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("saturate "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" Seq"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n test"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" ParameterizedAdder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("saturate"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 100 random tests")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" cycles "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("scala"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("util"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("Random\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("scala"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("math"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("min")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until cycles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Random"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("16")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_b "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Random"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextInt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("16")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in_a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_b"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in_b"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("saturate"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("min"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in_a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" in_b"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("15")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in_a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" in_b"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("16")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ensure we test saturation vs. truncation")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("15.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_b"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("15.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("saturate"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("15.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("14.")]),t._v("U"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nprintln"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SUCCESS!!"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("在 Chisel 中,"),a("code",[t._v("+&")]),t._v("是一个用于加法的运算符,它会考虑输入的进位,得到一个比最大输入位宽更宽的结果。如果输入是 4 位"),a("code",[t._v("UInt")]),t._v(",标准加法结果"),a("code",[t._v("io.in_a + io.in_b")]),t._v("会是 4 位,可能会截断超出的位。而"),a("code",[t._v("+&")]),t._v("加法会产生一个 5 位的结果,这可以用于在必要时实现饱和加法逻辑。连接一个 4 位的"),a("code",[t._v("UInt")]),t._v("线到一个 5 位的"),a("code",[t._v("UInt")]),t._v("线(一个 4.W 的量等于 5.W 的量),默认会截断最高位(MSB)。这样,你可以用这个方法来轻松实现非饱和加法器,只保留 5 位和的低 4 位。")])])}),[],!1,null,null,null);a.default=p.exports}}]); \ No newline at end of file diff --git a/assets/js/41.21ba8adf.js b/assets/js/41.21ba8adf.js new file mode 100644 index 0000000..328de46 --- /dev/null +++ b/assets/js/41.21ba8adf.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[41],{300:function(t,s,a){t.exports=a.p+"assets/img/FSM.a8105ac5.png"},397:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-02-25-2-3-control-flow"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-25-2-3-control-flow"}},[t._v("#")]),t._v(" 2024.02.25-2.3 Control Flow")]),t._v(" "),s("h2",{attrs:{id:"last-connect-semantics"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#last-connect-semantics"}},[t._v("#")]),t._v(" Last Connect Semantics")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" LastConnect "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("U\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.")]),t._v("U\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("U\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Test LastConnect")]),t._v("\ntest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" LastConnect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("当有多个值被赋值给一个量时,最后的那个生效")]),t._v(" "),s("h2",{attrs:{id:"when-elsewhen-and-otherwise"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#when-elsewhen-and-otherwise"}},[t._v("#")]),t._v(" "),s("code",[t._v("when")]),t._v(", "),s("code",[t._v("elsewhen")]),t._v(", and "),s("code",[t._v("otherwise")])]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("someBooleanCondition"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// things to do when true")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("elsewhen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("someOtherBooleanCondition"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// things to do on this condition")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// things to do if none of th boolean conditions are true")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("code",[t._v("when")]),t._v("是一种特殊的构造,它用于硬件生成。它类似于软件编程中的"),s("code",[t._v("if")]),t._v("语句,但是在硬件描述中,"),s("code",[t._v("when")]),t._v("会生成实际的硬件逻辑,如多路复用器。而标准的"),s("code",[t._v("if")]),t._v("语句通常用于生成时(编译时)的控制流,并不直接生成硬件。"),s("code",[t._v("if")]),t._v("语句在 Scala(因此在 Chisel 的生成时)可以有返回值,可以用于赋值或者作为表达式的一部分。相比之下,"),s("code",[t._v("when")]),t._v("是一种专门为硬件设计提供的控制结构,用于生成条件硬件逻辑,如多路复用器或条件赋值,但它不返回值。因此,当你需要根据输入信号在运行时动态地选择硬件行为时,你会使用"),s("code",[t._v("when")]),t._v("。而当你在编译时根据某些条件生成不同的硬件模块时,你会使用"),s("code",[t._v("if")]),t._v("。")]),t._v(" "),s("p",[t._v("在 Scala 中,"),s("code",[t._v("==")]),t._v("用于基本类型和对象的相等性比较,而在 Chisel 中(一个建立在 Scala 之上的硬件构建语言),"),s("code",[t._v("===")]),t._v("用于硬件信号之间的相等性比较。这是因为 Chisel 需要区分硬件操作和 Scala 的软件操作,"),s("code",[t._v("===")]),t._v("在 Chisel 中被定义为生成硬件电路中的等于比较逻辑。而在 Scala 的"),s("code",[t._v("if")]),t._v("语句中,"),s("code",[t._v("==")]),t._v("仍然用于比较两个值是否相等。这种区分确保了代码的清晰性,以及硬件设计中逻辑正确性的维护。因此,在"),s("code",[t._v("when")]),t._v("中使用"),s("code",[t._v("===")]),t._v("来生成判断相等的硬件电路")]),t._v(" "),s("h2",{attrs:{id:"the-wire-construct"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#the-wire-construct"}},[t._v("#")]),t._v(" The "),s("code",[t._v("Wire")]),t._v(" Construct")]),t._v(" "),s("p",[s("code",[t._v("Wire")]),t._v("是一种基本的硬件构造类型,用于创建一个可以在模块内部读取和写入的信号。它主要用于表示组合逻辑或暂存数据,允许在硬件描述中定义中间变量或内部连接。使用"),s("code",[t._v("Wire")]),t._v("时,需要指定信号的数据类型,如"),s("code",[t._v("UInt")]),t._v("或"),s("code",[t._v("SInt")]),t._v("等。"),s("code",[t._v("Wire")]),t._v("类型的变量在定义时不持有初始值,需要在逻辑中显式赋值。在使用过程中,可以根据需要多次对其赋值,但在每个时钟周期结束时,"),s("code",[t._v("Wire")]),t._v("仅保留最后一次赋值的结果。"),s("code",[t._v("val myWire = Wire(UInt(32.W))")])]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("permutations"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("foreach "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" i0 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" i1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" i2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" i3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" Nil "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sorting ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("i0")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("i1")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("i2")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("i3")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("permutations"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("foreach "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" i0 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" i1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" i2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" _ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" Nil "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sorting ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("i0")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("i1")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("i2")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("使用 Scala 的集合和模式匹配功能来遍历"),s("code",[t._v("List(1, 2, 3, 4)")]),t._v("的所有排列组合。"),s("code",[t._v("List(1, 2, 3, 4).permutations")]),t._v("生成一个包含所有可能排列的列表的迭代器。"),s("code",[t._v("foreach")]),t._v("循环遍历这些排列。")]),t._v(" "),s("p",[t._v("在"),s("code",[t._v("foreach")]),t._v("的代码块中,"),s("code",[t._v("case i0 :: i1 :: i2 :: i3 :: Nil =>")]),t._v("是一个模式匹配表达式,用于解构每个排列列表。这个表达式匹配一个包含四个元素的列表,将这四个元素分别绑定到变量"),s("code",[t._v("i0")]),t._v("、"),s("code",[t._v("i1")]),t._v("、"),s("code",[t._v("i2")]),t._v("、"),s("code",[t._v("i3")]),t._v("。"),s("code",[t._v("Nil")]),t._v("在这里表示列表的末尾,确保列表只有这四个元素。这种方式允许直接访问每个排列中的元素,然后可以将它们打印出来或用于其他逻辑操作。")]),t._v(" "),s("h3",{attrs:{id:"exercise-polynomial"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#exercise-polynomial"}},[t._v("#")]),t._v(" Exercise: Polynomial")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Polynomial "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" select "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("SInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" fOfX "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("SInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("SInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" square "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("SInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n square "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x\n when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("select "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" square "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("S "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("S\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("elsewhen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("select "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("S "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" square "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("6.")]),t._v("S "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.")]),t._v("S\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("S "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" square "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("S "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5.")]),t._v("S\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fOfX "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" result\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Test Polynomial")]),t._v("\ntest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Polynomial"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" to "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("select "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" to "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("select"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("select"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("S"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fOfX"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("poly"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("select"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("S"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"exercise-finite-state-machine"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#exercise-finite-state-machine"}},[t._v("#")]),t._v(" Exercise: Finite State Machine")]),t._v(" "),s("p",[t._v("Grad students pass through four states in their career: Idle, Coding, Writing, and Graduating. These states transition based off three inputs: Coffee, Ideas they come up with, and Pressure from their advisor to make progress. Once they Graduate, they return to the Idle state. The FSM diagram below shows these states and transitions. Any unlabelled transition (i.e. when there are no inputs) returns a grad student to the Idle state instead of staying in the current state. The input precedence is coffee > idea > pressure, so when in the Idle state and receiving both coffee and pressure, a graduate student will move to the Coding state.")]),t._v(" "),s("p",[s("img",{attrs:{src:a(300),alt:"Untitled"}})]),t._v(" "),s("p",[t._v("检查逻辑:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// state map")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" states "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"idle"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"coding"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"writing"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"grad"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// life is full of question marks")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" gradLife "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" coffee"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" idea"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" pressure"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"idle"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"idle"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("coffee"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"coding"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("idea"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"idle"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("pressure"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"writing"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"idle"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"coding"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("coffee"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"coding"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("idea"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"writing"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("pressure"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"writing"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"idle"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"writing"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("coffee"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"writing"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("idea"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"writing"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("pressure"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"grad"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"idle"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n nextState\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// some sanity checks")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("size"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("foreach"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" state "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("gradLife"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"idle"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nassert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("gradLife"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"writing"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"writing"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nassert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("gradLife"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"idle"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"coding"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nassert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("gradLife"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"idle"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"idle"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nassert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("gradLife"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"grad"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"idle"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("Chisel:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" GradLife "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" coffee "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" idea "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" pressure "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" idle "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" coding "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" writing "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" grad "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" Nil "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Enum"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" idle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("coffee"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" coding"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("elsewhen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("idea"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" idle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("elsewhen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pressure"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" writing"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" idle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("elsewhen "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" coding"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n when "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("coffee"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" coding "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("elsewhen "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("idea "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pressure"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" writing "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" idle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("elsewhen "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" writing"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n when "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("coffee "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("idea"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" writing "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("elsewhen "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pressure"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" grad "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" idle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextState "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" idle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Test")]),t._v("\ntest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" GradLife"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// verify that the hardware matches the golden model")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" to "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("coffee "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("idea "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("pressure "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("coffee"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("coffee"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("idea"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("idea"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pressure"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("pressure"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextState"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("gradLife"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" coffee"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" idea"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" pressure"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/42.3356861f.js b/assets/js/42.3356861f.js new file mode 100644 index 0000000..525acef --- /dev/null +++ b/assets/js/42.3356861f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{301:function(t,s,a){t.exports=a.p+"assets/img/ShiftRegister.c44a0985.svg"},399:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-02-26-2-4-sequential-logic"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-26-2-4-sequential-logic"}},[t._v("#")]),t._v(" 2024.02.26-2.4 Sequential Logic")]),t._v(" "),s("h2",{attrs:{id:"registers"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#registers"}},[t._v("#")]),t._v(" Registers")]),t._v(" "),s("p",[t._v("A "),s("code",[t._v("Reg")]),t._v(" holds its output value until the rising edge of its clock, at which time it takes on the value of its input.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" RegisterModule "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// val register : UInt = Reg(UInt(12.W))")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" register "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Reg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n register "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" register\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\ntest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" RegisterModule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SUCCESS!!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("Notice: One important note is that Chisel distinguishes between types (like "),s("code",[t._v("UInt")]),t._v(") and hardware nodes (like the literal "),s("code",[t._v("2.U")]),t._v(", or the output of "),s("code",[t._v("myReg")]),t._v(").")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// legal because a Reg needs a data type as a model")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myReg "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Reg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// error because `2.U` is already a hardware node and can't be used as a model")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myReg "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Reg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h3",{attrs:{id:"reginit"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#reginit"}},[t._v("#")]),t._v(" "),s("code",[t._v("RegInit")])]),t._v(" "),s("p",[t._v("The register in "),s("code",[t._v("RegisterModule")]),t._v(" was initialized to random data for simulation. Unless otherwised specified, registers do not have a reset value (or a reset). The way to create a register that resets to a given value is with "),s("code",[t._v("RegInit")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// The first argument is a type node that specified the datatype and its width.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// The second argument is a hardware node that specified the reset value, in this case 0.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myReg "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// It is a hardware node that specifies the reset value, but normally `0.U`.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myReg "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[s("code",[t._v("RegInit")]),t._v(" 不仅初始化,也创建了这个 reg,因此不需要先创建再 init")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" RegInitModule "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" register "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n register "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" register\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"regnext"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#regnext"}},[t._v("#")]),t._v(" "),s("code",[t._v("RegNext")])]),t._v(" "),s("p",[s("code",[t._v("RegNext")]),t._v(" 在 Chisel 中是一个用于创建寄存器并在下一个时钟周期将输入信号的值传递给该寄存器的便捷方法。它简化了寄存器的声明和初始化,使得您可以轻松地创建一个将当前输入信号的值保存到下一个时钟周期的寄存器。使用"),s("code",[t._v("RegNext")]),t._v("时,可以指定一个初始值,如果不指定,则寄存器在复位时的值是未定义的")]),t._v(" "),s("p",[t._v("在 Chisel 中使用 "),s("code",[t._v("RegNext")]),t._v(" 的基本语法如下:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myReg "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegNext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("inputSignal"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" initValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("ul",[s("li",[s("code",[t._v("inputSignal")]),t._v(" 是你希望在下一个时钟周期传递给寄存器的信号。")]),t._v(" "),s("li",[s("code",[t._v("initValue")]),t._v(" 是可选参数,用于指定寄存器在复位时的初始值。如果不提供初始值,寄存器在复位时的值是未定义的。")])]),t._v(" "),s("h2",{attrs:{id:"shift-register"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#shift-register"}},[t._v("#")]),t._v(" Shift Register")]),t._v(" "),s("p",[s("img",{attrs:{src:a(301),alt:"Untitled"}})]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" MyShiftRegister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" init"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" init"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" stateTemp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("asUInt\n state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" stateTemp\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\ntest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" MyShiftRegister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("init\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// poke in LSB of i (i % 2)")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// update expected state")]),t._v("\n state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0xf")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SUCCESS!!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h3",{attrs:{id:"parameterized-shift-register"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameterized-shift-register"}},[t._v("#")]),t._v(" Parameterized Shift Register")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// n is the output width (number of delays - 1)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// init state to init")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" MyOptionalShiftRegister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" init"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" BigInt "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" en "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("init"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("en"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" state\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test different depths")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("24")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("65")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Testing n=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("i")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" MyOptionalShiftRegister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" inSeq "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("init\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("en"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// poke in repeated inSeq")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" toPoke "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" inSeq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" inSeq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("toPoke "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// update expected state")]),t._v("\n state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" toPoke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" BigInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SUCCESS!!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("Notice: Chisel 中变量被声明为常量"),s("code",[t._v("val")]),t._v(",因此一个变量只能被赋值一次,因为这表示硬件电路连接,但是会根据输入等的不同而具有不同的值。因此不能多次给一个变量赋值,如果需要,可以把中间值重新命名为一个"),s("code",[t._v("val")]),t._v("来调用")]),t._v(" "),s("h2",{attrs:{id:"appendix-explicit-clock-and-reset"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#appendix-explicit-clock-and-reset"}},[t._v("#")]),t._v(" Appendix: Explicit clock and reset")]),t._v(" "),s("p",[t._v("Chisel 模块默认使用隐式的时钟和复位信号,每个内部创建的寄存器都会使用这些默认信号。在某些情况下,你可能需要覆盖这种默认行为,比如使用生成时钟或复位信号的黑盒,或者设计多时钟系统。Chisel 提供了"),s("code",[t._v("withClock() {}")]),t._v("、"),s("code",[t._v("withReset() {}")]),t._v("和"),s("code",[t._v("withClockAndReset() {}")]),t._v("等构造来处理这些情况,允许分别或同时覆盖时钟和复位。需要注意的是,至本教程编写时,复位信号总是同步的并且是"),s("code",[t._v("Bool")]),t._v("类型。时钟在 Chisel 中有其自身的类型("),s("code",[t._v("Clock")]),t._v("),并且应该相应声明。"),s("code",[t._v("Bool")]),t._v("类型可以通过调用"),s("code",[t._v("asClock()")]),t._v("转换为"),s("code",[t._v("Clock")]),t._v("类型,但需要确保这样做是合理的。同时,"),s("code",[t._v("chisel-testers")]),t._v("目前对多时钟设计的支持并不完全。")]),t._v(" "),s("h3",{attrs:{id:"example-multi-clock-module"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-multi-clock-module"}},[t._v("#")]),t._v(" Example: Multi-Clock Module")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we need to import multi-clock features")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("chisel3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("experimental"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("withClock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" withReset"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" withClockAndReset"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" ClockExamples "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" alternateReset "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" alternateClock "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" outImplicit "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" outAlternateReset "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" outAlternateClock "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" outAlternateBoth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" imp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n imp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("outImplicit "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" imp\n\n withReset"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("alternateReset"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// everything in this scope with have alternateReset as the reset")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" altRst "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n altRst "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("outAlternateReset "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" altRst\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n withClock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("alternateClock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" altClk "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n altClk "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("outAlternateClock "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" altClk\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n withClockAndReset"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("alternateClock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("alternateReset"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" alt "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n alt "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("outAlternateBoth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" alt\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getVerilog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" ClockExamples"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("通过"),s("code",[t._v("import chisel3.experimental.{withClock, withReset, withClockAndReset}")]),t._v("引入了多时钟特性。"),s("code",[t._v("ClockExamples")]),t._v("模块定义了一个 10 位宽的输入"),s("code",[t._v("io.in")]),t._v(",以及替代的复位和时钟信号"),s("code",[t._v("io.alternateReset")]),t._v("和"),s("code",[t._v("io.alternateClock")]),t._v("。模块输出了四种不同情况下的寄存器值:使用默认时钟和复位、只替换复位、只替换时钟、同时替换时钟和复位。")]),t._v(" "),s("ol",[s("li",[s("code",[t._v("withReset(io.alternateReset) {...}")]),t._v("块定义了一个新的作用域,其中所有寄存器的复位信号被替换为"),s("code",[t._v("io.alternateReset")]),t._v("。在这个作用域内,"),s("code",[t._v("altRst")]),t._v("寄存器在被替代复位信号复位时初始化为 0,并在每个时钟周期将"),s("code",[t._v("io.in")]),t._v("的值赋给它。")]),t._v(" "),s("li",[s("code",[t._v("withClock(io.alternateClock) {...}")]),t._v("块定义了另一个作用域,其中所有寄存器的时钟信号被替换为"),s("code",[t._v("io.alternateClock")]),t._v("。在这个作用域内,"),s("code",[t._v("altClk")]),t._v("寄存器在被替代时钟信号驱动时初始化为 0,并在每个时钟周期将"),s("code",[t._v("io.in")]),t._v("的值赋给它。")]),t._v(" "),s("li",[s("code",[t._v("withClockAndReset(io.alternateClock, io.alternateReset) {...}")]),t._v("块同时替换了寄存器的时钟和复位信号为"),s("code",[t._v("io.alternateClock")]),t._v("和"),s("code",[t._v("io.alternateReset")]),t._v("。在这个作用域内,"),s("code",[t._v("alt")]),t._v("寄存器同时被替代的时钟和复位信号控制,初始化为 0,并在每个时钟周期将"),s("code",[t._v("io.in")]),t._v("的值赋给它。")])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/43.a0c5e0dc.js b/assets/js/43.a0c5e0dc.js new file mode 100644 index 0000000..95f38ec --- /dev/null +++ b/assets/js/43.a0c5e0dc.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[43],{304:function(t,s,a){t.exports=a.p+"assets/img/FIR.5888a130.jpeg"},401:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-02-28-2-5-fir-filter"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-28-2-5-fir-filter"}},[t._v("#")]),t._v(" 2024.02.28-2.5 FIR Filter")]),t._v(" "),s("p",[s("img",{attrs:{src:a(304),alt:"Untitled"}})]),t._v(" "),s("p"),s("p",[s("mjx-container",{staticClass:"MathJax",attrs:{jax:"CHTML",display:"true"}},[s("mjx-math",{staticClass:"MJX-TEX",attrs:{display:"true"}},[s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"y"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"["}})],1),s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"n"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"]"}})],1),s("mjx-mo",{staticClass:"mjx-n",attrs:{space:"4"}},[s("mjx-c",{attrs:{c:"="}})],1),s("mjx-msub",{attrs:{space:"4"}},[s("mjx-mi",{staticClass:"mjx-i",attrs:{noIC:"true"}},[s("mjx-c",{attrs:{c:"b"}})],1),s("mjx-script",{staticStyle:{"vertical-align":"-0.15em"}},[s("mjx-mn",{staticClass:"mjx-n",attrs:{size:"s"}},[s("mjx-c",{attrs:{c:"0"}})],1)],1)],1),s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"x"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"["}})],1),s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"n"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"]"}})],1),s("mjx-mo",{staticClass:"mjx-n",attrs:{space:"3"}},[s("mjx-c",{attrs:{c:"+"}})],1),s("mjx-msub",{attrs:{space:"3"}},[s("mjx-mi",{staticClass:"mjx-i",attrs:{noIC:"true"}},[s("mjx-c",{attrs:{c:"b"}})],1),s("mjx-script",{staticStyle:{"vertical-align":"-0.15em"}},[s("mjx-mn",{staticClass:"mjx-n",attrs:{size:"s"}},[s("mjx-c",{attrs:{c:"1"}})],1)],1)],1),s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"x"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"["}})],1),s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"n"}})],1),s("mjx-mo",{staticClass:"mjx-n",attrs:{space:"3"}},[s("mjx-c",{attrs:{c:"2212"}})],1),s("mjx-mn",{staticClass:"mjx-n",attrs:{space:"3"}},[s("mjx-c",{attrs:{c:"1"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"]"}})],1),s("mjx-mo",{staticClass:"mjx-n",attrs:{space:"3"}},[s("mjx-c",{attrs:{c:"+"}})],1),s("mjx-msub",{attrs:{space:"3"}},[s("mjx-mi",{staticClass:"mjx-i",attrs:{noIC:"true"}},[s("mjx-c",{attrs:{c:"b"}})],1),s("mjx-script",{staticStyle:{"vertical-align":"-0.15em"}},[s("mjx-mn",{staticClass:"mjx-n",attrs:{size:"s"}},[s("mjx-c",{attrs:{c:"2"}})],1)],1)],1),s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"x"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"["}})],1),s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"n"}})],1),s("mjx-mo",{staticClass:"mjx-n",attrs:{space:"3"}},[s("mjx-c",{attrs:{c:"2212"}})],1),s("mjx-mn",{staticClass:"mjx-n",attrs:{space:"3"}},[s("mjx-c",{attrs:{c:"2"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"]"}})],1),s("mjx-mo",{staticClass:"mjx-n",attrs:{space:"3"}},[s("mjx-c",{attrs:{c:"+"}})],1),s("mjx-mo",{staticClass:"mjx-n",attrs:{space:"3"}},[s("mjx-c",{attrs:{c:"22EF"}})],1)],1)],1)],1),s("p"),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" My4ElementFir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("b0"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b3"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" reg_1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" reg_2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" reg_3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n reg_1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n reg_2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" reg_1\n reg_3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" reg_2\n\n\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 或者使用RegNext来一并定义初始化及赋值")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" reg_1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegNext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" reg_2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegNext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reg_1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" reg_3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegNext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reg_2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" b0"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" reg_1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" reg_2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" reg_3\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"fir-filter-generator"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#fir-filter-generator"}},[t._v("#")]),t._v(" FIR Filter Generator")]),t._v(" "),s("p",[t._v("一个有限脉冲响应(FIR)滤波器生成器。生成器的"),s("code",[t._v("length")]),t._v("参数决定了滤波器的抽头数目,即滤波器的长度。这个生成器有三个输入:"),s("code",[t._v("in")]),t._v("(滤波器的输入信号)、"),s("code",[t._v("valid")]),t._v("(一个布尔值,表示输入是否有效)和"),s("code",[t._v("consts")]),t._v("(一个向量,包含所有抽头的系数)。还有一个输出"),s("code",[t._v("out")]),t._v(",即滤波器的输出。")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("taps")]),t._v("是一个序列,包含输入和一系列寄存器,用于实现滤波器的延迟线。")]),t._v(" "),s("li",[t._v("当"),s("code",[t._v("valid")]),t._v("信号为真时,序列中的每个元素(除了第一个)被更新为前一个元素的值。")]),t._v(" "),s("li",[t._v("输出"),s("code",[t._v("out")]),t._v("是抽头值和对应系数乘积之和。")])]),t._v(" "),s("p",[t._v("这个结构允许滤波器动态处理不同长度的输入,通过改变"),s("code",[t._v("consts")]),t._v("向量的内容来改变滤波器的特性。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" MyManyDynamicElementVecFir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" valid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" consts "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Such concision! You'll learn what all this means later.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" taps "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fill"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("consts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n taps"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zip"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("taps"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tail"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("foreach "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" when "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" taps"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zip"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("consts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reduce"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nvisualize"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" MyManyDynamicElementVecFir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("ol",[s("li",[s("p",[s("code",[t._v("val io = IO(new Bundle {...})")]),t._v("定义了模块的接口,包括 8 位宽的输入"),s("code",[t._v("in")]),t._v(",一个有效信号"),s("code",[t._v("valid")]),t._v(",8 位宽输出"),s("code",[t._v("out")]),t._v(",和长度为"),s("code",[t._v("length")]),t._v("的系数向量"),s("code",[t._v("consts")]),t._v("。")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("val taps = Seq(io.in) ++ Seq.fill(io.consts.length - 1)(RegInit(0.U(8.W)))")]),t._v("这行代码在 FIR 滤波器实现中创建了一个名为"),s("code",[t._v("taps")]),t._v("的序列,用于存储当前和之前的输入值,从而实现数据的时间序列延迟。首先,它将输入信号"),s("code",[t._v("io.in")]),t._v("作为序列的第一个元素。随后,使用"),s("code",[t._v("++")]),t._v("操作符将"),s("code",[t._v("io.in")]),t._v("与一个新的序列连接起来,后者通过"),s("code",[t._v("Seq.fill(io.consts.length - 1)(RegInit(0.U(8.W)))")]),t._v("创建,其中包含"),s("code",[t._v("length - 1")]),t._v("个初始化为 0 的 8 位寄存器。这样,"),s("code",[t._v("taps")]),t._v("序列就包含了一个输入信号和"),s("code",[t._v("length - 1")]),t._v("个延迟寄存器,总共"),s("code",[t._v("length")]),t._v("个元素,每个元素对应滤波器的一个抽头。在 Chisel 中,虽然"),s("code",[t._v("io.in")]),t._v("不是寄存器,但"),s("code",[t._v("taps")]),t._v("序列可以包含不同类型的元素,因为在 Chisel 里,所有这些都被视为"),s("code",[t._v("Data")]),t._v("类型的子类,可以被综合为硬件。在这个上下文中,"),s("code",[t._v("io.in")]),t._v("是直接的输入信号,而后续元素是寄存器类型,但它们共同构成了一个序列,用于表示滤波器的不同时间点上的信号值。这种混合类型的序列是可行的,并可以在 Chisel 生成的硬件中正确表达相应的逻辑。")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("taps.zip(taps.tail).foreach { case (a, b) => when (io.valid) { b := a } }")]),t._v("在输入"),s("code",[t._v("valid")]),t._v("为真时,将"),s("code",[t._v("taps")]),t._v("序列中每个元素的值传递到下一个元素,实现数据在寄存器间的移动。")]),t._v(" "),s("p",[s("code",[t._v("zip")]),t._v("是一个方法,它将两个集合中对应位置的元素组成一对,生成一个新的集合。在这里,"),s("code",[t._v("taps.zip(taps.tail)")]),t._v("的作用是将"),s("code",[t._v("taps")]),t._v("列表中的每个元素与其后面的元素配对。"),s("code",[t._v("tail")]),t._v("是一个方法,返回除第一个元素外的列表所有元素。例如,如果"),s("code",[t._v("taps")]),t._v("是"),s("code",[t._v("[in, reg1, reg2, reg3]")]),t._v(",那么"),s("code",[t._v("taps.tail")]),t._v("就是"),s("code",[t._v("[reg1, reg2, reg3]")]),t._v("。"),s("code",[t._v("taps.zip(taps.tail)")]),t._v("的结果将是"),s("code",[t._v("[(in, reg1), (reg1, reg2), (reg2, reg3)]")]),t._v("。这样,"),s("code",[t._v("foreach")]),t._v("就可以遍历这些配对,根据"),s("code",[t._v("valid")]),t._v("信号更新寄存器的值,实现数据的逐级传递。")]),t._v(" "),s("p",[s("code",[t._v("case (a, b) =>")]),t._v("是模式匹配的语法,用于解构元组,将"),s("code",[t._v("zip")]),t._v("操作生成的元素对分别赋值给"),s("code",[t._v("a")]),t._v("(当前元素)和"),s("code",[t._v("b")]),t._v("(下一个元素)。")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("io.out := taps.zip(io.consts).map { case (a, b) => a * b }.reduce(_ + _)")]),t._v("计算输出"),s("code",[t._v("out")]),t._v(",即将每个延迟元素与其对应的系数相乘,并将所有乘积求和得到最终结果。")]),t._v(" "),s("p",[t._v("在这段代码中,"),s("code",[t._v("map")]),t._v("和"),s("code",[t._v("reduce")]),t._v("是 Scala 中的集合操作方法:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("map")]),t._v(":对集合中的每个元素应用一个函数。这里"),s("code",[t._v("map { case (a, b) => a * b }")]),t._v("对每对"),s("code",[t._v("(a, b)")]),t._v("应用乘法操作,"),s("code",[t._v("a")]),t._v("来自"),s("code",[t._v("taps")]),t._v(","),s("code",[t._v("b")]),t._v("来自"),s("code",[t._v("io.consts")]),t._v(",分别代表寄存器中的数据和滤波器的系数。")]),t._v(" "),s("li",[s("code",[t._v("reduce")]),t._v(":对集合中的元素应用一个二元操作,逐步将集合减少为单一结果。这里的"),s("code",[t._v("reduce(_ + _)")]),t._v("将所有乘法结果相加,得到最终的滤波输出。")])]),t._v(" "),s("p",[t._v("不使用"),s("code",[t._v("foreach")]),t._v("是因为"),s("code",[t._v("foreach")]),t._v("仅用于执行操作而不返回结果,而这里的目的是计算经过滤波器后的输出值,需要通过"),s("code",[t._v("map")]),t._v("和"),s("code",[t._v("reduce")]),t._v("聚合计算结果。")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/44.5c5a7720.js b/assets/js/44.5c5a7720.js new file mode 100644 index 0000000..619ffd2 --- /dev/null +++ b/assets/js/44.5c5a7720.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[44],{305:function(t,s,a){t.exports=a.p+"assets/img/4-inputSort.a02239ea.png"},403:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-03-01-3-1-generators-parameters"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-01-3-1-generators-parameters"}},[t._v("#")]),t._v(" 2024.03.01-3.1 Generators: Parameters")]),t._v(" "),s("h2",{attrs:{id:"parameter-passing"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameter-passing"}},[t._v("#")]),t._v(" Parameter Passing")]),t._v(" "),s("h3",{attrs:{id:"example-parameterized-scala-object"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-parameterized-scala-object"}},[t._v("#")]),t._v(" Example: Parameterized Scala Object")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" ParameterizedScalaObject"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("param1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" param2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"I have parameters: param1 = ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("param1")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(" and param2 = ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("param2")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" obj1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" ParameterizedScalaObject"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" obj2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" ParameterizedScalaObject"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"World"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h3",{attrs:{id:"example-parameterized-chisel-object"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-parameterized-chisel-object"}},[t._v("#")]),t._v(" Example: Parameterized Chisel Object")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" ParameterizedWidthAdder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in0Width"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" in1Width"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sumWidth"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n require"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in0Width "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n require"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in1Width "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n require"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sumWidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in0 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in0Width"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in1Width"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" sum "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sumWidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// a +& b includes the carry, a + b does not")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sum "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in0 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in1\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getVerilog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" ParameterizedWidthAdder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("The above code block has some "),s("code",[t._v("require(...)")]),t._v(" statements. These are pre-elaboration assertions, which are useful when your generator only works with certain parameterizations or when some parameterizations are mutually exclusive or nonsensical. The above code block checks that widths are non-negative.")]),t._v(" "),s("h3",{attrs:{id:"example-parameterized-4-input-sort"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-parameterized-4-input-sort"}},[t._v("#")]),t._v(" Example: Parameterized 4-input Sort")]),t._v(" "),s("p",[s("img",{attrs:{src:a(305),alt:"Untitled"}})]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" Sort4 sorts its "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),t._v(" inputs to "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("its")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),t._v(" outputs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Sort4"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ascending"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in0 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out0 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this comparison funtion decides < or > based on the module's parameterization")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" comp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("l"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" r"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Bool "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ascending"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n l "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" r\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n l "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" r\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" row10 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" row11 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" row12 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" row13 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("comp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in0"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n row10 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in0 "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// preserve first two elements")]),t._v("\n row11 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in1\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n row10 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in1 "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// swap first two elements")]),t._v("\n row11 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in0\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("comp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n row12 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in2 "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// preserve last two elements")]),t._v("\n row13 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in3\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n row12 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in3 "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// swap last two elements")]),t._v("\n row13 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in2\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" row21 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" row22 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("comp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("row11"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" row12"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n row21 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row11 "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// preserve middle 2 elements")]),t._v("\n row22 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row12\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n row21 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row12 "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// swap middle two elements")]),t._v("\n row22 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row11\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" row20 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" row23 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("comp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("row10"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" row13"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n row20 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row10 "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// preserve the first and the forth elements")]),t._v("\n row23 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row13\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n row20 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row13 "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// swap the first and the forth elements")]),t._v("\n row23 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row10\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("comp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("row20"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" row21"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out0 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row20 "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// preserve first two elements")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row21\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out0 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row21 "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// swap first two elements")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row20\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("comp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("row22"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" row23"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row22 "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// preserve first two elements")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row23\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row23 "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// swap first two elements")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row22\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"option-and-defualt-arguments"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#option-and-defualt-arguments"}},[t._v("#")]),t._v(" Option and Defualt Arguments")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" map "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("get"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("get"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("在 Scala 中,"),s("code",[t._v("Map.get(key)")]),t._v("方法返回一个"),s("code",[t._v("Option")]),t._v("类型:如果键存在,则返回"),s("code",[t._v("Some(value)")]),t._v(";如果键不存在,则返回"),s("code",[t._v("None")]),t._v("。在您的例子中,"),s("code",[t._v('map.get("a")')]),t._v("返回"),s("code",[t._v("Some(1)")]),t._v(',因为"a"是映射中的一个键,值为 1。然而,'),s("code",[t._v('map.get("b")')]),t._v("返回"),s("code",[t._v("None")]),t._v(',因为"b"不是映射中的键。'),s("code",[t._v("Some")]),t._v("和"),s("code",[t._v("None")]),t._v("用于 Scala 中以安全且表达性的方式处理值的存在或缺失,避免空指针异常。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" some "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Some"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" none "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" None\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("some"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("get"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Returns 1")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// println(none.get) // Errors!")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("some"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("getOrElse"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Returns 1")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("none"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("getOrElse"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Returns 2")]),t._v("\n")])])]),s("p",[s("code",[t._v("getOrElse")]),t._v("是一个常用于"),s("code",[t._v("Option")]),t._v("类型的方法,它允许你为"),s("code",[t._v("Option")]),t._v("可能不包含值(即为"),s("code",[t._v("None")]),t._v(")的情况提供一个默认值。"),s("code",[t._v("getOrElse")]),t._v("接受一个参数,这个参数是当"),s("code",[t._v("Option")]),t._v("为"),s("code",[t._v("None")]),t._v("时将返回的值。如果"),s("code",[t._v("Option")]),t._v("是"),s("code",[t._v("Some")]),t._v(",则"),s("code",[t._v("getOrElse")]),t._v("会返回包裹在"),s("code",[t._v("Some")]),t._v("中的值。")]),t._v(" "),s("h3",{attrs:{id:"options-for-parameters-with-defaults"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#options-for-parameters-with-defaults"}},[t._v("#")]),t._v(" Options for Parameters with Defaults")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" DelayBy1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resetValue"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Option"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" None"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" reg "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resetValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isDefined"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// resetValue = Some(number)")]),t._v("\n RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resetValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("get"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//resetValue = None")]),t._v("\n Reg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n reg "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" reg\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getVerilog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" DelayBy1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getVerilog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" DelayBy1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Some"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("将 "),s("code",[t._v("resetValue")]),t._v(" 默认初始化为 "),s("code",[t._v("Option[UInt] = None")]),t._v(","),s("code",[t._v("Reg(UInt())")]),t._v(" 可以从上下文中自动推断,不过最好还是指定位宽")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 还可以用match来实现ifelse")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" DelayBy1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resetValue"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Option"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" None"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" reg "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" resetValue "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" Some"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" None "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" Reg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n reg "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" reg\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"match-case-statements"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#match-case-statements"}},[t._v("#")]),t._v(" Match/Case Statements")]),t._v(" "),s("p",[t._v("Scala 中的匹配概念在 Chisel 中被广泛使用,是每个 Chisel 程序员必须理解的基础知识。Scala 提供的 match 操作符支持以下功能:")]),t._v(" "),s("ul",[s("li",[t._v("用于检测多种情况的简单测试,类似于 C 语言中的 switch 语句。")]),t._v(" "),s("li",[t._v("对值的复杂组合进行测试。")]),t._v(" "),s("li",[t._v("根据变量的类型采取行动,当变量类型未知或未完全指定时,例如:\n"),s("ul",[s("li",[t._v("从异构列表中取变量,如"),s("code",[t._v('val mixedList = List(1, "string", false)')]),t._v("。")]),t._v(" "),s("li",[t._v("变量已知属于一个超类,但不确定是哪个具体的子类。")])])]),t._v(" "),s("li",[t._v("使用正则表达式提取字符串的子串。")])]),t._v(" "),s("h3",{attrs:{id:"example-value-matching"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-value-matching"}},[t._v("#")]),t._v(" Example: Value Matching")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// y is an integer variable defined somewhere else in the code")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" y "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/// ...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" y "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"zero"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// One common syntax, preferred if fits in one line")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Another common syntax, preferred if does not fit in one line.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"one"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Note the code block continues until the next case")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Another syntax, but curly braces are not required")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"two"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" _ "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"many"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// _ is a wildcard that matches all values")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"y is "')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// out: y is many")]),t._v("\n")])])]),s("p",[t._v("y 为 7,不匹配,因此采用默认值")]),t._v(" "),s("ul",[s("li",[t._v("每个跟在"),s("code",[t._v("=>")]),t._v("操作符后面的代码块都会继续执行,直到它到达"),s("code",[t._v("match")]),t._v("的结束大括号或下一个"),s("code",[t._v("case")]),t._v("语句。")]),t._v(" "),s("li",[s("code",[t._v("match")]),t._v("会按照"),s("code",[t._v("case")]),t._v("语句的顺序进行搜索,一旦匹配到一个"),s("code",[t._v("case")]),t._v("语句,就不会再对其他"),s("code",[t._v("case")]),t._v("语句进行检查。")]),t._v(" "),s("li",[t._v("使用下划线"),s("code",[t._v("_")]),t._v("作为通配符,来处理任何未找到匹配的值。")])]),t._v(" "),s("h3",{attrs:{id:"example-multiple-value-matching"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-multiple-value-matching"}},[t._v("#")]),t._v(" Example: Multiple Value Matching")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" animalType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("biggerThanBreadBox"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" meanAsCanBe"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("biggerThanBreadBox"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" meanAsCanBe"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wolverine"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"elephant"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"shrew"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"puppy"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("animalType"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// wolverine")]),t._v("\n")])])]),s("h3",{attrs:{id:"example-type-matching"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-type-matching"}},[t._v("#")]),t._v(" Example: Type Matching")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" sequence "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nsequence"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("foreach "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n x "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("x")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' is a String"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("x")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' is an Int"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Double")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("x")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' is a Double"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" _ "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("x")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' is an unknown type!"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("code",[t._v("Seq")]),t._v("是 Scala 集合中的一个接口,它代表序列,而"),s("code",[t._v("List")]),t._v("是"),s("code",[t._v("Seq")]),t._v("的一个具体实现。在这个例子中,可以直接用"),s("code",[t._v('List("a", 1, 0.0)')]),t._v("来代替"),s("code",[t._v('Seq("a", 1, 0.0)')]),t._v(",而不会影响"),s("code",[t._v("foreach")]),t._v("和"),s("code",[t._v("match")]),t._v("语句的行为。")]),t._v(" "),s("h3",{attrs:{id:"example-multiple-type-matching"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-multiple-type-matching"}},[t._v("#")]),t._v(" Example: Multiple Type Matching")]),t._v(" "),s("p",[t._v("If you want to match on whether a value has one of many types, use the following syntax. Note that you must use an "),s("code",[t._v("_")]),t._v(" when matching.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" sequence "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nsequence"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("foreach "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n x "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Double")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("x")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' is a number!"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" _ "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("x")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' is an unknown type!"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"example-type-matching-and-erasure"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-type-matching-and-erasure"}},[t._v("#")]),t._v(" Example: Type Matching and Erasure")]),t._v(" "),s("p",[t._v("类型匹配在 Scala 中有一些限制。由于 Scala 运行在 JVM 上,而 JVM 不保持多态类型信息,因此你不能在运行时基于它们进行匹配(因为这些类型信息已被擦除)。注意下面的例子始终匹配第一个 case 语句,因为"),s("code",[t._v("[String]")]),t._v("、"),s("code",[t._v("[Int]")]),t._v("、"),s("code",[t._v("[Double]")]),t._v("这些多态类型在运行时被擦除了,case 语句实际上只是在匹配"),s("code",[t._v("Seq")]),t._v("。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" sequence "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nsequence"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("foreach "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n x "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("x")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' is a String"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("x")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' is an Int"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Double")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("x")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' is a Double"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在 Scala 中,类型擦除指的是 JVM 在运行时不保留泛型的具体类型信息。因此,当你对"),s("code",[t._v("Seq[String]")]),t._v("、"),s("code",[t._v("Seq[Int]")]),t._v("或"),s("code",[t._v("Seq[Double]")]),t._v("进行模式匹配时,JVM 实际上无法区分这些"),s("code",[t._v("Seq")]),t._v("的元素类型,因为泛型信息"),s("code",[t._v("[String]")]),t._v("、"),s("code",[t._v("[Int]")]),t._v("、"),s("code",[t._v("[Double]")]),t._v("已经被擦除,只留下了基础的"),s("code",[t._v("Seq")]),t._v("类型。所以,这些 case 语句在运行时都被视为对"),s("code",[t._v("Seq")]),t._v("类型的匹配,而无法区分具体是哪种"),s("code",[t._v("Seq")]),t._v("。因此,匹配总是成功于第一个 case,无论其实际参数是什么类型的"),s("code",[t._v("Seq")]),t._v("。这就是为什么在运行时你看到的行为似乎是它总是匹配"),s("code",[t._v("Seq")]),t._v("的原因。")]),t._v(" "),s("h2",{attrs:{id:"ios-with-optional-fields"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#ios-with-optional-fields"}},[t._v("#")]),t._v(" IOs with Optional Fields")]),t._v(" "),s("p",[t._v("有时我们希望 IO 端口能够根据需要选择性地包含或排除。例如,在调试时可能需要查看一些内部状态,但在生成器用于系统时希望将其隐藏。或者,你的生成器可能有一些输入在某些情况下不需要连接,因为存在合理的默认值。")]),t._v(" "),s("h3",{attrs:{id:"example-optional-io-with-option"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-optional-io-with-option"}},[t._v("#")]),t._v(" Example: Optional IO with Option")]),t._v(" "),s("p",[t._v("示例中展示了一个可选地接收进位信号的一位加法器。如果包含进位,"),s("code",[t._v("io.carryIn")]),t._v("将是"),s("code",[t._v("Some[UInt]")]),t._v("类型并包含在 IO 束中;如果不包含进位,"),s("code",[t._v("io.carryIn")]),t._v("将是"),s("code",[t._v("None")]),t._v("类型并从 IO 束中排除。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" HalfFullAdder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" hasCarry"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" carryIn "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("hasCarry"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" Some"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" None\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" s "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" carryOut "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" sum "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("b "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("carryIn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("getOrElse"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("s "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" sum"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("carryOut "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" sum"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"example-optional-io-with-zero-width-wires"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-optional-io-with-zero-width-wires"}},[t._v("#")]),t._v(" Example: Optional IO with Zero-Width Wires")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" HalfFullAdder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" hasCarry"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" carryIn "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("hasCarry"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" s "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" carryOut "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" sum "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("b "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("carryIn\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("s "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" sum"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("carryOut "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" sum"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("也可以用一个 0 宽度的 wire 来代替 None。An IO with width zero is pruned from the emitted Verilog, and anything that tries to use the value of a zero-width wire gets a constant zero.")]),t._v(" "),s("h2",{attrs:{id:"implicits"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#implicits"}},[t._v("#")]),t._v(" Implicits")]),t._v(" "),s("p",[t._v("为了减少大量重复的模板代码,Scala 引入了*隐式(implicits)*的概念,允许编译器为你自动进行一些语法简化。由于很多操作是在背后进行,隐式使用可能显得很神奇。")]),t._v(" "),s("h3",{attrs:{id:"implicit-arguments"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#implicit-arguments"}},[t._v("#")]),t._v(" Implicit Arguments")]),t._v(" "),s("p",[t._v("隐式参数的一个常见用途是当你的代码在深层的函数调用中需要访问某个顶层变量时,可以使用隐式参数自动传递这个变量,而不是手动在每个函数调用中传递它。")]),t._v(" "),s("h3",{attrs:{id:"example-implicit-cats"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-implicit-cats"}},[t._v("#")]),t._v(" Example: Implicit Cats")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" CatDog "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implicit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" numberOfCats"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//implicit val numberOfDogs: Int = 5")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" tooManyCats"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("nDogs"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implicit")]),t._v(" nCats"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" nCats "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" nDogs\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" imp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tooManyCats"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Argument passed implicitly!")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" exp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" tooManyCats"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Argument passed explicitly!")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nCatDog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("imp\nCatDog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exp\n")])])]),s("p",[t._v("首先,我们定义了一个隐式值"),s("code",[t._v("numberOfCats")]),t._v("。在给定的作用域中,同一类型的隐式值只能有一个。然后,我们定义了一个函数,它接受两个参数列表;第一个是任何显式参数,第二个是任何隐式参数。当我们调用"),s("code",[t._v("tooManyCats")]),t._v("时,我们可以省略第二个隐式参数列表(让编译器为我们找到它),或者显式提供一个参数(这个参数可以与隐式值不同)。")]),t._v(" "),s("p",[t._v("隐式参数可能失败的情况包括:")]),t._v(" "),s("ul",[s("li",[t._v("在一个作用域中定义了给定类型的两个或多个隐式值")]),t._v(" "),s("li",[t._v("如果编译器找不到调用函数所需的隐式值")])]),t._v(" "),s("p",[s("code",[t._v("object")]),t._v("定义了一个单例对象,它是一个类的单一实例。与"),s("code",[t._v("class")]),t._v("不同,当你定义一个"),s("code",[t._v("object")]),t._v("时,Scala 会自动为你创建这个类的一个实例。你不需要使用"),s("code",[t._v("new")]),t._v("关键字来创建它的实例。在这个例子中,"),s("code",[t._v("CatDog")]),t._v("是一个单例对象,可以直接访问其成员,无需创建实例。这在定义工具方法或当你需要一个全局唯一的实体时非常有用,比如这里的"),s("code",[t._v("numberOfCats")]),t._v("隐式值和"),s("code",[t._v("tooManyCats")]),t._v("方法。")]),t._v(" "),s("h3",{attrs:{id:"example-implicit-logging"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-implicit-logging"}},[t._v("#")]),t._v(" Example: Implicit Logging")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sealed")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("trait")]),t._v(" Verbosity\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implicit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" Silent "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Verbosity\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" Verbose "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Verbosity\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" ParameterizedWidthAdder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in0Width"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" in1Width"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sumWidth"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implicit")]),t._v(" verbosity"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Verbosity"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" log"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("msg"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Unit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" verbosity "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" Silent "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" Verbose "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("msg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n require"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in0Width "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n log"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in0Width of ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("in0Width")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' OK"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n require"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in1Width "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n log"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in1Width of ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("in1Width")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' OK"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n require"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sumWidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n log"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"sumWidth of ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("sumWidth")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' OK"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in0 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in0Width"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in1Width"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" sum "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sumWidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n log"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Made IO"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\t"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 对于结果位宽自然容纳进位的情况,直接使用+也是可行的。")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sum "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in0 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in1\n log"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Assigned output"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getVerilog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" ParameterizedWidthAdder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getVerilog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" ParameterizedWidthAdder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Verbose"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("ol",[s("li",[t._v("定义了一个名为"),s("code",[t._v("Verbosity")]),t._v("的密封特质("),s("code",[t._v("sealed trait")]),t._v(")和两个实现这个特质的对象。"),s("code",[t._v("sealed trait Verbosity")]),t._v("表示"),s("code",[t._v("Verbosity")]),t._v("是一个可以被继承的类型,但所有继承它的类必须定义在同一个文件中,这有助于实现模式匹配的完整性检查。"),s("code",[t._v("implicit case object Silent extends Verbosity")]),t._v("定义了一个隐式的单例对象"),s("code",[t._v("Silent")]),t._v(",它是"),s("code",[t._v("Verbosity")]),t._v("的一个实现,可以在需要"),s("code",[t._v("Verbosity")]),t._v("类型的隐式参数时自动使用。"),s("code",[t._v("case object Verbose extends Verbosity")]),t._v("定义了另一个名为"),s("code",[t._v("Verbose")]),t._v("的单例对象,也是"),s("code",[t._v("Verbosity")]),t._v("的实现。"),s("code",[t._v("case object")]),t._v("通常用于代表不可变、无状态的值或单例定义.")]),t._v(" "),s("li",[s("code",[t._v("msg: => String")]),t._v("这样的参数定义使用了名为“call-by-name”的参数传递机制。这种机制意味着,只有在函数内部实际使用到"),s("code",[t._v("msg")]),t._v("时,传入的字符串表达式才会被计算。这对于条件日志记录来说非常有用,因为它允许延迟计算日志消息直到确实需要打印消息时。例如,如果"),s("code",[t._v("verbosity")]),t._v("是"),s("code",[t._v("Silent")]),t._v(",则"),s("code",[t._v("msg")]),t._v("根本不会被计算,这样就避免了不必要的性能开销。")])]),t._v(" "),s("h3",{attrs:{id:"implicit-conversions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#implicit-conversions"}},[t._v("#")]),t._v(" Implicit Conversions")]),t._v(" "),s("p",[t._v("隐式函数(也称为隐式转换)用于减少模板代码。更具体地说,它们用于自动将一个 Scala 对象转换为另一个对象。")]),t._v(" "),s("h3",{attrs:{id:"example-implicit-conversion"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-implicit-conversion"}},[t._v("#")]),t._v(" Example: Implicit Conversion")]),t._v(" "),s("p",[t._v("在下面的例子中,我们有两个类,"),s("code",[t._v("Animal")]),t._v("和"),s("code",[t._v("Human")]),t._v("。"),s("code",[t._v("Animal")]),t._v("有一个"),s("code",[t._v("species")]),t._v("字段,但"),s("code",[t._v("Human")]),t._v("没有。然而,通过实现一个隐式转换,我们可以在"),s("code",[t._v("Human")]),t._v("上调用"),s("code",[t._v("species")]),t._v("方法。这意味着即使"),s("code",[t._v("Human")]),t._v("类原本不包含"),s("code",[t._v("species")]),t._v("字段,通过隐式转换,我们也可以像访问自己的属性一样访问"),s("code",[t._v("species")]),t._v(",就好像这个属性是"),s("code",[t._v("Human")]),t._v("类的一部分一样。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Animal"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" species"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Human"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implicit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" human2animal"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("h"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Human"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Animal "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Animal"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("h"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Homo sapiens"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" me "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Human"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Adam"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("me"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("species"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/45.3ad1b537.js b/assets/js/45.3ad1b537.js new file mode 100644 index 0000000..8dcf6ee --- /dev/null +++ b/assets/js/45.3ad1b537.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[45],{306:function(t,s,a){t.exports=a.p+"assets/img/ArtificialNeuronModel_english.741f68e5.png"},408:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-03-07-3-5-functional-programming"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-07-3-5-functional-programming"}},[t._v("#")]),t._v(" 2024.03.07-3.5 Functional Programming")]),t._v(" "),s("h1",{attrs:{id:"functional-programming-in-scala"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#functional-programming-in-scala"}},[t._v("#")]),t._v(" Functional Programming in Scala")]),t._v(" "),s("h2",{attrs:{id:"example-custom-functions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-custom-functions"}},[t._v("#")]),t._v(" Example: Custom Functions")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// No inputs or outputs (two versions).")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// To produce no output, return the Unit type")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" hello1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Unit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" print"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" hello2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" print"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello again!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Math operation: one input and one output.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" times2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" x\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Inputs can have default values, and explicitly specifying the return type is optional.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Note that we recommend specifying the return types to avoid surprises/bugs.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" timesN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" x\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Call the functions listed above.")]),t._v("\nhello1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nhello2\ntimes2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\ntimesN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// no need to specify n to use the default value")]),t._v("\ntimesN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// argument order is the same as the order where the function was defined")]),t._v("\ntimesN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// arguments may be reordered and assigned to explicitly")]),t._v("\n")])])]),s("h1",{attrs:{id:"functions-as-objects"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#functions-as-objects"}},[t._v("#")]),t._v(" Functions as Objects")]),t._v(" "),s("h2",{attrs:{id:"example-function-objects"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-function-objects"}},[t._v("#")]),t._v(" Example: Function Objects")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// These are normal functions.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" plus1funct"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" times2funct"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// These are functions as vals.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// The first one explicitly specifies the return type.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" plus1val"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" times2val "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Calling both looks the same.")]),t._v("\nplus1funct"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nplus1val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nplus1funct"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//plus1val(x=4) // this doesn't work")]),t._v("\n")])])]),s("h3",{attrs:{id:"hint"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#hint"}},[t._v("#")]),t._v(" Hint:")]),t._v(" "),s("ol",[s("li",[t._v("函数对象定义时使用 "),s("code",[t._v("val")]),t._v(" ,并且不指明参数")]),t._v(" "),s("li",[t._v("指明返回类型时使用 "),s("code",[t._v("type ⇒ type = x ⇒ x + 1")])]),t._v(" "),s("li",[t._v("没有指明返回类型时使用 "),s("code",[t._v("funcName = value ⇒ value")])])]),t._v(" "),s("h2",{attrs:{id:"example-higher-order-functions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-higher-order-functions"}},[t._v("#")]),t._v(" Example: Higher-Order Functions")]),t._v(" "),s("p",[t._v("Functions that take or produce functions are called "),s("em",[t._v("higher-order functions")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create our function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" plus1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" times2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// pass it to map, a list function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myListPlus "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" myList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("plus1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myListTimes "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" myList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("times2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a custom function, which performs an operation on X N times using recursion")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" opN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" op"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" opN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("op"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" op"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nopN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" plus1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nopN"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" times2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h2",{attrs:{id:"example-functions-vs-objects"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-functions-vs-objects"}},[t._v("#")]),t._v(" Example: Functions vs. Objects")]),t._v(" "),s("p",[t._v("A possibly confusing situation arises when using functions without arguments. Functions are evaluated every time they are called, while "),s("code",[t._v("val")]),t._v("s are evaluated at instantiation.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("scala"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("Random\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// both x and y call the nextInt function, but x is evaluated immediately and y is a function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Random"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextInt\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" y "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Random"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextInt "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// def y : Int = Random.nextInt")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// x was previously evaluated, so it is a constant")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"x = ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("x")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"x = ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("x")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// y is a function and gets reevaluated at each call, thus these produce different results")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"y = ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("y")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"y = ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("y")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// output:")]),t._v("\nx "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2133939285")]),t._v("\nx "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2133939285")]),t._v("\ny "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1035018406")]),t._v("\ny "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("968348688")]),t._v("\n")])])]),s("ol",[s("li",[t._v("使用 "),s("code",[t._v("val")]),t._v(" 的函数对象在定义时就初始化了,后面调用不会改变值")]),t._v(" "),s("li",[t._v("而普通的函数每一次调用都会再运行一次")])]),t._v(" "),s("h1",{attrs:{id:"anonymous-functions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#anonymous-functions"}},[t._v("#")]),t._v(" Anonymous Functions")]),t._v(" "),s("h2",{attrs:{id:"example-anonymous-functions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-anonymous-functions"}},[t._v("#")]),t._v(" Example: Anonymous Functions")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add one to every item in the list using an anonymous function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// arguments get passed to the underscore variable")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// these all do the same thing")]),t._v("\nmyList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nmyList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// a common situation is to use case statements within an anonymous function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myAnyList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"3"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4L")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" myList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nmyAnyList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Long")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Number"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"String"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" _ "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"error"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("如果只使用一次的函数对象,就没有必要建立一个 "),s("code",[t._v("val")]),t._v(" 了")]),t._v(" "),s("h2",{attrs:{id:"exercise-sequence-manipulation"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#exercise-sequence-manipulation"}},[t._v("#")]),t._v(" Exercise: Sequence Manipulation")]),t._v(" "),s("p",[t._v("在 Scala 集合中,"),s("code",[t._v("scanLeft")]),t._v("/"),s("code",[t._v("scanRight")]),t._v("、"),s("code",[t._v("reduceLeft")]),t._v("/"),s("code",[t._v("reduceRight")]),t._v(" 和 "),s("code",[t._v("foldLeft")]),t._v("/"),s("code",[t._v("foldRight")]),t._v(" 是重要的函数,用于对集合进行累积运算。理解每个函数的工作方式及其适用场景是很重要的。默认情况下,"),s("code",[t._v("scan")]),t._v("、"),s("code",[t._v("reduce")]),t._v(" 和 "),s("code",[t._v("fold")]),t._v(" 的方向是从左到右。")]),t._v(" "),s("ol",[s("li",[t._v("scanLeft/scanRight:\n"),s("ul",[s("li",[s("code",[t._v("scanLeft")]),t._v(" 和 "),s("code",[t._v("scanRight")]),t._v(" 是累积函数,它们对集合中的元素逐个应用累积函数,并返回一个包含所有中间结果的新集合。")]),t._v(" "),s("li",[s("code",[t._v("scanLeft")]),t._v(" 从集合的头部开始向尾部递进,而 "),s("code",[t._v("scanRight")]),t._v(" 则从尾部开始向头部递进。")]),t._v(" "),s("li",[t._v("例如,"),s("code",[t._v("List(1, 2, 3).scanLeft(0)(_ + _)")]),t._v(" 会计算 "),s("code",[t._v("(0, 1, 3, 6)")]),t._v(",其中 "),s("code",[t._v("0")]),t._v(" 是初始值,累加过程是 "),s("code",[t._v("0 + 1 = 1")]),t._v(","),s("code",[t._v("1 + 2 = 3")]),t._v(","),s("code",[t._v("3 + 3 = 6")]),t._v("。")])])]),t._v(" "),s("li",[t._v("reduceLeft/reduceRight:\n"),s("ul",[s("li",[s("code",[t._v("reduceLeft")]),t._v(" 和 "),s("code",[t._v("reduceRight")]),t._v(" 是累积函数,它们对集合中的元素逐个应用累积函数,但只返回最终的累积结果。")]),t._v(" "),s("li",[s("code",[t._v("reduceLeft")]),t._v(" 从集合的头部开始应用累积函数,直到尾部;"),s("code",[t._v("reduceRight")]),t._v(" 则从尾部开始应用,直到头部。")]),t._v(" "),s("li",[t._v("注意:"),s("code",[t._v("reduceLeft")]),t._v(" 和 "),s("code",[t._v("reduceRight")]),t._v(" 不能为空集合使用,因为它们没有初始值。")]),t._v(" "),s("li",[t._v("例如,"),s("code",[t._v("List(1, 2, 3).reduceLeft(_ + _)")]),t._v(" 会计算 "),s("code",[t._v("1 + 2 + 3 = 6")]),t._v("。")])])]),t._v(" "),s("li",[t._v("foldLeft/foldRight:\n"),s("ul",[s("li",[s("code",[t._v("foldLeft")]),t._v(" 和 "),s("code",[t._v("foldRight")]),t._v(" 和 "),s("code",[t._v("reduceLeft")]),t._v("/"),s("code",[t._v("reduceRight")]),t._v(" 类似,但它们接受一个初始值作为累积的起点。")]),t._v(" "),s("li",[s("code",[t._v("foldLeft")]),t._v(" 从集合的头部开始应用累积函数,而 "),s("code",[t._v("foldRight")]),t._v(" 则从尾部开始。")]),t._v(" "),s("li",[s("code",[t._v("foldLeft")]),t._v(" 和 "),s("code",[t._v("foldRight")]),t._v(" 可以在空集合上使用,因为它们有初始值。")]),t._v(" "),s("li",[t._v("例如,"),s("code",[t._v("List(1, 2, 3).foldLeft(0)(_ + _)")]),t._v(" 会计算 "),s("code",[t._v("0 + 1 + 2 + 3 = 6")]),t._v("。")])])])]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" exList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// write a custom function to add two numbers, then use reduce to find the sum of all values in exList")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" add"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" sum "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" exList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reduce"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("add"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// find the sum of exList using an anonymous function (hint: you've seen this before!)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" anon_sum "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" exList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reduce"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// find the moving average of exList from right to left using scan; make the result (ma2) a list of doubles")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" avg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Double")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Double")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.0")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" ma2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" exList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("scanRight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("avg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("这个 "),s("code",[t._v("scanRight")]),t._v(" 调用将执行以下操作:")]),t._v(" "),s("ol",[s("li",[t._v("开始于最右侧元素 "),s("code",[t._v("100")]),t._v(" 和初始值 "),s("code",[t._v("0.0")]),t._v(":\n"),s("ul",[s("li",[t._v("应用 "),s("code",[t._v("avg(100, 0.0)")]),t._v(" 得到 "),s("code",[t._v("(100 + 0.0) / 2 = 50.0")]),t._v("。这是第一个累积值,它将作为下一个右侧元素的累积输入。")])])]),t._v(" "),s("li",[t._v("向左移动到元素 "),s("code",[t._v("7")]),t._v(":\n"),s("ul",[s("li",[t._v("使用刚刚计算得到的累积值 "),s("code",[t._v("50.0")]),t._v(" 和当前元素 "),s("code",[t._v("7")]),t._v(" 应用 "),s("code",[t._v("avg")]),t._v(",得到 "),s("code",[t._v("avg(7, 50.0) = (7 + 50.0) / 2 = 28.5")]),t._v("。这成为下一步的累积输入。")])])]),t._v(" "),s("li",[t._v("接着移动到元素 "),s("code",[t._v("5")]),t._v(":\n"),s("ul",[s("li",[t._v("应用 "),s("code",[t._v("avg(5, 28.5)")]),t._v(" 得到 "),s("code",[t._v("(5 + 28.5) / 2 = 16.75")]),t._v("。")])])]),t._v(" "),s("li",[t._v("最后移动到元素 "),s("code",[t._v("1")]),t._v(":\n"),s("ul",[s("li",[t._v("应用 "),s("code",[t._v("avg(1, 16.75)")]),t._v(" 得到 "),s("code",[t._v("(1 + 16.75) / 2 = 8.875")]),t._v("。")])])]),t._v(" "),s("li",[t._v("收集和返回结果:\n"),s("ul",[s("li",[s("code",[t._v("scanRight")]),t._v(" 不仅返回最终的累积结果,它还返回经过每个步骤的中间结果。所以对于这个特定的列表和 "),s("code",[t._v("avg")]),t._v(" 函数,"),s("code",[t._v("scanRight")]),t._v(" 会返回一个新的列表:"),s("code",[t._v("List(8.875, 16.75, 28.5, 50.0, 0.0)")]),t._v("。")])])])]),t._v(" "),s("h1",{attrs:{id:"functional-programming-in-chisel"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#functional-programming-in-chisel"}},[t._v("#")]),t._v(" Functional Programming in Chisel")]),t._v(" "),s("h2",{attrs:{id:"exercise-fir-filter"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#exercise-fir-filter"}},[t._v("#")]),t._v(" Exercise: FIR Filter")]),t._v(" "),s("p",[t._v("使用函数生成 FIR 的系数:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get some math functions")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("scala"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("math"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("abs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" round"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cos"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Pi"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" pow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// simple triangular window")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" TriangularWindow"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" raw_coeffs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("abs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toDouble"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" scaled_coeffs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" raw_coeffs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Double")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" round"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" pow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n scaled_coeffs\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Hamming window")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" HammingWindow"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" raw_coeffs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.54")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.46")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("cos"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("Pi"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" scaled_coeffs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" raw_coeffs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Double")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" round"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" pow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n scaled_coeffs\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// check it out! first argument is the window length, and second argument is the bitwidth")]),t._v("\nTriangularWindow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nHammingWindow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("创建一个接受函数为参数的 Chisel FIR 模块:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// our FIR has parameterized window length, IO bitwidth, and windowing function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" MyFir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" window"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// expect bit growth, conservative but lazy")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// calculate the coefficients using the provided window function, mapping to UInts")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" coeffs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create an array holding the output of the delays")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// note: we avoid using a Vec here since we don't need dynamic indexing")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" delays "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fill"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("scan"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("prev"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegNext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("prev"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n next\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// multiply, putting result in "mults"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" mults "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" delays"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zip"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("coeffs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("delay"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" coeff"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" delay "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" coeff "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add up multiplier outputs with bit growth")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mults"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reduce"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// connect output")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" result\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nvisualize"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" MyFir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" TriangularWindow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[s("code",[t._v("delays.zip(coeffs)")]),t._v(" 也可以写成 "),s("code",[t._v("(delays zip coeffs)")])]),t._v(" "),s("h2",{attrs:{id:"example-fir-filter-tester"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-fir-filter-tester"}},[t._v("#")]),t._v(" Example: FIR Filter Tester")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// math imports")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("scala"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("math"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("pow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Pi"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("breeze"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("signal"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" OptOverhang"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("breeze"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("signal"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("support"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("CanFilter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" FIRKernel1D"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("breeze"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("linalg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("DenseVector\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test parameters")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" bitwidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// must be less than 15, otherwise Int can't represent the data, need BigInt")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" window "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" TriangularWindow\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test our FIR")]),t._v("\ntest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" MyFir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test data")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// input length")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" sine_freq "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" samp_freq "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// sample data, scale to between 0 and 2^bitwidth")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" max_value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" pow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" sine "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("max_value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" max_value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("sin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("Pi"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("sine_freq"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("samp_freq"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('//println(s"input = ${sine.toArray.deep.mkString(", ")}")')]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// coefficients")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" coeffs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('//println(s"coeffs = ${coeffs.toArray.deep.mkString(", ")}")')]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use breeze filter as golden model; need to reverse coefficients")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" expected "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n DenseVector"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sine"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toArray"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n FIRKernel1D"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("DenseVector"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("coeffs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reverse"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toArray"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n OptOverhang"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("None\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n expected"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toArray "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// seems to be necessary")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('//println(s"exp_out = ${expected.toArray.deep.mkString(", ")}") // this seems to be necessary')]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// push data through our FIR and check the result")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reset"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reset"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sine"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// wait for all registers to be initialized since we didn't zero-pad the data")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" expectValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" expected"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('//println(s"expected value is $expectValue")')]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("expected"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('//println(s"cycle $i, got ${c.io.out.peek()}, expect ${expected(i-length+1)}")')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h1",{attrs:{id:"chisel-exercise"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#chisel-exercise"}},[t._v("#")]),t._v(" Chisel Exercise")]),t._v(" "),s("h2",{attrs:{id:"exercise-neural-network-neuron"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#exercise-neural-network-neuron"}},[t._v("#")]),t._v(" Exercise: Neural Network Neuron")]),t._v(" "),s("h3",{attrs:{id:"basic-multiply"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#basic-multiply"}},[t._v("#")]),t._v(" Basic Multiply")]),t._v(" "),s("p",[s("img",{attrs:{src:a(306),alt:"Neuron"}})]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Neuron"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("inputs"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" act"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" FixedPoint "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" FixedPoint"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("inputs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" FixedPoint"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" weights "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("inputs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" FixedPoint"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("FixedPoint"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" act"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in zip io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("weights"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reduce"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在 Chisel 中,"),s("code",[t._v("FixedPoint")]),t._v(" 类型用于表示定点数,这是一种在硬件设计中常用的数值表示方法,特别适用于数字信号处理(DSP)等领域。"),s("code",[t._v("FixedPoint")]),t._v(" 类型提供了一种方式来指定数值的位宽和小数点位置,这在设计需要精确控制数值精度和范围的硬件时非常有用。")]),t._v(" "),s("p",[s("code",[t._v("FixedPoint(16.W, 8.BP)")]),t._v(" 创建了一个定点数,其中:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("16.W")]),t._v(" 指定了该定点数的总位宽为 16 位。这包括了整数部分和小数部分的所有位。")]),t._v(" "),s("li",[s("code",[t._v("8.BP")]),t._v(" 指定了该定点数的二进制小数点位置(Binary Point)。这里,"),s("code",[t._v("8.BP")]),t._v(" 意味着小数部分有 8 位。")])]),t._v(" "),s("p",[t._v("当您在 Chisel 中使用不同格式的 "),s("code",[t._v("FixedPoint")]),t._v(" 数进行运算时,首先需要调整它们,以确保具有相同的位宽和小数点位置。以下是如何进行这种转换和随后的加法运算的示例。")]),t._v(" "),s("p",[t._v("假设您有两个 "),s("code",[t._v("FixedPoint")]),t._v(" 数,分别定义如下:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("num1")]),t._v(" 有 16 位宽,其中 8 位是小数位:"),s("code",[t._v("FixedPoint(16.W, 8.BP)")])]),t._v(" "),s("li",[s("code",[t._v("num2")]),t._v(" 有 18 位宽,其中 10 位是小数位:"),s("code",[t._v("FixedPoint(18.W, 10.BP)")])])]),t._v(" "),s("p",[t._v("要进行加法运算,您首先需要决定一个目标格式,通常是选择两者中更“大”的格式,也就是位宽更宽、小数位更多的那个。在这个例子中,目标格式将是 "),s("code",[t._v("FixedPoint(18.W, 10.BP)")]),t._v("。")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("扩展 "),s("code",[t._v("num1")]),t._v(" 到更大的格式:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" num1Extended "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" num1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("setBinaryPoint"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("asFixedPoint"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("18.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("这行代码将 "),s("code",[t._v("num1")]),t._v(" 的小数点位置扩展到 10 位,并将整个数扩展到 18 位宽。")])]),t._v(" "),s("li",[s("p",[t._v("确保 "),s("code",[t._v("num2")]),t._v(" 也符合目标格式:")]),t._v(" "),s("p",[t._v("虽然 "),s("code",[t._v("num2")]),t._v(" 已经是 "),s("code",[t._v("FixedPoint(18.W, 10.BP)")]),t._v(",我们通常在实际代码中不需要对其进行任何操作,但是为了代码的清晰性和一致性,您可以明确指出这一点(尽管在实践中这不是必需的):")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" num2Adjusted "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" num2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("asFixedPoint"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("18.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])]),t._v(" "),s("li",[s("p",[t._v("进行加法运算:")]),t._v(" "),s("p",[t._v("一旦两个数都调整到了相同的格式,就可以直接进行加法运算了:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" sum "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" num1Extended "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" num2Adjusted\n")])])]),s("p",[t._v("这样,"),s("code",[t._v("sum")]),t._v(" 将会是两个数的和,也具有相同的格式 "),s("code",[t._v("FixedPoint(18.W, 10.BP)")]),t._v("。")])])]),t._v(" "),s("p",[t._v("这个示例说明了如何在 Chisel 中将两个不同格式的 "),s("code",[t._v("FixedPoint")]),t._v(" 数调整为相同格式,然后进行加法运算。通过这种方式,您可以确保运算的正确性,并避免由于格式不匹配导致的精度损失。")]),t._v(" "),s("h3",{attrs:{id:"activation-functions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#activation-functions"}},[t._v("#")]),t._v(" Activation Functions")]),t._v(" "),s("p",[t._v("现在让我们创建一些激活函数!我们将使用零作为阈值。典型的激活函数包括 Sigmoid 函数和修正线性单元(ReLU)。")]),t._v(" "),s("p",[t._v("我们将使用的 Sigmoid 被称为 "),s("a",{attrs:{href:"https://en.wikipedia.org/wiki/Logistic_function",target:"_blank",rel:"noopener noreferrer"}},[t._v("逻辑函数"),s("OutboundLink")],1),t._v(",其公式为:")]),t._v(" "),s("p"),s("p",[s("mjx-container",{staticClass:"MathJax",attrs:{jax:"CHTML",display:"true"}},[s("mjx-math",{staticClass:"MJX-TEX",attrs:{display:"true"}},[s("mjx-mtext",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"l"}}),s("mjx-c",{attrs:{c:"o"}}),s("mjx-c",{attrs:{c:"g"}}),s("mjx-c",{attrs:{c:"i"}}),s("mjx-c",{attrs:{c:"s"}}),s("mjx-c",{attrs:{c:"t"}}),s("mjx-c",{attrs:{c:"i"}}),s("mjx-c",{attrs:{c:"c"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"("}})],1),s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"x"}})],1),s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:")"}})],1),s("mjx-mo",{staticClass:"mjx-n",attrs:{space:"4"}},[s("mjx-c",{attrs:{c:"="}})],1),s("mjx-mfrac",{attrs:{space:"4"}},[s("mjx-frac",{attrs:{type:"d"}},[s("mjx-num",[s("mjx-nstrut",{attrs:{type:"d"}}),s("mjx-mn",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"1"}})],1)],1),s("mjx-dbox",[s("mjx-dtable",[s("mjx-line",{attrs:{type:"d"}}),s("mjx-row",[s("mjx-den",[s("mjx-dstrut",{attrs:{type:"d"}}),s("mjx-mrow",[s("mjx-mn",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"1"}})],1),s("mjx-mo",{staticClass:"mjx-n",attrs:{space:"3"}},[s("mjx-c",{attrs:{c:"+"}})],1),s("mjx-msup",{attrs:{space:"3"}},[s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"e"}})],1),s("mjx-script",{staticStyle:{"vertical-align":"0.363em"}},[s("mjx-TeXAtom",{attrs:{size:"s"}},[s("mjx-mo",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"2212"}})],1),s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"3B2"}})],1),s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"x"}})],1)],1)],1)],1)],1)],1)],1)],1)],1)],1)],1)],1)],1)],1),s("p"),t._v(" "),s("p",[t._v("其中 "),s("mjx-container",{staticClass:"MathJax",attrs:{jax:"CHTML"}},[s("mjx-math",{staticClass:"MJX-TEX"},[s("mjx-mi",{staticClass:"mjx-i"},[s("mjx-c",{attrs:{c:"3B2"}})],1)],1)],1),t._v(" 是斜率因子。然而,在硬件中计算指数函数是相当具有挑战性和开销的。我们将近似这个为阶跃函数。")],1),t._v(" "),s("p"),s("p",[s("mjx-container",{staticClass:"MathJax",attrs:{jax:"CHTML",display:"true"}},[s("mjx-math",{staticClass:"MJX-TEX",attrs:{display:"true"}},[s("mjx-merror",[s("mjx-mtext",{staticClass:"mjx-n"},[s("mjx-c",{attrs:{c:"5C"}}),s("mjx-c",{attrs:{c:"t"}}),s("mjx-c",{attrs:{c:"e"}}),s("mjx-c",{attrs:{c:"x"}}),s("mjx-c",{attrs:{c:"t"}}),s("mjx-c",{attrs:{c:"{"}}),s("mjx-c",{attrs:{c:"s"}}),s("mjx-c",{attrs:{c:"t"}}),s("mjx-c",{attrs:{c:"e"}}),s("mjx-c",{attrs:{c:"p"}}),s("mjx-c",{attrs:{c:"}"}}),s("mjx-c",{attrs:{c:"("}}),s("mjx-c",{attrs:{c:"x"}}),s("mjx-c",{attrs:{c:")"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"="}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"5C"}}),s("mjx-c",{attrs:{c:"b"}}),s("mjx-c",{attrs:{c:"e"}}),s("mjx-c",{attrs:{c:"g"}}),s("mjx-c",{attrs:{c:"i"}}),s("mjx-c",{attrs:{c:"n"}}),s("mjx-c",{attrs:{c:"{"}}),s("mjx-c",{attrs:{c:"c"}}),s("mjx-c",{attrs:{c:"a"}}),s("mjx-c",{attrs:{c:"s"}}),s("mjx-c",{attrs:{c:"e"}}),s("mjx-c",{attrs:{c:"s"}}),s("mjx-c",{attrs:{c:"}"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"0"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"&"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"5C"}}),s("mjx-c",{attrs:{c:"t"}}),s("mjx-c",{attrs:{c:"e"}}),s("mjx-c",{attrs:{c:"x"}}),s("mjx-c",{attrs:{c:"t"}}),s("mjx-c",{attrs:{c:"{"}}),s("mjx-utext",{staticStyle:{"font-family":"serif"},attrs:{variant:"normal"}},[t._v("如")]),s("mjx-utext",{staticStyle:{"font-family":"serif"},attrs:{variant:"normal"}},[t._v("果")]),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"}"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"x"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"5C"}}),s("mjx-c",{attrs:{c:"l"}}),s("mjx-c",{attrs:{c:"e"}}),s("mjx-c",{attrs:{c:"q"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"0"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"5C"}}),s("mjx-c",{attrs:{c:"5C"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"1"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"&"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"5C"}}),s("mjx-c",{attrs:{c:"t"}}),s("mjx-c",{attrs:{c:"e"}}),s("mjx-c",{attrs:{c:"x"}}),s("mjx-c",{attrs:{c:"t"}}),s("mjx-c",{attrs:{c:"{"}}),s("mjx-utext",{staticStyle:{"font-family":"serif"},attrs:{variant:"normal"}},[t._v("如")]),s("mjx-utext",{staticStyle:{"font-family":"serif"},attrs:{variant:"normal"}},[t._v("果")]),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"}"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"x"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:">"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"0"}}),s("mjx-c",{attrs:{c:"5C"}}),s("mjx-c",{attrs:{c:" "}}),s("mjx-c",{attrs:{c:"e"}}),s("mjx-c",{attrs:{c:"n"}}),s("mjx-c",{attrs:{c:"d"}}),s("mjx-c",{attrs:{c:"{"}}),s("mjx-c",{attrs:{c:"c"}}),s("mjx-c",{attrs:{c:"a"}}),s("mjx-c",{attrs:{c:"s"}}),s("mjx-c",{attrs:{c:"e"}}),s("mjx-c",{attrs:{c:"s"}}),s("mjx-c",{attrs:{c:"}"}})],1)],1)],1)],1)],1),s("p"),t._v(" "),s("p",[t._v("第二个函数,"),s("code",[t._v("ReLU")]),t._v(",由类似的公式给出。")]),t._v(" "),s("p"),s("p",[t._v("\\text{relu}(x) =\n\\begin{cases}\n0 & \\text{如果 } x \\leq 0 \\\\\nx & \\text{如果 } x > 0\n\\end{cases}")]),s("p"),t._v(" "),s("p",[t._v("在下面实现这两个函数。您可以像这样指定一个固定点数值 "),s("code",[t._v("-3.14.F(8.BP)")]),t._v("。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" Step"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" FixedPoint "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" FixedPoint "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" FixedPoint"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" Mux"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.F")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.F")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.F")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" ReLU"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" FixedPoint "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" FixedPoint "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" FixedPoint"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" Mux"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.F")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.F")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[s("code",[t._v("Mux")]),t._v(" 的第一个参数是比较表达式 "),s("code",[t._v("x > 0.F(0.BP)")]),t._v(",如果这个表达式为真(即 x>0),"),s("code",[t._v("Mux")]),t._v(" 返回第二个参数 "),s("code",[t._v("1.F(0.BP)")]),t._v(";如果为假(即 x<=0),"),s("code",[t._v("Mux")]),t._v(" 返回第三个参数 "),s("code",[t._v("0.F(0.BP)")]),t._v("。")]),t._v(" "),s("h3",{attrs:{id:"tester"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#tester"}},[t._v("#")]),t._v(" Tester")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test our Neuron")]),t._v("\ntest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Neuron"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" inputs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// make this a sequence of two values")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" weights "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// push data through our Neuron and check the result (AND gate)")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reset"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reset"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" inputs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("F"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("F"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("weights"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("weights"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("F"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("weights"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("weights"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("F"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("F"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在您的 "),s("code",[t._v("Neuron")]),t._v(" 测试代码中,改变 "),s("code",[t._v("weights")]),t._v(" 中值的类型从整数 "),s("code",[t._v("1")]),t._v(" 到浮点数 "),s("code",[t._v("1.0")]),t._v(" 是可行的,但这样做后需要确保 "),s("code",[t._v("weights")]),t._v(" 的值赋予 "),s("code",[t._v("FixedPoint")]),t._v(" 类型时小数点位置(binary point)被正确指定。在这个特定的情况下,由于您定义的权重值是 "),s("code",[t._v("1.0")]),t._v(",其实并没有小数部分,转换成定点数时小数部分是 0,所以您可以将其直接视为没有小数点的值。")]),t._v(" "),s("p",[t._v("如果您将 "),s("code",[t._v("weights")]),t._v(" 定义为:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" weights "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("然后在 "),s("code",[t._v("poke")]),t._v(" 操作时,您需要将它们转换为适当的 "),s("code",[t._v("FixedPoint")]),t._v(" 形式。您的权重值 "),s("code",[t._v("1.0")]),t._v(" 实际上在没有小数时与 "),s("code",[t._v("1")]),t._v(" 是等价的,但从概念上讲,使用 "),s("code",[t._v("1.0")]),t._v(" 表示这是一个可以有小数部分的数值。当您将这些权重值赋给 "),s("code",[t._v("FixedPoint")]),t._v(" 信号时,您可以这样操作:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("weights"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("weights"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("F"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("weights"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("weights"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("F"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("BP"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("在这个 "),s("code",[t._v("poke")]),t._v(" 调用中,虽然 "),s("code",[t._v("weights")]),t._v(" 的值是 "),s("code",[t._v("1.0")]),t._v(",但是由于我们这里用的是 "),s("code",[t._v(".F(16.W, 8.BP)")]),t._v(" 转换,它会被认为是没有小数部分的数。在这里,小数点的位置被设置为 8,但由于权重是整数 "),s("code",[t._v("1")]),t._v(" 的等价形式 "),s("code",[t._v("1.0")]),t._v(",其实没有影响。")]),t._v(" "),s("p",[t._v("在决定是否使用小数点时,主要考虑的是您期望的数值范围和精度。如果您的权重值确实需要小数部分,那么您应该使用 "),s("code",[t._v("1.0")]),t._v(" 这样的浮点数表示,并在将其赋给 "),s("code",[t._v("FixedPoint")]),t._v(" 类型时注意指定正确的小数点位置。在您的案例中,由于 "),s("code",[t._v("1.0")]),t._v(" 等价于整数 "),s("code",[t._v("1")]),t._v(",所以实际上并不涉及小数点处理,而是直接转换为了等效的定点数表示。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/46.e01fd024.js b/assets/js/46.e01fd024.js new file mode 100644 index 0000000..eb39d5f --- /dev/null +++ b/assets/js/46.e01fd024.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[46],{311:function(a,t,s){a.exports=s.p+"assets/img/20.0ec3fffd.png"},416:function(a,t,s){"use strict";s.r(t);var e=s(14),n=Object(e.a)({},(function(){var a=this,t=a._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[t("h1",{attrs:{id:"_2024-04-02-练习-2-用-make-来代替-python"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-02-练习-2-用-make-来代替-python"}},[a._v("#")]),a._v(" 2024.04.02-练习 2:用 Make 来代替 Python")]),a._v(" "),t("h2",{attrs:{id:"_1-使用-make"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-使用-make"}},[a._v("#")]),a._v(" 1. 使用 Make")]),a._v(" "),t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[t("span",{pre:!0,attrs:{class:"token function"}},[a._v("make")]),a._v(" ex1\n"),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("CFLAGS")]),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"-Wall"')]),a._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("make")]),a._v(" ex1\n")])])]),t("p",[a._v("第一个命令中你告诉 make,“我想创建名为 ex1 的文件”。于是 Make 执行下面的动作:")]),a._v(" "),t("ul",[t("li",[a._v("文件"),t("code",[a._v("ex1")]),a._v("存在吗?")]),a._v(" "),t("li",[a._v("没有。好的,有没有其他文件以"),t("code",[a._v("ex1")]),a._v("开头?")]),a._v(" "),t("li",[a._v("有,叫做"),t("code",[a._v("ex1.c")]),a._v("。我知道如何构建"),t("code",[a._v(".c")]),a._v("文件吗?")]),a._v(" "),t("li",[a._v("是的,我会运行命令"),t("code",[a._v("cc ex1.c -o ex1")]),a._v("来构建它。")]),a._v(" "),t("li",[a._v("我将使用"),t("code",[a._v("cc")]),a._v("从"),t("code",[a._v("ex1.c")]),a._v("文件来为你构建"),t("code",[a._v("ex1")]),a._v("。")])]),a._v(" "),t("p",[a._v("上面列出的第二条命令是一种向 make 命令传递“修改器”的途径。如果你不熟悉 Unix shell 如何工作,你可以创建这些“环境变量”,它们会在程序运行时生效。有时你会用一条类似于"),t("code",[a._v('export CFLAGS="-Wall"')]),a._v("的命令来执行相同的事情,取决于你所用的 shell。然而你可以仅仅把它们放到你想执行的命令前面,于是环境变量只会在程序运行时有效。")]),a._v(" "),t("p",[a._v("在这个例子中我执行了"),t("code",[a._v('CFLAGS="-Wall" make ex1')]),a._v(",所以它会给 make 通常使用的"),t("code",[a._v("cc")]),a._v("命令添加"),t("code",[a._v("-Wall")]),a._v("选项。这行命令告诉"),t("code",[a._v("cc")]),a._v("编译器要报告所有的警告(然而实际上不可能报告所有警告)。")]),a._v(" "),t("p",[a._v("实际上你可以深入探索使用 make 的上述方法,但是先让我们来看看"),t("code",[a._v("Makefile")]),a._v(",以便让你对 make 了解得更多一点。首先,创建文件并写入以下内容:")]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[a._v("CFLAGS"),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("-Wall -g\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("clean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n rm -f ex1\n")])])]),t("p",[a._v("将文件在你的当前文件夹上保存为"),t("code",[a._v("Makefile")]),a._v("。Make 会自动假设当前文件夹中有一个叫做"),t("code",[a._v("Makefile")]),a._v("的文件,并且会执行它。此外,一定要注意:确保你只输入了 TAB 字符,而不是空格和 TAB 的混合。")]),a._v(" "),t("p",[t("code",[a._v("Makefile")]),a._v("向你展示了 make 的一些新功能。首先我们在文件中设置"),t("code",[a._v("CFLAGS")]),a._v(",所以之后就不用再设置了。并且,我们添加了"),t("code",[a._v("-g")]),a._v("标识来获取调试信息。接着我们写了一个叫做"),t("code",[a._v("clean")]),a._v("的部分,它告诉 make 如何清理我们的小项目。")]),a._v(" "),t("p",[a._v("确保它和你的"),t("code",[a._v("ex1.c")]),a._v("文件在相同的目录中,之后运行以下命令:")]),a._v(" "),t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[t("span",{pre:!0,attrs:{class:"token function"}},[a._v("make")]),a._v(" clean\n"),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("make")]),a._v(" ex1\n")])])]),t("h2",{attrs:{id:"_2-makefile"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-makefile"}},[a._v("#")]),a._v(" 2. Makefile")]),a._v(" "),t("h3",{attrs:{id:"_2-1-语法规则"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-语法规则"}},[a._v("#")]),a._v(" 2.1 语法规则")]),a._v(" "),t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[a._v("目标 "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("..")]),a._v(". "),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(":")]),a._v(" 依赖 "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("..")]),a._v(".\n\t命令1\n\t命令2\n\t"),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(".")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(".")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(".")]),a._v("\n")])])]),t("p",[a._v("Makefile 的核心规则,类似于一位厨神做菜,目标就是做好一道菜,那么所谓的依赖就是各种食材,各种厨具等等,然后需要厨师好的技术方法类似于命令,才能作出一道好菜。同时这些依赖也有可能此时并不存在,需要现场制作,或者是由其他厨师做好,那么这个依赖就成为了其他规则的目标,该目标也会有他自己的依赖和命令。这样就形成了一层一层递归依赖组成了 Makefile 文件。Makefile 并不会关心命令是如何执行的,仅仅只是会去执行所有定义的命令,和我们平时直接输入命令行是一样的效果。")]),a._v(" "),t("p",[a._v("1、目标即要生成的文件。如果目标文件的更新时间晚于依赖文件更新时间,则说明依赖文件没有改动,目标文件不需要重新编译。否则会进行重新编译并更新目标文件。")]),a._v(" "),t("p",[a._v("2、默认情况下 Makefile 的第一个目标为终极目标。")]),a._v(" "),t("p",[a._v("3、依赖:即目标文件由哪些文件生成。")]),a._v(" "),t("p",[a._v("4、命令:即通过执行命令由依赖文件生成目标文件。注意每条命令之前必须有一个 tab 保持缩进,这是语法要求(会有一些编辑工具默认 tab 为 4 个空格,会造成 Makefile 语法错误)。")]),a._v(" "),t("p",[a._v("5、all:Makefile 文件默认只生成第一个目标文件即完成编译,但是我们可以通过 all 指定所需要生成的目标文件。")]),a._v(" "),t("h3",{attrs:{id:"_2-2-变量"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-变量"}},[a._v("#")]),a._v(" 2.2 变量")]),a._v(" "),t("p",[t("code",[a._v("$")]),a._v('符号表示取变量的值,当变量名多于一个字符时,使用"( )"')]),a._v(" "),t("p",[t("code",[a._v("$")]),a._v("符的其他用法")]),a._v(" "),t("p",[t("code",[a._v("$^")]),a._v(" 表示所有的依赖文件")]),a._v(" "),t("p",[t("code",[a._v("$@")]),a._v(" 表示生成的目标文件")]),a._v(" "),t("p",[t("code",[a._v("$<")]),a._v(" 代表第一个依赖文件")]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[a._v("SRC "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("wildcard")]),a._v(" *.c"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\nOBJ "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("patsubst")]),a._v(" %.c, %.o, "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("SRC"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("ALL")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" hello.out\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("hello.out")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("OBJ"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n gcc "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$^")]),a._v(" -o "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$@")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),a._v("(OBJ)")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("SRC"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n gcc -c "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$^")]),a._v(" -o "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$@")]),a._v("\n")])])]),t("h3",{attrs:{id:"_2-3-变量赋值"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-变量赋值"}},[a._v("#")]),a._v(" 2.3 变量赋值")]),a._v(" "),t("p",[a._v('1、"'),t("strong",[a._v("=")]),a._v('"是最普通的等号,在 Makefile 中容易搞错赋值等号,使用 “=”进行赋值,变量的值是整个 Makefile 中最后被指定的值。')]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[a._v("VIR_A "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" A\nVIR_B "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("VIR_A"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" B\nVIR_A "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" AA\n")])])]),t("p",[a._v("经过上面的赋值后,最后 VIR_B 的值是 AA B,而不是 A B,在 make 时,会把整个 Makefile 展开,来决定变量的值")]),a._v(" "),t("p",[a._v('2、"'),t("strong",[a._v(":=")]),a._v('" 表示直接赋值,赋予当前位置的值。')]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[a._v("VIR_A "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":=")]),a._v(" A\nVIR_B "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("VIR_A"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" B\nVIR_A "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":=")]),a._v(" AA\n")])])]),t("p",[a._v("最后 BIR_B 的值是 A B,即根据当前位置进行赋值。因此相当于“=”,“:=”才是真正意义上的直接赋值")]),a._v(" "),t("p",[a._v('3、"'),t("strong",[a._v("?=")]),a._v('" 表示如果该变量没有被赋值,赋值予等号后面的值。')]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[a._v("VIR "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("?=")]),a._v(" new_value\n")])])]),t("p",[a._v("如果 VIR 在之前没有被赋值,那么 VIR 的值就为 new_value。")]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[a._v("VIR "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":=")]),a._v(" old_value\nVIR "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("?=")]),a._v(" new_value\n")])])]),t("p",[a._v("这种情况下,VIR 的值就是 old_value")]),a._v(" "),t("p",[a._v('4、"'),t("strong",[a._v("+=")]),a._v('"和平时写代码的理解是一样的,表示将符号后面的值添加到前面的变量上')]),a._v(" "),t("h3",{attrs:{id:"_2-4-预定义变量"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-4-预定义变量"}},[a._v("#")]),a._v(" 2.4 预定义变量")]),a._v(" "),t("p",[a._v("CC:c 编译器的名称,默认值为 cc。cpp c 预编译器的名称默认值为$(CC) -E")]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[a._v("CC "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" gcc\n")])])]),t("p",[a._v("回显问题,Makefile 中的命令都会被打印出来。如果不想打印命令部分 可以使用@去除回显")]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("@")]),a._v("echo "),t("span",{pre:!0,attrs:{class:"token string"}},[a._v('"clean done!"')]),a._v("\n")])])]),t("p",[t("code",[a._v("@")]),a._v("符号:在"),t("code",[a._v("Makefile")]),a._v("中,当你在命令行前加上"),t("code",[a._v("@")]),a._v("符号,它告诉"),t("code",[a._v("make")]),a._v("在执行这个命令时不要将命令本身输出到标准输出(即不在控制台显示命令)。通常,"),t("code",[a._v("make")]),a._v("会打印每个命令到标准输出,然后执行它。通过在命令前加上"),t("code",[a._v("@")]),a._v("符号,你可以避免显示命令,只显示命令的输出或者执行结果。这可以让你的构建输出看起来更简洁。")]),a._v(" "),t("h3",{attrs:{id:"_2-5-函数"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-函数"}},[a._v("#")]),a._v(" 2.5 函数")]),a._v(" "),t("p",[a._v("通配符 "),t("code",[a._v("SRC = $(wildcard ./*.c)")]),a._v(" 匹配目录下所有.c 文件,并将其赋值给 SRC 变量。")]),a._v(" "),t("p",[t("code",[a._v("OBJ = $(patsubst %.c, %.o, $(SRC))")]),a._v(" 这个函数有三个参数,意思是取出 SRC 中的所有值,然后将.c 替换为.o 最后赋值给 OBJ 变量。")]),a._v(" "),t("p",[a._v("示例:如果目录下有很多个.c 源文件,就不需要写很多条规则语句了,而是可以像下面这样写")]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[a._v("SRC "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("wildcard")]),a._v(" *.c"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\nOBJ "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("patsubst")]),a._v(" %.c, %.o, "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("SRC"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("ALL")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" hello.out\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("hello.out")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("OBJ"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n gcc "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("OBJ"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" -o hello.out\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),a._v("(OBJ)")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("SRC"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n gcc -c "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("SRC"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" -o "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("OBJ"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n")])])]),t("p",[a._v("这里先将所有.c 文件编译为 .o 文件,这样后面更改某个 .c 文件时,其他的 .c 文件将不在编译,而只是编译有更改的 .c 文件,可以大大提高大项目中的编译速度。")]),a._v(" "),t("h3",{attrs:{id:"_2-6-伪目标-phony"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-伪目标-phony"}},[a._v("#")]),a._v(" 2.6 伪目标 .PHONY")]),a._v(" "),t("p",[a._v("伪目标只是一个标签,clean 是个伪目标没有依赖文件,只有用 make 来调用时才会执行")]),a._v(" "),t("p",[a._v("当目录下有与 make 命令 同名的文件时 执行 make 命令就会出现错误。")]),a._v(" "),t("p",[a._v("解决办法就是使用伪目标")]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[a._v("SRC "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("wildcard")]),a._v(" *.c"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\nOBJ "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("patsubst")]),a._v(" %.c, %.o, "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("SRC"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("ALL")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" hello.out\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("hello.out")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("OBJ"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n gcc "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$<")]),a._v(" -o "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$@")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),a._v("(OBJ)")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("SRC"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n gcc -c "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$<")]),a._v(" -o "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$@")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("clean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n rm -rf "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("OBJ"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" hello.out\n\n"),t("span",{pre:!0,attrs:{class:"token builtin-target builtin"}},[a._v(".PHONY")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" clean ALL\n")])])]),t("p",[a._v("通常也会把 ALL 设置成伪目标")]),a._v(" "),t("h3",{attrs:{id:"_2-7-其他常用功能"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-7-其他常用功能"}},[a._v("#")]),a._v(" 2.7 其他常用功能")]),a._v(" "),t("p",[a._v("代码清理 clean")]),a._v(" "),t("p",[a._v("我们可以编译一条属于自己的 clean 语句,来清理 make 命令所产生的所有文件,列如")]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[a._v("SRC "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("wildcard")]),a._v(" *.c"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\nOBJ "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),t("span",{pre:!0,attrs:{class:"token function"}},[a._v("patsubst")]),a._v(" %.c, %.o, "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("SRC"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("ALL")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" hello.out\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("hello.out")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("OBJ"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n gcc "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$<")]),a._v(" -o "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$@")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),a._v("(OBJ)")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("SRC"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n gcc -c "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$<")]),a._v(" -o "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$@")]),a._v("\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("clean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n rm -rf "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("OBJ"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" hello.out\n")])])]),t("h3",{attrs:{id:"_2-8-嵌套执行-makefile"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-8-嵌套执行-makefile"}},[a._v("#")]),a._v(" 2.8 嵌套执行 Makefile")]),a._v(" "),t("p",[a._v("在一些大工程中,会把不同模块或不同功能的源文件放在不同的目录中,我们可以在每个目录中都写一个该目录的 Makefile 这有利于让我们的 Makefile 变的更加简洁,不至于把所有东西全部写在一个 Makefile 中。")]),a._v(" "),t("p",[a._v("列如在子目录 subdir 目录下有个 Makefile 文件,来指明这个目录下文件的编译规则。外部总 Makefile 可以这样写")]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("subsystem")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n cd subdir && "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("MAKE"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n其等价于:\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("subsystem")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("MAKE"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" -C subdir\n")])])]),t("p",[a._v('定义$(MAKE)宏变量的意思是,也许我们的 make 需要一些参数,所以定义成一个变量比较有利于维护。两个例子意思都是先进入"subdir"目录,然后执行 make 命令')]),a._v(" "),t("p",[a._v('我们把这个 Makefile 叫做总控 Makefile,总控 Makefile 的变量可以传递到下级的 Makefile 中,但是不会覆盖下层 Makefile 中所定义的变量,除非指定了 "-e"参数。')]),a._v(" "),t("p",[a._v("如果传递变量到下级 Makefile 中,那么可以使用这样的声明 "),t("code",[a._v("export")]),a._v(" 如果不想让某些变量传递到下级 Makefile,可以使用 "),t("code",[a._v("unexport")])]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("export")]),a._v(" variable "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" value\n等价于\nvariable "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" value\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("export")]),a._v(" variable\n等价于\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("export")]),a._v(" variable "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":=")]),a._v(" value\n等价于\nvariable "),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":=")]),a._v(" value\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("export")]),a._v(" variable\n如果需要传递所有变量,那么只要一个"),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("export")]),a._v("就行了。后面什么也不用跟,表示传递所有变量\n")])])]),t("h3",{attrs:{id:"_2-9-指定头文件路径"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-9-指定头文件路径"}},[a._v("#")]),a._v(" 2.9 指定头文件路径")]),a._v(" "),t("p",[a._v('一般都是通过"'),t("strong",[a._v("-I")]),a._v('"(大写 i)来指定,假设头文件在: '),t("code",[a._v("/home/develop/include")])]),a._v(" "),t("p",[a._v("则可以通过-I 指定: "),t("code",[a._v("-I/home/develop/include")]),a._v(" 将该目录添加到头文件搜索路径中")]),a._v(" "),t("p",[a._v("在 Makefile 中则可以这样写:")]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[a._v("CFLAGS"),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("-I/home/develop/"),t("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("include")]),a._v("\n")])])]),t("p",[a._v("然后在编译的时候,引用 CFLAGS 即可,如下")]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("yourapp")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("*.c\n gcc "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("CFLAGS"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" -o yourapp\n")])])]),t("h2",{attrs:{id:"_3-附加题"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-附加题"}},[a._v("#")]),a._v(" 3. 附加题")]),a._v(" "),t("h3",{attrs:{id:"_3-1-创建目标all-ex1-可以以单个命令make构建ex1"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-创建目标all-ex1-可以以单个命令make构建ex1"}},[a._v("#")]),a._v(" 3.1 创建目标"),t("code",[a._v("all:ex1")]),a._v(",可以以单个命令"),t("code",[a._v("make")]),a._v("构建"),t("code",[a._v("ex1")])]),a._v(" "),t("p",[t("img",{attrs:{src:s(311),alt:"Untitled"}})]),a._v(" "),t("div",{staticClass:"language-makefile extra-class"},[t("pre",{pre:!0,attrs:{class:"language-makefile"}},[t("code",[a._v("CC"),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("gcc\n\nCFLAGS"),t("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("-Wall -g\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("all")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("ex1\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("ex1")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("ex1.o\n\t"),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("CC"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("CFLAGS"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" ex1.o -o ex1\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("ex1.o")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("ex1.c\n\t"),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("CC"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("CFLAGS"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" -c ex1.c -o ex1.o\n\n"),t("span",{pre:!0,attrs:{class:"token target symbol"}},[a._v("clean")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v("\n\trm -f ex1 ex1.o\n"),t("span",{pre:!0,attrs:{class:"token builtin-target builtin"}},[a._v(".PHONY")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(":")]),a._v(" all clean\n")])])]),t("h3",{attrs:{id:"_3-2-阅读man-cc来了解关于-wall和-g行为的更多信息"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-阅读man-cc来了解关于-wall和-g行为的更多信息"}},[a._v("#")]),a._v(" 3.2 阅读"),t("code",[a._v("man cc")]),a._v("来了解关于"),t("code",[a._v("-Wall")]),a._v("和"),t("code",[a._v("-g")]),a._v("行为的更多信息")]),a._v(" "),t("p",[t("strong",[a._v("-Wall")])]),a._v(" "),t("ul",[t("li",[t("code",[a._v("Wall")]),a._v("是一个编译器选项,代表“warn all”,告诉编译器产生尽可能多的警告信息。尽管名称暗示它会启用所有警告,实际上它只启用了最常见的一组警告。这些警告可以帮助开发者发现代码中的潜在问题,比如变量未使用、可能的数据类型不匹配、未初始化的变量等。")]),a._v(" "),t("li",[a._v("使用"),t("code",[a._v("Wall")]),a._v("是一种很好的做法,因为它可以帮助你提前识别潜在的错误或不一致,从而提高代码质量。在开发过程中,尽量解决所有"),t("code",[a._v("Wall")]),a._v("引发的警告,可以避免未来发生更复杂的问题。")])]),a._v(" "),t("p",[t("strong",[a._v("-g")])]),a._v(" "),t("ul",[t("li",[t("code",[a._v("g")]),a._v("选项用于在编译时生成调试信息。这些调试信息包括了程序中的变量、函数、类等符号的名称和类型信息,以及它们在源代码中的位置。这使得调试器(如 GDB)能够理解程序的结构,允许开发者进行断点调试、单步执行、查看变量值等调试操作。")]),a._v(" "),t("li",[a._v("在不使用"),t("code",[a._v("g")]),a._v("选项的情况下编译的程序仍然可以运行,但如果需要调试,缺少调试信息会让这一过程变得非常困难。因此,开发阶段建议总是加上"),t("code",[a._v("g")]),a._v("选项来编译程序,以便在遇到问题时能够更容易地调试。")]),a._v(" "),t("li",[a._v("需要注意的是,添加"),t("code",[a._v("g")]),a._v("选项编译的程序会因为包含了额外的调试信息而变得更大。在发布产品时,通常会移除调试信息(不使用"),t("code",[a._v("g")]),a._v("选项或使用像"),t("code",[a._v("s")]),a._v("这样的选项来剔除调试信息),以减小程序的大小和提高运行时性能。")])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/47.3160d2d2.js b/assets/js/47.3160d2d2.js new file mode 100644 index 0000000..a6f7c47 --- /dev/null +++ b/assets/js/47.3160d2d2.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[47],{326:function(t,s,a){t.exports=a.p+"assets/img/100.f1925d8e.png"},422:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-04-练习10-字符串数组和循环"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-04-练习10-字符串数组和循环"}},[t._v("#")]),t._v(" 2024.04.04-练习10:字符串数组和循环")]),t._v(" "),s("h2",{attrs:{id:"_1-字符串数组"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-字符串数组"}},[t._v("#")]),t._v(" 1. "),s("strong",[t._v("字符串数组")])]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// go through each string in argv")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// why am I skipping argv[0]?")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"arg %d: %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// let's make our own array of strings")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"California"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Oregon"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Washington"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Texas"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" num_states "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" num_states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"state %d: %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("code",[t._v("argv[0]")]),t._v(" 是程序的名称")]),t._v(" "),s("p",[t._v("如果 num_states 大于4,会报段错误,因为这些索引超出了数组 "),s("code",[t._v("states")]),t._v(" ****的初始化范围,它们没有被初始化指向任何有效的字符串。")]),t._v(" "),s("h2",{attrs:{id:"_2-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-附加题"}},[t._v("#")]),t._v(" 2. 附加题")]),t._v(" "),s("h3",{attrs:{id:"_2-1-在for循环的每一部分可以放置什么代码"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-在for循环的每一部分可以放置什么代码"}},[t._v("#")]),t._v(" 2.1 在"),s("code",[t._v("for")]),t._v("循环的每一部分可以放置什么代码")]),t._v(" "),s("ol",[s("li",[t._v("初始化表达式")])]),t._v(" "),s("ul",[s("li",[t._v("这部分在循环开始前执行一次。")]),t._v(" "),s("li",[t._v("常用于初始化循环控制变量。")]),t._v(" "),s("li",[t._v("可以定义一个或多个变量(C99标准之后),也可以是空操作,如果没有需要初始化的变量。")]),t._v(" "),s("li",[t._v("可以执行任何有效的赋值操作或函数调用。")])]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[t._v("条件表达式")])]),t._v(" "),s("ul",[s("li",[t._v("这部分在每次循环迭代之前评估。")]),t._v(" "),s("li",[t._v("决定是否执行循环体。")]),t._v(" "),s("li",[t._v("必须是能够评估为布尔值的表达式。如果表达式结果为"),s("code",[t._v("true")]),t._v("(非零),循环继续;如果为"),s("code",[t._v("false")]),t._v("(零),循环结束。")]),t._v(" "),s("li",[t._v("可以是复杂的表达式,包含逻辑和关系运算符。")])]),t._v(" "),s("ol",{attrs:{start:"3"}},[s("li",[t._v("循环后表达式")])]),t._v(" "),s("ul",[s("li",[t._v("这部分在每次循环迭代的末尾执行,即循环体执行完毕后。")]),t._v(" "),s("li",[t._v("通常用于更新循环控制变量。")]),t._v(" "),s("li",[t._v("可以执行多个更新操作,使用逗号运算符分隔。")])]),t._v(" "),s("h3",{attrs:{id:"_2-2-for-循环中的逗号"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-for-循环中的逗号"}},[t._v("#")]),t._v(" 2.2 "),s("code",[t._v("for")]),t._v(" 循环中的逗号")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" j "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"_2-3-null"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-null"}},[t._v("#")]),t._v(" 2.3 "),s("code",[t._v("NULL")])]),t._v(" "),s("p",[t._v("在C语言中,"),s("code",[t._v("NULL")]),t._v("是一个宏,通常用来表示指针不指向任何有效的对象或位置。它在多个头文件中被定义,如"),s("code",[t._v("")]),t._v("、"),s("code",[t._v("")]),t._v("、"),s("code",[t._v("")]),t._v("等,通常被定义为"),s("code",[t._v("((void *)0)")]),t._v(",即一个类型为"),s("code",[t._v("void*")]),t._v("的空指针。")]),t._v(" "),s("p",[t._v("将"),s("code",[t._v("NULL")]),t._v("用作字符指针数组"),s("code",[t._v("states")]),t._v("的一个元素,相当于在数组中插入一个不指向任何有效字符串的指针。在打印时,尝试访问这个"),s("code",[t._v("NULL")]),t._v("指针所指向的字符串将触发未定义行为(Undefined Behavior, UB),因为试图访问一个不存在的内存位置。在大多数情况下,这可能会导致程序崩溃,因为"),s("code",[t._v("printf")]),t._v("的"),s("code",[t._v("%s")]),t._v("格式化选项期望一个指向有效C字符串的指针。")]),t._v(" "),s("h3",{attrs:{id:"_2-4"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-4"}},[t._v("#")]),t._v(" 2.4")]),t._v(" "),s("p",[s("img",{attrs:{src:a(326),alt:"Untitled"}})])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/48.0c6882e7.js b/assets/js/48.0c6882e7.js new file mode 100644 index 0000000..584a754 --- /dev/null +++ b/assets/js/48.0c6882e7.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[48],{346:function(t,s,a){t.exports=a.p+"assets/img/440.73503d7b.png"},434:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-12-练习44-环形缓冲区"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-12-练习44-环形缓冲区"}},[t._v("#")]),t._v(" 2024.04.12-练习44:环形缓冲区")]),t._v(" "),s("h2",{attrs:{id:"_1-头文件"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-头文件"}},[t._v("#")]),t._v(" 1. 头文件")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("ifndef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("_lcthw_RingBuffer_h")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name"}},[t._v("_lcthw_RingBuffer_h")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typedef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" start"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" end"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" RingBuffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nRingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_empty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_full")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_space")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nbstring "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_gets")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("start "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("RingBuffer_available_space")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("RingBuffer_full")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("RingBuffer_empty")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("RingBuffer_puts")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" D"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bdata")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("D"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("blength")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("D"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("RingBuffer_get_all")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_gets")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("RingBuffer_starts_at")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("buffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("start"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("RingBuffer_ends_at")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("buffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("end"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("RingBuffer_commit_read")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("start "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("start "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("RingBuffer_commit_write")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("endif")])]),t._v("\n")])])]),s("p",[t._v("这段代码定义了一个环形缓冲区(Ring Buffer),它是一种数据结构,用于在有限的缓冲区空间中高效地处理数据流。这种结构非常适合于需要循环利用空间的场景,比如网络通信或文件流处理。以下是代码中各部分的详细解释:")]),t._v(" "),s("h3",{attrs:{id:"头文件和宏定义"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#头文件和宏定义"}},[t._v("#")]),t._v(" 头文件和宏定义")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("ifndef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("_lcthw_RingBuffer_h")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name"}},[t._v("_lcthw_RingBuffer_h")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n")])])]),s("p",[t._v("这部分代码使用预处理命令来防止头文件被重复包含。"),s("code",[t._v("#include ")]),t._v("是引入一个字符串库,这个库可能提供了一些额外的字符串处理功能。")]),t._v(" "),s("h3",{attrs:{id:"结构体定义"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#结构体定义"}},[t._v("#")]),t._v(" 结构体定义")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typedef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" start"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" end"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" RingBuffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("这是环形缓冲区的基础结构,包含了以下字段:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("char *buffer")]),t._v(":指向实际存储数据的内存区域。")]),t._v(" "),s("li",[s("code",[t._v("int length")]),t._v(":缓冲区的总长度。")]),t._v(" "),s("li",[s("code",[t._v("int start")]),t._v(":指示数据开始的位置。")]),t._v(" "),s("li",[s("code",[t._v("int end")]),t._v(":指示数据结束的位置。")])]),t._v(" "),s("h3",{attrs:{id:"函数原型"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#函数原型"}},[t._v("#")]),t._v(" 函数原型")]),t._v(" "),s("p",[t._v("环形缓冲区的操作包括创建、销毁、读取、写入以及检查缓冲区的状态:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("RingBuffer_create(int length)")]),t._v(":创建一个指定长度的环形缓冲区。")]),t._v(" "),s("li",[s("code",[t._v("RingBuffer_destroy(RingBuffer *buffer)")]),t._v(":销毁缓冲区,释放资源。")]),t._v(" "),s("li",[s("code",[t._v("RingBuffer_read(RingBuffer *buffer, char *target, int amount)")]),t._v(":从缓冲区读取数据到"),s("code",[t._v("target")]),t._v("数组。")]),t._v(" "),s("li",[s("code",[t._v("RingBuffer_write(RingBuffer *buffer, char *data, int length)")]),t._v(":将数据写入缓冲区。")]),t._v(" "),s("li",[s("code",[t._v("bstring RingBuffer_gets(RingBuffer *buffer, int amount)")]),t._v(":读取指定数量的数据为一个"),s("code",[t._v("bstring")]),t._v("。")])]),t._v(" "),s("h3",{attrs:{id:"宏定义"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#宏定义"}},[t._v("#")]),t._v(" 宏定义")]),t._v(" "),s("p",[t._v("这些宏定义提供了一种快速访问缓冲区状态的方式,比如检查缓冲区是否空或满:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("RingBuffer_available_data(B)")]),t._v(":计算缓冲区中已存储的数据量。")]),t._v(" "),s("li",[s("code",[t._v("RingBuffer_available_space(B)")]),t._v(":计算缓冲区中剩余的空间量。")]),t._v(" "),s("li",[s("code",[t._v("RingBuffer_full(B)")]),t._v(":检查缓冲区是否已满。")]),t._v(" "),s("li",[s("code",[t._v("RingBuffer_empty(B)")]),t._v(":检查缓冲区是否为空。")]),t._v(" "),s("li",[s("code",[t._v("RingBuffer_puts(B, D)")]),t._v(":便捷函数,用于将"),s("code",[t._v("bstring")]),t._v("类型的数据写入缓冲区。")]),t._v(" "),s("li",[s("code",[t._v("RingBuffer_get_all(B)")]),t._v(":获取缓冲区中的所有数据。")])]),t._v(" "),s("h3",{attrs:{id:"提交数据的宏"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#提交数据的宏"}},[t._v("#")]),t._v(" 提交数据的宏")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("RingBuffer_commit_read(B, A)")]),t._v(":在读取操作后更新"),s("code",[t._v("start")]),t._v("位置。")]),t._v(" "),s("li",[s("code",[t._v("RingBuffer_commit_write(B, A)")]),t._v(":在写入操作后更新"),s("code",[t._v("end")]),t._v("位置。")])]),t._v(" "),s("h2",{attrs:{id:"_2-源文件"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-源文件"}},[t._v("#")]),t._v(" 2. 源文件")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("undef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("NDEBUG")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\nRingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("calloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("start "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("buffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("calloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("start "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_space")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Not enough space: %d request, %d available"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("memcpy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_ends_at")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to write data into buffer."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_commit_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nerror"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check_debug")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("amount "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Not enough in the buffer: has %d, needs %d"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("memcpy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_starts_at")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to write buffer into data."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_commit_read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("start"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("start "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nerror"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nbstring "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_gets")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("amount "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Need more than 0 for gets, you gave: %d "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check_debug")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("amount "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Not enough in the buffer."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n bstring result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("blk2bstr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_starts_at")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to create gets result."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("blength")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Wrong result length."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_commit_read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error in read commit."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nerror"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("这个 "),s("code",[t._v("RingBuffer_write")]),t._v(" 函数是一个环形缓冲区的写操作函数,其作用是将数据从一个指定的源("),s("code",[t._v("data")]),t._v(" 参数)写入到环形缓冲区中。这段代码涉及错误检查、内存复制以及更新缓冲区指针的操作。下面我将逐步解析这个函数的每一部分。")]),t._v(" "),s("h3",{attrs:{id:"ringbuffer-write函数签名"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#ringbuffer-write函数签名"}},[t._v("#")]),t._v(" "),s("code",[t._v("RingBuffer_write")]),t._v("函数签名")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("这个函数接收三个参数:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("buffer")]),t._v(":指向 "),s("code",[t._v("RingBuffer")]),t._v(" 类型的指针,代表目标环形缓冲区。")]),t._v(" "),s("li",[s("code",[t._v("data")]),t._v(":指向需要写入缓冲区的数据的指针。")]),t._v(" "),s("li",[s("code",[t._v("length")]),t._v(":指定要写入的数据长度。")])]),t._v(" "),s("p",[t._v("函数返回写入的字节数,如果出现错误,则返回 "),s("code",[t._v("-1")]),t._v("。")]),t._v(" "),s("h3",{attrs:{id:"函数体"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#函数体"}},[t._v("#")]),t._v(" 函数体")]),t._v(" "),s("h3",{attrs:{id:"确定起始位置"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#确定起始位置"}},[t._v("#")]),t._v(" 确定起始位置")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("start "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" buffer"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("这里检查缓冲区是否为空(没有数据)。如果是空的,将 "),s("code",[t._v("start")]),t._v(" 和 "),s("code",[t._v("end")]),t._v(" 指针都重置为 "),s("code",[t._v("0")]),t._v("。这种重置是为了优化写入性能,确保从缓冲区的开始位置写入数据。")]),t._v(" "),s("h3",{attrs:{id:"检查是否有足够空间"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#检查是否有足够空间"}},[t._v("#")]),t._v(" 检查是否有足够空间")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_space")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Not enough space: %d request, %d available"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("使用 "),s("code",[t._v("check")]),t._v(" 宏(这通常是一个错误处理宏)来确保要写入的数据长度不会超过缓冲区的可用空间。如果超出可用空间,则打印错误信息并跳转到错误处理代码("),s("code",[t._v("error:")]),t._v(" 标签)。")]),t._v(" "),s("h3",{attrs:{id:"数据复制"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#数据复制"}},[t._v("#")]),t._v(" 数据复制")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("memcpy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_ends_at")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to write data into buffer."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("通过 "),s("code",[t._v("memcpy")]),t._v(" 函数将数据从 "),s("code",[t._v("data")]),t._v(" 指针复制到缓冲区中由 "),s("code",[t._v("RingBuffer_ends_at(buffer)")]),t._v(" 返回的位置。"),s("code",[t._v("memcpy")]),t._v(" 应该总是返回其目的地址,除非发生异常。这里的检查是为了确保数据确实被写入了。")]),t._v(" "),s("h3",{attrs:{id:"提交写操作"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#提交写操作"}},[t._v("#")]),t._v(" 提交写操作")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_commit_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("buffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("更新缓冲区的 "),s("code",[t._v("end")]),t._v(" 指针,以反映新写入的数据量。这通过 "),s("code",[t._v("RingBuffer_commit_write")]),t._v(" 宏实现,它会适当地调整 "),s("code",[t._v("end")]),t._v(" 指针,包括处理可能的环形回绕。")]),t._v(" "),s("h3",{attrs:{id:"成功返回"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#成功返回"}},[t._v("#")]),t._v(" 成功返回")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("如果一切正常,函数返回写入的字节数。")]),t._v(" "),s("h3",{attrs:{id:"错误处理"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#错误处理"}},[t._v("#")]),t._v(" 错误处理")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[t._v("error"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("如果在检查或写操作中遇到任何问题,函数跳转到这里并返回 "),s("code",[t._v("-1")]),t._v(",表示发生了错误。")]),t._v(" "),s("h3",{attrs:{id:"ringbuffer-write总结"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#ringbuffer-write总结"}},[t._v("#")]),t._v(" "),s("code",[t._v("RingBuffer_write")]),t._v("总结")]),t._v(" "),s("p",[s("code",[t._v("RingBuffer_write")]),t._v(" 是一个典型的环形缓冲区数据写入函数,它涵盖了错误处理、空间检查、数据复制和指针更新等关键操作。这种实现保证了数据的安全写入,并且能有效地利用缓冲区的空间。通过适当的指针和边界管理,环形缓冲区可以在有限的内存空间内循环使用,非常适用于如 I/O 数据流处理等场景。")]),t._v(" "),s("p",[s("code",[t._v("RingBuffer_read")]),t._v(" 和 "),s("code",[t._v("RingBuffer_gets")]),t._v(" 都是环形缓冲区中用于从缓冲区读取数据的函数,但它们在处理数据的方式和返回类型上有所不同。这两个函数各有其特定的用途和行为,下面详细解释这两者之间的区别:")]),t._v(" "),s("h3",{attrs:{id:"ringbuffer-read"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#ringbuffer-read"}},[t._v("#")]),t._v(" "),s("code",[t._v("RingBuffer_read")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("功能")]),t._v(":将数据从环形缓冲区复制到另一个缓冲区(通常是一个字符数组)。")]),t._v(" "),s("li",[s("strong",[t._v("参数")]),t._v(":\n"),s("ul",[s("li",[s("code",[t._v("buffer")]),t._v(":指向 "),s("code",[t._v("RingBuffer")]),t._v(" 结构的指针。")]),t._v(" "),s("li",[s("code",[t._v("target")]),t._v(":目标缓冲区,用于接收从环形缓冲区复制的数据。")]),t._v(" "),s("li",[s("code",[t._v("amount")]),t._v(":要从环形缓冲区读取的数据字节数。")])])]),t._v(" "),s("li",[s("strong",[t._v("行为")]),t._v(":\n"),s("ul",[s("li",[t._v("使用 "),s("code",[t._v("memcpy")]),t._v(" 从 "),s("code",[t._v("RingBuffer_starts_at(buffer)")]),t._v(" 的位置开始,将 "),s("code",[t._v("amount")]),t._v(" 字节的数据复制到 "),s("code",[t._v("target")]),t._v(" 中。")]),t._v(" "),s("li",[t._v("读取操作完成后,通过 "),s("code",[t._v("RingBuffer_commit_read")]),t._v(" 更新 "),s("code",[t._v("start")]),t._v(" 指针。")]),t._v(" "),s("li",[t._v("如果 "),s("code",[t._v("start")]),t._v(" 和 "),s("code",[t._v("end")]),t._v(" 指针相等,表示缓冲区变为空,将它们重置为0。")])])]),t._v(" "),s("li",[s("strong",[t._v("返回值")]),t._v(":成功时返回读取的字节数,失败时返回 "),s("code",[t._v("1")]),t._v("。")])]),t._v(" "),s("h3",{attrs:{id:"ringbuffer-gets"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#ringbuffer-gets"}},[t._v("#")]),t._v(" "),s("code",[t._v("RingBuffer_gets")])]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("功能")]),t._v(":从环形缓冲区获取一定数量的数据,并返回一个 "),s("code",[t._v("bstring")]),t._v(" 对象。")]),t._v(" "),s("li",[s("strong",[t._v("参数")]),t._v(":\n"),s("ul",[s("li",[s("code",[t._v("buffer")]),t._v(":指向 "),s("code",[t._v("RingBuffer")]),t._v(" 结构的指针。")]),t._v(" "),s("li",[s("code",[t._v("amount")]),t._v(":要从环形缓冲区读取的数据字节数。")])])]),t._v(" "),s("li",[s("strong",[t._v("行为")]),t._v(":\n"),s("ul",[s("li",[t._v("使用 "),s("code",[t._v("blk2bstr")]),t._v(" 从环形缓冲区的 "),s("code",[t._v("start")]),t._v(" 位置创建一个新的 "),s("code",[t._v("bstring")]),t._v(" 对象,其中包含 "),s("code",[t._v("amount")]),t._v(" 字节的数据。")]),t._v(" "),s("li",[t._v("类似于 "),s("code",[t._v("RingBuffer_read")]),t._v(",读取操作后通过 "),s("code",[t._v("RingBuffer_commit_read")]),t._v(" 更新 "),s("code",[t._v("start")]),t._v(" 指针。")]),t._v(" "),s("li",[t._v("检查返回的 "),s("code",[t._v("bstring")]),t._v(" 的长度是否正确,并确保没有数据处理错误。")])])]),t._v(" "),s("li",[s("strong",[t._v("返回值")]),t._v(":成功时返回一个 "),s("code",[t._v("bstring")]),t._v(" 对象,失败时返回 "),s("code",[t._v("NULL")]),t._v("。")])]),t._v(" "),s("h3",{attrs:{id:"主要区别"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#主要区别"}},[t._v("#")]),t._v(" 主要区别")]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("返回类型")]),t._v(":\n"),s("ul",[s("li",[s("code",[t._v("RingBuffer_read")]),t._v(" 返回一个整数(读取的字节数),并将数据直接写入提供的目标缓冲区。")]),t._v(" "),s("li",[s("code",[t._v("RingBuffer_gets")]),t._v(" 返回一个 "),s("code",[t._v("bstring")]),t._v(" 对象,这是一个封装了数据和长度的结构体,用于更方便的字符串处理。")])])]),t._v(" "),s("li",[s("strong",[t._v("数据处理方式")]),t._v(":\n"),s("ul",[s("li",[s("code",[t._v("RingBuffer_read")]),t._v(" 直接操作原始字节数据。")]),t._v(" "),s("li",[s("code",[t._v("RingBuffer_gets")]),t._v(" 则可能更适用于处理文本数据,因为它提供了一种易于管理和操作的字符串形式。")])])]),t._v(" "),s("li",[s("strong",[t._v("错误处理和安全性")]),t._v(":\n"),s("ul",[s("li",[s("code",[t._v("RingBuffer_gets")]),t._v(" 在创建 "),s("code",[t._v("bstring")]),t._v(" 时进行了额外的检查,如长度验证和空值检查,这可以提供更高的数据完整性保证。")])])]),t._v(" "),s("li",[s("strong",[t._v("使用场景")]),t._v(":\n"),s("ul",[s("li",[s("code",[t._v("RingBuffer_read")]),t._v(" 更多地用于需要直接处理字节数据的场景,如文件读写、网络数据传输等。")]),t._v(" "),s("li",[s("code",[t._v("RingBuffer_gets")]),t._v(" 适用于需要字符串操作的场景,比如解析文本命令或读取配置文件等。")])])])]),t._v(" "),s("p",[t._v("总之,选择 "),s("code",[t._v("RingBuffer_read")]),t._v(" 还是 "),s("code",[t._v("RingBuffer_gets")]),t._v(" 取决于你的应用场景和对数据类型的需求。如果你需要直接处理原始数据,"),s("code",[t._v("RingBuffer_read")]),t._v(" 是合适的;如果你需要处理和存储字符串数据,并可能在之后进行进一步的字符串操作,"),s("code",[t._v("RingBuffer_gets")]),t._v(" 会是更好的选择。")]),t._v(" "),s("h2",{attrs:{id:"_3-测试"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-测试"}},[t._v("#")]),t._v(" 3. 测试")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"minunit.h"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 引入MinUnit头文件")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RingBuffer.h"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 引入环形缓冲区的实现")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name"}},[t._v("NUM_TESTS")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" RingBuffer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("rb "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n rb "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1024")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rb "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to create RingBuffer"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rb"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1025")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RingBuffer length incorrect"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_empty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rb"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RingBuffer should be empty after creation"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_write_read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_write")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rb"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RingBuffer_write should write 4 bytes"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 确保有足够的空间和零初始化")]),t._v("\n result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_read")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rb"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RingBuffer_read should read 4 bytes"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strcmp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RingBuffer_read did not read the correct data"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_puts_get_all")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n bstring data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bfromcstr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_puts")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rb"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n bstring result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_get_all")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rb"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("biseq")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RingBuffer_get_all did not return the correct data"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bdestroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bdestroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_puts_gets")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n bstring data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bfromcstr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_puts")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rb"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n bstring result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_gets")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rb"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("biseq")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"RingBuffer_gets did not return the correct data"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bdestroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bdestroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rb "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to create RingBuffer#2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rb"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("all_tests")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_suite_start")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 初始化测试套件")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_run_test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("test_create"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_run_test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("test_write_read"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_run_test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("test_puts_get_all"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_run_test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("test_puts_gets"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_run_test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("test_destroy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用RUN_TESTS宏运行所有测试")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RUN_TESTS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("all_tests"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("img",{attrs:{src:a(346),alt:"Untitled"}})]),t._v(" "),s("h2",{attrs:{id:"_4-一些修改"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-一些修改"}},[t._v("#")]),t._v(" 4. 一些修改")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//#define RingBuffer_available_data(B) (((B)->end + 1) % (B)->length - (B)->start - 1)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("start"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("end "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("start"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("start "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("end"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//#define RingBuffer_available_space(B) ((B)->length - (B)->end - 1)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("RingBuffer_available_space")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//#define RingBuffer_full(B) (RingBuffer_available_data((B)) - (B)->length == 0)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("RingBuffer_full")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("RingBuffer_available_space")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n")])])]),s("p",[t._v("原来的宏并没有判断end与start的前后位置。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/49.936e67cd.js b/assets/js/49.936e67cd.js new file mode 100644 index 0000000..4d1d994 --- /dev/null +++ b/assets/js/49.936e67cd.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[49],{367:function(a,s,t){a.exports=t.p+"assets/img/G4E.f2c635d7.jpeg"},461:function(a,s,t){"use strict";t.r(s);var e=t(14),n=Object(e.a)({},(function(){var a=this,s=a._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[s("h1",{attrs:{id:"_2023-02-13-在超算上搭建singularity环境并配置geant4"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2023-02-13-在超算上搭建singularity环境并配置geant4"}},[a._v("#")]),a._v(" 2023.02.13-在超算上搭建Singularity环境并配置Geant4")]),a._v(" "),s("h2",{attrs:{id:"i-制作singularity包"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#i-制作singularity包"}},[a._v("#")]),a._v(" I. 制作singularity包")]),a._v(" "),s("h3",{attrs:{id:"_1-进入fakeroot节点"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-进入fakeroot节点"}},[a._v("#")]),a._v(" 1. 进入fakeroot节点")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("ssh")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("<")]),a._v("user_id"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(">")]),a._v("@162.105.133.209\n")])])]),s("h3",{attrs:{id:"_2-制作并进入sandbox镜像"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-制作并进入sandbox镜像"}},[a._v("#")]),a._v(" 2. 制作并进入sandbox镜像")]),a._v(" "),s("ol",[s("li",[s("p",[a._v("搭建ubuntu")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("singularity build "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--fakeroot")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--sandbox")]),a._v(" Geant4 docker://ubuntu:22.04\n")])])])]),a._v(" "),s("li",[s("p",[a._v("进入Geant4环境(sandbox)")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("singularity shell "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--fakeroot")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" Geant4\n")])])])])]),a._v(" "),s("h3",{attrs:{id:"_3-配置geant4环境"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-配置geant4环境"}},[a._v("#")]),a._v(" 3. 配置geant4环境")]),a._v(" "),s("ol",[s("li",[s("p",[a._v("安装基本环境")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("apt-get")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" build-essential\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("apt-get")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("wget")]),a._v("\n")])])])]),a._v(" "),s("li",[s("p",[a._v("下载geant4")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("mkdir")]),a._v(" geant4\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("wget")]),a._v(" https://geant4-data.web.cern.ch/releases/geant4-v11.1.0.tar.gz\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("tar")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-xzvf")]),a._v(" geant4-v11.1.0.tar.gz\n")])])])]),a._v(" "),s("li",[s("p",[a._v("安装依赖包(若报错,则分别单独安装)")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sudo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("apt-get")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-y")]),a._v(" cmake libx11-dev libxext-dev libxtst-dev libxrender-dev libxmu-dev libxmuu-dev libhdf5-serial-dev hdf5-tools\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sudo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("apt-get")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-y")]),a._v(" libexpat1-dev\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sudo")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("apt")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-y")]),a._v(" qt5*\n")])])])]),a._v(" "),s("li",[s("p",[a._v("编译安装")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("mkdir")]),a._v(" build\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("cd")]),a._v(" build\ncmake "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-DCMAKE_INSTALL_PREFIX")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("/root/Geant4/home/geant4 /root/Geant4/home/geant4-v11.1.0\ncmake "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-DGEANT4_INSTALL_DATA")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("ON "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(".")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("make")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-jN")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# N表示处理器数量,需修改为实际值")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("make")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("install")]),a._v("\n")])])])]),a._v(" "),s("li",[s("p",[a._v("配置环境变量")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("cd")]),a._v(" /root/Geant4/etc/skel/\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("vim")]),a._v(" .bashrc\n")])])]),s("p",[a._v("将下列内容添加到 "),s("code",[a._v(".bashrc")])]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("source")]),a._v(" /root/Geant4/home/geant4/bin/geant4.sh\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("source")]),a._v(" /root/Geant4/home/geant4/share/Geant4/geant4make/geant4make.sh\n")])])]),s("p",[a._v("配置")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("cp")]),a._v(" /root/Geant4/etc/skel/.bashrc /root/Geant4/home\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("cd")]),a._v(" /root/Geant4/home\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("source")]),a._v(" .bashrc\n")])])])]),a._v(" "),s("li",[s("p",[a._v("检验geant4是否配置成功")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("cd")]),a._v(" /root/Geant4/home/geant4/share/Geant4/examples/basic/B1\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("mkdir")]),a._v(" build "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("&&")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("cd")]),a._v(" build\ncmake "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("..")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("make")]),a._v("\n./exampleB1 run1.mac\n")])])]),s("p",[a._v("若无报错则配置成功")])]),a._v(" "),s("li",[s("p",[a._v("退出")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exit")]),a._v("\n")])])])])]),a._v(" "),s("h3",{attrs:{id:"_4-打包"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-打包"}},[a._v("#")]),a._v(" 4. 打包")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("singularity build "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--fakeroot")]),a._v(" s-Geant4.sif Geant4/\n")])])]),s("hr"),a._v(" "),s("h2",{attrs:{id:"ii-配置go-singularity"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#ii-配置go-singularity"}},[a._v("#")]),a._v(" II. 配置go&singularity")]),a._v(" "),s("h3",{attrs:{id:"_1-配置go环境"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-配置go环境"}},[a._v("#")]),a._v(" 1. 配置go环境")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 超算Data节点")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("VERSION")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("1.17")]),a._v(".2 "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("OS")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("linux "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("ARCH")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("amd64\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("wget")]),a._v(" https://dl.google.com/go/go"),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$VERSION")]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$OS")]),a._v("-"),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$ARCH")]),a._v(".tar.gz\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("tar")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-xzvf")]),a._v(" go1.17.2.linux-amd64.tar.gz\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("rm")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-f")]),a._v(" go1.17.2.linux-amd64.tar.gz\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("export")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s("span",{pre:!0,attrs:{class:"token environment constant"}},[a._v("PATH")])]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v("/lustre/home/"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("<")]),a._v("user_id"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(">")]),a._v("/go/bin:"),s("span",{pre:!0,attrs:{class:"token environment constant"}},[a._v("$PATH")]),a._v("\n")])])]),s("h3",{attrs:{id:"_2-安装singularity"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-安装singularity"}},[a._v("#")]),a._v(" 2. 安装singularity")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("module load singularity/3.11.3\n")])])]),s("h3",{attrs:{id:"_3-环境变量"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-环境变量"}},[a._v("#")]),a._v(" 3. 环境变量")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("cd")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token environment constant"}},[a._v("$HOME")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("vim")]),a._v(" .bashrc\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 将下列语句添加到.bashrc中")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# export PATH=/lustre/home//go/bin:$PATH")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("source")]),a._v(" .bashrc\n")])])]),s("hr"),a._v(" "),s("h2",{attrs:{id:"iii-启用singularity"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#iii-启用singularity"}},[a._v("#")]),a._v(" III. 启用singularity")]),a._v(" "),s("h3",{attrs:{id:"_1-将sif镜像下载到常规节点"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-将sif镜像下载到常规节点"}},[a._v("#")]),a._v(" 1. 将SIF镜像下载到常规节点")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("scp")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-r")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("<")]),a._v("user_id"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(">")]),a._v("@162.105.133.209:/home/"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("<")]),a._v("user_id"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(">")]),a._v("/s-Geant4.sif /gpfs/share/home/"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("<")]),a._v("user_id"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(">")]),a._v("/\n")])])]),s("h3",{attrs:{id:"_2-转换成sandbox镜像并启用"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-转换成sandbox镜像并启用"}},[a._v("#")]),a._v(" 2. 转换成sandbox镜像并启用")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[a._v("singularity build "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--sandbox")]),a._v(" Geant4 s-Geant4.sif\nsingularity shell "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" Geant4\n")])])]),s("h3",{attrs:{id:"_3-配置环境变量"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-配置环境变量"}},[a._v("#")]),a._v(" 3. 配置环境变量")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("cd")]),a._v(" Geant4/home\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("vim")]),a._v(" .bashrc\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 将下列语句添加到文件末尾")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# source /lustre/home/2201210084/singularity/Geant4/home/geant4/bin/geant4.sh")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# source /lustre/home/2201210084/singularity/Geant4/home/geant4/share/Geant4/geant4make/geant4make.sh")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("source")]),a._v(" .bashrc\n")])])]),s("p",[a._v("看见如下字样表示成功")]),a._v(" "),s("p",[s("img",{attrs:{src:t(367),alt:"Untitled"}})]),a._v(" "),s("h2",{attrs:{id:"iv-附录"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#iv-附录"}},[a._v("#")]),a._v(" IV. 附录")]),a._v(" "),s("h3",{attrs:{id:"_1-sif容器与sandbox相互转换"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-sif容器与sandbox相互转换"}},[a._v("#")]),a._v(" 1. SIF容器与sandbox相互转换")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 1. 将SIF格式的容器转换成sandbox;")]),a._v("\nsingularity build "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--sandbox")]),a._v(" XXX XXX.sif\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 2. 将sandbox容器镜像转化成SIF格式;")]),a._v("\nsingularity build XXX.sif XXX\n")])])]),s("h3",{attrs:{id:"_2-在fakeroot节点上删除sandbox镜像"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-在fakeroot节点上删除sandbox镜像"}},[a._v("#")]),a._v(" 2. 在fakeroot节点上删除sandbox镜像")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 假设要删除的为文件夹名为molspin的sandbox镜像")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 首先,以可读的模式进入要删除的镜像")]),a._v("\nsingularity shell "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--fakeroot")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-w")]),a._v(" molspin\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 删除掉容器中,基于fakeroot创建的所有文件")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("rm")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-rf")]),a._v(" /* "),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[a._v("1")]),a._v(">")]),a._v("/dev/null "),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[a._v("2")]),a._v(">")]),s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[a._v("&1")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 退出镜像")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("exit")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 将创建好的软件镜像上传到高性能计算集群,加载singularity软件环境")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 删除掉剩下的")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("rm")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-rf")]),a._v(" molspin\n")])])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/5.936fe44f.js b/assets/js/5.936fe44f.js new file mode 100644 index 0000000..db7c5b0 --- /dev/null +++ b/assets/js/5.936fe44f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[5],{280:function(t,e,a){},294:function(t,e,a){"use strict";a(280)},381:function(t,e,a){"use strict";a.r(e);var s={name:"CodeBlock",props:{title:{type:String,required:!0},active:{type:Boolean,default:!1}},mounted(){this.$parent&&this.$parent.loadTabs&&this.$parent.loadTabs()}},i=(a(294),a(14)),n=Object(i.a)(s,(function(){return(0,this._self._c)("div",{staticClass:"theme-code-block",class:{"theme-code-block__active":this.active}},[this._t("default")],2)}),[],!1,null,"759a7d02",null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/50.47755b12.js b/assets/js/50.47755b12.js new file mode 100644 index 0000000..f85380e --- /dev/null +++ b/assets/js/50.47755b12.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[50],{375:function(t,e,o){t.exports=o.p+"assets/img/4.5c72e81f.png"},472:function(t,e,o){"use strict";o.r(e);var r=o(14),v=Object(r.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"_04-🥙-目录挂载"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_04-🥙-目录挂载"}},[t._v("#")]),t._v(" 04. 🥙 目录挂载")]),t._v(" "),e("h3",{attrs:{id:"现存问题"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#现存问题"}},[t._v("#")]),t._v(" 现存问题")]),t._v(" "),e("ul",[e("li",[t._v("使用 Docker 运行后,我们改了项目代码不会立刻生效,需要重新"),e("code",[t._v("build")]),t._v("和"),e("code",[t._v("run")]),t._v(",很是麻烦。")]),t._v(" "),e("li",[t._v("容器里面产生的数据,例如 log 文件,数据库备份文件,容器删除后就丢失了。")])]),t._v(" "),e("blockquote",[e("p",[t._v("目录挂载解决以上问题")])]),t._v(" "),e("blockquote",[e("p",[t._v("本文档课件配套 视频教程")])]),t._v(" "),e("h3",{attrs:{id:"几种挂载方式"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#几种挂载方式"}},[t._v("#")]),t._v(" 几种挂载方式")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("bind mount")]),t._v(" 直接把宿主机目录映射到容器内,适合挂代码目录和配置文件。可挂到多个容器上")]),t._v(" "),e("li",[e("code",[t._v("volume")]),t._v(" 由容器创建和管理,创建在宿主机,所以删除容器不会丢失,官方推荐,更高效,Linux 文件系统,适合存储数据库数据。可挂到多个容器上")]),t._v(" "),e("li",[e("code",[t._v("tmpfs mount")]),t._v(" 适合存储临时文件,存宿主机内存中。不可多容器共享。")])]),t._v(" "),e("p",[t._v("文档参考:"),e("a",{attrs:{href:"https://docs.docker.com/storage/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://docs.docker.com/storage/"),e("OutboundLink")],1)]),t._v(" "),e("p",[e("img",{attrs:{src:o(375),alt:"Untitled"}})]),t._v(" "),e("h3",{attrs:{id:"挂载演示"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#挂载演示"}},[t._v("#")]),t._v(" 挂载演示")]),t._v(" "),e("p",[e("code",[t._v("bind mount")]),t._v(" 方式用绝对路径 "),e("code",[t._v("-v D:/code:/app")])]),t._v(" "),e("p",[e("code",[t._v("volume")]),t._v(" 方式,只需要一个名字 "),e("code",[t._v("-v db-data:/app")])]),t._v(" "),e("p",[t._v("示例:")]),t._v(" "),e("p",[e("code",[t._v("docker run -p 8080:8080 --name test-hello -v D:/code:/app -d test:v1")])]),t._v(" "),e("blockquote",[e("p",[t._v("注意!")]),t._v(" "),e("p",[t._v("因为挂载后,容器里的代码就会替换为你本机的代码了,如果你代码目录没有"),e("code",[t._v("node_modules")]),t._v("目录,你需要在代码目录执行下"),e("code",[t._v("npm install --registry=https://registry.npm.taobao.org")]),t._v("确保依赖库都已经安装,否则可能会提示“Error: Cannot find module ‘koa’”")]),t._v(" "),e("p",[t._v("如果你的电脑没有安装 "),e("a",{attrs:{href:"https://nodejs.org/en/",target:"_blank",rel:"noopener noreferrer"}},[t._v("nodejs"),e("OutboundLink")],1),t._v(",你需要安装一下才能执行上面的命令。")])])])}),[],!1,null,null,null);e.default=v.exports}}]); \ No newline at end of file diff --git a/assets/js/51.ac66a436.js b/assets/js/51.ac66a436.js new file mode 100644 index 0000000..1023b4b --- /dev/null +++ b/assets/js/51.ac66a436.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[51],{376:function(a,s,t){a.exports=t.p+"assets/img/1212.4aca9893.png"},478:function(a,s,t){"use strict";t.r(s);var e=t(14),r=Object(e.a)({},(function(){var a=this,s=a._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[s("h1",{attrs:{id:"_2023-12-12-制作定制镜像"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2023-12-12-制作定制镜像"}},[a._v("#")]),a._v(" 2023.12.12-制作定制镜像")]),a._v(" "),s("h2",{attrs:{id:"_1-获取ubuntu系统"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-获取ubuntu系统"}},[a._v("#")]),a._v(" 1. 获取Ubuntu系统")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" ubuntu:22.04 /bin/bash\n")])])]),s("p",[s("img",{attrs:{src:t(376),alt:"Untitled"}})]),a._v(" "),s("h2",{attrs:{id:"_2-在容器内配置容器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-在容器内配置容器"}},[a._v("#")]),a._v(" 2. 在容器内配置容器")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("apt-get")]),a._v(" update "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("&&")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("apt-get")]),a._v(" upgrade\n")])])]),s("h2",{attrs:{id:"_3-将容器打包成镜像"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-将容器打包成镜像"}},[a._v("#")]),a._v(" 3. 将容器打包成镜像")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" commit "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-m")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"geant4 installed"')]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-a")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"OutisPKU"')]),a._v(" f87240cdb380 outispku/geant4:v1\n")])])]),s("h2",{attrs:{id:"_4-将镜像实例化为容器并运行终端"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-将镜像实例化为容器并运行终端"}},[a._v("#")]),a._v(" 4. 将镜像实例化为容器并运行终端")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-it")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-v")]),a._v(" D:"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v("BaiduSyncdisk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v("Postgraduate"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v("Research"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v("Geant4"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v("Project:/home "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--name")]),a._v(" geant4_test outispku/geant4:v1 /bin/bash\n")])])]),s("p",[a._v("其中"),s("code",[a._v("-v D:\\BaiduSyncdisk\\Postgraduate\\Research\\Geant4\\Project:/home")]),a._v("为将主机的目录映射到容器中")]),a._v(" "),s("h1",{attrs:{id:"使用dockerfile创建镜像"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用dockerfile创建镜像"}},[a._v("#")]),a._v(" 使用Dockerfile创建镜像")]),a._v(" "),s("h2",{attrs:{id:"_1-编写容器启动脚本start-sh"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-编写容器启动脚本start-sh"}},[a._v("#")]),a._v(" 1. 编写容器启动脚本"),s("code",[a._v("start.sh")])]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token shebang important"}},[a._v("#!/bin/bash")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# Source Geant4 environment scripts")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("source")]),a._v(" /geant4/bin/geant4.sh\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("source")]),a._v(" /geant4/share/Geant4/geant4make/geant4make.sh\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 获取系统的线程数")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("NUM_THREADS")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$(")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("expr")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("$(")]),a._v("nproc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" - "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("1")]),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v(")")])]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("cd")]),a._v(" /program\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 构建命令")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("CMD_TO_ADD")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"/run/numberOfThreads '),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$NUM_THREADS")]),a._v('"')]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 将命令添加到 run.mac 的第一行")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("sed")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-i")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"1i '),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$CMD_TO_ADD")]),a._v('"')]),a._v(" ./run.mac\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 定义目录路径")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[a._v("BUILD_DIR")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"/program/build"')]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 检查目录是否存在")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("if")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("[")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-d")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"'),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BUILD_DIR")]),a._v('"')]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("then")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 如果目录存在,删除它")]),a._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("rm")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-rf")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"'),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BUILD_DIR")]),a._v('"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("fi")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 创建新的目录")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("mkdir")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-p")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"'),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$BUILD_DIR")]),a._v('"')]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v("cd")]),a._v(" build\ncmake "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("..")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("make")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-j")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[a._v("$NUM_THREADS")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# PKU_Trim_Geant4 为程序名称(可执行文件),由CMakeLists.txt中的add_executable(PKU_Trim_Geant4 PKU_Trim_Geant4.cc)决定")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 使用前请修改")]),a._v("\n./PKU_Trim_Geant4 run.mac "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(">")]),a._v(" /dev/null "),s("span",{pre:!0,attrs:{class:"token operator"}},[s("span",{pre:!0,attrs:{class:"token file-descriptor important"}},[a._v("2")]),a._v(">>")]),a._v("error.txt\n")])])]),s("h2",{attrs:{id:"_2-编写dockerfile"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-编写dockerfile"}},[a._v("#")]),a._v(" 2. 编写"),s("code",[a._v("Dockerfile")])]),a._v(" "),s("div",{staticClass:"language-docker extra-class"},[s("pre",{pre:!0,attrs:{class:"language-docker"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 原单Geant4镜像")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token instruction"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("FROM")]),a._v(" outispku/geant4:v1")]),a._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[a._v("# 指定启动脚本")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token instruction"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("COPY")]),a._v(" start.sh /")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token instruction"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("RUN")]),a._v(" chmod +x /start.sh")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token instruction"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("RUN")]),a._v(" mkdir program")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token instruction"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("ENTRYPOINT")]),a._v(" ["),s("span",{pre:!0,attrs:{class:"token string"}},[a._v('"/start.sh"')]),a._v("]")]),a._v("\n")])])]),s("h2",{attrs:{id:"_3-构建镜像"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-构建镜像"}},[a._v("#")]),a._v(" 3. 构建镜像")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" build "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-t")]),a._v(" outispku/geant4:v2 "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[a._v(".")]),a._v("\n")])])]),s("h2",{attrs:{id:"_4-运行容器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-运行容器"}},[a._v("#")]),a._v(" 4. 运行容器")]),a._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[a._v("docker")]),a._v(" run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("-v")]),a._v(" D:"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("\\")]),a._v("FinFET:/program "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[a._v("--name")]),a._v(" geant4_program outispku/geant4:v2\n")])])])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/52.d4c332c8.js b/assets/js/52.d4c332c8.js new file mode 100644 index 0000000..4c56cb2 --- /dev/null +++ b/assets/js/52.d4c332c8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[52],{386:function(t,s,a){"use strict";a.r(s);var r=a(14),i=Object(r.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"_1-一生一芯计划"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-一生一芯计划"}},[this._v("#")]),this._v(" 1. 一生一芯计划")]),this._v(" "),t("h2",{attrs:{id:"预学习阶段"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#预学习阶段"}},[this._v("#")]),this._v(" "),t("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段.html"}},[this._v("预学习阶段")])],1)])}),[],!1,null,null,null);s.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/53.3ff99155.js b/assets/js/53.3ff99155.js new file mode 100644 index 0000000..24a48e3 --- /dev/null +++ b/assets/js/53.3ff99155.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[53],{387:function(t,s,i){"use strict";i.r(s);var h=i(14),e=Object(h.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"_2-2024-02-21-chisel"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-2024-02-21-chisel"}},[this._v("#")]),this._v(" 2. 2024.02.21-Chisel")]),this._v(" "),t("h2",{attrs:{id:"_2024-02-21-chisel-bootcamp"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-21-chisel-bootcamp"}},[this._v("#")]),this._v(" "),t("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot.html"}},[this._v("2024.02.21-Chisel Bootcamp")])],1)])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/54.a8fd5825.js b/assets/js/54.a8fd5825.js new file mode 100644 index 0000000..48f48fe --- /dev/null +++ b/assets/js/54.a8fd5825.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[54],{388:function(t,s,a){"use strict";a.r(s);var r=a(14),e=Object(r.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_1-verilog-基础语法"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-verilog-基础语法"}},[t._v("#")]),t._v(" 1. Verilog 基础语法")]),t._v(" "),s("h2",{attrs:{id:"格式"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#格式"}},[t._v("#")]),t._v(" 格式")]),t._v(" "),s("p",[t._v("Verilog 是区分大小写的。")]),t._v(" "),s("p",[t._v("格式自由,可以在一行内编写,也可跨多行编写。")]),t._v(" "),s("p",[t._v("每个语句必须以分号为结束符。空白符(换行、制表、空格)都没有实际的意义,在编译阶段可忽略。例如下面两中编程方式都是等效的。")]),t._v(" "),s("h3",{attrs:{id:"不换行-不推荐"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#不换行-不推荐"}},[t._v("#")]),t._v(" 不换行(不推荐)")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("wire")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" results "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("assign")]),t._v(" results "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1'b0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b01")]),t._v(" : "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1'b0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b10")]),t._v(" : "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b11")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"换行-推荐"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#换行-推荐"}},[t._v("#")]),t._v(" 换行(推荐)")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("wire")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" results "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("assign")]),t._v(" results "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1'b0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b01")]),t._v(" :"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1'b0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b10")]),t._v(" :"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b11")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"注释"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#注释"}},[t._v("#")]),t._v(" 注释")]),t._v(" "),s("p",[t._v("Verilog 中有 2 种注释方式:")]),t._v(" "),s("p",[t._v("用  "),s("code",[t._v("//")]),t._v("  进行单行注释:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" counter "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// A definition of counter register")]),t._v("\n")])])]),s("p",[t._v("用"),s("code",[t._v("/* */")]),t._v("进行跨行注释:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("wire")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("11")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" addr "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*\nNext are notes with multiple lines.\nCodes here cannot be compiled.\n*/")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("assign")]),t._v(" addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12'b0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"标识符与关键字"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#标识符与关键字"}},[t._v("#")]),t._v(" 标识符与关键字")]),t._v(" "),s("p",[t._v("标识符(identifier)可以是任意一组字母、数字、$  符号和  _(下划线)符号的合,但标识符的第一个字符必须是字母或者下划线,不能以数字或者美元符开始。")]),t._v(" "),s("p",[t._v("另外,标识符是区分大小写的。")]),t._v(" "),s("p",[t._v("关键字是 Verilog 中预留的用于定义语言结构的特殊标识符。")]),t._v(" "),s("p",[t._v("Verilog 中关键字全部为小写。")]),t._v(" "),s("h3",{attrs:{id:"实例"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" counter "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//reg 为关键字, counter 为标识符*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" clk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//input 为关键字,clk 为标识符*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" CLK"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//CLK 与 clk是 2 个不同的标识符*")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/55.2f020a30.js b/assets/js/55.2f020a30.js new file mode 100644 index 0000000..982b322 --- /dev/null +++ b/assets/js/55.2f020a30.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[55],{389:function(s,a,t){"use strict";t.r(a);var r=t(14),e=Object(r.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h1",{attrs:{id:"_2-verilog-数值表示"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-verilog-数值表示"}},[s._v("#")]),s._v(" 2. Verilog 数值表示")]),s._v(" "),a("h2",{attrs:{id:"数值种类"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#数值种类"}},[s._v("#")]),s._v(" 数值种类")]),s._v(" "),a("p",[s._v("Verilog HDL 有下列四种基本的值来表示硬件电路中的电平逻辑:")]),s._v(" "),a("ul",[a("li",[s._v('0:逻辑 0 或 "假"')]),s._v(" "),a("li",[s._v('1:逻辑 1 或 "真"')]),s._v(" "),a("li",[s._v("x 或 X:未知")]),s._v(" "),a("li",[s._v("z 或 Z:高阻")])]),s._v(" "),a("p",[a("code",[s._v("x")]),s._v("  意味着信号数值的不确定,即在实际电路里,信号可能为 1,也可能为 0。")]),s._v(" "),a("p",[a("code",[s._v("z")]),s._v("  意味着信号处于高阻状态,常见于信号(input, reg)没有驱动时的逻辑结果。例如一个 pad 的 input 呈现高阻状态时,其逻辑值和上下拉的状态有关系。上拉则逻辑值为 1,下拉则为 0 。")]),s._v(" "),a("h2",{attrs:{id:"整数数值表示方法"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#整数数值表示方法"}},[s._v("#")]),s._v(" 整数数值表示方法")]),s._v(" "),a("p",[s._v("数字声明时,合法的基数格式有 4 中,包括:十进制('d 或 'D),十六进制('h 或 'H),二进制('b 或 'B),八进制('o 或 'O)。数值可指明位宽,也可不指明位宽。")]),s._v(" "),a("h3",{attrs:{id:"指明位宽"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#指明位宽"}},[s._v("#")]),s._v(" 指明位宽:")]),s._v(" "),a("div",{staticClass:"language-verilog extra-class"},[a("pre",{pre:!0,attrs:{class:"language-verilog"}},[a("code",[a("span",{pre:!0,attrs:{class:"token number"}},[s._v("4'b1011")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 4bit 数值*")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("32'h3022_c0de")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 32bit 的数值 一个16进制的数需要4bit来表示*")]),s._v("\n")])])]),a("p",[s._v("其中,下划线  "),a("code",[s._v("_")]),s._v("  是为了增强代码的可读性。")]),s._v(" "),a("h3",{attrs:{id:"不指明位宽"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#不指明位宽"}},[s._v("#")]),s._v(" 不指明位宽:")]),s._v(" "),a("p",[s._v("一般直接写数字时,默认为十进制表示,例如下面的 3 种写法是等效的:")]),s._v(" "),a("div",{staticClass:"language-verilog extra-class"},[a("pre",{pre:!0,attrs:{class:"language-verilog"}},[a("code",[s._v("counter "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("'d100")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("//一般会根据编译器自动分频位宽,常见的为32bit*")]),s._v("\ncounter "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("100")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\ncounter "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("32'h64")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),a("h3",{attrs:{id:"负数表示"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#负数表示"}},[s._v("#")]),s._v(" 负数表示")]),s._v(" "),a("p",[s._v("通常在表示位宽的数字前面加一个减号来表示负数。例如:")]),s._v(" "),a("div",{staticClass:"language-verilog extra-class"},[a("pre",{pre:!0,attrs:{class:"language-verilog"}},[a("code",[a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("6'd15")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("15")]),s._v("\n")])])]),a("ul",[a("li",[s._v("15 在 5 位二进制中的形式为 5'b10001, 在 6 位二进制中的形式为 6'b11_0001。")])]),s._v(" "),a("p",[s._v("需要注意的是,减号放在基数和数字之间是非法的,例如下面的表示方法是错误的:")]),s._v(" "),a("div",{staticClass:"language-verilog extra-class"},[a("pre",{pre:!0,attrs:{class:"language-verilog"}},[a("code",[a("span",{pre:!0,attrs:{class:"token number"}},[s._v("4")]),s._v("'d"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("//非法说明")]),s._v("\n")])])]),a("h2",{attrs:{id:"实数表示方法"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#实数表示方法"}},[s._v("#")]),s._v(" 实数表示方法")]),s._v(" "),a("p",[s._v("实数表示方法主要有两种方式:")]),s._v(" "),a("h3",{attrs:{id:"十进制"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#十进制"}},[s._v("#")]),s._v(" 十进制:")]),s._v(" "),a("div",{staticClass:"language-verilog extra-class"},[a("pre",{pre:!0,attrs:{class:"language-verilog"}},[a("code",[a("span",{pre:!0,attrs:{class:"token number"}},[s._v("30.123")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("6.0")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("3.0")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0.001")]),s._v("\n")])])]),a("h3",{attrs:{id:"科学计数法"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#科学计数法"}},[s._v("#")]),s._v(" 科学计数法:")]),s._v(" "),a("div",{staticClass:"language-verilog extra-class"},[a("pre",{pre:!0,attrs:{class:"language-verilog"}},[a("code",[a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1.2e4")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("//大小为12000")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1_0001e4")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("//大小为100010000")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1E-3")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("//大小为0.001")]),s._v("\n")])])]),a("h2",{attrs:{id:"字符串表示方法"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#字符串表示方法"}},[s._v("#")]),s._v(" 字符串表示方法")]),s._v(" "),a("p",[s._v('字符串是由双引号包起来的字符队列。字符串不能多行书写,即字符串中不能包含回车符。Verilog 将字符串当做一系列的单字节 ASCII 字符队列。例如,为存储字符串 "www.runoob.com", 需要 14*8bit 的存储单元。例如:')]),s._v(" "),a("div",{staticClass:"language-verilog extra-class"},[a("pre",{pre:!0,attrs:{class:"language-verilog"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("reg")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("14")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("8")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" str "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("initial")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("begin")]),s._v(" \n\t\t\tstr "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"www.runoob.com"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("end")]),s._v("\n")])])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/56.c06b9f19.js b/assets/js/56.c06b9f19.js new file mode 100644 index 0000000..f2d4a6f --- /dev/null +++ b/assets/js/56.c06b9f19.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[56],{390:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_3-verilog-数据类型"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-verilog-数据类型"}},[t._v("#")]),t._v(" 3. Verilog 数据类型")]),t._v(" "),s("p",[t._v("Verilog 最常用的 2 种数据类型就是线网(wire)与寄存器(reg),其余类型可以理解为这两种数据类型的扩展或辅助。")]),t._v(" "),s("h2",{attrs:{id:"线网-wire"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#线网-wire"}},[t._v("#")]),t._v(" 线网(wire)")]),t._v(" "),s("p",[t._v('wire 类型表示硬件单元之间的物理连线,由其连接的器件输出端连续驱动。如果没有驱动元件连接到 wire 型变量,缺省值一般为 "Z"。举例如下:')]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("wire")]),t._v(" interrupt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("wire")]),t._v(" flag1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" flag2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("wire")]),t._v(" gnd "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1'b0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("线网型还有其他数据类型,包括 "),s("code",[t._v("wand,wor,wri,triand,trior,trireg")]),t._v(" 等。这些数据类型用的频率不是很高,这里不做介绍。")]),t._v(" "),s("h2",{attrs:{id:"寄存器-reg"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#寄存器-reg"}},[t._v("#")]),t._v(" 寄存器(reg)")]),t._v(" "),s("p",[t._v("寄存器(reg)用来表示存储单元,它会保持数据原有的值,直到被改写。声明举例如下:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" clk_temp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" flag1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" flag2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("例如在 always 块中,寄存器可能被综合成边沿触发器,在组合逻辑中可能被综合成 wire 型变量。寄存器不需要驱动源,也不一定需要时钟信号。在仿真时,寄存器的值可在任意时刻通过赋值操作进行改写。例如:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" rstn "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("initial")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("begin")]),t._v(" \n\t\trstn "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1'b0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("#100")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n rstn "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1'b1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("end")]),t._v("\n")])])]),s("h2",{attrs:{id:"向量"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#向量"}},[t._v("#")]),t._v(" 向量")]),t._v(" "),s("p",[t._v("当位宽大于 1 时,wire 或 reg 即可声明为向量的形式。例如:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" counter "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//声明4bit位宽的寄存器counter*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("wire")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" gpio_data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//声明32bit位宽的线型变量gpio_data*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("wire")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" addr "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//声明7bit位宽的线型变量addr,位宽范围为8:2*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("31")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//声明32bit位宽的寄存器变量data, 最高有效位为0*")]),t._v("\n")])])]),s("p",[t._v("对于上面的向量,我们可以指定某一位或若干相邻位,作为其他逻辑使用。例如:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("wire")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" data_low "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("addr_temp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1'b1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Verilog 支持可变的向量域选择,例如:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("31")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" data1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" byte1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("integer")]),t._v(" j "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token important"}},[t._v("always@")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("begin")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("begin")]),t._v("\n byte1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//把data1[7:0]…data1[31:24]依次赋值给byte1[0][7:0]…byte[3][7:0]*")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("end")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("end")]),t._v("\n")])])]),s("p",[t._v("Verilog 还支持指定 bit 位后固定位宽的向量域选择访问。")]),t._v(" "),s("ul",[s("li",[t._v("[bit+: width] : 从起始 bit 位开始递增,位宽为 width。")]),t._v(" "),s("li",[t._v("[bit-: width] : 从起始 bit 位开始递减,位宽为 width。")])]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//下面 2 种赋值是等效的*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("31")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("31")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("24")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//下面 2 种赋值是等效的*")]),t._v("\nB "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nB "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("对信号重新进行组合成新的向量时,需要借助大括号。例如:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("wire")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("31")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" temp1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" temp2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("assign")]),t._v(" temp1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("{")]),t._v("byte1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("31")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//数据拼接*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("assign")]),t._v(" temp2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1'b0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("}}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//赋值32位的数值0*")]),t._v("\n")])])]),s("h2",{attrs:{id:"整数-实数-时间寄存器变量"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#整数-实数-时间寄存器变量"}},[t._v("#")]),t._v(" 整数,实数,时间寄存器变量")]),t._v(" "),s("p",[t._v("整数,实数,时间等数据类型实际也属于寄存器类型。")]),t._v(" "),s("h3",{attrs:{id:"整数-integer"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#整数-integer"}},[t._v("#")]),t._v(" 整数(integer)")]),t._v(" "),s("p",[t._v("整数类型用关键字 integer 来声明。声明时不用指明位宽,位宽和编译器有关,一般为 32 bit。reg 型变量为无符号数,而 integer 型变量为有符号数。例如:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("31")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" data1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" byte1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//数组变量,后续介绍*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("integer")]),t._v(" j "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//整型变量,用来辅助生成数字电路*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token important"}},[t._v("always@")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("begin")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("begin")]),t._v("\n byte1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//把data1[7:0]…data1[31:24]依次赋值给byte1[0][7:0]…byte[3][7:0]*")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("end")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("end")]),t._v("\n")])])]),s("p",[t._v("此例中,integer 信号 j 作为辅助信号,将 data1 的数据依次赋值给数组 byte1。综合后实际电路里并没有 j 这个信号,j 只是辅助生成相应的硬件电路。")]),t._v(" "),s("h3",{attrs:{id:"实数-real"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实数-real"}},[t._v("#")]),t._v(" 实数(real)")]),t._v(" "),s("p",[t._v("实数用关键字 real 来声明,可用十进制或科学计数法来表示。实数声明不能带有范围,默认值为 0。如果将一个实数赋值给一个整数,则只有实数的整数部分会赋值给整数。例如:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("real")]),t._v(" data1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("integer")]),t._v(" temp "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("initial")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("begin")]),t._v("\n data1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2e3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n data1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.75")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("end")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("initial")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("begin")]),t._v("\n temp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//temp 值的大小为3*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("end")]),t._v("\n")])])]),s("h3",{attrs:{id:"时间-time"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#时间-time"}},[t._v("#")]),t._v(" 时间(time)")]),t._v(" "),s("p",[t._v("Verilog 使用特殊的时间寄存器 time 型变量,对仿真时间进行保存。其宽度一般为 64 bit,通过调用系统函数 $time 获取当前仿真时间。例如:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("time")]),t._v(" current_time "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("initial")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("begin")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("#100")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n current_time "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token kernel-function property"}},[t._v("$time")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//current_time 的大小为 100*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("end")]),t._v("\n")])])]),s("h3",{attrs:{id:"数组"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#数组"}},[t._v("#")]),t._v(" 数组")]),t._v(" "),s("p",[t._v("在 Verilog 中允许声明 "),s("code",[t._v("reg, wire, integer, time, real")]),t._v(" 及其向量类型的数组。")]),t._v(" "),s("p",[t._v("数组维数没有限制。线网数组也可以用于连接实例模块的端口。数组中的每个元素都可以作为一个标量或者向量,以同样的方式来使用,形如:数组名[下标]。对于多维数组来讲,用户需要说明其每一维的索引。例如:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("integer")]),t._v(" flag "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//8个整数组成的数组*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" counter "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//由4个4bit计数器组成的数组*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("wire")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" addr_bus "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//由4个8bit wire型变量组成的数组*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("wire")]),t._v(" data_bit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//声明1bit wire型变量的二维数组*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("31")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" data_4d"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("11")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("255")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//声明4维的32bit数据变量数组*")]),t._v("\n")])])]),s("p",[t._v("下面显示了对数组元素的赋值操作:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("flag "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32'd0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//将flag数组中第二个元素赋值为32bit的0值*")]),t._v("\ncounter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'hF")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//将数组counter中第4个元素的值赋值为4bit 十六进制数F,等效于counter[3][3:0] = 4'hF,即可省略宽度;*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("assign")]),t._v(" addr_bus"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8'b0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//将数组addr_bus中第一个元素的值赋值为0*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("assign")]),t._v(" data_bit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1'b1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//将数组data_bit的第1行第2列的元素赋值为1,这里不能省略第二个访问标号,即 assign data_bit[0] = 1'b1; 是非法的。*")]),t._v("\ndata_4d"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("15")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("15'd3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//将数组data_4d中标号为[0][0][0][0]的寄存器单元的15~0bit赋值为3*")]),t._v("\n")])])]),s("p",[t._v("虽然数组与向量的访问方式在一定程度上类似,但不要将向量和数组混淆。向量是一个单独的元件,位宽为 n;数组由多个元件组成,其中每个元件的位宽为 n 或 1。它们在结构的定义上就有所区别。")]),t._v(" "),s("h2",{attrs:{id:"存储器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#存储器"}},[t._v("#")]),t._v(" 存储器")]),t._v(" "),s("p",[t._v("存储器变量就是一种寄存器数组,可用来描述 RAM 或 ROM 的行为。例如:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" membit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("255")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//256bit的1bit存储器*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" mem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1023")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//1Kbyte存储器,位宽8bit*")]),t._v("\nmem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("511")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8'b0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//令第512个8bit的存储单元值为0*")]),t._v("\n")])])]),s("h2",{attrs:{id:"参数"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#参数"}},[t._v("#")]),t._v(" 参数")]),t._v(" "),s("p",[t._v("参数用来表示常量,用关键字 parameter 声明,只能赋值一次。例如:")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("parameter")]),t._v(" data_width "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10'd32")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("parameter")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" k"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("parameter")]),t._v(" mem_size "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data_width "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("但是,通过实例化的方式,可以更改参数在模块中的值。此部分以后会介绍。")]),t._v(" "),s("p",[t._v("局部参数用 localparam 来声明,其作用和用法与 parameter 相同,区别在于它的值不能被改变。所以当参数只在本模块中调用时,可用 localparam 来说明。")]),t._v(" "),s("h2",{attrs:{id:"字符串"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#字符串"}},[t._v("#")]),t._v(" 字符串")]),t._v(" "),s("p",[t._v("字符串保存在 reg 类型的变量中,每个字符占用一个字节(8bit)。因此寄存器变量的宽度应该足够大,以保证不会溢出。")]),t._v(" "),s("p",[t._v('字符串不能多行书写,即字符串中不能包含回车符。如果寄存器变量的宽度大于字符串的大小,则使用 0 来填充左边的空余位;如果寄存器变量的宽度小于字符串大小,则会截去字符串左边多余的数据。例如,为存储字符串 "run.runoob.com", 需要 14*8bit 的存储单元:')]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("14")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" str "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("initial")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("begin")]),t._v("\n str "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"run.runoob.com"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("end")]),t._v("\n")])])]),s("p",[t._v("有一些特殊字符在显示字符串中有特殊意义,例如换行符,制表符等。如果需要在字符串中显示这些特殊的字符,则需要在前面加前缀转义字符  \\ 。例如下表所示:")]),t._v(" "),s("table",[s("thead",[s("tr",[s("th",[t._v("转义字符")]),t._v(" "),s("th",[t._v("显示字符")])])]),t._v(" "),s("tbody",[s("tr",[s("td",[t._v("\\n")]),t._v(" "),s("td",[t._v("换行")])]),t._v(" "),s("tr",[s("td",[t._v("\\t")]),t._v(" "),s("td",[t._v("制表符")])]),t._v(" "),s("tr",[s("td",[t._v("%%")]),t._v(" "),s("td",[t._v("%")])]),t._v(" "),s("tr",[s("td",[t._v("\\")]),t._v(" "),s("td",[t._v("\\")])]),t._v(" "),s("tr",[s("td",[t._v('"')]),t._v(" "),s("td",[t._v('"')])]),t._v(" "),s("tr",[s("td",[t._v("\\ooo")]),t._v(" "),s("td",[t._v("1 到 3 个 8 进制数字字符")])])])]),t._v(" "),s("p",[t._v("其实,在 SystemVerilog(主要用于 Verilog 仿真的编程语言)语言中,已经可以直接用关键字 string 来表示字符串变量类型,这为 Verilog 的仿真带来了极大的便利。有兴趣的学者可以简单学习下 SystemVerilog。")])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/57.c9329eb3.js b/assets/js/57.c9329eb3.js new file mode 100644 index 0000000..80d803b --- /dev/null +++ b/assets/js/57.c9329eb3.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[57],{391:function(t,s,a){"use strict";a.r(s);var r=a(14),n=Object(r.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_4-verilog-表达式"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-verilog-表达式"}},[t._v("#")]),t._v(" 4. Verilog 表达式")]),t._v(" "),s("h3",{attrs:{id:"表达式"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#表达式"}},[t._v("#")]),t._v(" 表达式")]),t._v(" "),s("p",[t._v("表达式由操作符和操作数构成,其目的是根据操作符的意义得到一个计算结果。表达式可以在出现数值的任何地方使用。例如:")]),t._v(" "),s("h2",{attrs:{id:"实例"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("^")]),t._v("b "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//a与b进行异或操作*")]),t._v("\naddress"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10'b1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//地址累加*")]),t._v("\nflag1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" flag2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//逻辑与操作*")]),t._v("\n")])])]),s("h3",{attrs:{id:"操作数"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#操作数"}},[t._v("#")]),t._v(" 操作数")]),t._v(" "),s("p",[t._v("操作数可以是任意的数据类型,只是某些特定的语法结构要求使用特定类型的操作数。")]),t._v(" "),s("p",[t._v("操作数可以为常数,整数,实数,线网,寄存器,时间,位选,域选,存储器及函数调用等。")]),t._v(" "),s("h2",{attrs:{id:"实例-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例-2"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("module")]),t._v(" test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//实数*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("real")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//寄存器*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" cprmu_1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cprmu_2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token important"}},[t._v("always @")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("posedge")]),t._v(" clk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("begin")]),t._v("\n cprmu_2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" cprmu_1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("^")]),t._v(" cprmu_2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("end")]),t._v("\n \n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//函数*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" flag1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nflag "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("calculate_result")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//非法操作数*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("wire")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" temp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token important"}},[t._v("always@")]),t._v(" ("),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(")"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("begin")]),t._v("\n res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" cprmu_2 – cprmu_1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//temp = cprmu_2 – cprmu_1 ; //不合法,always块里赋值对象不能是wire型*")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("end")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("endmodule")]),t._v("\n")])])]),s("h3",{attrs:{id:"操作符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#操作符"}},[t._v("#")]),t._v(" 操作符")]),t._v(" "),s("p",[t._v("Verilog 中提供了大约 9 种操作符,分别是算术、关系、等价、逻辑、按位、归约、移位、拼接、条件操作符。")]),t._v(" "),s("p",[t._v("大部分操作符与 C 语言中类似。同类型操作符之间,除条件操作符从右往左关联,其余操作符都是自左向右关联。圆括号内表达式优先执行。例如下面每组的 2 种写法都是等价的。")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//自右向左关联,两种写法等价")]),t._v("\nA"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("C "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v("B)"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("C "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//自右向左关联,两种写法等价,结果为 B、D 或 F")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" C "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" D "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" F "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("C "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" D "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" F"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//自右向左关联,两种写法不等价")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" C"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" D "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" F "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果 D 或 F")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" C "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" D "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" F "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为 B、D 或 F")]),t._v("\n")])])]),s("p",[t._v("不同操作符之间,优先级是不同的。下表列出了操作符优先级从高至低的排列顺序。当没有圆括号时,Verilog 会根据操作符优先级对表达式进行计算。为了避免由操作符优先级导致的计算混乱,在不确定优先级时,建议用圆括号将表达式区分开来。")]),t._v(" "),s("table",[s("thead",[s("tr",[s("th",[t._v("操作符")]),t._v(" "),s("th",[t._v("操作符号")]),t._v(" "),s("th",[t._v("优先级")])])]),t._v(" "),s("tbody",[s("tr",[s("td",[t._v("单目运算")]),t._v(" "),s("td",[t._v("+ - ! ~")]),t._v(" "),s("td",[t._v("最高")])]),t._v(" "),s("tr",[s("td",[t._v("乘、除、取模")]),t._v(" "),s("td",[t._v("* / %")]),t._v(" "),s("td")]),t._v(" "),s("tr",[s("td",[t._v("加减")]),t._v(" "),s("td",[t._v("+ -")]),t._v(" "),s("td")]),t._v(" "),s("tr",[s("td",[t._v("移位")]),t._v(" "),s("td",[t._v("<<  >>")]),t._v(" "),s("td")]),t._v(" "),s("tr",[s("td",[t._v("关系")]),t._v(" "),s("td",[t._v("<  <=  >  >=")]),t._v(" "),s("td")]),t._v(" "),s("tr",[s("td",[t._v("等价")]),t._v(" "),s("td",[t._v("==  !=  ===  !===")]),t._v(" "),s("td")]),t._v(" "),s("tr",[s("td",[t._v("归约")]),t._v(" "),s("td",[t._v("& ~&")]),t._v(" "),s("td")]),t._v(" "),s("tr",[s("td"),t._v(" "),s("td",[t._v("^ ~^")]),t._v(" "),s("td")]),t._v(" "),s("tr",[s("td"),t._v(" "),s("td"),t._v(" "),s("td",[t._v("~")])]),t._v(" "),s("tr",[s("td",[t._v("逻辑")]),t._v(" "),s("td",[t._v("&&")]),t._v(" "),s("td")]),t._v(" "),s("tr",[s("td"),t._v(" "),s("td"),t._v(" "),s("td")]),t._v(" "),s("tr",[s("td",[t._v("条件")]),t._v(" "),s("td",[t._v("?:")]),t._v(" "),s("td",[t._v("最低")])])])]),t._v(" "),s("h3",{attrs:{id:"算术操作符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#算术操作符"}},[t._v("#")]),t._v(" 算术操作符")]),t._v(" "),s("p",[t._v("算术操作符包括单目操作符和双目操作符。")]),t._v(" "),s("p",[t._v("双目操作符对 2 个操作数进行算术运算,包括乘(*)、除(/)、加(+)、减(-)、求幂()、取模(%)。")]),t._v(" "),s("h2",{attrs:{id:"实例-3"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例-3"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\na "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'b0010")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nb "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'b1001")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为c=b'b1011*")]),t._v("\nc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为c=4,取整*")]),t._v("\n")])])]),s("p",[t._v("如果操作数某一位为 X,则计算结果也会全部出现 X。例如:")]),t._v(" "),s("h2",{attrs:{id:"实例-4"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例-4"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("b "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'b100x")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v("b "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为c=4'bxxxx*")]),t._v("\n")])])]),s("p",[t._v("对变量进行声明时,要根据变量的操作符对变量的位宽进行合理声明,不要让结果溢出。上述例子中,相加的 2 个变量位宽为 4bit,那么结果寄存器变量位宽最少为 5bit。否则,高位将被截断,导致结果高位丢失。无符号数乘法时,结果变量位宽应该为 2 个操作数位宽之和。")]),t._v(" "),s("h2",{attrs:{id:"实例-5"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例-5"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" mula "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" mulb"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("reg")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmula "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'he")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmulb "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'h3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nres "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mula "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" mulb "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为res=6'h2a, 数据结果没有丢失位数*")]),t._v("\n")])])]),s("ul",[s("li",[t._v("和 - 也可以作为单目操作符来使用,表示操作数的正负性。此类操作符优先级最高。")])]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("-4 //表示负4\n+3 //表示正3\n")])])]),s("p",[t._v("负数表示时,可以直接在十进制数字前面增加一个减号 -,也可以指定位宽。因为负数使用二进制补码来表示,不指定位宽来表示负数,编译器在转换时,会自动分配位宽,从而导致意想不到的结果。例如:")]),t._v(" "),s("h2",{attrs:{id:"实例-6"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例-6"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("mula "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'd4")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmulb "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nres "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mula "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" mulb "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//计算结果为res=-6'd8, 即res=6'h38,正常*")]),t._v("\nres "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mula "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("'d4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//(4的32次幂-4) * 2, 结果异常*")]),t._v("\n")])])]),s("h3",{attrs:{id:"关系操作符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#关系操作符"}},[t._v("#")]),t._v(" 关系操作符")]),t._v(" "),s("p",[t._v("关系操作符有大于(>),小于(<),大于等于(>=),小于等于(<=)。")]),t._v(" "),s("p",[t._v("关系操作符的正常结果有 2 种,真(1)或假(0)。")]),t._v(" "),s("p",[t._v("如果操作数中有一位为 x 或 z,则关系表达式的结果为 x。")]),t._v(" "),s("h2",{attrs:{id:"实例-7"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例-7"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("A "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nB "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nX "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3'b1xx")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//为真*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//为假*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" Z "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//为X,不确定*")]),t._v("\n")])])]),s("h3",{attrs:{id:"等价操作符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#等价操作符"}},[t._v("#")]),t._v(" 等价操作符")]),t._v(" "),s("p",[t._v("等价操作符包括逻辑相等(==),逻辑不等(!=),全等(===),非全等(!==)。")]),t._v(" "),s("p",[t._v("等价操作符的正常结果有 2 种:为真(1)或假(0)。")]),t._v(" "),s("p",[t._v("逻辑相等/不等操作符不能比较 x 或 z,当操作数包含一个 x 或 z,则结果为不确定值。")]),t._v(" "),s("p",[t._v("全等比较时,如果按位比较有相同的 x 或 z,返回结果也可以为 1,即全等比较可比较 x 或 z。所以,全等比较的结果一定不包含 x。举例如下:")]),t._v(" "),s("h2",{attrs:{id:"实例-8"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例-8"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("A "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nB "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8'h04")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nC "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'bxxxx")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nD "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'hx")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//为真*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//为假*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" C "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//为X,不确定*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" C "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//为假,返回值为0*")]),t._v("\nC "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" D "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//为真,返回值为1*")]),t._v("\n")])])]),s("h3",{attrs:{id:"逻辑操作符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#逻辑操作符"}},[t._v("#")]),t._v(" 逻辑操作符")]),t._v(" "),s("p",[t._v("逻辑操作符主要有 3 个:&&(逻辑与), ||(逻辑或),!(逻辑非)。")]),t._v(" "),s("p",[t._v("逻辑操作符的计算结果是一个 1 bit 的值,0 表示假,1 表示真,x 表示不确定。")]),t._v(" "),s("p",[t._v("如果一个操作数不为 0,它等价于逻辑 1;如果一个操作数等于 0,它等价于逻辑 0。如果它任意一位为 x 或 z,它等价于 x。")]),t._v(" "),s("p",[t._v("如果任意一个操作数包含 x,逻辑操作符运算结果不一定为 x。")]),t._v(" "),s("p",[t._v("逻辑操作符的操作数可以为变量,也可以为表达式。例如:")]),t._v(" "),s("h2",{attrs:{id:"实例-9"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例-9"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("A "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nB "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nC "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b1x")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 为假*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 为真*! A *// 为假*! B *// 为真*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" C "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 为X,不确定*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" C "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 为真,因为A为真*(A==2) && (! B) *//为真,此时第一个操作数为表达式*")]),t._v("\n")])])]),s("h3",{attrs:{id:"按位操作符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#按位操作符"}},[t._v("#")]),t._v(" 按位操作符")]),t._v(" "),s("p",[t._v("按位操作符包括:取反(~),与(&),或(|),异或(^),同或(~^)。")]),t._v(" "),s("p",[t._v("按位操作符对 2 个操作数的每 1 bit 数据进行按位操作。")]),t._v(" "),s("p",[t._v("如果 2 个操作数位宽不相等,则用 0 向左扩展补充较短的操作数。")]),t._v(" "),s("p",[t._v("取反操作符只有一个操作数,它对操作数的每 1 bit 数据进行取反操作。")]),t._v(" "),s("p",[t._v("下图给出了按位操作符的逻辑规则。")]),t._v(" "),s("table",[s("thead",[s("tr",[s("th",[t._v("&(与)")]),t._v(" "),s("th",[t._v("0")]),t._v(" "),s("th",[t._v("1")]),t._v(" "),s("th",[t._v("x")]),t._v(" "),s("th"),t._v(" "),s("th"),t._v(" "),s("th",[t._v("(或)")]),t._v(" "),s("th",[t._v("0")]),t._v(" "),s("th",[t._v("1")]),t._v(" "),s("th",[t._v("x")])])]),t._v(" "),s("tbody",[s("tr",[s("td",[t._v("0")]),t._v(" "),s("td",[t._v("0")]),t._v(" "),s("td",[t._v("0")]),t._v(" "),s("td",[t._v("0")]),t._v(" "),s("td"),t._v(" "),s("td",[t._v("0")]),t._v(" "),s("td",[t._v("0")]),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td")]),t._v(" "),s("tr",[s("td",[t._v("1")]),t._v(" "),s("td",[t._v("0")]),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td"),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td")]),t._v(" "),s("tr",[s("td",[t._v("x")]),t._v(" "),s("td",[t._v("0")]),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td"),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td")])])]),t._v(" "),s("table",[s("thead",[s("tr",[s("th",[t._v("^(异或)")]),t._v(" "),s("th",[t._v("0")]),t._v(" "),s("th",[t._v("1")]),t._v(" "),s("th",[t._v("x")]),t._v(" "),s("th"),t._v(" "),s("th",[t._v("~^(同或)")]),t._v(" "),s("th",[t._v("0")]),t._v(" "),s("th",[t._v("1")]),t._v(" "),s("th",[t._v("x")])])]),t._v(" "),s("tbody",[s("tr",[s("td",[t._v("0")]),t._v(" "),s("td",[t._v("0")]),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td"),t._v(" "),s("td",[t._v("0")]),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td",[t._v("0")]),t._v(" "),s("td",[t._v("x")])]),t._v(" "),s("tr",[s("td",[t._v("1")]),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td",[t._v("0")]),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td"),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td",[t._v("0")]),t._v(" "),s("td",[t._v("1")]),t._v(" "),s("td",[t._v("x")])]),t._v(" "),s("tr",[s("td",[t._v("x")]),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td"),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td",[t._v("x")]),t._v(" "),s("td",[t._v("x")])])])]),t._v(" "),s("h2",{attrs:{id:"实例-10"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例-10"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("A "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'b0101")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nB "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'b1001")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nC "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'bx010")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("~")]),t._v("A "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//4'b1010*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//4'b0001*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//4'b1101*")]),t._v("\nA"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("^")]),t._v("B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//4'b1100*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("~^")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//4'b0011*")]),t._v("\nB "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" C "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//4'b1011*")]),t._v("\nB"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("C "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//4'bx000*")]),t._v("\n")])])]),s("h3",{attrs:{id:"归约操作符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#归约操作符"}},[t._v("#")]),t._v(" 归约操作符")]),t._v(" "),s("p",[t._v("归约操作符包括:归约与(&),归约与非(~&),归约或(|),归约或非(~|),归约异或(^),归约同或(~^)。")]),t._v(" "),s("p",[t._v("归约操作符只有一个操作数,它对这个向量操作数逐位进行操作,最终产生一个 1bit 结果。")]),t._v(" "),s("p",[t._v("逻辑操作符、按位操作符和归约操作符都使用相同的符号表示,因此有时候容易混淆。区分这些操作符的关键是分清操作数的数目,和计算结果的规则。")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("A "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'b1010")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("A "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为 1 & 0 & 1 & 0 = 1'b0,可用来判断变量A是否全1")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("~|")]),t._v("A "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为 ~(1 | 0 | 1 | 0) = 1'b0, 可用来判断变量A是否为全0")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("^")]),t._v("A "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为 1 ^ 0 ^ 1 ^ 0 = 1'b0")]),t._v("\n")])])]),s("h3",{attrs:{id:"移位操作符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#移位操作符"}},[t._v("#")]),t._v(" 移位操作符")]),t._v(" "),s("p",[t._v("移位操作符包括左移(<<),右移(>>),算术左移(<<<),算术右移(>>>)。")]),t._v(" "),s("p",[t._v("移位操作符是双目操作符,两个操作数分别表示要进行移位的向量信号(操作符左侧)与移动的位数(操作符右侧)。")]),t._v(" "),s("p",[t._v("算术左移和逻辑左移时,右边低位会补 0。")]),t._v(" "),s("p",[t._v("逻辑右移时,左边高位会补 0;而算术右移时,左边高位会补充符号位,以保证数据缩小后值的正确性。")]),t._v(" "),s("h2",{attrs:{id:"实例-11"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例-11"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("A "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'b1100")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nB "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'b0010")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" A "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为 4'b0011*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" A "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为 4'b1000*")]),t._v("\nA "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" A "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为 4'b1000*")]),t._v("\nC "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" B "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>>")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为 2 + (-4/4) = 1, 4'b0001*")]),t._v("\n")])])]),s("h3",{attrs:{id:"拼接操作符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#拼接操作符"}},[t._v("#")]),t._v(" 拼接操作符")]),t._v(" "),s("p",[t._v("拼接操作符用大括号 {,} 来表示,用于将多个操作数(向量)拼接成新的操作数(向量),信号间用逗号隔开。")]),t._v(" "),s("p",[t._v("拼接符操作数必须指定位宽,常数的话也需要指定位宽。例如:")]),t._v(" "),s("h2",{attrs:{id:"实例-12"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例-12"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("A "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'b1010")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nB "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1'b1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nY1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("{")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4'h3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为Y1='b1100_0011*")]),t._v("\nY2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("{")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3'd4")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为 Y2=7'b111_1100*")]),t._v("\nY3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1'b0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("}}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//结果为 Y3=32h0,常用作寄存器初始化时匹配位宽的赋初值*")]),t._v("\n")])])]),s("h3",{attrs:{id:"条件操作符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#条件操作符"}},[t._v("#")]),t._v(" 条件操作符")]),t._v(" "),s("p",[t._v("条件表达式有 3 个操作符,结构描述如下:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("condition_expression ? true_expression : false_expression\n")])])]),s("p",[t._v("计算时,如果 condition_expression 为真(逻辑值为 1),则运算结果为 true_expression;如果 condition_expression 为假(逻辑值为 0),则计算结果为 false_expression。")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("assign")]),t._v(" hsel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" hsel_p1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" hsel_p2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//当信号 addr 高 2bit 为 0 时,hsel 赋值为 hsel_p1; 否则,将 hsel_p2 赋值给 hsel。")]),t._v("\n")])])]),s("p",[t._v("其实,条件表达式类似于 2 路(或多路)选择器,其描述方式完全可以用 if-else 语句代替。")]),t._v(" "),s("p",[t._v("当然条件操作符也能进行嵌套,完成一个多次选择的逻辑。例如:")]),t._v(" "),s("h2",{attrs:{id:"实例-13"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#实例-13"}},[t._v("#")]),t._v(" 实例")]),t._v(" "),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("assign")]),t._v(" hsel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b00")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" hsel_p1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b01")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" hsel_p2 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" hsel_p3 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2'b11")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" hsel_p4 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/58.95e33269.js b/assets/js/58.95e33269.js new file mode 100644 index 0000000..e805eb7 --- /dev/null +++ b/assets/js/58.95e33269.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[58],{398:function(t,r,e){"use strict";e.r(r);var a=e(14),i=Object(a.a)({},(function(){var t=this,r=t._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h1",{attrs:{id:"_2024-02-21-chisel-bootcamp"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-21-chisel-bootcamp"}},[t._v("#")]),t._v(" 2024.02.21-Chisel BootCamp")]),t._v(" "),r("h2",{attrs:{id:"_2024-02-21-1-introduction-to-scala"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-21-1-introduction-to-scala"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.21-1 Introduction to Scala.html"}},[t._v("2024.02.21-1. Introduction to Scala")])],1),t._v(" "),r("h2",{attrs:{id:"_2024-02-23-2-1-first-chisel-module"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-23-2-1-first-chisel-module"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.23-2.1 First Chisel Module.html"}},[t._v("2024.02.23-2.1 First Chisel Module")])],1),t._v(" "),r("h2",{attrs:{id:"_2024-02-24-2-2-combinational-logic"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-24-2-2-combinational-logic"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.24-2.2 Combinational Logic.html"}},[t._v("2024.02.24-2.2 Combinational Logic")])],1),t._v(" "),r("h2",{attrs:{id:"_2024-02-25-2-3-control-flow"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-25-2-3-control-flow"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.25-2.3 Control Flow.html"}},[t._v("2024.02.25-2.3 Control Flow")])],1),t._v(" "),r("h2",{attrs:{id:"_2024-02-26-2-4-sequential-logic"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-26-2-4-sequential-logic"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.26-2.4 Sequential Logic.html"}},[t._v("2024.02.26-2.4 Sequential Logic")])],1),t._v(" "),r("h2",{attrs:{id:"_2024-02-28-2-5-fir-filter"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-28-2-5-fir-filter"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.28-2.5 FIR Filter.html"}},[t._v("2024.02.28-2.5 FIR Filter")])],1),t._v(" "),r("h2",{attrs:{id:"_2024-02-29-2-6-more-on-chiseltest"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-29-2-6-more-on-chiseltest"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.29-2.6 More on ChiselTest.html"}},[t._v("2024.02.29-2.6 More on ChiselTest")])],1),t._v(" "),r("h2",{attrs:{id:"_2024-03-01-3-1-generators-parameters"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-01-3-1-generators-parameters"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.01-3.1 Generators Parameters.html"}},[t._v("2024.03.01-3.1 Generators: Parameters")])],1),t._v(" "),r("h2",{attrs:{id:"_2024-03-03-3-2-generators-collections"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-03-3-2-generators-collections"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.03-3.2 Generators Collections.html"}},[t._v("2024.03.03-3.2 Generators: Collections")])],1),t._v(" "),r("h2",{attrs:{id:"_2024-03-04-3-3-interlude-chisel-standard-library"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-04-3-3-interlude-chisel-standard-library"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.04-3.3 Interlude Chisel Standard Library.html"}},[t._v("2024.03.04-3.3 Interlude: Chisel Standard Library")])],1),t._v(" "),r("h2",{attrs:{id:"_2024-03-05-3-4-higher-order-functions"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-05-3-4-higher-order-functions"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.05-3.4 Higher-Order Functions.html"}},[t._v("2024.03.05-3.4 Higher-Order Functions")])],1),t._v(" "),r("h2",{attrs:{id:"_2024-03-07-3-5-functional-programming"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-07-3-5-functional-programming"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.07-3.5 Functional Programming.html"}},[t._v("2024.03.07-3.5 Functional Programming")])],1),t._v(" "),r("h2",{attrs:{id:"_2024-03-08-3-6-object-oriented-programming"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-08-3-6-object-oriented-programming"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.09-3.6 Object Oriented Programming.html"}},[t._v("2024.03.08-3.6 Object Oriented Programming")])],1),t._v(" "),r("h2",{attrs:{id:"_2024-03-12-3-7-generator-types"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-12-3-7-generator-types"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.12-3.7 Generators Types.html"}},[t._v("2024.03.12-3.7 Generator Types")])],1)])}),[],!1,null,null,null);r.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/59.fac7a2fb.js b/assets/js/59.fac7a2fb.js new file mode 100644 index 0000000..14cc67a --- /dev/null +++ b/assets/js/59.fac7a2fb.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[59],{394:function(t,s,a){"use strict";a.r(s);var e=a(14),n=Object(e.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-02-21-1-introduction-to-scala"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-21-1-introduction-to-scala"}},[t._v("#")]),t._v(" 2024.02.21-1. Introduction to Scala")]),t._v(" "),s("h2",{attrs:{id:"variables-and-constants-var-and-val"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#variables-and-constants-var-and-val"}},[t._v("#")]),t._v(" Variables and Constants - "),s("code",[t._v("var")]),t._v(" and "),s("code",[t._v("val")])]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" numberOfKittens "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" kittensPerHouse "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("101")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" alphabet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"abcdefghijklmnopqrstuvwxyz"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" done "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('/*\nnumberOfKittens: Int = 6\nkittensPerHouse: Int = 101\nalphabet: String = "abcdefghijklmnopqrstuvwxyz"\ndone: Boolean = false\n*/')]),t._v("\n")])])]),s("p",[t._v("变量使用"),s("code",[t._v("var")]),t._v("声明,常量则使用"),s("code",[t._v("val")])]),t._v(" "),s("h2",{attrs:{id:"conditionals"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#conditionals"}},[t._v("#")]),t._v(" Conditionals")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("done"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"we are done"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("numberOfKittens "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" kittensPerHouse"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"more kittens!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n numberOfKittens "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n done "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("类似于 C++,如果只有一行,可以省略大括号")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" likelyCharactersSet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("alphabet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("26")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"english"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"not english"')]),t._v("\n\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("likelyCharactersSet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// likelyCharactersSet: String = "english"')]),t._v("\n")])])]),s("p",[s("code",[t._v("if")]),t._v("这一串的返回值又所选择的分支的最后一行确定")]),t._v(" "),s("h2",{attrs:{id:"methods-functions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#methods-functions"}},[t._v("#")]),t._v(" Methods (Functions)")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Simple scaling function with an input argument, e.g., times2(3) returns 6")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Curly braces can be omitted for short one-line functions.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" times2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" x\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// More complicated function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" distance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" returnPositive"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" xy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" y\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("returnPositive"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" xy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("abs "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("xy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("abs\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"overloading-functions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#overloading-functions"}},[t._v("#")]),t._v(" Overloading Functions")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Overloaded function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" times2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" x\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" times2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt\n\ntimes2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 10")]),t._v("\ntimes2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"7"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 14")]),t._v("\n")])])]),s("h3",{attrs:{id:"recursive-and-nested-functions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#recursive-and-nested-functions"}},[t._v("#")]),t._v(" Recursive and Nested Functions")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" asciiTriangle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// This is cute: multiplying "X" makes a string with many copies of "X"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Unit means no return value")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" printRow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("columns"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Unit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"X"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" columns"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rows "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n printRow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n asciiTriangle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rows "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Here is the recursive call")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// printRow(1) // This would not work, since we're calling printRow outside its scope")]),t._v("\nasciiTriangle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Output:")]),t._v("\nXXXXXX\nXXXXX\nXXXX\nXXX\nXX\nX\n")])])]),s("h3",{attrs:{id:"named-parameters-and-parameter-defaults"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#named-parameters-and-parameter-defaults"}},[t._v("#")]),t._v(" Named Parameters and Parameter Defaults")]),t._v(" "),s("p",[t._v("Consider the following method definition.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" myMethod"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" wrap"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" wrapValue"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("24")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Unit")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("When calling the method, you will often see the parameter names along with the passed-in values.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("myMethod"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" wrap"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" wrapValue"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("23")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("Using named parameters, you can even call the function with a different ordering.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("myMethod"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wrapValue"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("23")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" wrap"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("For frequently called methods, the parameter ordering may be obvious. But for less common methods and, in particular, boolean arguments, including the names with calls can make your code a lot more readable. If methods have a long list of arguments of the same type, using names also decreases the chance of error. Parameters to class definitions also use this named argument scheme (they are actually just the parameters to the constructor method for the class).")]),t._v(" "),s("p",[t._v("When certain parameters have default values (that don't need to be overridden), callers only have to pass (by name) specific arguments that do not use defaults. Notice that the parameter  "),s("code",[t._v("wrapValue")]),t._v(" has a default value of 24. Therefore, this will work as if 24 had been passed in.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("myMethod"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wrap"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h2",{attrs:{id:"lists"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#lists"}},[t._v("#")]),t._v(" Lists")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" y "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("14")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" list1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" list2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" y "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" y "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" Nil "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// An alternate notation for assembling a list")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Nil就是一个空的List[Nothing],即一个可以封装任何类型元素但又没有元素的容器")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" list3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),t._v(" list2 "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Appends the second list to the first list")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" m "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" s "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("size\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" headOfList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("head "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Gets the first element of the list")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" restOfList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tail "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Get a new list with first element removed")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" third "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Gets the third element of a list (0-indexed)")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Output:")]),t._v("\nx"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),t._v("\ny"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("14")]),t._v("\nlist1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nlist2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("14")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("14")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nlist3"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("14")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("14")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nm"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\ns"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\nheadOfList"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\nrestOfList"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nthird"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\n")])])]),s("h2",{attrs:{id:"for-statement"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#for-statement"}},[t._v("#")]),t._v(" "),s("code",[t._v("for")]),t._v(" Statement")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" to "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" print"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('" "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// include 7")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\ni "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// exclude 7")]),t._v("\ni "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" to "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" by "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("\n")])])]),s("p",[s("code",[t._v("print")]),t._v(" 用于连续输出不换行,而 "),s("code",[t._v("println")]),t._v(" 用于输出后换行。")]),t._v(" "),s("p",[s("code",[t._v("<-")]),t._v(" 是用在 for 循环构造中的一个操作符,表示从一个集合中逐一取出元素")]),t._v(" "),s("h2",{attrs:{id:"packages-and-imports"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#packages-and-imports"}},[t._v("#")]),t._v(" Packages and Imports")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("package")]),t._v(" 用于定义一个命名空间,它可以包含类、对象和特质(traits),以及其他包。包主要用于组织和管理代码,防止命名冲突,并提供访问控制。")]),t._v(" "),s("li",[s("code",[t._v("class")]),t._v(" 是定义数据结构及其行为的蓝图。它可以包含数据成员(属性)和方法。类用于实例化对象,每个对象都可以拥有不同的属性值。")])]),t._v(" "),s("p",[s("code",[t._v("import")]),t._v("语句可以用来引入包、类、对象,甚至是特定的方法或属性。这意味着你可以使用"),s("code",[t._v("import")]),t._v("来引用几乎任何你需要的代码实体。以下是一些例子:")]),t._v(" "),s("ul",[s("li",[t._v("引入一个包中的所有成员:"),s("code",[t._v("import scala.collection.mutable._")]),t._v(",这里的"),s("code",[t._v("_")]),t._v("相当于 Java 中的``,表示引入"),s("code",[t._v("mutable")]),t._v("包下的所有成员。")]),t._v(" "),s("li",[t._v("引入一个特定的类:"),s("code",[t._v("import scala.collection.mutable.ListBuffer")]),t._v(",这表示只引入"),s("code",[t._v("ListBuffer")]),t._v("类。")]),t._v(" "),s("li",[t._v("引入一个包中的多个类:"),s("code",[t._v("import scala.collection.mutable.{ArrayBuffer, LinkedList}")]),t._v(",这表示同时引入"),s("code",[t._v("ArrayBuffer")]),t._v("和"),s("code",[t._v("LinkedList")]),t._v("两个类。")]),t._v(" "),s("li",[t._v("引入一个对象中的特定成员:"),s("code",[t._v("import java.lang.System.{out => stdout}")]),t._v(",这里还演示了将"),s("code",[t._v("System.out")]),t._v("重命名为"),s("code",[t._v("stdout")]),t._v(",以便在代码中使用简化的名称。")])]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 从chisel3.iotesters包中引入特定的几个类:ChiselFlatSpec、Driver、和PeekPokeTester")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("chisel3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("iotesters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("ChiselFlatSpec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Driver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" PeekPokeTester"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"class"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#class"}},[t._v("#")]),t._v(" Class")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// WrapCounter counts up to a max value based on a bit size")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" WrapCounter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("counterBits"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" max"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Long")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<<")]),t._v(" counterBits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" counter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0L")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" inc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Long")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n counter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" counter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("counter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" max"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n counter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n counter\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"counter created with max value ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("max")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[s("code",[t._v("class WrapCounter")]),t._v(" -- This is the definition of WrapCounter.")]),t._v(" "),s("li",[s("code",[t._v("(counterBits: Int)")]),t._v(" -- Creating a WrapCounter requires an integer parameter, nicely named to suggest it is the bit width of the counter.")]),t._v(" "),s("li",[t._v("Braces ({}) delimit a block of code. Most classes use a code block to define variables, constants, and methods (functions).")]),t._v(" "),s("li",[s("code",[t._v("val max: Long =")]),t._v(" -- the class contains a member variable max, declared as type "),s("code",[t._v("Long")]),t._v(" and initialized as the class is created.")]),t._v(" "),s("li",[s("code",[t._v("(1 << counterBits) - 1")]),t._v(" computes the maximum value that can be contained in counterBits bits. Since max was created with "),s("code",[t._v("val")]),t._v(" it cannot be changed.")]),t._v(" "),s("li",[t._v("A variable counter is created and initialized to 0L. The L says that 0 is a long value; thus, counter is inferred to be Long.")]),t._v(" "),s("li",[t._v("max and counter are commonly called "),s("em",[t._v("member variables")]),t._v(" of the class.")]),t._v(" "),s("li",[t._v("A class method inc is defined which takes no arguments and returns a Long value.")]),t._v(" "),s("li",[t._v("The body of the method inc is a code block that has:\n"),s("ul",[s("li",[s("code",[t._v("counter = counter + 1")]),t._v(" increments counter.")]),t._v(" "),s("li",[s("code",[t._v("if (counter > max) { counter = 0 }")]),t._v(" tests if the counter is greater than the max value and sets it back to zero if it is.")]),t._v(" "),s("li",[s("code",[t._v("counter")]),t._v(" -- The last line of the code block is important.\n"),s("ul",[s("li",[t._v("Any value expressed as the last line of a code block is considered to be the return value of that code block. The return value can be used or ignored by the calling statement.")]),t._v(" "),s("li",[t._v("This applies quite generally; for example, since an "),s("code",[t._v("if")]),t._v(" then "),s("code",[t._v("else")]),t._v(" statement defines its true and false clauses with code blocks, it can return a value i.e., "),s("code",[t._v('val result = if (10 * 10 > 90) "greater" else "lesser"')]),t._v(" would create a "),s("code",[t._v("val")]),t._v(' with the value "greater".')])])]),t._v(" "),s("li",[t._v("So in this case the function inc returns the value of counter.")])])]),t._v(" "),s("li",[s("code",[t._v('println(s"counter created with max value $max")')]),t._v(" prints a string to standard output. Because the println is directly in the defining code block, it is part of the class initialization code and is run, i.e. prints out the string, every time an instance of this class is created.")]),t._v(" "),s("li",[t._v("The string printed in this case is an "),s("em",[t._v("interpolated")]),t._v(" string.\n"),s("ul",[s("li",[t._v("The leading s in front of the first double quote identifies this as an interpolated string.")]),t._v(" "),s("li",[t._v("An interpolated string is processed at run time.")]),t._v(" "),s("li",[t._v("The $max is replaced with the value of max.")]),t._v(" "),s("li",[t._v("If the $ is followed by a code block, arbitrary Scala can be in that code block.\n"),s("ul",[s("li",[t._v("For example, "),s("code",[t._v('println(s"doubled max is ${max + max}")')]),t._v(".")]),t._v(" "),s("li",[t._v("The return value of this code block will be inserted in place of "),s("code",[t._v("${...}")]),t._v(".")]),t._v(" "),s("li",[t._v("If the return value is not a string, it will be converted to one; virtually every class or type in scala has an implicit conversion to a string defined).")])])]),t._v(" "),s("li",[t._v("You should generally avoid printing something every time an instance of a class is created to avoid flooding standard output, unless you're debugging.")])]),t._v(" "),s("h3",{attrs:{id:"creating-an-instance-of-a-class"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#creating-an-instance-of-a-class"}},[t._v("#")]),t._v(" Creating an Instance of a Class")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" WrapCounter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Increments the counter")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Member variables of the instance x are visible to the outside, unless they are declared private")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("counter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("max"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"counter is about to wrap"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nx inc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Scala allows the dots to be omitted; this can be useful for making embedded DSL's look more natural")]),t._v("\n")])])]),t._v("有时候实例化类时不需要使用"),s("code",[t._v("new")]),t._v("关键字,这通常是因为该类定义了一个或多个"),s("code",[t._v("apply")]),t._v("方法。"),s("code",[t._v("apply")]),t._v("方法可以在类的伴生对象(companion object)中定义,允许你直接通过类名加括号的方式创建类的实例,而不需要显式地使用"),s("code",[t._v("new")]),t._v("关键字。这种方式提供了一种更简洁的语法来创建对象,同时也可以在"),s("code",[t._v("apply")]),t._v("方法内部执行初始化操作或参数处理,为对象创建提供更多的灵活性和控制。\n例如,假设有一个名为"),s("code",[t._v("Person")]),t._v("的类及其伴生对象,伴生对象中定义了"),s("code",[t._v("apply")]),t._v("方法:"),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" Person "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" apply"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Person "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),t._v("在这个例子中,可以通过调用"),s("code",[t._v("Person")]),t._v("伴生对象的"),s("code",[t._v("apply")]),t._v("方法来创建"),s("code",[t._v("Person")]),t._v("类的实例,而不需要使用"),s("code",[t._v("new")]),t._v("关键字:"),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" person "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Alice"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// 相当于调用 Person.apply("Alice")')]),t._v("\n")])])]),t._v("这里,"),s("code",[t._v('Person("Alice")')]),t._v("实际上调用的是伴生对象中的"),s("code",[t._v("apply")]),t._v("方法,该方法内部使用"),s("code",[t._v("new")]),t._v("关键字创建了"),s("code",[t._v("Person")]),t._v("类的实例。这种方式使得代码看起来更简洁,同时保留了通过构造函数创建对象的灵活性。")])]),t._v(" "),s("h2",{attrs:{id:"code-blocks"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#code-blocks"}},[t._v("#")]),t._v(" Code Blocks")]),t._v(" "),s("p",[t._v("Code blocks are delimited by braces. A block can contain zero or more lines of Scala code. The last line of Scala code becomes the return value (which may be ignored) of the code block. A code block with no lines would return a special null-like object called "),s("code",[t._v("Unit")]),t._v(". Code blocks are used throughout Scala: they are the bodies of class definitions, they form function and method definitions, they are the clauses of "),s("code",[t._v("if")]),t._v(" statements, and they are the bodies of "),s("code",[t._v("for")]),t._v(" and many other Scala operators.")]),t._v(" "),s("h3",{attrs:{id:"parameterized-code-blocks"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameterized-code-blocks"}},[t._v("#")]),t._v(" Parameterized Code Blocks")]),t._v(" "),s("p",[t._v("Code blocks can take parameters. In the case of class and method definitions, these parameters look like those in most conventional programming languages. In the example below, "),s("code",[t._v("c")]),t._v(" and "),s("code",[t._v("s")]),t._v(" are parameters of the code blocks.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// A one-line code block doesn't need to be enclosed in {}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" add1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" RepeatString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" repeatedString "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" s "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" s\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("IMPORTANT: There is another way in which code blocks may be parameterized. Here is an example.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" intList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" stringList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" intList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toString\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("使用"),s("code",[t._v("map")]),t._v("方法对"),s("code",[t._v("intList")]),t._v("中的每个元素应用一个函数,该函数将整数转换为其对应的字符串表示。具体来说,"),s("code",[t._v("map")]),t._v("方法遍历"),s("code",[t._v("intList")]),t._v("中的每个元素(用"),s("code",[t._v("i")]),t._v("表示),并对每个元素执行"),s("code",[t._v("i.toString")]),t._v("操作,将其转换为字符串。This type of code block is called an anonymous function, and more details on anonymous functions are provided in a later module.")])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/6.78a547ee.js b/assets/js/6.78a547ee.js new file mode 100644 index 0000000..d7547a1 --- /dev/null +++ b/assets/js/6.78a547ee.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[6],{281:function(e,t,a){},295:function(e,t,a){"use strict";a(281)},382:function(e,t,a){"use strict";a.r(t);var o={name:"CodeGroup",data:()=>({codeTabs:[],activeCodeTabIndex:-1}),watch:{activeCodeTabIndex(e){this.activateCodeTab(e)}},mounted(){this.loadTabs()},methods:{changeCodeTab(e){this.activeCodeTabIndex=e},loadTabs(){this.codeTabs=(this.$slots.default||[]).filter(e=>Boolean(e.componentOptions)).map((e,t)=>(""===e.componentOptions.propsData.active&&(this.activeCodeTabIndex=t),{title:e.componentOptions.propsData.title,elm:e.elm})),-1===this.activeCodeTabIndex&&this.codeTabs.length>0&&(this.activeCodeTabIndex=0),this.activateCodeTab(0)},activateCodeTab(e){this.codeTabs.forEach(e=>{e.elm&&e.elm.classList.remove("theme-code-block__active")}),this.codeTabs[e].elm&&this.codeTabs[e].elm.classList.add("theme-code-block__active")}}},s=(a(295),a(14)),c=Object(s.a)(o,(function(){var e=this,t=e._self._c;return t("ClientOnly",[t("div",{staticClass:"theme-code-group"},[t("div",{staticClass:"theme-code-group__nav"},[t("ul",{staticClass:"theme-code-group__ul"},e._l(e.codeTabs,(function(a,o){return t("li",{key:a.title,staticClass:"theme-code-group__li"},[t("button",{staticClass:"theme-code-group__nav-tab",class:{"theme-code-group__nav-tab-active":o===e.activeCodeTabIndex},on:{click:function(t){return e.changeCodeTab(o)}}},[e._v("\n "+e._s(a.title)+"\n ")])])})),0)]),e._v(" "),e._t("default"),e._v(" "),e.codeTabs.length<1?t("pre",{staticClass:"pre-blank"},[e._v("// Make sure to add code blocks to your code group")]):e._e()],2)])}),[],!1,null,"deefee04",null);t.default=c.exports}}]); \ No newline at end of file diff --git a/assets/js/60.04e108eb.js b/assets/js/60.04e108eb.js new file mode 100644 index 0000000..2a0edfd --- /dev/null +++ b/assets/js/60.04e108eb.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[60],{395:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-02-23-2-1-first-chisel-module"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-23-2-1-first-chisel-module"}},[t._v("#")]),t._v(" 2024.02.23-2.1 First Chisel Module")]),t._v(" "),s("h2",{attrs:{id:"setup"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setup"}},[t._v("#")]),t._v(" Setup")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" path "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" System"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("getProperty"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"user.dir"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/source/load-ivy.sc"')]),t._v("\ninterp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("load"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("module"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ammonite"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ops"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("java"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("FileSystems"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("getDefault"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("getPath"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("chisel3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("chisel3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("chisel3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tester"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("chisel3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tester"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("RawTester"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("test\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("dotvisualizer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n")])])]),s("p",[t._v("这两句代码在使用 Chisel(一种硬件描述语言)时,涉及到 Ammonite 脚本的动态加载。第一句定义了一个"),s("code",[t._v("path")]),t._v("变量,它通过获取系统属性"),s("code",[t._v('"user.dir"')]),t._v("(当前用户目录)并附加上"),s("code",[t._v('"/source/load-ivy.sc"')]),t._v("路径,用于指定一个 Scala 脚本文件的位置。第二句使用 Ammonite 的"),s("code",[t._v("interp.load.module")]),t._v("方法动态加载这个指定路径下的 Scala 脚本文件。")]),t._v(" "),s("p",[t._v("动态加载脚本在使用 Chisel 编写代码时可以有多个用途,如:")]),t._v(" "),s("ol",[s("li",[t._v("引入依赖:动态加载"),s("code",[t._v("load-ivy.sc")]),t._v("脚本可以用来引入或更新 Ammonite 会话中的 Ivy 依赖,确保代码运行时有必要的库支持。")]),t._v(" "),s("li",[t._v("执行初始化代码:可以在脚本中执行必要的初始化操作,为后续的 Chisel 硬件设计代码执行设置适当的环境或参数。")]),t._v(" "),s("li",[t._v("灵活性和模块化:通过动态加载脚本,可以根据需要灵活地加载和卸载模块,使代码结构更加模块化,便于管理和维护。")])]),t._v(" "),s("ul",[s("li",[s("code",[t._v("import chisel3._")]),t._v(":基础的 Chisel 功能,包括定义硬件组件的基本构建块。")]),t._v(" "),s("li",[s("code",[t._v("import chisel3.util._")]),t._v(":提供了一些实用工具和额外的硬件构建块,比如计数器、移位寄存器等。")]),t._v(" "),s("li",[s("code",[t._v("import chisel3.tester._")]),t._v(":提供了测试 Chisel 硬件设计的工具和框架。")]),t._v(" "),s("li",[s("code",[t._v("import chisel3.tester.RawTester.test")]),t._v(":是"),s("code",[t._v("chisel3.tester")]),t._v("中的一个具体的测试功能,用于执行硬件测试。")])]),t._v(" "),s("h2",{attrs:{id:"example-module"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-module"}},[t._v("#")]),t._v(" Example Module")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Passthrough "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// with parameter")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" PassthroughGenerator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("width"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("width"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("width"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Passthrough "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n")])])]),s("p",[t._v("我们声明一个叫做"),s("code",[t._v("Passthrough")]),t._v("的新模块。"),s("code",[t._v("Module")]),t._v("是 Chisel 内置的一个类,所有硬件模块都必须扩展它")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("我们在一个特殊的"),s("code",[t._v("io")]),t._v("变量中声明所有的输入和输出端口。它必须被命名为"),s("code",[t._v("io")]),t._v(",并且是一个"),s("code",[t._v("IO")]),t._v("对象或实例,这需要形如"),s("code",[t._v("IO(_instantiated_bundle_)")]),t._v("的东西")]),t._v(" "),s("p",[t._v("在 Chisel 中,"),s("code",[t._v("io")]),t._v("、"),s("code",[t._v("in")]),t._v("和"),s("code",[t._v("out")]),t._v("被声明为"),s("code",[t._v("val")]),t._v("(不可变引用)而不是"),s("code",[t._v("var")]),t._v("(可变引用),因为它们代表硬件模块的接口。在硬件设计中,接口的结构(例如信号的数量、类型和方向)在编译时确定且不会改变。虽然信号的值在模拟过程中会变化,但信号的定义(即接口)是固定的。使用"),s("code",[t._v("val")]),t._v("声明这些接口强调了它们是不变的结构,而信号值的变化则通过信号之间的连接和赋值来体现,这与软件编程中变量的概念有所不同。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("我们声明了一个新的硬件结构类型(Bundle),它包含了一些命名的信号"),s("code",[t._v("in")]),t._v("和"),s("code",[t._v("out")]),t._v(",分别具有输入和输出的方向。")]),t._v(" "),s("p",[t._v("在 Chisel 中,"),s("code",[t._v("Bundle")]),t._v("是一种用于定义一组相关信号的类,类似于 Verilog 中的"),s("code",[t._v("module")]),t._v("内部信号或 VHDL 中的"),s("code",[t._v("record")]),t._v("。它允许开发者将多个信号组合成一个单一的复合类型,这样可以更方便地管理和传递数据结构。每个"),s("code",[t._v("Bundle")]),t._v("内的信号可以有不同的类型和方向(如输入"),s("code",[t._v("Input")]),t._v("、输出"),s("code",[t._v("Output")]),t._v("),使其成为定义模块接口和内部数据结构的强大工具。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("我们声明了信号的硬件类型。在这个案例中,它是宽度为 4 的无符号整数。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n")])])]),s("p",[t._v("我们将我们的输入端口连接到我们的输出端口,这样"),s("code",[t._v("io.in")]),s("em",[t._v("驱动")]),s("code",[t._v("io.out")]),t._v("。注意,"),s("code",[t._v(":=")]),t._v("操作符是一个"),s("em",[t._v("Chisel")]),t._v("操作符,它表示右手边的信号驱动左手边的信号。它是一个有方向的操作符。")]),t._v(" "),s("p",[t._v("硬件构建语言(HCLs)的一个整洁之处在于我们可以使用底层的编程语言作为脚本语言。例如,在声明我们的 Chisel 模块之后,我们接着使用 Scala 调用 Chisel 编译器将 Chisel 的"),s("code",[t._v("Passthrough")]),t._v("翻译成 Verilog 的"),s("code",[t._v("Passthrough")]),t._v("。这个过程被称为"),s("em",[t._v("精炼")]),t._v("。")]),t._v(" "),s("h3",{attrs:{id:"generate-verilog"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#generate-verilog"}},[t._v("#")]),t._v(" Generate Verilog")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getVerilog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Passthrough"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("module")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Passthrough")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" reset"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" io_in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("output")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" io_out\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("assign")]),t._v(" io_out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io_in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @[cmd2.sc 6:10]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("endmodule")]),t._v("\n")])])]),s("h3",{attrs:{id:"generate-firrtl"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#generate-firrtl"}},[t._v("#")]),t._v(" Generate Firrtl")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getFirrtl"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Passthrough"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("div",{staticClass:"language-verilog extra-class"},[s("pre",{pre:!0,attrs:{class:"language-verilog"}},[s("code",[t._v("circuit Passthrough "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("module")]),t._v(" Passthrough "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" clock "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" Clock\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("input")]),t._v(" reset "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("output")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("{")]),t._v(" flip in "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">}")]),t._v("\n\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in @"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("cmd2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sc "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("h2",{attrs:{id:"example-tester"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-tester"}},[t._v("#")]),t._v(" Example Tester")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Scala Code: `test` runs the unit test.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test takes a user Module and has a code block that applies pokes and expects to the")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// circuit under test (c)")]),t._v("\ntest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Passthrough"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set our input to value 0")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Assert that the output correctly has 0")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set our input to value 1")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Assert that the output correctly has 1")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set our input to value 2")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Assert that the output correctly has 2")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SUCCESS!!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Scala Code: if we get here, our tests passed!")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Test with width 10")]),t._v("\ntest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" PassthroughGenerator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set our input to value 0")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Assert that the output correctly has 0")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set our input to value 1")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Assert that the output correctly has 1")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Set our input to value 2")]),t._v("\n\t\tc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Assert that the output correctly has 2")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[s("code",[t._v("c.io.in.poke(0.U)")]),t._v(":设置模块的输入"),s("code",[t._v("in")]),t._v("为 0。")]),t._v(" "),s("li",[s("code",[t._v("c.io.out.expect(0.U)")]),t._v(":检查模块的输出"),s("code",[t._v("out")]),t._v("是否为 0,确保电路按预期工作。")]),t._v(" "),s("li",[t._v("接下来,代码以相同的方式测试输入值 1 和 2,分别使用"),s("code",[t._v("poke")]),t._v("方法设置输入值,并用"),s("code",[t._v("expect")]),t._v("方法验证输出值。")])]),t._v(" "),s("p",[t._v("在 Scala 中,可以直接在函数调用后跟一个代码块,这是因为 Scala 支持高阶函数,即可以接受函数作为参数的函数。在这个例子中,"),s("code",[t._v("test")]),t._v("函数接受两个参数:一个是"),s("code",[t._v("Passthrough")]),t._v("模块的实例,另一个是一个匿名函数(或称为代码块),这个匿名函数以"),s("code",[t._v("c")]),t._v("作为参数进行操作。这种语法使得代码更加简洁易读,允许直接在调用函数时定义行为逻辑,非常适合进行单元测试等场景。当一个函数的最后一个参数是函数类型时,可以使用特殊的语法糖允许将这个函数参数写在方法调用的外部。这种语法不仅使得代码更加清晰,而且在使用匿名函数或代码块作为参数时尤其有用,因为它允许代码块在视觉上更为突出,从而提高了代码的可读性。这就是为什么"),s("code",[t._v("test(new Passthrough())")]),t._v("后面可以直接跟一个代码块的原因。")]),t._v(" "),s("p",[s("code",[t._v("c =>")]),t._v("是一个函数字面量(匿名函数)的语法,用于定义一个函数。这里,"),s("code",[t._v("c")]),t._v("是函数的参数,"),s("code",[t._v("=>")]),t._v("后面跟着的是函数体。在这个上下文中,"),s("code",[t._v("c")]),t._v("代表传递给测试代码块的模块实例(如"),s("code",[t._v("Passthrough")]),t._v("模块实例),然后在代码块内部,你可以使用"),s("code",[t._v("c")]),t._v("来访问和操作这个实例的输入和输出端口。在 Scala 的函数字面量中,参数类型通常是通过上下文推断出来的,不需要显式声明。在"),s("code",[t._v("test(new Passthrough()) { c => ... }")]),t._v("这段代码中,"),s("code",[t._v("c")]),t._v("是由"),s("code",[t._v("test")]),t._v("函数根据其参数类型推断出的"),s("code",[t._v("Passthrough")]),t._v("模块实例。也就是说,当你写"),s("code",[t._v("c =>")]),t._v("时,"),s("code",[t._v("c")]),t._v("的类型(在这个例子中是"),s("code",[t._v("Passthrough")]),t._v("模块实例)是由"),s("code",[t._v("test")]),t._v("函数的定义确定的,根据这个函数期望的参数类型。这就是为什么可以直接使用"),s("code",[t._v("c")]),t._v("来访问"),s("code",[t._v("Passthrough")]),t._v("实例的成员,如"),s("code",[t._v("c.io.in")]),t._v("和"),s("code",[t._v("c.io.out")]),t._v(",而不需要额外的类型声明。")]),t._v(" "),s("p",[t._v("Note that the "),s("code",[t._v("poke")]),t._v(" and "),s("code",[t._v("expect")]),t._v(" use chisel hardware literal notation. Both operations expect literals of the correct type.\nIf "),s("code",[t._v("poke")]),t._v("ing a "),s("code",[t._v("UInt()")]),t._v(" you must supply a "),s("code",[t._v("UInt")]),t._v(" literal (example: "),s("code",[t._v("c.io.in.poke(10.U)")]),t._v("), likewise if the input is a "),s("code",[t._v("Bool()")]),t._v(" the "),s("code",[t._v("poke")]),t._v(" would expect either "),s("code",[t._v("true.B")]),t._v(" or "),s("code",[t._v("false.B")]),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"appendix-a-note-on-printf-debugging"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#appendix-a-note-on-printf-debugging"}},[t._v("#")]),t._v(' Appendix: A Note on "printf" Debugging')]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" PrintingModule "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n\n printf"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Print during simulation: Input is %d\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// chisel printf has its own string interpolator too")]),t._v("\n printf"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("p")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Print during simulation: IO is ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("io")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('\\n"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Print during generation: Input is ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// s用于一般的Scala字符串插值,而p专门为Chisel设计,用于更方便地在仿真中打印硬件信号和对象")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\ntest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" PrintingModule "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// circuit will print")]),t._v("\n\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Print during testing: Input is ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("Elaborating design"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\nPrint during generation"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Input is UInt"),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("4"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("IO in unelaborated PrintingModule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nDone elaborating"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\nPrint during simulation"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Input is "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\nPrint during simulation"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IO is AnonymousBundle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nPrint during simulation"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Input is "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\nPrint during simulation"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IO is AnonymousBundle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nPrint during simulation"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Input is "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\nPrint during simulation"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IO is AnonymousBundle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nPrint during simulation"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Input is "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\nPrint during simulation"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IO is AnonymousBundle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nPrint during simulation"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Input is "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\nPrint during simulation"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IO is AnonymousBundle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nPrint during testing"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Input is UInt"),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("4"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nPrint during simulation"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Input is "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\nPrint during simulation"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IO is AnonymousBundle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\ntest PrintingModule Success"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" tests passed in "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),t._v(" cycles in "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.003471")]),t._v(" seconds "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2016.88")]),t._v(" Hz\n")])])]),s("p",[t._v("这段代码定义了一个"),s("code",[t._v("PrintingModule")]),t._v("类,它扩展了 Chisel 的"),s("code",[t._v("Module")]),t._v(",用于演示在不同阶段打印信息:")]),t._v(" "),s("ol",[s("li",[t._v("模块定义中的"),s("code",[t._v("printf")]),t._v("语句:这些在仿真时每个时钟周期都会打印。"),s("code",[t._v('printf("Print during simulation: Input is %d\\n", io.in)')]),t._v("会打印输入信号的值,而"),s("code",[t._v('printf(p"Print during simulation: IO is $io\\n")')]),t._v("会打印"),s("code",[t._v("io")]),t._v("对象的信息。这些仅在仿真(运行时)生效。")]),t._v(" "),s("li",[t._v("模块定义中的"),s("code",[t._v("println")]),t._v("语句:这句话在模块的"),s("em",[t._v("生成")]),t._v("阶段打印,即代码编译时,打印到终端或控制台。它不会在仿真时打印,因为它是 Scala 的打印语句,不是 Chisel 的。")]),t._v(" "),s("li",[t._v("测试块中的"),s("code",[t._v("println")]),t._v("语句:这在 Scala 测试环境中执行,用于打印测试时的信息。如"),s("code",[t._v('println(s"Print during testing: Input is ${c.io.in.peek()}")')]),t._v("将在测试过程中打印输入信号的当前值。")])]),t._v(" "),s("ul",[s("li",[s("code",[t._v("c.io.in.poke(3.U)")]),t._v("设置输入为 3。")]),t._v(" "),s("li",[s("code",[t._v("c.io.out.expect(3.U)")]),t._v("期望输出为 3,这个测试会通过,因为输出应该与输入相同。")]),t._v(" "),s("li",[s("code",[t._v("c.clock.step(5)")]),t._v("推进仿真时钟 5 个周期,这期间"),s("code",[t._v("printf")]),t._v("语句会打印信息。")])]),t._v(" "),s("ol",[s("li",[t._v("最后的"),s("code",[t._v("Print during simulation: Input is 0")]),t._v(" 是因为被重置回到默认状态")]),t._v(" "),s("li",[t._v("7 周期则是因为测试中执行了"),s("code",[t._v("c.clock.step(5)")]),t._v(",推进了 5 个时钟周期,加上测试开始前后的各 1 个周期")])]),t._v(" "),s("p",[t._v("综上,"),s("code",[t._v("println")]),t._v("用于代码生成阶段和测试代码中,打印到 Scala 的执行环境;"),s("code",[t._v("printf")]),t._v("用于仿真阶段,打印到仿真的输出中。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/61.14b5149d.js b/assets/js/61.14b5149d.js new file mode 100644 index 0000000..22b8602 --- /dev/null +++ b/assets/js/61.14b5149d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[61],{402:function(t,e,s){"use strict";s.r(e);var a=s(14),n=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"_2024-02-29-2-6-more-on-chiseltest"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-29-2-6-more-on-chiseltest"}},[t._v("#")]),t._v(" 2024.02.29-2.6 More on ChiselTest")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th"),t._v(" "),e("th",[t._v("iotesters")]),t._v(" "),e("th",[t._v("ChiselTest")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[t._v("poke")]),t._v(" "),e("td",[t._v("poke(c.io.in1, 6)")]),t._v(" "),e("td",[t._v("c.io.in1.poke(6.U)")])]),t._v(" "),e("tr",[e("td",[t._v("peek")]),t._v(" "),e("td",[t._v("peek(c.io.out1)")]),t._v(" "),e("td",[t._v("c.io.out1.peek()")])]),t._v(" "),e("tr",[e("td",[t._v("expect")]),t._v(" "),e("td",[t._v("expect(c.io.out1, 6)")]),t._v(" "),e("td",[t._v("c.io.out1.expect(6.U)")])]),t._v(" "),e("tr",[e("td",[t._v("step")]),t._v(" "),e("td",[t._v("step(1)")]),t._v(" "),e("td",[t._v("c.clock.step(1)")])]),t._v(" "),e("tr",[e("td",[t._v("initiate")]),t._v(" "),e("td",[t._v("Driver.execute(...) { c =>")]),t._v(" "),e("td",[t._v("test(...) { c =>")])])])]),t._v(" "),e("h2",{attrs:{id:"modules-with-decoupled-interfaces"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#modules-with-decoupled-interfaces"}},[t._v("#")]),t._v(" Modules with Decoupled Interfaces")]),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" QueueModule"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("T "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Data"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ioType"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" T"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" entries"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" MultiIOModule "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Flipped"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Decoupled"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ioType"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Decoupled"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ioType"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n out "),e("span",{pre:!0,attrs:{class:"token generics"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" Queue"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" entries"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ol",[e("li",[e("code",[t._v("class QueueModule[T <: Data](ioType: T, entries: Int) extends MultiIOModule")]),t._v(" 定义了一个泛型队列模块,其中"),e("code",[t._v("T <: Data")]),t._v("表示"),e("code",[t._v("T")]),t._v("是"),e("code",[t._v("Data")]),t._v("类型或其子类型。"),e("code",[t._v("ioType")]),t._v("是队列中数据的类型,"),e("code",[t._v("entries")]),t._v("是队列的大小。")]),t._v(" "),e("li",[e("code",[t._v("Decoupled(ioType)")]),t._v("是一个 Chisel 提供的高级接口,自动包含了"),e("code",[t._v("valid")]),t._v("、"),e("code",[t._v("bits")]),t._v("和"),e("code",[t._v("ready")]),t._v("信号。"),e("code",[t._v("valid")]),t._v("和"),e("code",[t._v("bits")]),t._v("组合用于传输有效数据,而"),e("code",[t._v("ready")]),t._v("信号用于流量控制。当你声明一个"),e("code",[t._v("Decoupled")]),t._v("接口时,这些信号都会被自动创建。")]),t._v(" "),e("li",[e("code",[t._v("IO(Flipped(Decoupled(ioType)))")]),t._v(" 创建了一个输入端口,"),e("code",[t._v("Flipped")]),t._v("意味着通常的输入输出方向被反转(即原本是输出的"),e("code",[t._v("valid")]),t._v("和"),e("code",[t._v("bits")]),t._v("成为输入,原本是输入的"),e("code",[t._v("ready")]),t._v("成为输出),"),e("code",[t._v("Decoupled")]),t._v("表示它是一个可以被反压的接口。")]),t._v(" "),e("li",[e("code",[t._v("out <> Queue(in, entries)")]),t._v(" 将输出端口"),e("code",[t._v("out")]),t._v("连接到一个新建的"),e("code",[t._v("Queue")]),t._v("实例,"),e("code",[t._v("Queue(in, entries)")]),t._v("创建了一个队列,其中"),e("code",[t._v("in")]),t._v("是输入端口,"),e("code",[t._v("entries")]),t._v("是队列大小。"),e("code",[t._v("<>")]),t._v("是连接操作符,表示双向连接。确保了数据可以从"),e("code",[t._v("in")]),t._v("流向队列,经过处理后,再从队列流向"),e("code",[t._v("out")]),t._v("。")])]),t._v(" "),e("h3",{attrs:{id:"enqueuenow-and-expectdequeuenow"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#enqueuenow-and-expectdequeuenow"}},[t._v("#")]),t._v(" EnqueueNow and expectDequeueNow")]),t._v(" "),e("p",[e("code",[t._v("EnqueueNow")]),t._v("和"),e("code",[t._v("expectDequeueNow")]),t._v("是用于测试队列行为的方法。"),e("code",[t._v("EnqueueNow")]),t._v("用于立即将数据入队,而不需要等待队列准备好。"),e("code",[t._v("expectDequeueNow")]),t._v("用于立即从队列中出队数据,并验证其值是否符合预期。这两个方法都是在基于队列的测试中非常有用,使得测试代码可以直接控制和验证队列中数据的流动。这样,测试者可以确保队列正确地处理了入队和出队操作,并且数据的传输符合设计的预期。")]),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[t._v("test"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" QueueModule"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("9.")]),t._v("W"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" entries "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example testsequence showing the use and behavior of Queue")]),t._v("\n c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("initSource"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("setSourceClock"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("initSink"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("setSinkClock"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" testVector "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tabulate"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" i "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" i"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n testVector"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zip"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("testVector"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("foreach "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("enqueueNow"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expectDequeueNow"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("out"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("There is some required boiler plate "),e("code",[t._v("initSource")]),t._v(", "),e("code",[t._v("setSourceClock")]),t._v(", etc that is necessary to ensure that the "),e("code",[t._v("ready")]),t._v(" and "),e("code",[t._v("valid")]),t._v(" fields are all initialized correctly at the beginning of the test.")]),t._v(" "),e("h3",{attrs:{id:"enqueueseq-and-dequeueseq"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#enqueueseq-and-dequeueseq"}},[t._v("#")]),t._v(" EnqueueSeq and DequeueSeq")]),t._v(" "),e("p",[e("code",[t._v("EnqueueSeq")]),t._v(" 允许你一次性将一个序列的元素批量入队,这对于测试需要连续多个数据处理的场景特别有用。"),e("code",[t._v("DequeueSeq")]),t._v(", 相应地,用于一次性从队列中出队多个元素,并验证这些元素是否符合预期的序列。"),e("code",[t._v("enqueueSeq")]),t._v(" must finish before the "),e("code",[t._v("expectDequeueSeq")]),t._v(" can begin. This example would fail if the "),e("code",[t._v("testVector")]),t._v("'s size is made larger than the queue depth, because the queue would fill up and not be able to complete the "),e("code",[t._v("enqueueSeq")]),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"fork-and-join"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#fork-and-join"}},[t._v("#")]),t._v(" Fork and Join")]),t._v(" "),e("p",[e("code",[t._v("fork")]),t._v("和"),e("code",[t._v("join")]),t._v("用于创建并发测试,允许同时执行多个操作或测试场景。使用"),e("code",[t._v("fork")]),t._v("可以启动一个并发的测试过程,这个过程可以与主测试流程同时运行。可以在"),e("code",[t._v("fork")]),t._v("后使用多个测试命令定义并发执行的操作。随后,"),e("code",[t._v("join")]),t._v("用于等待所有并发启动的测试过程完成。这样,你可以在一个测试中执行多个并行操作,例如同时对多个模块输入不同的信号,或者同时观察多个输出。这在需要模拟复杂交互或并行处理时特别有用。")]),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[t._v("test"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" QueueModule"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("9.")]),t._v("W"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" entries "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example testsequence showing the use and behavior of Queue")]),t._v("\n c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("initSource"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("setSourceClock"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("initSink"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("setSinkClock"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" testVector "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tabulate"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("300")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" i "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" i"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n fork "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("enqueueSeq"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("testVector"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fork "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expectDequeueSeq"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("testVector"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("join"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("虽然"),e("code",[t._v("fork")]),t._v("启动了两个并发过程,似乎表明"),e("code",[t._v("c.in.enqueueSeq(testVector)")]),t._v("和"),e("code",[t._v("c.out.expectDequeueSeq(testVector)")]),t._v("应该同时执行,但实际上,它们在逻辑上是有先后顺序的。"),e("code",[t._v("enqueueSeq")]),t._v("首先向队列中填充数据,而"),e("code",[t._v("expectDequeueSeq")]),t._v("则等待这些数据从队列中出现并验证它们。在 ChiselTest 中,"),e("code",[t._v("fork")]),t._v("创建的并发线程会同时开始执行,但是"),e("code",[t._v("expectDequeueSeq")]),t._v("自然会在等待有数据可以出队之后才开始验证,确保了数据的正确流向和测试的逻辑顺序。")])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/62.9d7660e9.js b/assets/js/62.9d7660e9.js new file mode 100644 index 0000000..dbb5d28 --- /dev/null +++ b/assets/js/62.9d7660e9.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[62],{404:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-03-03-3-2-generators-collections"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-03-3-2-generators-collections"}},[t._v("#")]),t._v(" 2024.03.03-3.2 Generators: Collections")]),t._v(" "),s("h2",{attrs:{id:"generators-and-collections"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#generators-and-collections"}},[t._v("#")]),t._v(" Generators and Collections")]),t._v(" "),s("h3",{attrs:{id:"fir-golden-model"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#fir-golden-model"}},[t._v("#")]),t._v(" FIR Golden Model")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" A naive implementation of an FIR filter "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("with")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("an")]),t._v(" arbitrary number of taps"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" ScalaFirFilter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("taps"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" pseudoRegisters "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fill"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("taps"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n pseudoRegisters "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("::")]),t._v(" pseudoRegisters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("take"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("taps"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" accumulator "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" taps"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("indices"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n accumulator "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" taps"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" pseudoRegisters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n accumulator\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"seq"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#seq"}},[t._v("#")]),t._v(" Seq")]),t._v(" "),s("p",[t._v("当"),s("code",[t._v("taps")]),t._v("变为"),s("code",[t._v("Seq[Int]")]),t._v("时,意味着类的用户可以在构造类时传递任意长度的"),s("code",[t._v("Int")]),t._v("序列。")]),t._v(" "),s("h3",{attrs:{id:"寄存器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#寄存器"}},[t._v("#")]),t._v(" 寄存器")]),t._v(" "),s("p",[t._v("使用"),s("code",[t._v("var pseudoRegisters = List.fill(taps.length)(0)")]),t._v("创建了一个"),s("code",[t._v("List")]),t._v(",用于存储前几个周期的值。选择"),s("code",[t._v("List")]),t._v("是因为其添加元素到头部和移除最后一个元素的语法非常简单。理论上可以使用 Scala 集合家族中的任何成员。这个列表被初始化为全零。")]),t._v(" "),s("h3",{attrs:{id:"poke"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#poke"}},[t._v("#")]),t._v(" Poke")]),t._v(" "),s("p",[t._v("我们的类添加了一个 poke 函数/方法,模拟将新输入放入过滤器并循环时钟。")]),t._v(" "),s("h3",{attrs:{id:"更新寄存器"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#更新寄存器"}},[t._v("#")]),t._v(" 更新寄存器")]),t._v(" "),s("p",[s("code",[t._v("pseudoRegisters = value :: pseudoRegisters.take(taps.length - 1)")]),t._v("首先使用列表的"),s("code",[t._v("take")]),t._v("方法保留除最后一个元素外的所有元素,然后使用"),s("code",[t._v("::")]),t._v("列表连接操作符将"),s("code",[t._v("value")]),t._v("添加到缩减版列表的头部。")]),t._v(" "),s("h3",{attrs:{id:"计算输出"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#计算输出"}},[t._v("#")]),t._v(" 计算输出")]),t._v(" "),s("p",[t._v("一个简单的 for 循环和累加器用于求和列表中每个元素与其对应抽头系数的乘积。仅含"),s("code",[t._v("accumulator")]),t._v("的行将该值作为函数结果返回。")]),t._v(" "),s("h3",{attrs:{id:"test-circuit-using-the-golden-model"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#test-circuit-using-the-golden-model"}},[t._v("#")]),t._v(" Test circuit using the golden model")]),t._v(" "),s("p",[t._v("为了避免使用繁杂的手动验证,这里使用 Golden Model 来生成期望的值,并与 Chisel 的结果对比")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" goldenModel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" ScalaFirFilter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\ntest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" My4ElementFir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" input "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" scala"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Random"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" goldenModelResult "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" goldenModel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("goldenModelResult"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"i ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("i")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", input ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("input")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", gm ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("goldenModelResult")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("注意:这里软件上的 Golden Model 没有考虑位宽,而硬件则与位宽有很大关系。这里只考虑了 8 以内,即 3bit 的数,因此不存在这个问题")]),t._v(" "),s("h3",{attrs:{id:"example-parameterized-fir-generator"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-parameterized-fir-generator"}},[t._v("#")]),t._v(" Example: Parameterized FIR Generator")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" MyManyElementFir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("consts"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitWidth"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitWidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitWidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" regs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mutable"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ArrayBuffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until consts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" regs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" regs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" RegNext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("regs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" muls "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mutable"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ArrayBuffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until consts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n muls "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" regs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" consts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" scan "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mutable"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ArrayBuffer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until consts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" scan "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" muls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" scan "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" muls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" scan"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" scan"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("last\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ol",[s("li",[s("code",[t._v("val regs = mutable.ArrayBuffer[UInt]()")]),t._v("声明了一个名为"),s("code",[t._v("regs")]),t._v("的不可变变量,它被初始化为一个可变的"),s("code",[t._v("ArrayBuffer")]),t._v(",其中包含"),s("code",[t._v("UInt")]),t._v("类型的元素。"),s("code",[t._v("ArrayBuffer")]),t._v("是一个可变的序列,允许在序列两端高效地添加或删除元素,适用于需要动态修改元素的场景。在这里,"),s("code",[t._v("regs")]),t._v("可以被用来存储和更新"),s("code",[t._v("UInt")]),t._v("类型的数据,但由于使用了"),s("code",[t._v("val")]),t._v(","),s("code",[t._v("regs")]),t._v("本身的引用是不可变的,尽管它指向的"),s("code",[t._v("ArrayBuffer")]),t._v("内容是可变的。")]),t._v(" "),s("li",[s("code",[t._v("regs += io.in")]),t._v("这行代码的意思是将"),s("code",[t._v("io.in")]),t._v("这个"),s("code",[t._v("UInt")]),t._v("信号添加到"),s("code",[t._v("regs")]),t._v("这个"),s("code",[t._v("ArrayBuffer")]),t._v("中。这里没有直接的数值相加操作,而是将"),s("code",[t._v("io.in")]),t._v("这个元素添加(追加)到"),s("code",[t._v("regs")]),t._v("这个列表的末尾。"),s("code",[t._v("regs")]),t._v("是一个容器,可以逐个添加元素,即使一开始"),s("code",[t._v("regs")]),t._v("是空的。这行代码的作用是初始化"),s("code",[t._v("regs")]),t._v("列表的第一个元素,后续元素则在循环中通过"),s("code",[t._v("RegNext")]),t._v("添加。")]),t._v(" "),s("li",[s("code",[t._v("regs")]),t._v("作为一个"),s("code",[t._v("ArrayBuffer")]),t._v(",可以包含不同类型的"),s("code",[t._v("UInt")]),t._v("元素。在这种情况下,"),s("code",[t._v("io.in")]),t._v("是一个"),s("code",[t._v("Input(UInt)")]),t._v("类型,而"),s("code",[t._v("RegNext(regs(i - 1), 0.U)")]),t._v("生成的是一个"),s("code",[t._v("Reg(UInt)")]),t._v("类型。尽管"),s("code",[t._v("io.in")]),t._v("和通过"),s("code",[t._v("RegNext")]),t._v("创建的寄存器在硬件层面扮演不同的角色(一个是输入信号,另一个是寄存器),但它们都是"),s("code",[t._v("UInt")]),t._v("类型,可以存储在同一个"),s("code",[t._v("ArrayBuffer")]),t._v("中。在 Chisel 生成的硬件逻辑中,这将创建一个信号和寄存器链,其中信号和寄存器可以互相连接。")]),t._v(" "),s("li",[t._v("使用"),s("code",[t._v("scan")]),t._v("数组缓存逐步累加的结果而不是直接对"),s("code",[t._v("muls")]),t._v("求和,是为了展示在每一步如何逐渐累积计算的中间值。这种方法在某些复杂的 FIR 滤波器设计中可以提供更多的灵活性,比如在需要逐个访问累加过程中的中间结果时。尽管在这个特定例子中,只需要最终的累加结果,直接对"),s("code",[t._v("muls")]),t._v("求和看似更直接,但展开累加过程可以帮助理解和调试滤波器的行为,尤其是在更复杂或参数化的设计中。然而,如果目标只是获取最终的累加和,直接使用"),s("code",[t._v("muls.reduce(_ + _)")]),t._v("确实会更简洁高效。")])]),t._v(" "),s("h3",{attrs:{id:"test-a-bunch-of-different-sized-fir-filters"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#test-a-bunch-of-different-sized-fir-filters"}},[t._v("#")]),t._v(" Test a bunch of different sized FIR filters")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n scala"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Random"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1024")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" run a test comparing software and hardware filters\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" run "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" at least twice as many samples as taps\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" runOneTest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("taps"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" goldenModel "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" ScalaFirFilter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("taps"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" MyManyElementFir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("taps"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" taps"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" input "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" goldenModelResult "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" goldenModel"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("expect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("goldenModelResult"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"i ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("i")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", input ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("input")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", gm ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("goldenModelResult")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tapSize "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" until "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),t._v(" by "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" taps "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fill"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tapSize"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a sequence of random coefficients")]),t._v("\n\n runOneTest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("taps"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ol",[s("li",[t._v("在 Chisel 测试中,"),s("code",[t._v("c.clock.step(1)")]),t._v("通常放在对输出进行期望检查("),s("code",[t._v("expect")]),t._v(")之后,因为我们希望在提供输入后推进仿真一个时钟周期,然后在下一个时钟边沿检查输出。这样可以确保寄存器已经更新到了因输入变化而触发的新状态。")]),t._v(" "),s("li",[t._v("字符串"),s("code",[t._v('s"i $i, input $input, gm $goldenModelResult, ${c.io.out.peek().litValue}"')]),t._v("是 Scala 的字符串插值,用于构造包含变量值的字符串。这里它构建了一个描述当前测试状态的字符串,包括迭代次数"),s("code",[t._v("i")]),t._v(",当前输入"),s("code",[t._v("input")]),t._v(",金标准模型"),s("code",[t._v("goldenModel")]),t._v("的结果"),s("code",[t._v("goldenModelResult")]),t._v(",以及从待测试模块的输出"),s("code",[t._v("c.io.out")]),t._v("中提取的值。这对于调试和理解测试失败的上下文非常有用。")])]),t._v(" "),s("h2",{attrs:{id:"hardware-collections"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#hardware-collections"}},[t._v("#")]),t._v(" Hardware Collections")]),t._v(" "),s("h3",{attrs:{id:"example-add-run-time-configurable-taps-to-our-fir"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-add-run-time-configurable-taps-to-our-fir"}},[t._v("#")]),t._v(" Example: Add run-time configurable taps to our FIR")]),t._v(" "),s("p",[t._v("在 FIR 生成器的 IO 中添加了一个额外的"),s("code",[t._v("consts")]),t._v("向量,允许在电路生成后从外部改变系数。这是通过 Chisel 集合类型"),s("code",[t._v("Vec")]),t._v("实现的。"),s("code",[t._v("Vec")]),t._v("支持许多 Scala 集合方法,但只能包含 Chisel 硬件元素。仅在普通 Scala 集合无法满足需求的情况下使用"),s("code",[t._v("Vec")]),t._v(",主要是以下两种情况:"),s("em",[t._v("1.")]),t._v(" 在 Bundle 中需要元素集合,通常是作为 IO 使用的 Bundle。"),s("em",[t._v("2.")]),t._v(" 需要通过硬件部分的索引访问集合(如寄存器文件)。")]),t._v(" "),s("p",[t._v("原因在于"),s("code",[t._v("Vec")]),t._v("能够创建一组硬件元素的集合,而这些硬件元素可以在生成的硬件电路中被索引和操作。相反,普通的 Scala 集合,如"),s("code",[t._v("List")]),t._v("或"),s("code",[t._v("Seq")]),t._v(",仅仅在 Scala 软件环境中存在,它们不能直接映射到硬件电路中。因此,当定义硬件模块的 IO 接口或需要在硬件级别按索引访问元素时,应该使用"),s("code",[t._v("Vec")]),t._v("。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" MyManyDynamicElementVecFir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" consts "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Reference solution")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" regs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("VecInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fill"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" regs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" regs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" regs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" muls "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" muls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("consts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" muls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" regs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("consts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" scan "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" scan"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" muls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" scan"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" muls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" scan"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" scan"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ol",[s("li",[s("p",[s("code",[t._v("VecInit")]),t._v("用于创建一个"),s("code",[t._v("Vec")]),t._v(",这是 Chisel 中的一种集合类型,专门用于存储硬件元素。"),s("code",[t._v("Seq.fill(length - 1)(0.U(8.W))")]),t._v("生成一个长度为"),s("code",[t._v("length - 1")]),t._v(",每个元素初始化为 8 位宽的 0 的序列。"),s("code",[t._v("VecInit")]),t._v("将这个序列转换成一个"),s("code",[t._v("Vec")]),t._v(",以便在硬件设计中使用。"),s("code",[t._v("RegInit")]),t._v("则将这个"),s("code",[t._v("Vec")]),t._v("初始化为寄存器,使得其值在复位时为指定的初始值。这种方式常用于定义具有多个初始相同值的寄存器数组。")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("Wire(Vec(length, UInt(8.W)))")]),t._v(" 用于创建一个具有 "),s("code",[t._v("length")]),t._v(" 元素的向量,每个元素是 8 位无符号整数。这是在硬件描述语言中创建信号数组的标准方法,允许这些信号在生成的硬件电路中被实例化。")]),t._v(" "),s("p",[t._v("相比之下,"),s("code",[t._v("mutable.ArrayBuffer[UInt]()")]),t._v(" 是 Scala 的一个集合类型,主要用于软件程序中的数据存储和处理。在 Chisel 的上下文中,你不能直接将 "),s("code",[t._v("ArrayBuffer")]),t._v(" 用作硬件信号的容器,因为 "),s("code",[t._v("ArrayBuffer")]),t._v(" 是一个可变的、仅在 Scala 软件执行环境中存在的数据结构,它不会被合成到硬件中。")]),t._v(" "),s("p",[t._v("简单来说:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("Wire(Vec(length, UInt(8.W)))")]),t._v(" 在 Chisel 中创建一个硬件向量,这个向量可以在生成的硬件电路中存在并携带信号。")]),t._v(" "),s("li",[s("code",[t._v("mutable.ArrayBuffer[UInt]()")]),t._v(" 创建一个仅在 Scala 软件执行时存在的内存数组,它不能直接用于硬件设计。")])]),t._v(" "),s("p",[t._v("所以,在你的代码中使用 "),s("code",[t._v("Wire(Vec(length, UInt(8.W)))")]),t._v(" 是为了定义一个可以在硬件层面操作和传递信号的向量,这对于硬件设计至关重要。")]),t._v(" "),s("h3",{attrs:{id:"example-32-bit-risc-v-processor"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-32-bit-risc-v-processor"}},[t._v("#")]),t._v(" Example: 32-bit RISC-V Processor")]),t._v(" "),s("p",[t._v("Register file: An array of registers that can be read from or written to via a number of read or write ports. Each port consists of an address and data field.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" RegisterFile"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("readPorts"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n require"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("readPorts "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" wen "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" waddr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" wdata "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" raddr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("readPorts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" rdata "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("readPorts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// A Register of a vector of UInts")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" reg "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RegInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("VecInit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fill"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("wen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n reg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("waddr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("wdata\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until readPorts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("raddr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("rdata"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("rdata"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" reg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("raddr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("code",[t._v("readPorts")]),t._v(" 表示寄存器文件的读端口数量。这个数量决定了在任何给定的时钟周期内,可以同时读取多少个独立寄存器的数据。每个读端口由其自己的读取地址("),s("code",[t._v("raddr")]),t._v(")和读取数据("),s("code",[t._v("rdata")]),t._v(")组成。在这种设置中,你可以在一个时钟周期内并行读取多个寄存器的值,而不是一次只能读取一个,这对于增加处理器的数据吞吐量非常有用。")]),t._v(" "),s("p",[t._v("具体到代码:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("readPorts")]),t._v(":定义了有多少个并行的读端口可用于同时读取寄存器文件中的数据。")]),t._v(" "),s("li",[s("code",[t._v("io.raddr")]),t._v(":一个向量,包含了每个读端口对应的读取地址。每个读端口都可以独立地从寄存器文件中选择一个寄存器进行读取。")]),t._v(" "),s("li",[s("code",[t._v("io.rdata")]),t._v(":一个向量,用于输出每个读端口读取到的寄存器值。每个端口根据对应的"),s("code",[t._v("raddr")]),t._v("读取寄存器文件中的数据,并将其放置在"),s("code",[t._v("rdata")]),t._v("的相应位置。")])])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/63.81ae9ced.js b/assets/js/63.81ae9ced.js new file mode 100644 index 0000000..f054dde --- /dev/null +++ b/assets/js/63.81ae9ced.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[63],{406:function(t,s,a){"use strict";a.r(s);var n=a(14),p=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-03-04-3-3-interlude-chisel-standard-library"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-04-3-3-interlude-chisel-standard-library"}},[t._v("#")]),t._v(" 2024.03.04-3.3 Interlude: Chisel Standard Library")]),t._v(" "),s("h2",{attrs:{id:"decoupled-a-standard-ready-valid-interface"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#decoupled-a-standard-ready-valid-interface"}},[t._v("#")]),t._v(" Decoupled: A Standard Ready-Valid Interface")]),t._v(" "),s("p",[t._v("在 Chisel 中,"),s("code",[t._v("DecoupledIO")]),t._v(" 是一种标准的准备就绪(ready-valid)接口,广泛用于不同模块间的数据传输,提供了一种带有流控制的通信机制。使用 "),s("code",[t._v("DecoupledIO")]),t._v(" 可以有效地处理数据传输的同步问题,特别是在生产者(source)和消费者(sink)速率不匹配时,确保数据的正确传输与接收。")]),t._v(" "),s("h3",{attrs:{id:"组件"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#组件"}},[t._v("#")]),t._v(" 组件")]),t._v(" "),s("p",[s("code",[t._v("DecoupledIO")]),t._v(" 接口由以下三个主要部分组成:")]),t._v(" "),s("ol",[s("li",[t._v("valid(有效) - 这是一个输出信号(从数据源角度看),用于表明当前的数据是有效的,可以被读取。当数据源有数据准备好发送时,它会将 "),s("code",[t._v("valid")]),t._v(" 信号置为高电平。")]),t._v(" "),s("li",[t._v("ready(准备就绪) - 这是一个输入信号(从数据源角度看),用于表明目标模块(接收端)准备好接收数据。当接收端可以接收新的数据时,它会将 "),s("code",[t._v("ready")]),t._v(" 信号置为高电平。")]),t._v(" "),s("li",[t._v("bits(数据位) - 这个信号承载了要传输的实际数据。数据的宽度和类型可以是任意的,从简单的 "),s("code",[t._v("UInt")]),t._v(" 或 "),s("code",[t._v("Bool")]),t._v(" 到复杂的用户定义 "),s("code",[t._v("Bundle")]),t._v("。")])]),t._v(" "),s("h3",{attrs:{id:"数据传输"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#数据传输"}},[t._v("#")]),t._v(" 数据传输")]),t._v(" "),s("p",[t._v("在 "),s("code",[t._v("DecoupledIO")]),t._v(" 接口中,数据传输在以下条件下发生:")]),t._v(" "),s("ul",[s("li",[t._v("数据源设置 "),s("code",[t._v("valid")]),t._v(" 为高电平,表示其有数据要发送。")]),t._v(" "),s("li",[t._v("接收端设置 "),s("code",[t._v("ready")]),t._v(" 为高电平,表示其准备好接收数据。")])]),t._v(" "),s("p",[t._v("当且仅当同一时钟周期内 "),s("code",[t._v("valid")]),t._v(" 和 "),s("code",[t._v("ready")]),t._v(" 同时为高电平时,数据才会被传输。这允许在接收端或发送端任一端控制数据流,实现背压(backpressure)机制:")]),t._v(" "),s("ul",[s("li",[t._v("如果接收端未准备好接收("),s("code",[t._v("ready")]),t._v(" 为低),即使发送端有数据发送("),s("code",[t._v("valid")]),t._v(" 为高),数据也不会被传输。")]),t._v(" "),s("li",[t._v("如果发送端没有数据要发送("),s("code",[t._v("valid")]),t._v(" 为低),即使接收端准备好了("),s("code",[t._v("ready")]),t._v(" 为高),也不会有数据传输。")])]),t._v(" "),s("h3",{attrs:{id:"使用场景"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#使用场景"}},[t._v("#")]),t._v(" 使用场景")]),t._v(" "),s("p",[s("code",[t._v("DecoupledIO")]),t._v(" 非常适用于生产者和消费者速率不一致的情况,如:")]),t._v(" "),s("ul",[s("li",[t._v("在 FIFO 队列的实现中,确保数据不会在缓冲区满时被写入,或在缓冲区空时被读出。")]),t._v(" "),s("li",[t._v("在处理器设计中,用于不同执行单元间的数据传输,确保在数据未准备好或处理单元未准备好时不发生数据传输。")])]),t._v(" "),s("h3",{attrs:{id:"代码示例"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#代码示例"}},[t._v("#")]),t._v(" 代码示例")]),t._v(" "),s("p",[t._v("以下是如何在 Chisel 中创建一个 "),s("code",[t._v("DecoupledIO")]),t._v(" 接口的简单示例:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 定义数据宽度")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" decoupledData "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Decoupled"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 创建 DecoupledIO 接口")]),t._v("\n")])])]),s("p",[t._v("这里,"),s("code",[t._v("decoupledData")]),t._v(" 将是一个拥有 "),s("code",[t._v("valid")]),t._v("、"),s("code",[t._v("ready")]),t._v(" 和 "),s("code",[t._v("bits")]),t._v(" 字段的 "),s("code",[t._v("DecoupledIO")]),t._v(" Bundle,可用于模块间的数据传输。")]),t._v(" "),s("h2",{attrs:{id:"queue"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#queue"}},[t._v("#")]),t._v(" Queue")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example circuit using a Queue")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Flipped"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Decoupled"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Decoupled"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" queue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Queue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2-element queue")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" queue\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Enqueue an element")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("42.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Starting:"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tio.in: ready=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tio.out: valid=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", bits=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Enqueue another element")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("43.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// What do you think io.out.valid and io.out.bits will be?")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"After first enqueue:"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tio.in: ready=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tio.out: valid=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", bits=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Read a element, attempt to enqueue")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("44.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// What do you think io.in.ready will be, and will this enqueue succeed, and what will be read?")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"On first read:"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tio.in: ready=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tio.out: valid=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", bits=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Read elements out")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// What do you think will be read here?")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"On second read:"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tio.in: ready=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tio.out: valid=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", bits=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Will a third read produce anything?")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"On third read:"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tio.in: ready=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tio.out: valid=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", bits=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("Starting"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n\tio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ready"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n\tio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" valid"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bits"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\nAfter first enqueue"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n\tio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ready"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n\tio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" valid"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bits"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),t._v("\nOn first read"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n\tio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ready"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n\tio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" valid"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bits"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),t._v("\nOn second read"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n\tio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ready"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n\tio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" valid"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bits"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("43")]),t._v("\nOn third read"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n\tio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ready"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n\tio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" valid"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bits"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),t._v("\n")])])]),s("ol",[s("li",[s("p",[s("code",[t._v("val in = Flipped(Decoupled(UInt(8.W)))")]),t._v(" 这里的"),s("code",[t._v("Flipped")]),t._v("表示是"),s("code",[t._v("Input")]),t._v(",因为"),s("code",[t._v("Decoupled")]),t._v("默认是"),s("code",[t._v("Output")])])]),t._v(" "),s("li",[s("p",[s("code",[t._v("val queue = Queue(io.in, 2)")]),t._v(" 连接 "),s("code",[t._v("io.in")]),t._v(" 到队列的输入端: 这意味着 "),s("code",[t._v("io.in")]),t._v(" 上发生的任何事情(比如信号变化)都会直接影响到队列。具体来说,当您在测试代码中设置 "),s("code",[t._v("io.in.valid")]),t._v(" 和 "),s("code",[t._v("io.in.bits")]),t._v(",您实际上是在向队列的入队端提供数据。")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("io.out <> queue")]),t._v(" 时,你实际上是在将模块的输出接口 "),s("code",[t._v("io.out")]),t._v(" 和队列 "),s("code",[t._v("queue")]),t._v(" 的出队接口双向连接。")]),t._v(" "),s("p",[t._v("具体来说,对于 "),s("code",[t._v("DecoupledIO")]),t._v(" 接口:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("io.out.valid")]),t._v(" 会连接到 "),s("code",[t._v("queue.io.deq.valid")]),t._v("。")]),t._v(" "),s("li",[s("code",[t._v("io.out.bits")]),t._v(" 会连接到 "),s("code",[t._v("queue.io.deq.bits")]),t._v("。")]),t._v(" "),s("li",[s("code",[t._v("queue.io.deq.ready")]),t._v(" 会连接到 "),s("code",[t._v("io.out.ready")]),t._v("。")])]),t._v(" "),s("p",[t._v("这种连接方式确保了数据可以从 "),s("code",[t._v("queue")]),t._v(" 的出队端传输到模块的输出 "),s("code",[t._v("io.out")]),t._v(",同时允许 "),s("code",[t._v("io.out")]),t._v(" 控制背压(通过 "),s("code",[t._v("ready")]),t._v(" 信号)以及 "),s("code",[t._v("queue")]),t._v(" 报告其状态(通过 "),s("code",[t._v("valid")]),t._v(" 信号)。")])])]),t._v(" "),s("ul",[s("li",[t._v("开始时:\n"),s("ul",[s("li",[t._v("首先,输出端 "),s("code",[t._v("io.out.ready")]),t._v(" 被设为 "),s("code",[t._v("false")]),t._v(",表示消费者还没准备好接收数据。")]),t._v(" "),s("li",[t._v("输入端 "),s("code",[t._v("io.in.valid")]),t._v(" 被设为 "),s("code",[t._v("true")]),t._v(",并通过 "),s("code",[t._v("io.in.bits")]),t._v(" 提供了值 42,尝试将其入队。")]),t._v(" "),s("li",[t._v("打印的输出显示,初始时,"),s("code",[t._v("io.in.ready")]),t._v(" 应该为 "),s("code",[t._v("true")]),t._v("(队列未满,可以接收数据),而 "),s("code",[t._v("io.out.valid")]),t._v(" 应该为 "),s("code",[t._v("false")]),t._v("(数据尚未出队到输出端)。")])])]),t._v(" "),s("li",[t._v("首次入队后:\n"),s("ul",[s("li",[t._v("程序尝试将另一个值 43 入队,并再次检查状态。")]),t._v(" "),s("li",[t._v("由于队列不满,第二个值应该成功入队。"),s("code",[t._v("io.in.ready")]),t._v(" 仍然为 "),s("code",[t._v("true")]),t._v(",表明还可以接收更多数据。")]),t._v(" "),s("li",[s("code",[t._v("io.out.valid")]),t._v(" 被设置为 "),s("code",[t._v("true")]),t._v(" 并且 "),s("code",[t._v("io.out.bits")]),t._v(" 被更新为 42,因为队列内部确实有一个元素(42)准备好了并且尝试发送。即使 "),s("code",[t._v("io.out.ready")]),t._v(" 是 "),s("code",[t._v("false")]),t._v(","),s("code",[t._v("io.out.valid")]),t._v(" 和 "),s("code",[t._v("io.out.bits")]),t._v(" 仍然会反映队列出口处的数据状态。")]),t._v(" "),s("li",[t._v("尽管 "),s("code",[t._v("io.out.valid")]),t._v(" 为 "),s("code",[t._v("true")]),t._v(" 并且 "),s("code",[t._v("io.out.bits")]),t._v(" 显示了数据(42),但由于 "),s("code",[t._v("io.out.ready")]),t._v(" 为 "),s("code",[t._v("false")]),t._v(',这次数据传输并不会真正完成。换句话说,42 在逻辑上是"准备发送"的,但由于缺乏接收准备就绪的确认(即 '),s("code",[t._v("io.out.ready")]),t._v(" 为 "),s("code",[t._v("false")]),t._v('),它实际上并没有"被接收"。')])])]),t._v(" "),s("li",[t._v("首次读取尝试:\n"),s("ul",[s("li",[t._v("程序尝试同时进行读取(将 "),s("code",[t._v("io.out.ready")]),t._v(" 设为 "),s("code",[t._v("true")]),t._v(")和入队(值 44)。")]),t._v(" "),s("li",[t._v("由于此时输出准备好接收数据,第一个入队的值(42)应该会被传递到 "),s("code",[t._v("io.out")]),t._v(","),s("code",[t._v("io.out.valid")]),t._v(" 应变为 "),s("code",[t._v("true")]),t._v(","),s("code",[t._v("io.out.bits")]),t._v(" 应显示 42。")]),t._v(" "),s("li",[s("code",[t._v("io.in.ready")]),t._v(" 为 "),s("code",[t._v("0")]),t._v("。这是因为队列("),s("code",[t._v("queue")]),t._v(")此时已经满了。")])])]),t._v(" "),s("li",[t._v("第二次读取:\n"),s("ul",[s("li",[t._v("这时不再有新数据入队,但 "),s("code",[t._v("io.out")]),t._v(" 准备好读取数据。")]),t._v(" "),s("li",[t._v("应该能读取到之前入队的第二个值 43,"),s("code",[t._v("io.out.valid")]),t._v(" 应为 "),s("code",[t._v("true")]),t._v(","),s("code",[t._v("io.out.bits")]),t._v(" 应显示 43。")])])]),t._v(" "),s("li",[t._v("第三次读取尝试:\n"),s("ul",[s("li",[t._v("在这一步,尽管 "),s("code",[t._v("io.out")]),t._v(" 依然准备好接收数据,但队列应该已经空了。")]),t._v(" "),s("li",[t._v("因此,"),s("code",[t._v("io.out.valid")]),t._v(" 应该变回 "),s("code",[t._v("false")]),t._v(",表示没有更多数据可读。")]),t._v(" "),s("li",[t._v("不过为什么是 42?\n注:")])]),t._v(" "),s("ol",[s("li",[s("code",[t._v("peek()")]),t._v(" 函数用于查看信号的当前值,而 "),s("code",[t._v(".litValue")]),t._v(" 用于获取这个值作为一个 Scala 的字面量(literal)。因此,"),s("code",[t._v("c.io.in.ready.peek().litValue")]),t._v(" 表示查看 "),s("code",[t._v("c.io.in.ready")]),t._v(" 信号的当前值,并获取其字面量值。")]),t._v(" "),s("li",[t._v("必须要"),s("code",[t._v("c.clock.step(1)")]),t._v("以后才会有输出")])])])]),t._v(" "),s("h2",{attrs:{id:"arbiter"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#arbiter"}},[t._v("#")]),t._v(" Arbiter")]),t._v(" "),s("p",[t._v("一个 Arbiter 是用于解决多个请求源争用单一资源的组件。它的基本功能是在多个输入信号中选择一个进行输出,基于某种特定的优先级或策略。在处理多个并发请求访问同一资源(例如,总线或共享内存)时,仲裁器确保每个时刻只有一个选定的请求被服务,同时遵循公平性或优先级规则,避免资源冲突或死锁。")]),t._v(" "),s("ol",[s("li",[s("p",[s("code",[t._v("Arbiter")]),t._v(":这是一个静态优先级仲裁器,它总是优先选择索引较低的生产者。如果有多个请求同时到达,"),s("code",[t._v("Arbiter")]),t._v(" 会根据请求信号的索引顺序来决定优先权,索引较小的请求者会获得优先服务。这意味着如果较低索引的请求者持续有请求,它将持续获得资源,而更高索引的请求者则需要等待。")]),t._v(" "),s("p",[t._v("示例代码如下:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example circuit using a priority arbiter")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Flipped"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Decoupled"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Decoupled"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Arbiter doesn't have a convenience constructor, so it's built like any Module")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" arbiter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Module"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Arbiter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2 to 1 Priority Arbiter")]),t._v("\n arbiter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" arbiter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Start:"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tin(0).ready=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", in(1).ready=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tout.valid=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out.bits=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Valid input 1")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("42.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// What do you think the output will be?")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"valid input 1:"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tin(0).ready=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", in(1).ready=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tout.valid=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out.bits=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Valid inputs 0 and 1")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("43.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// What do you think the output will be? Which inputs will be ready?")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"valid inputs 0 and 1:"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tin(0).ready=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", in(1).ready=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tout.valid=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out.bits=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Valid input 0")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// What do you think the output will be?")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"valid input 0:"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tin(0).ready=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", in(1).ready=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\tout.valid=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out.bits=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("Start"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\nvalid input "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),t._v("\nvalid inputs "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" and "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("43")]),t._v("\nvalid input "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ready"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("valid"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bits"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("43")]),t._v("\n")])])]),s("ol",[s("li",[s("p",[t._v("初始状态检查:")]),t._v(" "),s("ul",[s("li",[t._v("首先,测试确认在没有任何有效输入 ("),s("code",[t._v("io.in(0).valid")]),t._v(" 和 "),s("code",[t._v("io.in(1).valid")]),t._v(" 都为 "),s("code",[t._v("false")]),t._v(") 时,输出 ("),s("code",[t._v("io.out.valid")]),t._v(") 也应为 "),s("code",[t._v("false")]),t._v(",表示没有数据通过仲裁器。")])])]),t._v(" "),s("li",[s("p",[t._v("激活第二个输入:")]),t._v(" "),s("ul",[s("li",[t._v("然后,测试激活 "),s("code",[t._v("io.in(1)")]),t._v("(即索引为 1 的输入),同时保持 "),s("code",[t._v("io.out.ready")]),t._v(" 为 "),s("code",[t._v("true")]),t._v(",这模拟了接收端准备好接收数据的情况。预期 "),s("code",[t._v("io.in(1)")]),t._v(" 的数据应该通过到 "),s("code",[t._v("io.out")]),t._v("。")]),t._v(" "),s("li",[t._v("两个输入的 "),s("code",[t._v("ready")]),t._v(" 信号都是 "),s("code",[t._v("1")]),t._v("。这是因为 "),s("code",[t._v("Arbiter")]),t._v(" 的行为是基于它可以传递数据的能力。让我们分解这个情况:\n当只有 "),s("code",[t._v("io.in(1)")]),t._v(" 有效时:\n"),s("ul",[s("li",[s("code",[t._v("in(0).ready=1")]),t._v(":这意味着 "),s("code",[t._v("Arbiter")]),t._v(" 仲裁器准备好从 "),s("code",[t._v("io.in(0)")]),t._v(" 接收数据,尽管此时 "),s("code",[t._v("io.in(0)")]),t._v(" 没有数据(不是有效的)。"),s("code",[t._v("ready")]),t._v(" 信号为 "),s("code",[t._v("1")]),t._v(" 表示如果 "),s("code",[t._v("io.in(0)")]),t._v(" 有数据,"),s("code",[t._v("Arbiter")]),t._v(" 准备好接收它。")]),t._v(" "),s("li",[s("code",[t._v("in(1).ready=1")]),t._v(":同时,"),s("code",[t._v("Arbiter")]),t._v(" 也表示准备好接收 "),s("code",[t._v("io.in(1)")]),t._v(" 的数据,因为它是有效的。在这种情况下,由于 "),s("code",[t._v("io.out.ready")]),t._v(" 被设置为 "),s("code",[t._v("true")]),t._v(","),s("code",[t._v("Arbiter")]),t._v(" 知道输出端已经准备好接收数据,所以它将 "),s("code",[t._v("io.in(1)")]),t._v(" 的 "),s("code",[t._v("ready")]),t._v(" 也置为 "),s("code",[t._v("1")]),t._v("。")])])])]),t._v(" "),s("p",[t._v("这里的关键是 "),s("code",[t._v("ready")]),t._v(" 信号表示的是接收能力而非当前的数据有效性。即使 "),s("code",[t._v("io.in(0)")]),t._v(" 当前没有标记为有效,"),s("code",[t._v("Arbiter")]),t._v(" 也表明它准备好从该输入接收数据,这就是为什么在 "),s("code",[t._v("io.in(1)")]),t._v(" 有效时,"),s("code",[t._v("io.in(0).ready")]),t._v(" 也会是 "),s("code",[t._v("1")]),t._v("。")])]),t._v(" "),s("li",[s("p",[t._v("同时激活两个输入:")]),t._v(" "),s("ul",[s("li",[t._v("接下来,测试同时激活两个输入,即 "),s("code",[t._v("io.in(0)")]),t._v(" 和 "),s("code",[t._v("io.in(1)")]),t._v(" 都设置为有效。由于 "),s("code",[t._v("Arbiter")]),t._v(" 的静态优先级策略,预期 "),s("code",[t._v("io.in(0)")]),t._v(" 的数据(即优先级更高的输入)会被传递到 "),s("code",[t._v("io.out")]),t._v("。")]),t._v(" "),s("li",[t._v("当两个输入 "),s("code",[t._v("io.in(0)")]),t._v(" 和 "),s("code",[t._v("io.in(1)")]),t._v(" 都被设置为有效时,"),s("code",[t._v("Arbiter")]),t._v(" 会根据其内部逻辑来选择一个输入。对于普通的 "),s("code",[t._v("Arbiter")]),t._v(",它将优先选择索引较低的输入,即 "),s("code",[t._v("io.in(0)")]),t._v("。")]),t._v(" "),s("li",[t._v("由于 "),s("code",[t._v("io.in(0)")]),t._v(" 被选中,"),s("code",[t._v("io.in(1)")]),t._v(" 的 "),s("code",[t._v("ready")]),t._v(" 信号将会被置为 "),s("code",[t._v("false")]),t._v(",而 "),s("code",[t._v("io.in(0).ready")]),t._v(" 会是 "),s("code",[t._v("true")]),t._v(",表示 "),s("code",[t._v("Arbiter")]),t._v(" 准备接受 "),s("code",[t._v("io.in(0)")]),t._v(" 的数据。")]),t._v(" "),s("li",[t._v("在此情况下,即使您设置了 "),s("code",[t._v("io.in(1).bits")]),t._v(",这个数据也不会被 "),s("code",[t._v("Arbiter")]),t._v(" 选择,因为 "),s("code",[t._v("io.in(0)")]),t._v(" 有更高的优先级。")])])]),t._v(" "),s("li",[s("p",[t._v("只激活第一个输入:")]),t._v(" "),s("ul",[s("li",[t._v("最后,测试只激活 "),s("code",[t._v("io.in(0)")]),t._v("。即使之前 "),s("code",[t._v("io.in(1)")]),t._v(" 被激活过,在这一步中只有 "),s("code",[t._v("io.in(0)")]),t._v(" 有效,所以只有它的数据应该被传递到 "),s("code",[t._v("io.out")]),t._v("。")])])])])]),t._v(" "),s("li",[s("p",[s("code",[t._v("RRArbiter")]),t._v(":这是一个循环(round-robin)仲裁器,它按照循环的顺序为请求者提供服务,确保了长期的公平性。当一个请求被服务后,"),s("code",[t._v("RRArbiter")]),t._v(" 会记住最后被服务的请求,并在下一个服务周期中优先考虑下一个请求者。这样可以确保即使在高负载下,所有请求者也能获得均等的服务机会。")]),t._v(" "),s("p",[t._v("示例代码如下:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" rrArbiter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Module"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" RRArbiter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nrrArbiter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" producer0\nrrArbiter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" producer1\nconsumer "),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" rrArbiter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out\n")])])])])]),t._v(" "),s("p",[t._v("注:Ariter 是组合电路,不需要 step(1)")]),t._v(" "),s("h2",{attrs:{id:"misc-function-blocks"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#misc-function-blocks"}},[t._v("#")]),t._v(" Misc Function Blocks")]),t._v(" "),s("h3",{attrs:{id:"bitwise-utilities"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#bitwise-utilities"}},[t._v("#")]),t._v(" Bitwise Utilities")]),t._v(" "),s("h3",{attrs:{id:"popcount"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#popcount"}},[t._v("#")]),t._v(" PopCount")]),t._v(" "),s("p",[t._v("PopCount returns the number of high (1) bits in the input as a "),s("code",[t._v("UInt")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example circuit using PopCount")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" PopCount"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Integer.parseInt is used create an Integer from a binary specification")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Integer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"00000000"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=0b')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Integer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"00001111"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=0b')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Integer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"11001010"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=0b')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Integer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"11111111"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=0b')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("in"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b0"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b1111"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),t._v("\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b11001010"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),t._v("\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b11111111"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),t._v("\n")])])]),s("h3",{attrs:{id:"reverse"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#reverse"}},[t._v("#")]),t._v(" Reverse")]),t._v(" "),s("p",[t._v("Reverse returns the bit-reversed input")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example circuit using Reverse")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Reverse"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Integer.parseInt is used create an Integer from a binary specification")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Integer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"01010101"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=0b')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=0b")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Integer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"00001111"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=0b')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=0b")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Integer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"11110000"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=0b')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=0b")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Integer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"11001010"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=0b')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=0b")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("in"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b1010101"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b10101010\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b1111"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b11110000\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b11110000"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b1111\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b11001010"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b1010011\n")])])]),s("h3",{attrs:{id:"onehot-encoding-utilities"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#onehot-encoding-utilities"}},[t._v("#")]),t._v(" OneHot encoding utilities")]),t._v(" "),s("h3",{attrs:{id:"uinttooh"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#uinttooh"}},[t._v("#")]),t._v(" "),s("code",[t._v("UIntToOH")])]),t._v(" "),s("p",[t._v("UInt to OneHot")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example circuit using UIntToOH")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" UIntToOH"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=0b")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=0b")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=0b")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("15.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=0b")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b1\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b10\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b100000000\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("15")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b1000000000000000\n")])])]),s("h3",{attrs:{id:"ohtouint"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#ohtouint"}},[t._v("#")]),t._v(" "),s("code",[t._v("OHToUInt")])]),t._v(" "),s("p",[t._v("OneHot to UInt")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example circuit using OHToUInt")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" OHToUInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Integer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0000 0000 0000 0001"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("replace"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('" "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=0b')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Integer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0000 0000 1000 0000"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("replace"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('" "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=0b')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Integer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1000 0000 0000 0001"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("replace"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('" "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=0b')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Some invalid inputs:")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// None high")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Integer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0000 0000 0000 0000"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("replace"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('" "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=0b')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Multiple high")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Integer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0001 0100 0010 0000"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("replace"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('" "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in=0b')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b10000000"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),t._v("\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b1000000000000001"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("15")]),t._v("\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b0"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\nin"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("b1010000100000"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("15")]),t._v("\n")])])]),s("h3",{attrs:{id:"mux"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mux"}},[t._v("#")]),t._v(" MUX")]),t._v(" "),s("h3",{attrs:{id:"prioritymux"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#prioritymux"}},[t._v("#")]),t._v(" "),s("code",[t._v("PriorityMux")])]),t._v(" "),s("p",[t._v("Outputs the value associated with the lowest-index asserted select signal.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example circuit using PriorityMux")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_sels "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_bits "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" PriorityMux"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Select higher index only")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in_sels=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Select both - arbitration needed")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in_sels=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Select lower index only")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in_sels=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nin_sels"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),t._v("\nin_sels"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v("\nin_sels"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v("\n")])])]),s("p",[s("code",[t._v("PriorityMux")]),t._v(" 会根据 "),s("code",[t._v("in_sels")]),t._v(" 中的布尔值,从左到右(即从索引 0 开始)检查哪个输入是选中的,并输出第一个选中输入对应的 "),s("code",[t._v("in_bits")]),t._v(" 值。因此,同时使 "),s("code",[t._v("in_sels(0)")]),t._v(" 和 "),s("code",[t._v("in_sels(1)")]),t._v(" 为 "),s("code",[t._v("true")]),t._v(" 时,由于 "),s("code",[t._v("in_sels(0)")]),t._v(" 的优先级更高,"),s("code",[t._v("io.out")]),t._v(" 应该输出 "),s("code",[t._v("in_bits(0)")]),t._v(" 的值,即 "),s("code",[t._v("10.U")]),t._v("。")]),t._v(" "),s("h3",{attrs:{id:"onehot-mux-mux1h"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#onehot-mux-mux1h"}},[t._v("#")]),t._v(" OneHot Mux: "),s("code",[t._v("Mux1H")])]),t._v(" "),s("p",[t._v("An "),s("code",[t._v("Mux1H")]),t._v(" provides an efficient implementation when it is guaranteed that exactly one of the select signals will be high. Behavior is undefined if the assumption is not true.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example circuit using Mux1H")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_sels "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in_bits "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Mux1H"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_bits"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Select index 1")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in_sels=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Select index 0")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in_sels=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Select none (invalid)")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in_sels=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Select both (invalid)")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"in_sels=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in_sels"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", out=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nin_sels"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),t._v("\nin_sels"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v("\nin_sels"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\nin_sels"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),t._v("\n")])])]),s("h3",{attrs:{id:"counter"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#counter"}},[t._v("#")]),t._v(" "),s("code",[t._v("Counter")])]),t._v(" "),s("p",[t._v("A counter that can be incremented once every cycle, up to some specified limit, at which point it overflows. Note that it is not a Module, and its value is accessible.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example circuit with two counters")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" totalCycles "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Assuming 32-bit is enough for cycle count")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Counter for controlled increments")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" controlledCounter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Counter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 3-count Counter (outputs range [0...2])")]),t._v("\n when"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n controlledCounter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" controlledCounter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Counter for total cycles, counting up to (2^32)-1")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" totalCycleCounter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Counter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("math"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n totalCycleCounter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Increment every cycle")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("totalCycles "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" totalCycleCounter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"start: controlled counter value=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", total cycles=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("totalCycles"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"step 1: controlled counter value=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", total cycles=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("totalCycles"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"step 2: controlled counter value=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", total cycles=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("totalCycles"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"step without increment: controlled counter value=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", total cycles=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("totalCycles"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"step again: controlled counter value=')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", total cycles=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("totalCycles"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nstart"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" controlled counter value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" total cycles"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\nstep "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" controlled counter value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" total cycles"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\nstep "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" controlled counter value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" total cycles"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("\nstep without increment"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" controlled counter value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" total cycles"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\nstep again"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" controlled counter value"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" total cycles"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),t._v("\n")])])]),s("p",[t._v("在 Chisel 中创建一个计数器时,如果您传递的参数是 "),s("code",[t._v("n")]),t._v(",那么计数器能够表示的计数范围是从 0 到 n-1。所以,当您使用 "),s("code",[t._v("Counter(n)")]),t._v(" 时,计数器的实际最大计数值是 n-1。")])])}),[],!1,null,null,null);s.default=p.exports}}]); \ No newline at end of file diff --git a/assets/js/64.4a7dc366.js b/assets/js/64.4a7dc366.js new file mode 100644 index 0000000..29d5fa9 --- /dev/null +++ b/assets/js/64.4a7dc366.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[64],{405:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-03-05-3-4-higher-order-functions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-05-3-4-higher-order-functions"}},[t._v("#")]),t._v(" 2024.03.05-3.4 Higher-Order Functions")]),t._v(" "),s("h1",{attrs:{id:"a-tale-of-two-firs"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#a-tale-of-two-firs"}},[t._v("#")]),t._v(" A Tale of Two FIRs")]),t._v(" "),s("p",[t._v("From the last module, we had the convolution part of the FIR filter written like this:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" muls "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" muls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("consts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" muls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" regs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("consts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" scan "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" scan"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" muls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" scan"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" muls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" scan"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" scan"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("As a recap, the idea is to multiply each element of "),s("code",[t._v("io.in")]),t._v(" with the corresponding element of "),s("code",[t._v("io.consts")]),t._v(", and store it in "),s("code",[t._v("muls")]),t._v(". Then, the elements in "),s("code",[t._v("muls")]),t._v(" are accumulated into "),s("code",[t._v("scan")]),t._v(", with "),s("code",[t._v("scan(0) = muls(0)")]),t._v(", "),s("code",[t._v("scan(1) = scan(0) + muls(1) = muls(0) + muls(1)")]),t._v(", and in general "),s("code",[t._v("scan(n) = scan(n-1) + muls(n) = muls(0) + ... + muls(n-1) + muls(n)")]),t._v(". The last element in "),s("code",[t._v("scan")]),t._v(" (equal to the sum of all "),s("code",[t._v("muls")]),t._v(") is assigned to "),s("code",[t._v("io.out")]),t._v(".")]),t._v(" "),s("p",[t._v("However, it's very verbose for what might be considered quite a simple operation. In fact, all that could be written in one line:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("taps zip io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("consts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reduce"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("ul",[s("li",[t._v("假设 "),s("code",[t._v("taps")]),t._v(" 是所有样本的列表,其中 "),s("code",[t._v("taps(0) = io.in")]),t._v(","),s("code",[t._v("taps(1) = regs(0)")]),t._v(" 等等。")]),t._v(" "),s("li",[s("code",[t._v("(taps zip io.consts)")]),t._v(" 将两个列表 "),s("code",[t._v("taps")]),t._v(" 和 "),s("code",[t._v("io.consts")]),t._v(" 合并成一个列表,其中每个元素是一个元组,这个元组包含了在相应位置的输入元素。具体来说,它的值将是 "),s("code",[t._v("[(taps(0), io.consts(0)), (taps(1), io.consts(1)), ..., (taps(n), io.consts(n))]")]),t._v("。记住,在 Scala 中点号是可选的,所以这等同于 "),s("code",[t._v("(taps.zip(io.consts))")]),t._v("。")]),t._v(" "),s("li",[s("code",[t._v(".map { case (a, b) => a * b }")]),t._v(" 对列表中的元素应用一个匿名函数(接收两个元素的元组并返回它们的乘积),并返回结果。在这个情况下,结果等价于在冗长示例中的 "),s("code",[t._v("muls")]),t._v(",其值为 "),s("code",[t._v("[taps(0) * io.consts(0), taps(1) * io.consts(1), ..., taps(n) * io.consts(n)]")]),t._v("。")]),t._v(" "),s("li",[t._v("最后,"),s("code",[t._v(".reduce(_ + _)")]),t._v(" 同样应用一个函数(元素的加法)到列表的元素上。然而,它接收两个参数:第一个是当前的累加值,第二个是列表元素(在第一次迭代中,它只是将前两个元素相加)。这些由括号中的两个下划线表示。那么结果,假设是从左到右的遍历,将会是 "),s("code",[t._v("(((muls(0) + muls(1)) + muls(2)) + ...) + muls(n)")]),t._v(",更深层次括号内的结果先被计算。这就是卷积的输出结果。")])]),t._v(" "),s("h1",{attrs:{id:"functions-as-arguments"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#functions-as-arguments"}},[t._v("#")]),t._v(" Functions as Arguments")]),t._v(" "),s("p",[t._v("Formally, functions like "),s("code",[t._v("map")]),t._v(" and "),s("code",[t._v("reduce")]),t._v(" are called "),s("em",[t._v("higher-order functions")]),t._v(" : they are functions that take functions as arguments. As it turns out (and hopefully, as you can see from the above example), these are very powerful constructs that encapsulate a general computational pattern, allowing you to concentrate on the application logic instead of flow control, and resulting in very concise code.")]),t._v(" "),s("ul",[s("li",[t._v("对于每个参数只引用一次的函数,您"),s("em",[t._v("可以")]),t._v("使用下划线("),s("code",[t._v("_")]),t._v(")来引用每个参数。在上面的例子中,"),s("code",[t._v("reduce")]),t._v(" 函数接受两个参数,可以被指定为 "),s("code",[t._v("_ + _")]),t._v("。虽然这很方便,但它受制于一组额外的复杂规则,所以如果不起作用,您可以尝试:")]),t._v(" "),s("li",[t._v("明确指定输入参数列表。"),s("code",[t._v("reduce")]),t._v(" 可以被明确写成 "),s("code",[t._v("(a, b) => a + b")]),t._v(",通用形式是把参数列表放在括号里,后面跟着 "),s("code",[t._v("=>")]),t._v(",然后是引用这些参数的函数体。")]),t._v(" "),s("li",[t._v("当需要解包元组时,使用 "),s("code",[t._v("case")]),t._v(" 语句,如 "),s("code",[t._v("case (a, b) => a * b")]),t._v("。这接收一个参数,一个两个元素的元组,并将其解包到变量 "),s("code",[t._v("a")]),t._v(" 和 "),s("code",[t._v("b")]),t._v(" 中,然后可以在函数体中使用它们。")])]),t._v(" "),s("h2",{attrs:{id:"practice-in-scala"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#practice-in-scala"}},[t._v("#")]),t._v(" Practice in Scala")]),t._v(" "),s("p",[t._v("Scala 集合 API 中的主要类,如"),s("code",[t._v("List")]),t._v("。这些高阶函数是这些 API 的一部分。实际上,上面的示例使用了"),s("code",[t._v("List")]),t._v("上的"),s("code",[t._v("map")]),t._v("和"),s("code",[t._v("reduce")]),t._v(" API。在这一节中,我们将通过示例和练习熟悉这些方法。在这些示例中,我们将对 Scala 数字("),s("code",[t._v("Int")]),t._v(")操作,以简化和明确表示,但因为 Chisel 运算符的行为类似,所以这些概念应该是通用的。")]),t._v(" "),s("h3",{attrs:{id:"example-map"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-map"}},[t._v("#")]),t._v(" Example: map")]),t._v(" "),s("p",[s("code",[t._v("List[A].map")]),t._v(" 有类型签名 "),s("code",[t._v("map[B](f: (A) ⇒ B): List[B]")]),t._v("。现在,将类型 A 和 B 视为 "),s("code",[t._v("Int")]),t._v(" 或 "),s("code",[t._v("UInt")]),t._v(",意味着它们可以是软件或硬件类型。它接受一个类型为 "),s("code",[t._v("(f: (A) ⇒ B)")]),t._v(" 的参数,或者一个接受类型为 A(与输入列表的元素类型相同)的一个参数并返回类型为 B 的值的函数。"),s("code",[t._v("map")]),t._v(" 然后返回一个新的类型为 B(参数函数的返回类型)的列表。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// explicit argument list in function")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// equivalent to the above, but implicit arguments")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toString "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// the output element type can be different from the input element type")]),t._v("\n\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("y "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this unpacks a tuple, note use of curly braces")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Related: Scala has a syntax for constructing lists of sequential numbers")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" to "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// to is inclusive , the end point is part of the result")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// until is exclusive at the end, the end point is not part of the result")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Those largely behave like lists, and can be useful for generating indices:")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"d"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("myList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// output:")]),t._v("\nList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("21")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nRange "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" to "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v("\nRange "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v("\nVector"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" d"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("ol",[s("li",[s("p",[t._v("使用小括号而不显式使用 case 关键字:\n当您直接提供一个匿名函数时,您通常只需要小括号即可。例如:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("这里,您直接给出了一个处理元素的函数 "),s("code",[t._v("(a, b) => a + b")]),t._v(",没有使用 "),s("code",[t._v("case")]),t._v("。")])]),t._v(" "),s("li",[s("p",[t._v("使用大括号并显式使用 "),s("code",[t._v("case")]),t._v(" 关键字:\n如果您想要在处理集合元素时使用模式匹配,您可以使用大括号并在里面使用 "),s("code",[t._v("case")]),t._v(" 关键字。这种方式通常用于元组的解构或更复杂的模式匹配。例如:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在这个例子中,您使用 "),s("code",[t._v("{ case (a, b) => a + b }")]),t._v(" 对元组进行解构,并对解构后的元素应用函数。")])])]),t._v(" "),s("h3",{attrs:{id:"example-zipwithindex"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-zipwithindex"}},[t._v("#")]),t._v(" Example: "),s("code",[t._v("zipWithIndex")])]),t._v(" "),s("p",[s("code",[t._v("List.zipWithIndex")]),t._v(" has type signature "),s("code",[t._v("zipWithIndex: List[(A, Int)]")]),t._v(". It takes no arguments, but returns a list where each element is a tuple of the original elements, and the index (with the first one being zero). So "),s("code",[t._v('List("a", "b", "c", "d").zipWithIndex')]),t._v(" would return "),s("code",[t._v('List(("a", 0), ("b", 1), ("c", 2), ("d", 3))')])]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zipWithIndex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// note indices start at zero")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"d"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zipWithIndex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"a"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"b"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"c"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"d"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"e"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"f"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"g"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"h"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zipWithIndex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// tuples nest")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// output:")]),t._v("\nList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("d"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nList"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("d"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("f"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("g"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("h"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h3",{attrs:{id:"example-reduce"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-reduce"}},[t._v("#")]),t._v(" Example: "),s("code",[t._v("**reduce**")])]),t._v(" "),s("p",[s("code",[t._v("List[A].map")]),t._v(" has type signature similar to "),s("code",[t._v("reduce(op: (A, A) ⇒ A): A")]),t._v(". (it's actually more lenient, "),s("code",[t._v("A")]),t._v(" only has to be a supertype of the List type, but we're not going to deal with that syntax here)")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reduce"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// returns the sum of all the elements")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reduce"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// returns the product of all the elements")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reduce"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// you can chain reduce onto the result of a map")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reduce"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// returns the product of the double of the elements of the input list.")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// output:")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("24")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("14")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("384")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Important note: reduce will fail with an empty list")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reduce"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h3",{attrs:{id:"example-fold"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-fold"}},[t._v("#")]),t._v(" Example: "),s("code",[t._v("**fold**")])]),t._v(" "),s("p",[s("code",[t._v("List[A].fold")]),t._v(" is very similar to reduce, except that you can specify the initial accumulation value. It has type signature similar to "),s("code",[t._v("fold(z: A)(op: (A, A) ⇒ A): A")]),t._v(". (like "),s("code",[t._v("reduce")]),t._v(", the type of "),s("code",[t._v("A")]),t._v(" is also more lenient). Notably, it takes two argument lists, the first ("),s("code",[t._v("z")]),t._v(") is the initial value, and the second is the accumulation function. Unlike "),s("code",[t._v("reduce")]),t._v(", it will not fail with an empty list, instead returning the initial value directly.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fold"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// equivalent to the sum using reduce")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fold"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// like above, but accumulation starts at 1")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fold"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// unlike reduce, does not fail on an empty input")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fold"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// returns the double the product of the elements of the input list")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// output:")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("11")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("48")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/65.fb042b19.js b/assets/js/65.fb042b19.js new file mode 100644 index 0000000..cf64fe4 --- /dev/null +++ b/assets/js/65.fb042b19.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[65],{407:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-03-09-3-6-object-oriented-programming"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-09-3-6-object-oriented-programming"}},[t._v("#")]),t._v(" 2024.03.09-3.6 Object Oriented Programming")]),t._v(" "),s("h1",{attrs:{id:"object-oriented-programming"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#object-oriented-programming"}},[t._v("#")]),t._v(" Object Oriented Programming")]),t._v(" "),s("h2",{attrs:{id:"abstract-classes"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#abstract-classes"}},[t._v("#")]),t._v(" Abstract Classes")]),t._v(" "),s("h3",{attrs:{id:"example-abstract-classes"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-abstract-classes"}},[t._v("#")]),t._v(" Example: Abstract Classes")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("abstract")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" MyAbstractClass "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" myFunction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myValue"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" ConcreteClass "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" MyAbstractClass "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" myFunction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello World!"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Uncomment below to test!")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// val abstractClass = new MyAbstractClass() // Illegal! Cannot instantiate an abstract class")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" concreteClass "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" ConcreteClass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Legal!")]),t._v("\n")])])]),s("p",[t._v("不能实例化抽象类")]),t._v(" "),s("h2",{attrs:{id:"trait"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#trait"}},[t._v("#")]),t._v(" Trait")]),t._v(" "),s("p",[t._v("Traits are very similar to abstract classes in that they can define unimplemented values. However, they differ in two ways:")]),t._v(" "),s("ul",[s("li",[t._v("a class can inherit from multiple traits")]),t._v(" "),s("li",[t._v("a trait cannot have constructor parameters")])]),t._v(" "),s("h3",{attrs:{id:"example-trait-and-multiple-inheritance"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-trait-and-multiple-inheritance"}},[t._v("#")]),t._v(" Example: Trait and Multiple Inheritance")]),t._v(" "),s("p",[t._v("Traits are how Scala implements multiple inheritance, as shown in the example below. "),s("code",[t._v("MyClass")]),t._v(" extends from both traits "),s("code",[t._v("HasFunction")]),t._v(" and "),s("code",[t._v("HasValue")])]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("trait")]),t._v(" HasFunction "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" myFunction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("trait")]),t._v(" HasValue "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myValue"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myOtherValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" MyClass "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" HasFunction "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("with")]),t._v(" HasValue "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" myFunction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello World!"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Uncomment below to test!")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// val myTraitFunction = new HasFunction() // Illegal! Cannot instantiate a trait")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// val myTraitValue = new HasValue() // Illegal! Cannot instantiate a trait")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" myClass "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" MyClass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Legal!")]),t._v("\n")])])]),s("p",[s("code",[t._v("extends HasFunction with HasValue")]),t._v(": 使用 "),s("code",[t._v("with")]),t._v(" 来继承多个类")]),t._v(" "),s("p",[t._v("注:通常都推荐使用 trait 除非特别想强调只能继承一个父类")]),t._v(" "),s("h2",{attrs:{id:"object"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#object"}},[t._v("#")]),t._v(" Object")]),t._v(" "),s("p",[t._v("一类特殊的 Class,不能实例化,可以直接调用")]),t._v(" "),s("h3",{attrs:{id:"example-object"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-object"}},[t._v("#")]),t._v(" Example: Object")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" MyObject "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" hi"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello World!"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" apply"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("msg"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" msg\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("MyObject"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("hi"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("MyObject"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"This message is important!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// equivalent to MyObject.apply(msg)")]),t._v("\n")])])]),s("div",{staticClass:"language-markdown extra-class"},[s("pre",{pre:!0,attrs:{class:"language-markdown"}},[s("code",[s("span",{pre:!0,attrs:{class:"token title important"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("##")]),t._v(' Companion Objects')]),t._v("\n\nWhen a class and an object share the same name and defined in the same file, the object is called a companion object. When you use "),s("span",{pre:!0,attrs:{class:"token code-snippet code keyword"}},[t._v("`new`")]),t._v(" before the class/object name, it will instantiate the class. If you don't use "),s("span",{pre:!0,attrs:{class:"token code-snippet code keyword"}},[t._v("`new`")]),t._v(", it will reference the object:\n\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("span")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token special-attr"}},[s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),s("span",{pre:!0,attrs:{class:"token value css language-css"}},[s("span",{pre:!0,attrs:{class:"token property"}},[t._v("color")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("blue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Example: Companion Object"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("br")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])])]),s("h2",{attrs:{id:"companion-objects"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#companion-objects"}},[t._v("#")]),t._v(" Companion Objects")]),t._v(" "),s("p",[t._v("When a class and an object share the same name and defined in the same file, the object is called a companion object. When you use "),s("code",[t._v("new")]),t._v(" before the class/object name, it will instantiate the class. If you don't use "),s("code",[t._v("new")]),t._v(", it will reference the object.")]),t._v(" "),s("h3",{attrs:{id:"example-companion-object"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-companion-object"}},[t._v("#")]),t._v(" Example: Companion Object")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" Lion "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" roar"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Unit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"I\'M AN OBJECT!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Lion "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" roar"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Unit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"I\'M A CLASS!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Lion"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("roar"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nLion"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("roar"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("在 Scala 中,伴生对象是与特定类共享同一名称的单例对象。每个类只能有一个伴生对象,反之亦然。使用伴生对象主要有几个目的,如下所述:")]),t._v(" "),s("ol",[s("li",[t._v("包含与类相关的常量:\n通常,与特定类紧密相关的常量可以放在其伴生对象中。这样做的好处是可以直接通过类名访问这些常量,而不需要实例化该类。这类似于其他编程语言中的静态常量。例如,如果您有一个 "),s("code",[t._v("Circle")]),t._v(" 类,可能会在其伴生对象中定义一个 "),s("code",[t._v("Pi")]),t._v(" 常量。")]),t._v(" "),s("li",[t._v("在类构造器执行前后执行代码:\n有时您可能需要在类实例化之前或之后执行某些代码。由于伴生对象可以访问类的私有成员和构造器,您可以在伴生对象中定义工厂方法或初始化代码,以确保在创建类实例之前或之后完成特定的逻辑。")]),t._v(" "),s("li",[t._v("为类创建多个构造器:\nScala 中的类只能有一个主构造器,但有时需要多种方式来构造类的实例。通过在伴生对象中定义 "),s("code",[t._v("apply")]),t._v(" 方法,可以提供多个构造器。客户端代码可以通过调用这些 "),s("code",[t._v("apply")]),t._v(" 方法,而不是直接使用 "),s("code",[t._v("new")]),t._v(" 关键字来创建实例,使得代码更加简洁。这种模式在 Scala 集合库中非常常见。")])]),t._v(" "),s("p",[t._v("以下是一个简单的示例来说明这些用途:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Circle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("radius"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Double")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" area"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Double")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Circle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Pi "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" radius "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" radius\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" Circle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" Pi "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.141592653589793")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2. Code execution before/after class constructor")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" init"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Unit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Circle companion object initialized."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 3. Multiple constructors")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" apply"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("radius"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Double")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Circle "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n init"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Circle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("radius"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),s("p",[t._v("在上面的例子中:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("Pi")]),t._v(" 是作为与 "),s("code",[t._v("Circle")]),t._v(" 类相关的常量定义在伴生对象中。")]),t._v(" "),s("li",[s("code",[t._v("init")]),t._v(" 方法可以在创建类实例之前被调用。")]),t._v(" "),s("li",[t._v("伴生对象提供了一个 "),s("code",[t._v("apply")]),t._v(" 方法作为创建 "),s("code",[t._v("Circle")]),t._v(" 实例的替代构造器,它允许客户端代码通过 "),s("code",[t._v("Circle(radius)")]),t._v(" 而不是 "),s("code",[t._v("new Circle(radius)")]),t._v(" 来创建 "),s("code",[t._v("Circle")]),t._v(" 的实例,同时确保每次实例化前都调用 "),s("code",[t._v("init")]),t._v(" 方法。")])]),t._v(" "),s("p",[t._v("这样,伴生对象增强了 Scala 类的功能性,同时保持代码的组织性和简洁性。")]),t._v(" "),s("h3",{attrs:{id:"构造器和工厂函数"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#构造器和工厂函数"}},[t._v("#")]),t._v(" 构造器和工厂函数")]),t._v(" "),s("p",[t._v("在 Scala 中,类的构造器和工厂函数是用来创建类实例的,但它们的使用方式和上下文有所不同。")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("类的构造器:")]),t._v(" "),s("p",[t._v("类的构造器是类定义的一部分,用于初始化新创建的对象。Scala 中的构造器分为两种:主构造器和辅助构造器。")]),t._v(" "),s("ul",[s("li",[t._v("主构造器是类定义的一部分,紧跟在类名之后。主构造器的参数直接放在类名后面,而且这些参数可以被类中的方法直接访问。主构造器中的代码是类定义的一部分,当创建类的实例时,这些代码会被执行。"),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 主构造器的代码")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"A new person instance is created."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])])]),t._v(" "),s("li",[t._v("辅助构造器在类体中使用 "),s("code",[t._v("def this(...)")]),t._v(" 定义。每个辅助构造器必须以另一个已经定义好的构造器(主构造器或另一个辅助构造器)的调用开始。"),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 辅助构造器")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 调用主构造器")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])])])])]),t._v(" "),s("li",[s("p",[t._v("工厂函数:")]),t._v(" "),s("p",[t._v("工厂函数通常定义在类的伴生对象中,提供了一种灵活的创建类实例的方式,而不必直接使用 "),s("code",[t._v("new")]),t._v(" 关键字。工厂函数可以有不同的名字,但习惯上经常使用 "),s("code",[t._v("apply")]),t._v(" 方法。使用工厂函数的好处包括更简洁的语法和更丰富的逻辑处理能力。")]),t._v(" "),s("ul",[s("li",[t._v("工厂函数通常在伴生对象中实现,可以包含创建实例的特定逻辑,比如参数验证或者返回现有的实例(实现单例模式或缓存实例)。"),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" Person "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 工厂方法")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" apply"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Person "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 可以添加逻辑,例如参数校验或预处理")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])])])])])]),t._v(" "),s("p",[t._v("使用工厂函数创建实例时,可以省略 "),s("code",[t._v("new")]),t._v(" 关键字,直接通过类名加上参数调用:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" p "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Person"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Alice"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用工厂函数而非 new 关键字")]),t._v("\n\n")])])]),s("p",[t._v("总的来说,类的构造器直接定义了如何构建类的实例,而工厂函数提供了更灵活、更丰富的逻辑来创建和管理类实例。")]),t._v(" "),s("h2",{attrs:{id:"case-classes"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#case-classes"}},[t._v("#")]),t._v(" Case Classes")]),t._v(" "),s("p",[s("code",[t._v("case class")]),t._v("(样例类)是一种特殊类型的类,它们提供了一些附加功能,使得在函数式编程和模式匹配中非常有用。样例类在 Scala 编程中非常常见,以下是它们的一些有用特性:")]),t._v(" "),s("ol",[s("li",[t._v("允许外部访问类参数:样例类的构造器参数默认是公共的(public),因此可以直接访问。")]),t._v(" "),s("li",[t._v("无需使用 "),s("code",[t._v("new")]),t._v(" 关键字实例化:通常在创建普通类的实例时需要使用 "),s("code",[t._v("new")]),t._v(" 关键字。但对于样例类,Scala 允许您省略 "),s("code",[t._v("new")]),t._v(" 关键字直接创建实例。")]),t._v(" "),s("li",[t._v("自动创建 "),s("code",[t._v("unapply")]),t._v(" 方法:这使得样例类非常适合用于模式匹配。"),s("code",[t._v("unapply")]),t._v(" 方法可以从实例中提取构造器参数作为元组返回,这在模式匹配中特别有用。")]),t._v(" "),s("li",[t._v("不能被子类化:为了保证模式匹配的完整性和一致性,样例类不能被继承。这意味着每个样例类都是最终的(final)。")])]),t._v(" "),s("p",[t._v("这里是一个声明三个不同样例类 "),s("code",[t._v("Nail")]),t._v("、"),s("code",[t._v("Screw")]),t._v(" 和 "),s("code",[t._v("Staple")]),t._v(" 的例子:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Nail"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Regular class")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" nail "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Nail"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Requires the `new` keyword")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// println(nail.length) // Illegal! Class constructor parameters are not by default externally visible")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Screw"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" threadSpace"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// By using the `val` keyword, threadSpace is now externally visible")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" screw "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Screw"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Requires the `new` keyword")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("screw"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("threadSpace"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Staple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("isClosed"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Case class constructor parameters are, by default, externally visible")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" staple "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Staple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// No `new` keyword required")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("staple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isClosed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用模式匹配来检查 Staple 实例的 isClosed 属性")]),t._v("\nstaple "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" Staple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The staple is closed."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" Staple"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The staple is open."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// output:")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\nThe staple is "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n")])])]),s("h1",{attrs:{id:"inheritance-with-chisel"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#inheritance-with-chisel"}},[t._v("#")]),t._v(" Inheritance with Chisel")]),t._v(" "),s("h2",{attrs:{id:"module"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#module"}},[t._v("#")]),t._v(" Module")]),t._v(" "),s("h3",{attrs:{id:"example-gray-encoder-and-decoder"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-gray-encoder-and-decoder"}},[t._v("#")]),t._v(" Example: Gray Encoder and Decoder")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("scala"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("math"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pow")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a module")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" GrayCoder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" encode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// decode on false")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n when "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("encode"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//encode")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("^")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("otherwise "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// decode, much more complicated")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fill"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("log2Ceil"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zipWithIndex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fold"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("w1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("w2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n w2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" w1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("^")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("w1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" pow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" log2Ceil"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("i2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("w2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_1\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("定义了一个名为 "),s("code",[t._v("GrayCoder")]),t._v(" 的模块,用于执行格雷码的编码和解码。格雷码是一种二进制数码系统,其中两个连续的数值只有一个位数不同。这在某些硬件设计中非常有用,尤其是在减少位切换和错误率方面。")]),t._v(" "),s("p",[t._v("模块 "),s("code",[t._v("GrayCoder")]),t._v(" 接受三个输入:")]),t._v(" "),s("ol",[s("li",[s("code",[t._v("io.in")]),t._v(": 这是要编码或解码的输入值,其位宽由构造器参数 "),s("code",[t._v("bitwidth")]),t._v(" 指定。")]),t._v(" "),s("li",[s("code",[t._v("io.out")]),t._v(": 这是编码或解码后的输出值,位宽与输入相同。")]),t._v(" "),s("li",[s("code",[t._v("io.encode")]),t._v(": 这是一个布尔输入,用于指示模块是应执行编码操作(当 "),s("code",[t._v("encode")]),t._v(" 为 "),s("code",[t._v("true")]),t._v(")还是解码操作(当 "),s("code",[t._v("encode")]),t._v(" 为 "),s("code",[t._v("false")]),t._v(")。")])]),t._v(" "),s("p",[t._v("编码部分 ("),s("code",[t._v("io.encode")]),t._v(" 为真时) 相对简单:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("^")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),s("p",[t._v("在这里,进行格雷码编码的方式是将输入 "),s("code",[t._v("io.in")]),t._v(" 与其自身右移一位的结果进行异或操作。右移操作 "),s("code",[t._v("io.in >> 1.U")]),t._v(" 生成了 "),s("code",[t._v("io.in")]),t._v(" 每一位右移一位的结果,然后通过异或操作 "),s("code",[t._v("^")]),t._v(" 与原始输入进行比较,以生成格雷码。")]),t._v(" "),s("p",[t._v("解码部分 ("),s("code",[t._v("io.encode")]),t._v(" 为假时) 相对复杂:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fill"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("log2Ceil"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zipWithIndex"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fold"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("w1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("w2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n w2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" w1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("^")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("w1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" pow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" log2Ceil"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("i2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("w2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_1\n\n")])])]),s("p",[t._v("这部分是格雷码的解码逻辑。解码格雷码比编码更复杂,因为需要迭代地将已解码的部分与右移的值进行异或运算来恢复原始的二进制数:")]),t._v(" "),s("ol",[s("li",[s("code",[t._v("Seq.fill(log2Ceil(bitwidth))(Wire(UInt(bitwidth.W)))")]),t._v(": 这创建了一个足够长度的 "),s("code",[t._v("Wire")]),t._v(" 序列,每个元素的宽度都是 "),s("code",[t._v("bitwidth")]),t._v("。序列的长度由 "),s("code",[t._v("log2Ceil(bitwidth)")]),t._v(" 确定,这是对数的上取整结果,确保能够覆盖所有位。")]),t._v(" "),s("li",[s("code",[t._v("zipWithIndex")]),t._v(": 这将序列中的每个元素与其索引进行配对。")]),t._v(" "),s("li",[s("code",[t._v("fold")]),t._v(": 这在序列上执行折叠操作,用于迭代地计算解码结果。在每一步,都将当前的部分解码结果 "),s("code",[t._v("w1")]),t._v(" 与其右移特定位数后的值进行异或运算。移位的位数 "),s("code",[t._v("pow(2, log2Ceil(bitwidth)-i2-1).toInt")]),t._v(" 是递减的,这确保了在解码过程中正确地将各个位逐个恢复。")]),t._v(" "),s("li",[t._v("最终,"),s("code",[t._v("._1")]),t._v(" 用于从 "),s("code",[t._v("(w2, i1)")]),t._v(" 这个元组中取出 "),s("code",[t._v("w2")]),t._v(",即最终的解码值,将其赋给 "),s("code",[t._v("io.out")]),t._v("。")])]),t._v(" "),s("p",[t._v("通过这种方式,"),s("code",[t._v("GrayCoder")]),t._v(" 模块能够根据 "),s("code",[t._v("encode")]),t._v(" 信号的值选择执行格雷码的编码或解码,并输出相应的结果。")]),t._v(" "),s("h3",{attrs:{id:"test"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#test"}},[t._v("#")]),t._v(" Test")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test our gray coder")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" bitwidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),t._v("\ntest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" GrayCoder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" toBinary"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" digits"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("format"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" digits "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"s"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("replace"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("' '")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Encoding:"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until pow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("encode"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"In = ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("toBinary"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", Out = ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("toBinary"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Decoding:"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until pow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("encode"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"In = ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("toBinary"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", Out = ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("toBinary"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("这段代码是使用 Chisel 测试框架来测试 "),s("code",[t._v("GrayCoder")]),t._v(" 模块的一个实例。"),s("code",[t._v("GrayCoder")]),t._v(" 模块是一个旨在执行格雷码编码和解码的模块。测试主要分为两个部分:编码和解码。以下是代码的详细解释:")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("设置测试位宽:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" bitwidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),t._v("\n\n")])])]),s("p",[t._v("这里设定了 "),s("code",[t._v("bitwidth")]),t._v(" 为 4,这意味着测试将处理 4 位宽的输入和输出。在格雷码转换中,输入和输出都将具有相同的位宽。")])]),t._v(" "),s("li",[s("p",[t._v("测试实例的创建:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" GrayCoder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n\n")])])]),s("p",[t._v("这行代码启动了对 "),s("code",[t._v("GrayCoder")]),t._v(" 模块的测试,其中 "),s("code",[t._v("bitwidth")]),t._v(" 为 4,传递给 "),s("code",[t._v("GrayCoder")]),t._v(" 以设置其处理宽度。")])]),t._v(" "),s("li",[s("p",[t._v("定义二进制格式化函数:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" toBinary"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" digits"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("format"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" digits "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"s"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toBinaryString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("replace"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("' '")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),s("p",[s("code",[t._v("toBinary")]),t._v(" 函数用于将整数格式化为二进制字符串。"),s("code",[t._v("digits")]),t._v(" 参数指定了字符串的长度,未使用位用 '0' 填充。")])]),t._v(" "),s("li",[s("p",[t._v("编码测试:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Encoding:"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until pow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("encode"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"In = ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("toBinary"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", Out = ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("toBinary"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),s("p",[t._v("在编码测试部分,循环变量 "),s("code",[t._v("i")]),t._v(" 从 0 遍历到 "),s("code",[t._v("2^bitwidth - 1")]),t._v("。对于每个 "),s("code",[t._v("i")]),t._v(" 值:")]),t._v(" "),s("ul",[s("li",[t._v("使用 "),s("code",[t._v("poke")]),t._v(" 方法将 "),s("code",[t._v("i")]),t._v(" 作为输入写入到 "),s("code",[t._v("GrayCoder")]),t._v(" 模块的 "),s("code",[t._v("in")]),t._v(" 端口。")]),t._v(" "),s("li",[t._v("设置 "),s("code",[t._v("encode")]),t._v(" 信号为 "),s("code",[t._v("true")]),t._v(",指示模块执行编码操作。")]),t._v(" "),s("li",[t._v("执行时钟脉冲,触发模块操作。")]),t._v(" "),s("li",[t._v("打印输入值和经过编码后的输出值。")])])]),t._v(" "),s("li",[s("p",[t._v("解码测试:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Decoding:"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" until pow"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("encode"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("poke"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"In = ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("toBinary"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(", Out = ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("toBinary"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("peek"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("litValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitwidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),s("p",[t._v("解码测试遵循与编码测试相似的逻辑,不同之处在于:")]),t._v(" "),s("ul",[s("li",[t._v("设置 "),s("code",[t._v("encode")]),t._v(" 信号为 "),s("code",[t._v("false")]),t._v(",指示模块执行解码操作。")]),t._v(" "),s("li",[t._v("输入 "),s("code",[t._v("i")]),t._v(" 被认为是经过格雷码编码的值,测试检查模块是否能正确地将其解码回原始数值。")])])])]),t._v(" "),s("p",[t._v("通过这个测试脚本,可以验证 "),s("code",[t._v("GrayCoder")]),t._v(" 模块在给定位宽下对所有可能的输入值进行正确的编码和解码。输出结果提供了一个直观的方式来确认格雷码转换是否按预期执行。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/66.3f97b3ad.js b/assets/js/66.3f97b3ad.js new file mode 100644 index 0000000..35aeaea --- /dev/null +++ b/assets/js/66.3f97b3ad.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[66],{411:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-03-12-3-7-generators-types"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-12-3-7-generators-types"}},[t._v("#")]),t._v(" 2024.03.12-3.7 Generators: Types")]),t._v(" "),s("h1",{attrs:{id:"static-types"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#static-types"}},[t._v("#")]),t._v(" Static Types")]),t._v(" "),s("h2",{attrs:{id:"types-in-scala"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#types-in-scala"}},[t._v("#")]),t._v(" Types in Scala")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.")]),t._v("getClass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10.0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("getClass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ten"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("getClass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" MyClass "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" myMethod "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" MyClass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("getClass"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// output:")]),t._v("\nint\ndouble\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" java"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("lang"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" ammonite"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("$sess"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cmd4$Helper$MyClass\n")])])]),s("p",[t._v("没有返回值的函数,就设置返回值类型为 "),s("code",[t._v("Unit")])]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" counter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" increment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Unit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n counter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nincrement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h2",{attrs:{id:"scala-vs-chisel-types"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#scala-vs-chisel-types"}},[t._v("#")]),t._v(" Scala vs. Chisel Types")]),t._v(" "),s("p",[t._v("模块 2.2 讨论了 Chisel 类型和 Scala 类型之间的区别。例如,下面的代码是合法的,因为 "),s("code",[t._v("0.U")]),t._v(" 是 "),s("code",[t._v("UInt")]),t._v(" 类型(一个 Chisel 类型):")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\na "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U\n")])])]),s("p",[t._v("而下面的代码是非法的,因为 0 是 "),s("code",[t._v("Int")]),t._v(" 类型(一个 Scala 类型):")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\na "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("\n")])])]),s("p",[t._v("这同样适用于 "),s("code",[t._v("Bool")]),t._v(",这是一个 Chisel 类型,它与 Scala 的 "),s("code",[t._v("Boolean")]),t._v(" 类型不同:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" bool "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Wire"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" boolean"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 合法")]),t._v("\nwhen "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("boolean"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 非法")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nwhen "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("boolean"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("如果你错误地混合使用了 "),s("code",[t._v("UInt")]),t._v(" 和 "),s("code",[t._v("Int")]),t._v(" 或 "),s("code",[t._v("Bool")]),t._v(" 和 "),s("code",[t._v("Boolean")]),t._v(",Scala 编译器通常会为你捕捉到这些错误。这归功于 Scala 的静态类型系统。在编译时,编译器能够区分 Chisel 类型和 Scala 类型,并且能够理解 "),s("code",[t._v("if ()")]),t._v(" 期望一个 "),s("code",[t._v("Boolean")]),t._v(" 而 "),s("code",[t._v("when ()")]),t._v(" 期望一个 "),s("code",[t._v("Bool")]),t._v("。这种类型检查机制有助于避免类型相关的逻辑错误,确保您的硬件描述代码的正确性和稳定性。")]),t._v(" "),s("h2",{attrs:{id:"scala-tye-coercion"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#scala-tye-coercion"}},[t._v("#")]),t._v(" Scala Tye Coercion")]),t._v(" "),s("h3",{attrs:{id:"asinstanceof"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#asinstanceof"}},[t._v("#")]),t._v(" "),s("code",[t._v("asInstanceOf")])]),t._v(" "),s("p",[s("code",[t._v("x.asInstanceOf[T]")]),t._v(" casts the object "),s("code",[t._v("x")]),t._v(" to the type "),s("code",[t._v("T")]),t._v(". It throws an exception if the given object cannot be cast to type "),s("code",[t._v("T")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UInt "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3.")]),t._v("U\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("asInstanceOf"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" e"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" java"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("lang"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ClassCastException "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"As expected, we can\'t cast UInt to Int"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// But we can cast UInt to Data since UInt inherits from Data.")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("asInstanceOf"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h3",{attrs:{id:"type-casting-in-chisel"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#type-casting-in-chisel"}},[t._v("#")]),t._v(" Type Casting in Chisel")]),t._v(" "),s("p",[t._v("Chisel 提供了一套类型转换函数,可以帮助开发者在不同的 Chisel 类型之间转换数据。其中,"),s("code",[t._v("asTypeOf()")]),t._v(" 是最通用的类型转换函数,允许将一个 Chisel 数据类型转换成另一个指定的 Chisel 数据类型,只要这样的转换在逻辑上是有意义的。")]),t._v(" "),s("p",[t._v("除了 "),s("code",[t._v("asTypeOf()")]),t._v(",还有一些特定的转换函数,如 "),s("code",[t._v("asUInt()")]),t._v(" 和 "),s("code",[t._v("asSInt()")]),t._v(",这些函数分别用于将数据转换为无符号整数(UInt)和有符号整数(SInt)。使用这些函数可以确保类型转换的意图更加明确,同时也使代码更容易理解。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" TypeConvertDemo "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("SInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("asTypeOf"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h1",{attrs:{id:"type-matching"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#type-matching"}},[t._v("#")]),t._v(" Type Matching")]),t._v(" "),s("h2",{attrs:{id:"match-operator"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#match-operator"}},[t._v("#")]),t._v(" Match Operator")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" ConstantSum"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" chisel3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" in2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" chisel3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("chiselTypeOf"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// in case in1 is literal then just get its type")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" in2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" y\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" y\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" _ "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("throw")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Exception"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"I give up!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("下面代码会报错:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" InputIsZero "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// note that case 0.U is an error")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" _ "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("B\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getVerilog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" InputIsZero"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("这是因为在硬件描述语言中的 "),s("code",[t._v("match")]),t._v(" 语句并不像软件编程语言那样工作。在 Chisel(基于 Scala),"),s("code",[t._v("match")]),t._v(" 语句通常用于软件逻辑的模式匹配,而不是硬件逻辑。硬件描述中的条件判断应该使用 "),s("code",[t._v("when")]),t._v("、"),s("code",[t._v(".elsewhen")]),t._v(" 和 "),s("code",[t._v(".otherwise")]),t._v(" 等语句来实现。")]),t._v(" "),s("p",[t._v("在您的代码中,您尝试使用 "),s("code",[t._v("match")]),t._v(" 语句来为 "),s("code",[t._v("io.out")]),t._v(" 赋值,这是不允许的。您应该改用 "),s("code",[t._v("when")]),t._v(" 语句来判断 "),s("code",[t._v("io.in")]),t._v(" 是否为 0,并据此为 "),s("code",[t._v("io.out")]),t._v(" 赋值。以下是修改后的代码:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" InputIsZero "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用when语句代替match进行硬件条件判断")]),t._v("\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.")]),t._v("U\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),s("p",[t._v("在这段修正后的代码中,"),s("code",[t._v("io.out")]),t._v(" 直接被赋值为 "),s("code",[t._v("io.in === 0.U")]),t._v(" 的结果,这是 Chisel 中比较 "),s("code",[t._v("UInt")]),t._v(" 值的标准方法。这样的表达式直接评估 "),s("code",[t._v("io.in")]),t._v(" 是否等于 0,并将布尔结果赋给 "),s("code",[t._v("io.out")]),t._v(",无需使用 "),s("code",[t._v("when-otherwise")]),t._v(" 语句,因为这里是个直接的等式判断。")]),t._v(" "),s("h2",{attrs:{id:"unapply"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#unapply"}},[t._v("#")]),t._v(" Unapply")]),t._v(" "),s("p",[s("code",[t._v("unapply")]),t._v(" 方法在 Scala 中是模式匹配的一种强大特性,它通常与 "),s("code",[t._v("apply")]),t._v(" 方法相对应。"),s("code",[t._v("apply")]),t._v(" 方法允许你以一种简洁的方式构造对象(即不需要显式地使用 "),s("code",[t._v("new")]),t._v(" 关键字),而 "),s("code",[t._v("unapply")]),t._v(" 方法则用于在模式匹配中分解对象,提取出关键的信息或属性。对于每个 case 类,Scala 编译器会自动创建一个伴生对象(companion object),其中包含 "),s("code",[t._v("apply")]),t._v(" 和 "),s("code",[t._v("unapply")]),t._v(" 方法。"),s("code",[t._v("apply")]),t._v(" 方法使你能够不用 "),s("code",[t._v("new")]),t._v(" 关键字来创建对象,而 "),s("code",[t._v("unapply")]),t._v(" 方法则用于模式匹配和提取值。当你在模式匹配中使用 case 类时,"),s("code",[t._v("unapply")]),t._v(" 方法会自动被调用。该方法从主构造器接收的对象中提取出数据,并将其包装为一个选项(Option),通常是一个元组。模式匹配会检查这个选项,如果是 "),s("code",[t._v("Some")]),t._v(",则匹配成功,并允许进一步操作提取的值;如果是 "),s("code",[t._v("None")]),t._v(",则匹配失败,继续尝试下一个模式。")]),t._v(" "),s("p",[t._v("考虑下面的 "),s("code",[t._v("Something")]),t._v(" case 类:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Something"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("a"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("对于这个 case 类,Scala 编译器自动生成 "),s("code",[t._v("unapply")]),t._v(" 方法,当你执行类似下面的模式匹配时:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Something"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"A"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\na "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" Something"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"A"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Matched with value: ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("value")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" Something"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Matched with string: ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("str")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("这里发生的事情是:")]),t._v(" "),s("ol",[s("li",[t._v("在 "),s("code",[t._v('case Something("A", value)')]),t._v(" 中,"),s("code",[t._v("unapply")]),t._v(" 方法从对象 "),s("code",[t._v("a")]),t._v(" 中提取 "),s("code",[t._v("String")]),t._v(" 和 "),s("code",[t._v("Int")]),t._v(",并检查字符串是否等于 "),s("code",[t._v('"A"')]),t._v("。如果是,"),s("code",[t._v("value")]),t._v(" 被赋予 "),s("code",[t._v("Int")]),t._v(" 值,然后执行相应的代码块。")]),t._v(" "),s("li",[t._v("在 "),s("code",[t._v("case Something(str, 3)")]),t._v(" 中,同样利用 "),s("code",[t._v("unapply")]),t._v(" 方法提取,这次是检查 "),s("code",[t._v("Int")]),t._v(" 是否等于 "),s("code",[t._v("3")]),t._v("。如果是,"),s("code",[t._v("str")]),t._v(" 被赋予相应的 "),s("code",[t._v("String")]),t._v(" 值。")])]),t._v(" "),s("p",[s("code",[t._v("unapply")]),t._v(" 方法的存在让模式匹配变得非常强大和灵活,不仅可以检查类型,还可以提取并操作数据。这使得 Scala 的模式匹配在处理复杂数据结构时非常有用。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" SomeGeneratorParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n someWidth"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n someOtherWidth"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n pipelineMe"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n require"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("someWidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n require"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("someOtherWidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" totalWidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" someWidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" someOtherWidth\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" delay"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SomeGeneratorParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" p "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" SomeGeneratorParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sw"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" sw "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" sg "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@SomeGeneratorParameters")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" sg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("totalWidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("这个示例演示了如何在 Scala 中使用模式匹配结合 "),s("code",[t._v("unapply")]),t._v(" 方法,以及如何在 case 类和普通类中实现和使用这些方法。")]),t._v(" "),s("h3",{attrs:{id:"somegeneratorparameters-case-类"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#somegeneratorparameters-case-类"}},[t._v("#")]),t._v(" "),s("code",[t._v("SomeGeneratorParameters")]),t._v(" case 类")]),t._v(" "),s("p",[s("code",[t._v("SomeGeneratorParameters")]),t._v(" 是一个 case 类,它接受三个参数,其中两个有默认值。由于这是一个 case 类,Scala 编译器会自动生成 "),s("code",[t._v("apply")]),t._v(" 和 "),s("code",[t._v("unapply")]),t._v(" 方法:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("apply")]),t._v(" 方法允许你直接使用 "),s("code",[t._v("SomeGeneratorParameters(10, 10)")]),t._v(" 来构造实例,而不需要 "),s("code",[t._v("new")]),t._v(" 关键字。")]),t._v(" "),s("li",[s("code",[t._v("unapply")]),t._v(" 方法使你能够在模式匹配中解构 "),s("code",[t._v("SomeGeneratorParameters")]),t._v(" 对象。")])]),t._v(" "),s("h3",{attrs:{id:"delay-函数"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#delay-函数"}},[t._v("#")]),t._v(" "),s("code",[t._v("delay")]),t._v(" 函数")]),t._v(" "),s("p",[s("code",[t._v("delay")]),t._v(" 函数接受一个 "),s("code",[t._v("SomeGeneratorParameters")]),t._v(" 实例 "),s("code",[t._v("p")]),t._v(" 并根据其属性计算一个延迟值:")]),t._v(" "),s("ol",[s("li",[t._v("第一个 case 分支匹配任何 "),s("code",[t._v("pipelineMe")]),t._v(" 为 "),s("code",[t._v("false")]),t._v(" 的 "),s("code",[t._v("SomeGeneratorParameters")]),t._v(" 实例,计算延迟为 "),s("code",[t._v("someOtherWidth * 2")]),t._v("。")]),t._v(" "),s("li",[t._v("第二个 case 分支使用 "),s("code",[t._v("@")]),t._v(" 符号 ("),s("code",[t._v("sg @ SomeGeneratorParameters(...)")]),t._v(") 来同时绑定整个参数实例到 "),s("code",[t._v("sg")]),t._v(" 变量和匹配其属性。如果 "),s("code",[t._v("pipelineMe")]),t._v(" 是 "),s("code",[t._v("true")]),t._v(",则使用该实例的 "),s("code",[t._v("totalWidth")]),t._v(" 属性计算延迟为 "),s("code",[t._v("totalWidth * 3")]),t._v("。")])]),t._v(" "),s("h3",{attrs:{id:"模式匹配的不同语法"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#模式匹配的不同语法"}},[t._v("#")]),t._v(" 模式匹配的不同语法")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("直接匹配类型并引用参数值:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" p"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SomeGeneratorParameters "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" p"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("someOtherWidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("\n")])])]),s("p",[t._v("这表示匹配 "),s("code",[t._v("SomeGeneratorParameters")]),t._v(" 类型的任何实例 "),s("code",[t._v("p")]),t._v(",并使用其 "),s("code",[t._v("someOtherWidth")]),t._v(" 属性。")])]),t._v(" "),s("li",[s("p",[t._v("解构匹配并直接引用内部值:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" SomeGeneratorParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sw"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" sw "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("\n")])])]),s("p",[t._v("这表示解构 "),s("code",[t._v("SomeGeneratorParameters")]),t._v(" 实例,匹配任何值,但只关心 "),s("code",[t._v("someOtherWidth")]),t._v("("),s("code",[t._v("sw")]),t._v(")。")])]),t._v(" "),s("li",[s("p",[t._v("使用 "),s("code",[t._v("@")]),t._v(" 保留整个实例的引用同时匹配内部值:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" sg @ SomeGeneratorParameters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" sw"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" sw\n")])])]),s("p",[t._v("这使得 "),s("code",[t._v("sg")]),t._v(" 绑定到整个 "),s("code",[t._v("SomeGeneratorParameters")]),t._v(" 实例,同时解构匹配来引用 "),s("code",[t._v("someOtherWidth")]),t._v("。")])]),t._v(" "),s("li",[s("p",[t._v("嵌入条件检查:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SomeGeneratorParameters "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("pipelineMe "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("someOtherWidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("\n")])])]),s("p",[t._v("这表示匹配 "),s("code",[t._v("SomeGeneratorParameters")]),t._v(" 类型的实例,且只在 "),s("code",[t._v("pipelineMe")]),t._v(" 为 "),s("code",[t._v("true")]),t._v(" 时匹配。")])])]),t._v(" "),s("p",[t._v("所有这些语法形式都依赖于 "),s("code",[t._v("unapply")]),t._v(" 方法,它在 case 类的伴生对象中自动生成。如果您想为非 case 类实现类似的模式匹配功能,可以手动实现 "),s("code",[t._v("apply")]),t._v(" 和 "),s("code",[t._v("unapply")]),t._v(" 方法,如最后部分提及,但示例未给出具体实现。")]),t._v(" "),s("h3",{attrs:{id:"手动定义-unapply-方法"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#手动定义-unapply-方法"}},[t._v("#")]),t._v(" 手动定义 unapply 方法")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" Boat "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" unapply"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Option"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Some"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" apply"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Boat "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" getSmallBoats"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("seq"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("filter "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n b "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("60")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" boats "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Santa Maria"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("62")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Pinta"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("56")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Nina"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getSmallBoats"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("boats"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("mkString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('" and "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('" are small boats!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("在这个例子中,我们定义了一个名为 "),s("code",[t._v("Boat")]),t._v(" 的类,它有两个属性:"),s("code",[t._v("name")]),t._v(" 和 "),s("code",[t._v("length")]),t._v("。为了使 "),s("code",[t._v("Boat")]),t._v(" 类能够在模式匹配中使用,我们还定义了一个伴生对象 "),s("code",[t._v("Boat")]),t._v(",其中实现了 "),s("code",[t._v("apply")]),t._v(" 和 "),s("code",[t._v("unapply")]),t._v(" 方法。这样,即使 "),s("code",[t._v("Boat")]),t._v(" 不是一个 case 类,我们也可以使用模式匹配的功能,就像使用 case 类那样。")]),t._v(" "),s("ol",[s("li",[s("p",[s("code",[t._v("Boat")]),t._v(" 类定义:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("这个定义创建了一个拥有 "),s("code",[t._v("name")]),t._v("(船名)和 "),s("code",[t._v("length")]),t._v("(船长)两个属性的 "),s("code",[t._v("Boat")]),t._v(" 类。这两个属性是公开的,因此可以在类的外部访问。")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("Boat")]),t._v(" 伴生对象定义:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" Boat "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" unapply"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Option"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Some"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" apply"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Boat "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[s("code",[t._v("apply")]),t._v(" 方法允许我们以 "),s("code",[t._v('Boat("Santa Maria", 62)')]),t._v(" 的形式创建 "),s("code",[t._v("Boat")]),t._v(" 实例,而不需要使用 "),s("code",[t._v("new")]),t._v(" 关键字。")]),t._v(" "),s("li",[s("code",[t._v("unapply")]),t._v(" 方法用于模式匹配。它接收一个 "),s("code",[t._v("Boat")]),t._v(" 实例,并返回一个包含船名和船长的元组的 "),s("code",[t._v("Option")]),t._v("。如果 "),s("code",[t._v("Boat")]),t._v(" 实例不符合期望的格式(虽然在这里总是返回 "),s("code",[t._v("Some")]),t._v("),也可以返回 "),s("code",[t._v("None")]),t._v("。")])])]),t._v(" "),s("li",[s("p",[s("code",[t._v("getSmallBoats")]),t._v(" 函数定义:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" getSmallBoats"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("seq"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("filter "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n b "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("60")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" _ "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("这个函数接收一个 "),s("code",[t._v("Boat")]),t._v(" 序列,使用 "),s("code",[t._v("filter")]),t._v(" 方法和模式匹配来筛选出长度小于 60 的船。"),s("code",[t._v("case Boat(_, length) if length < 60 => true")]),t._v(" 这行代码使用 "),s("code",[t._v("unapply")]),t._v(" 方法从 "),s("code",[t._v("Boat")]),t._v(" 实例中提取长度,如果长度小于 60,就选择这艘船。")])]),t._v(" "),s("li",[s("p",[t._v("测试和输出:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" boats "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Santa Maria"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("62")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Pinta"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("56")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Nina"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getSmallBoats"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("boats"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("mkString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('" and "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('" are small boats!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("这部分代码创建了一个包含三艘船的序列,然后调用 "),s("code",[t._v("getSmallBoats")]),t._v(" 函数来筛选出其中的小船,并打印出这些小船的名字。")])])]),t._v(" "),s("p",[t._v("通过这个示例,你可以看到如何通过实现 "),s("code",[t._v("unapply")]),t._v(" 方法在普通类上使用模式匹配,以及如何将这些技术应用于实际问题。这展示了 Scala 在处理数据和模式匹配方面的强大功能。")]),t._v(" "),s("h2",{attrs:{id:"partial-functions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#partial-functions"}},[t._v("#")]),t._v(" Partial Functions")]),t._v(" "),s("p",[t._v("偏函数(Partial Function)是一种特殊的函数,它只对输入值的一个子集进行定义,并不对所有可能的输入值都给出定义。偏函数在 Scala 中通常用于模式匹配,特别是处理那些只对特定输入感兴趣的情况。")]),t._v(" "),s("p",[t._v("偏函数的类型是 "),s("code",[t._v("PartialFunction[A, B]")]),t._v(",其中 "),s("code",[t._v("A")]),t._v(" 是输入类型,"),s("code",[t._v("B")]),t._v(" 是输出类型。你可以使用 "),s("code",[t._v("{ case ... => ... }")]),t._v(" 语法来定义一个偏函数。在这个语法中,每个 "),s("code",[t._v("case")]),t._v(" 语句定义了函数的行为对于特定的输入值或输入模式。")]),t._v(" "),s("p",[t._v("偏函数非常适合用在模式匹配中,特别是当你只需要处理输入数据的一部分,而不关心其他数据时。这样做可以使代码更清晰和简洁。")]),t._v(" "),s("p",[t._v("让我们回顾 "),s("code",[t._v("getSmallBoats")]),t._v(" 函数的例子来看偏函数是如何工作的:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" getSmallBoats"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("seq"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("filter "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n b "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("60")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" _ "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在这个例子中,"),s("code",[t._v("filter")]),t._v(" 方法接受一个函数作为参数,这个函数将每个元素 "),s("code",[t._v("b")]),t._v(" 从序列 "),s("code",[t._v("seq")]),t._v(" 中传递到一个 "),s("code",[t._v("match")]),t._v(" 表达式。"),s("code",[t._v("match")]),t._v(" 表达式实际上定义了一个偏函数,它只对长度小于 60 的船只感兴趣。")]),t._v(" "),s("p",[t._v("我们可以将这段代码重构为使用显式的偏函数定义:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" smallBoat"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" PartialFunction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("60")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" getSmallBoats"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("seq"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Boat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("smallBoat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("lift"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("在这个重构后的版本中,"),s("code",[t._v("smallBoat")]),t._v(" 是一个偏函数,它仅在船的长度小于 60 时返回 "),s("code",[t._v("true")]),t._v("。"),s("code",[t._v("lift")]),t._v(" 方法将 "),s("code",[t._v("PartialFunction")]),t._v(" 转换为一个返回 "),s("code",[t._v("Option")]),t._v(" 的普通函数,使得其可以与 "),s("code",[t._v("filter")]),t._v(" 一起使用。这里的 "),s("code",[t._v("lift")]),t._v(" 将 "),s("code",[t._v("true")]),t._v(" 转换为 "),s("code",[t._v("Some(true)")]),t._v(",并将不匹配的情况转换为 "),s("code",[t._v("None")]),t._v(",然后 "),s("code",[t._v("filter")]),t._v(" 通过这些 "),s("code",[t._v("Some(true)")]),t._v(" 和 "),s("code",[t._v("None")]),t._v(" 值来决定哪些元素应该被保留。")]),t._v(" "),s("p",[t._v("通过这个例子,你可以看到偏函数如何提供一种强大且表达性很好的方式来处理特定的数据和模式,同时忽略其他不相关的情况。")]),t._v(" "),s("h1",{attrs:{id:"type-safe-connections"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#type-safe-connections"}},[t._v("#")]),t._v(" Type Safe Connections")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Bundle1 "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Bundle2 "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Bundle1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" BadTypeModule "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" bundleIn "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" bundleOut "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//io.out := io.c // won't work due to different types")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Okay, but Chisel will truncate the input width to 1 to match the output.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// io.out := io.in")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// // Compiles; Chisel will connect the common subelements of the two Bundles (in this case, 'a').")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// io.bundleOut := io.bundleIn")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getVerilog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" BadTypeModule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("在这个 Chisel 示例中,我们定义了两个 "),s("code",[t._v("Bundle")]),t._v(" 类("),s("code",[t._v("Bundle1")]),t._v(" 和 "),s("code",[t._v("Bundle2")]),t._v("),然后创建了一个名为 "),s("code",[t._v("BadTypeModule")]),t._v(" 的模块,用以展示不同类型赋值时的行为。这里同时展示了可以正常工作的代码和会引发问题的代码,让我们逐一进行解释:")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("Bundle 定义:")]),t._v(" "),s("p",[s("code",[t._v("Bundle1")]),t._v(" 和 "),s("code",[t._v("Bundle2")]),t._v(" 是 Chisel 中的两个数据包结构(或称为复合类型)。"),s("code",[t._v("Bundle2")]),t._v(" 继承了 "),s("code",[t._v("Bundle1")]),t._v(",所以它包含了 "),s("code",[t._v("Bundle1")]),t._v(" 的所有字段,并额外增加了一个字段 "),s("code",[t._v("b")]),t._v("。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Bundle1 "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" a "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Bundle2 "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Bundle1 "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" b "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("16.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]),t._v(" "),s("li",[s("p",[t._v("BadTypeModule 模块定义:")]),t._v(" "),s("p",[t._v("在 "),s("code",[t._v("BadTypeModule")]),t._v(" 模块中,定义了一些输入输出接口,包括标准的 "),s("code",[t._v("UInt")]),t._v(" 和特定的 "),s("code",[t._v("Bundle")]),t._v(" 类型。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" BadTypeModule "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Clock"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("UInt"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2.")]),t._v("W"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Bool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" bundleIn "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" bundleOut "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" Bundle1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("接下来是对 "),s("code",[t._v("io.out")]),t._v(" 赋值的不同尝试:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("io.out := io.c")]),t._v(" 这行代码是错误的尝试,因为 "),s("code",[t._v("io.c")]),t._v(" 是 "),s("code",[t._v("Clock()")]),t._v(" 类型,而 "),s("code",[t._v("io.out")]),t._v(" 是 "),s("code",[t._v("Bool()")]),t._v(" 类型。在 Chisel 中,不能直接将时钟信号赋给布尔型输出。")]),t._v(" "),s("li",[s("code",[t._v("io.out := io.in")]),t._v(" 这行是可以正常工作的,尽管 "),s("code",[t._v("io.in")]),t._v(" 是 "),s("code",[t._v("UInt(2.W)")]),t._v(" 类型,而 "),s("code",[t._v("io.out")]),t._v(" 是 "),s("code",[t._v("Bool()")]),t._v(" 类型。Chisel 在赋值时会进行类型转换,这里会将 "),s("code",[t._v("io.in")]),t._v(" 截断为 1 位以匹配 "),s("code",[t._v("Bool()")]),t._v(" 的宽度。")]),t._v(" "),s("li",[s("code",[t._v("io.bundleOut := io.bundleIn")]),t._v(" 也是可以正常工作的代码。尽管 "),s("code",[t._v("io.bundleIn")]),t._v(" 是 "),s("code",[t._v("Bundle2")]),t._v(" 类型,而 "),s("code",[t._v("io.bundleOut")]),t._v(" 是 "),s("code",[t._v("Bundle1")]),t._v(" 类型,Chisel 在赋值时会进行宽松匹配(loose coupling),只连接两个 Bundle 中相同的字段。因为 "),s("code",[t._v("Bundle2")]),t._v(" 继承自 "),s("code",[t._v("Bundle1")]),t._v(",所以 "),s("code",[t._v("Bundle1")]),t._v(" 中的字段 "),s("code",[t._v("a")]),t._v(" 在两者间会被正确连接。")])]),t._v(" "),s("h1",{attrs:{id:"type-generics"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#type-generics"}},[t._v("#")]),t._v(" Type Generics")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" seq1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"3"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Type is Seq[String]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" seq2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Type is Seq[Int]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" seq3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Type is Seq[Any]")]),t._v("\n")])])]),s("p",[t._v("有时需要用户指明多态类型")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//val default = Seq() // Error!")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" default "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// User must tell compiler that default is of type Seq[String]")]),t._v("\nSeq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("foldLeft"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("default"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("strings"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n next "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" strings "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" _ "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" strings\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("这段 Scala 代码演示了如何使用 "),s("code",[t._v("foldLeft")]),t._v(" 方法和模式匹配来从混合类型的序列中筛选出字符串类型的元素。我将逐步解释每一部分的功能和目的。")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("定义默认值:")]),t._v(" "),s("p",[t._v("初始的尝试定义 "),s("code",[t._v("default")]),t._v(" 时出现错误,因为仅写 "),s("code",[t._v("Seq()")]),t._v(" 没有足够的信息让编译器推断出序列的具体类型。这在类型推断的上下文中很重要。Scala 编译器需要明确的类型信息来保证类型安全和后续操作的正确性。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// val default = Seq() // Error!")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" default "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 明确指定 default 为 Seq[String] 类型")]),t._v("\n\n")])])]),s("p",[t._v("正确的做法是使用 "),s("code",[t._v("Seq[String]()")]),t._v(" 明确指定序列中包含的元素类型是 "),s("code",[t._v("String")]),t._v("。这样,"),s("code",[t._v("default")]),t._v(" 被明确为一个空的 "),s("code",[t._v("String")]),t._v(" 类型序列。")])]),t._v(" "),s("li",[s("p",[t._v("创建混合类型序列并应用 "),s("code",[t._v("foldLeft")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v("Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("foldLeft"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("default"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("strings"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n next "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("match")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" strings "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" _ "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" strings\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// output:")]),t._v("\ndefault"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nres17_1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Seq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("这里,我们有一个包含整数、字符串和布尔值的序列 "),s("code",[t._v('Seq(1, "2", true)')]),t._v("。目标是从中筛选出所有的字符串。")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("foldLeft")]),t._v(" 方法从 "),s("code",[t._v("default")]),t._v("(空的字符串序列)开始,逐个处理原始序列中的元素。")]),t._v(" "),s("li",[s("code",[t._v("(strings, next) => ...")]),t._v(" 是一个函数,其中 "),s("code",[t._v("strings")]),t._v(" 是累积结果(开始时是 "),s("code",[t._v("default")]),t._v("),"),s("code",[t._v("next")]),t._v(" 是当前遍历到的序列元素。")]),t._v(" "),s("li",[t._v("在函数体内,使用模式匹配来检查 "),s("code",[t._v("next")]),t._v(" 的类型:\n"),s("ul",[s("li",[t._v("如果 "),s("code",[t._v("next")]),t._v(" 是一个字符串("),s("code",[t._v("case s: String")]),t._v("),那么将这个字符串添加到累积结果 "),s("code",[t._v("strings")]),t._v(" 中,并返回更新后的序列。")]),t._v(" "),s("li",[t._v("如果 "),s("code",[t._v("next")]),t._v(" 不是字符串("),s("code",[t._v("case _")]),t._v("),仅返回当前的累积结果 "),s("code",[t._v("strings")]),t._v(",不做任何改动。")])])])])])]),t._v(" "),s("p",[t._v("通过上述步骤,"),s("code",[t._v("foldLeft")]),t._v(" 方法最终返回一个只包含原始序列中所有字符串的新序列。在这个例子中,它将构建并返回一个只包含 "),s("code",[t._v('"2"')]),t._v(" 的 "),s("code",[t._v("Seq[String]")]),t._v("。这段代码演示了如何结合使用 "),s("code",[t._v("foldLeft")]),t._v(" 和模式匹配来处理和筛选混合类型的数据集合。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" time"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("T"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("block"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" T"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" T "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" t0 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" System"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nanoTime"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" block\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" t1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" System"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nanoTime"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" timeMillis "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("t1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" t0"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000.0")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Block took ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("timeMillis")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' milliseconds!"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n result\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Adds 1 through a million")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" int "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" time "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" to "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reduce"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Add 1 through a million is ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("int")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// Finds the largest number under a million that, in hex, contains "beef"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" string "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" time "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" to "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toHexString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("contains"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"beef"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("last\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nprintln"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The largest number under a million that has beef: ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("string")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("这段代码定义了一个名为 "),s("code",[t._v("time")]),t._v(" 的函数,用于测量任何 Scala 代码块的执行时间。然后,它演示了如何使用 "),s("code",[t._v("time")]),t._v(' 函数来测量两个不同操作的执行时间:一个是将一百万个整数相加,另一个是在一百万个整数中查找以十六进制表示时包含字符串 "beef" 的最大数。下面是对每个部分的详细解释:')]),t._v(" "),s("ol",[s("li",[s("p",[t._v("时间测量函数 "),s("code",[t._v("time")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" time"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("T"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("block"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" T"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" T "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" t0 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" System"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nanoTime"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" block\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" t1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" System"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nanoTime"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" timeMillis "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("t1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" t0"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000.0")]),t._v("\n println"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Block took ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("timeMillis")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(' milliseconds!"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n result\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),s("ul",[s("li",[s("code",[t._v("time")]),t._v(" 函数接受一个代码块 "),s("code",[t._v("block")]),t._v(" 并返回该代码块的执行结果。"),s("code",[t._v("[T]")]),t._v(" 表示这是一个泛型函数,可以接受和返回任意类型的结果。\n这个 "),s("code",[t._v("time")]),t._v(" 函数的定义利用了 Scala 中的两个高级特性:泛型和按名参数。我将分解这个函数定义,帮助你理解每个部分的含义。\n"),s("ol",[s("li",[s("p",[t._v("泛型 "),s("code",[t._v("[T]")]),t._v(":")]),t._v(" "),s("p",[t._v("在这里,"),s("code",[t._v("[T]")]),t._v(" 表示 "),s("code",[t._v("time")]),t._v(" 函数是泛型的,即它可以接受并返回任意类型 "),s("code",[t._v("T")]),t._v(" 的结果。这种定义方式使 "),s("code",[t._v("time")]),t._v(" 函数非常灵活,因为它不限制代码块 "),s("code",[t._v("block")]),t._v(" 的返回类型。例如,"),s("code",[t._v("block")]),t._v(" 可以返回一个整数、字符串或任何其他类型的值,"),s("code",[t._v("time")]),t._v(" 函数将相应地处理并返回相同的类型。")])]),t._v(" "),s("li",[s("p",[t._v("按名参数 "),s("code",[t._v("(block: => T)")]),t._v(":")]),t._v(" "),s("p",[s("code",[t._v("(block: => T)")]),t._v(" 定义了一个按名参数 "),s("code",[t._v("block")]),t._v("。按名参数与普通(按值)参数不同,因为它不会在传递到函数时立即求值。相反,每次在函数体内访问 "),s("code",[t._v("block")]),t._v(" 时,都会执行代码块并计算其结果。")]),t._v(" "),s("p",[t._v("这里的 "),s("code",[t._v("block: => T")]),t._v(" 意味着 "),s("code",[t._v("block")]),t._v(" 是一个将被延迟执行的代码块,而不是一个已经计算好的值。这允许 "),s("code",[t._v("time")]),t._v(" 函数首先记录执行前的时间,然后执行 "),s("code",[t._v("block")]),t._v(",最后记录执行后的时间,从而测量出 "),s("code",[t._v("block")]),t._v(" 的执行时间。\n总结一下,"),s("code",[t._v("def time[T](block: => T): T = { ... }")]),t._v(" 的含义是:定义一个名为 "),s("code",[t._v("time")]),t._v(" 的泛型函数,它接受一个将被延迟执行的代码块 "),s("code",[t._v("block")]),t._v(" 作为输入,并返回 "),s("code",[t._v("block")]),t._v(" 执行的结果。"),s("code",[t._v("block")]),t._v(" 可以是任意复杂的表达式或操作,"),s("code",[t._v("time")]),t._v(" 函数将测量并打印出其执行时间,最终返回 "),s("code",[t._v("block")]),t._v(" 的结果。这种函数在性能分析或需要测量某段代码执行时间的场景中非常有用。")])])])]),t._v(" "),s("li",[s("code",[t._v("System.nanoTime()")]),t._v(" 用于获取纳秒级的当前时间,从而计算代码块执行前后的时间差。")]),t._v(" "),s("li",[s("code",[t._v("result")]),t._v(" 变量存储代码块 "),s("code",[t._v("block")]),t._v(" 的执行结果。")]),t._v(" "),s("li",[t._v("最后,函数打印出代码块的执行时间(以毫秒为单位),并返回执行结果 "),s("code",[t._v("result")]),t._v("。")])])]),t._v(" "),s("li",[s("p",[t._v("整数累加操作:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" int "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" time "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" to "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("reduce"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" _"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),s("ul",[s("li",[t._v("这一行使用 "),s("code",[t._v("time")]),t._v(" 函数测量 "),s("code",[t._v("(1 to 1000000).reduce(_ + _)")]),t._v(" 的执行时间,该表达式计算从 1 到 1000000 的整数和。")]),t._v(" "),s("li",[s("code",[t._v("reduce(_ + _)")]),t._v(" 使用简化操作,将序列中的所有数字累加。")])])]),t._v(" "),s("li",[s("p",[t._v("查找特定十六进制字符串的操作:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" string "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" time "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" to "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toHexString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("filter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("contains"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"beef"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("last\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),s("ul",[s("li",[t._v("这一行使用 "),s("code",[t._v("time")]),t._v(' 函数测量查找操作的执行时间。它将从 1 到 1000000 的整数转换为十六进制字符串,过滤出包含 "beef" 的字符串,然后获取满足条件的最大数。')]),t._v(" "),s("li",[s("code",[t._v("map(_.toHexString)")]),t._v(" 将每个整数转换为其十六进制表示形式。")]),t._v(" "),s("li",[s("code",[t._v('filter(_.contains("beef"))')]),t._v(' 过滤出包含 "beef" 的字符串。')]),t._v(" "),s("li",[s("code",[t._v(".last")]),t._v(" 获取满足条件的最后一个元素,即最大的一个。")])])])]),t._v(" "),s("p",[t._v("这两个 "),s("code",[t._v("time")]),t._v(" 函数调用展示了如何在实际应用中测量不同代码块的执行时间,为性能分析提供了便捷的工具。最后,程序打印出每个操作的结果以及执行时间。")]),t._v(" "),s("h2",{attrs:{id:"chisel-type-hierarchy"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#chisel-type-hierarchy"}},[t._v("#")]),t._v(" Chisel Type Hierarchy")]),t._v(" "),s("p",[s("code",[t._v("chisel3.Data")]),t._v(" 是 Chisel 硬件类型的基类。"),s("code",[t._v("UInt")]),t._v("、"),s("code",[t._v("SInt")]),t._v("、"),s("code",[t._v("Vec")]),t._v("、"),s("code",[t._v("Bundle")]),t._v(" 等都是 "),s("code",[t._v("Data")]),t._v(" 的实例。"),s("code",[t._v("Data")]),t._v(" 可以用在 IO 中,并支持 "),s("code",[t._v(":=")]),t._v("、wires、regs 等操作。寄存器是 Chisel 中多态代码的一个很好的例子。可以查看 "),s("code",[t._v("RegEnable")]),t._v("(带有 "),s("code",[t._v("Bool")]),t._v(" 使能信号的寄存器)的实现"),s("a",{attrs:{href:"https://github.com/freechipsproject/chisel3/blob/v3.0.0/src/main/scala/chisel3/util/Reg.scala#L10",target:"_blank",rel:"noopener noreferrer"}},[t._v("这里"),s("OutboundLink")],1),t._v("。apply 函数为 "),s("code",[t._v("[T <: Data]")]),t._v(" 模板化,这意味着 "),s("code",[t._v("RegEnable")]),t._v(" 将适用于所有 Chisel 硬件类型。一些操作只在 "),s("code",[t._v("Bits")]),t._v(" 的子类型上定义,例如 "),s("code",[t._v("+")]),t._v(" 操作。这就是为什么你可以对 "),s("code",[t._v("UInt")]),t._v(" 或 "),s("code",[t._v("SInt")]),t._v(" 进行加法操作,但不能对 "),s("code",[t._v("Bundle")]),t._v(" 或 "),s("code",[t._v("Vec")]),t._v(" 进行加法操作的原因。")]),t._v(" "),s("h3",{attrs:{id:"example-type-generic-shiftregister"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-type-generic-shiftregister"}},[t._v("#")]),t._v(" Example: Type Generic ShiftRegister")]),t._v(" "),s("p",[t._v("在本例中,我们希望能够在一个捆绑("),s("code",[t._v("Bundle")]),t._v(")中放置各种对象,能够使用 "),s("code",[t._v(":=")]),t._v(" 连接它们,并且能够用它们创建寄存器("),s("code",[t._v("RegNext")]),t._v(" 等)。这些操作不能对任意对象执行;例如,"),s("code",[t._v("wire := 3")]),t._v(" 是非法的,因为 "),s("code",[t._v("3")]),t._v(" 是一个 Scala 的 "),s("code",[t._v("Int")]),t._v(" 类型,而不是 Chisel 的 "),s("code",[t._v("UInt")]),t._v(" 类型。如果我们使用一个类型约束来指明类型 "),s("code",[t._v("T")]),t._v(" 是 "),s("code",[t._v("Data")]),t._v(" 的一个子类,那么我们就可以对任何类型为 "),s("code",[t._v("T")]),t._v(" 的对象使用 "),s("code",[t._v(":=")]),t._v(",因为所有的 "),s("code",[t._v("Data")]),t._v(" 类型都定义了 "),s("code",[t._v(":=")]),t._v(" 操作。")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" ShiftRegisterIO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("T "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("gen"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" T"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Bundle "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n require "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Shift register must have non-negative shift"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Input"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("gen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Vec"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" gen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// + 1 because in is included in out")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" cloneType"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" ShiftRegisterIO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("gen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("asInstanceOf"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" ShiftRegister"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("T "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("gen"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" T"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" Module "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" io "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" IO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" ShiftRegisterIO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("gen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("foldLeft"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" in\n RegNext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("这段代码定义了两个类:"),s("code",[t._v("ShiftRegisterIO")]),t._v(" 和 "),s("code",[t._v("ShiftRegister")]),t._v("。这两个类联合实现了一个泛型的移位寄存器,在 Chisel 中移位寄存器是一种常见的硬件结构,用于数据的时序延迟。这里使用了泛型编程来允许这个移位寄存器处理任何类型的 "),s("code",[t._v("Data")]),t._v("。让我们逐步分析这两个类的定义和功能:")]),t._v(" "),s("ol",[s("li",[s("p",[s("code",[t._v("ShiftRegisterIO")]),t._v(" 类:")]),t._v(" "),s("p",[s("code",[t._v("ShiftRegisterIO")]),t._v(" 是一个基于 "),s("code",[t._v("Bundle")]),t._v(" 的 IO 接口定义,它被参数化以接受任何继承自 "),s("code",[t._v("Data")]),t._v(" 的类型 "),s("code",[t._v("T")]),t._v(" 以及整数 "),s("code",[t._v("n")]),t._v(" 代表移位级数。")]),t._v(" "),s("ul",[s("li",[s("code",[t._v('require (n >= 0, "Shift register must have non-negative shift")')]),t._v(": 这行代码确保传入的移位级数 "),s("code",[t._v("n")]),t._v(" 是非负的,否则会在运行时抛出异常。")]),t._v(" "),s("li",[s("code",[t._v("val in = Input(gen)")]),t._v(": 定义了一个名为 "),s("code",[t._v("in")]),t._v(" 的输入端口,其类型为 "),s("code",[t._v("T")]),t._v("。")]),t._v(" "),s("li",[s("code",[t._v("val out = Output(Vec(n + 1, gen))")]),t._v(": 定义了一个名为 "),s("code",[t._v("out")]),t._v(" 的输出端口,其类型为 "),s("code",[t._v("Vec")]),t._v(",长度为 "),s("code",[t._v("n + 1")]),t._v(",向量中的每个元素类型为 "),s("code",[t._v("T")]),t._v("。长度为 "),s("code",[t._v("n + 1")]),t._v(" 是因为输出向量包括输入和所有中间移位寄存器的状态。")]),t._v(" "),s("li",[s("code",[t._v("override def cloneType")]),t._v(": 这个方法确保了 Chisel 在需要复制或实例化 "),s("code",[t._v("ShiftRegisterIO")]),t._v(" 对象时能正确处理类型信息。这是 Chisel 的类型系统要求的。")])])]),t._v(" "),s("li",[s("p",[s("code",[t._v("ShiftRegister")]),t._v(" 类:")]),t._v(" "),s("p",[s("code",[t._v("ShiftRegister")]),t._v(" 实现了泛型移位寄存器的功能。")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("val io = IO(new ShiftRegisterIO(gen, n))")]),t._v(": 这行代码实例化了上面定义的 "),s("code",[t._v("ShiftRegisterIO")]),t._v(",作为模块的 IO 接口。")]),t._v(" "),s("li",[s("code",[t._v("io.out.foldLeft(io.in) { case (in, out) => ... }")]),t._v(": 这是移位寄存器的核心实现。这里使用了 "),s("code",[t._v("foldLeft")]),t._v(" 方法来遍历输出向量 "),s("code",[t._v("io.out")]),t._v(" 并依次连接寄存器。对于输出向量中的每一项:\n"),s("ul",[s("li",[s("code",[t._v("out := in")]),t._v(": 当前输出连接到当前输入。")]),t._v(" "),s("li",[s("code",[t._v("RegNext(in)")]),t._v(": 使用 "),s("code",[t._v("RegNext")]),t._v(" 创建一个新的寄存器,其输入是 "),s("code",[t._v("in")]),t._v(",输出成为下一次迭代的输入。在 "),s("code",[t._v("foldLeft")]),t._v(" 中,每次迭代的结果通常用于更新累积值。但在这个特定的情况下,"),s("code",[t._v("RegNext(in)")]),t._v(" 的结果(即下一时钟周期的 "),s("code",[t._v("in")]),t._v(" 值)并没有直接赋给一个命名的变量;相反,它隐式地成为下一次迭代中 "),s("code",[t._v("in")]),t._v(" 参数的值。")])])])]),t._v(" "),s("p",[t._v("最终结果是,输入 "),s("code",[t._v("io.in")]),t._v(" 通过一系列寄存器传递,每个寄存器的输出连接到下一个寄存器的输入,形成了一个链式结构。"),s("code",[t._v("io.out")]),t._v(" 向量包含了这个链上的所有节点,因此它能够提供输入信号的每一步移位结果。")])])]),t._v(" "),s("p",[t._v("通过这种方式,"),s("code",[t._v("ShiftRegister")]),t._v(" 类可以用来创建任何数据类型 "),s("code",[t._v("T")]),t._v(" 的移位寄存器,其中 "),s("code",[t._v("T")]),t._v(" 必须是 "),s("code",[t._v("Data")]),t._v(" 的子类。这样的设计使得 "),s("code",[t._v("ShiftRegister")]),t._v(" 非常灵活,能够被用在多种不同的数据路径和时序电路设计中。")]),t._v(" "),s("h2",{attrs:{id:"type-generics-with-typeclasses"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#type-generics-with-typeclasses"}},[t._v("#")]),t._v(" Type Generics with Typeclasses")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/67.70683463.js b/assets/js/67.70683463.js new file mode 100644 index 0000000..b015d40 --- /dev/null +++ b/assets/js/67.70683463.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[67],{409:function(t,r,i){"use strict";i.r(r);var a=i(14),e=Object(a.a)({},(function(){var t=this,r=t._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h1",{attrs:{id:"_3-2023-11-07-verilog语法"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_3-2023-11-07-verilog语法"}},[t._v("#")]),t._v(" 3. 2023.11.07-Verilog语法")]),t._v(" "),r("h2",{attrs:{id:"_01-verilog-基础语法"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_01-verilog-基础语法"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2023.11.07-Verilog语法/01.Verilog 基础语法.html"}},[t._v("01. Verilog 基础语法")])],1),t._v(" "),r("h2",{attrs:{id:"_02-verilog-数值表示"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_02-verilog-数值表示"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2023.11.07-Verilog语法/02.Verilog 数值表示.html"}},[t._v("02. Verilog 数值表示")])],1),t._v(" "),r("h2",{attrs:{id:"_03-verilog-数据类型"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_03-verilog-数据类型"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2023.11.07-Verilog语法/03.Verilog 数据类型.html"}},[t._v("03. Verilog 数据类型")])],1),t._v(" "),r("h2",{attrs:{id:"_04-verilog-表达式"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_04-verilog-表达式"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2023.11.07-Verilog语法/04.Verilog 表达式.html"}},[t._v("04. Verilog 表达式")])],1),t._v(" "),r("h2",{attrs:{id:"_10-verilog-多路分支语句"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_10-verilog-多路分支语句"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2023.11.07-Verilog语法/10.Verilog 多路分支语句.html"}},[t._v("10. Verilog 多路分支语句")])],1),t._v(" "),r("h2",{attrs:{id:"_2023-11-15-vivado"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2023-11-15-vivado"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2023.11.07-Verilog语法/2023.11.15-Vivado.html"}},[t._v("2023.11.15-Vivado")])],1),t._v(" "),r("h2",{attrs:{id:"_2023-11-16-阻塞与非阻塞赋值"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_2023-11-16-阻塞与非阻塞赋值"}},[t._v("#")]),t._v(" "),r("RouterLink",{attrs:{to:"/Chip/Chip/2023.11.07-Verilog语法/2023.11.16-阻塞与非阻塞赋值.html"}},[t._v("2023.11.16-阻塞与非阻塞赋值")])],1)])}),[],!1,null,null,null);r.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/68.b0f38212.js b/assets/js/68.b0f38212.js new file mode 100644 index 0000000..241edb5 --- /dev/null +++ b/assets/js/68.b0f38212.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[68],{410:function(t,e,s){"use strict";s.r(e);var a=s(14),r=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"预学习阶段"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#预学习阶段"}},[t._v("#")]),t._v(" 预学习阶段")]),t._v(" "),e("h2",{attrs:{id:"the-missing-semester"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#the-missing-semester"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester.html"}},[t._v("The Missing Semester")])],1),t._v(" "),e("h2",{attrs:{id:"learn-c-the-hard-way"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#learn-c-the-hard-way"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way.html"}},[t._v("Learn C the hard way")])],1)])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/69.9b3ffefe.js b/assets/js/69.9b3ffefe.js new file mode 100644 index 0000000..342ec29 --- /dev/null +++ b/assets/js/69.9b3ffefe.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[69],{412:function(t,a,r){"use strict";r.r(a);var h=r(14),e=Object(h.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"learn-c-the-hard-way"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#learn-c-the-hard-way"}},[t._v("#")]),t._v(" Learn C the hard way")]),t._v(" "),a("h2",{attrs:{id:"_2024-04-02-练习-1-启用编译器"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-02-练习-1-启用编译器"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.02-练习1:启用编译器.html"}},[t._v("2024.04.02-练习 1:启用编译器")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-02-练习-2-用-make-来代替-python"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-02-练习-2-用-make-来代替-python"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.02-练习2:用Make来代替Python.html"}},[t._v("2024.04.02-练习 2:用 Make 来代替 Python")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-02-练习-3-格式化输出"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-02-练习-3-格式化输出"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.02-练习3:格式化输出.html"}},[t._v("2024.04.02-练习 3:格式化输出")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-03-练习-4-valgrind-介绍"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-03-练习-4-valgrind-介绍"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习4:Valgrind 介绍.html"}},[t._v("2024.04.03-练习 4:Valgrind 介绍")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-03-练习-5-一个-c-程序的结构"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-03-练习-5-一个-c-程序的结构"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习5:一个C程序的结构.html"}},[t._v("2024.04.03-练习 5:一个 C 程序的结构")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-03-练习-6-变量类型"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-03-练习-6-变量类型"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习6:变量类型.html"}},[t._v("2024.04.03-练习 6:变量类型")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-03-练习-7-更多变量和一些算术"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-03-练习-7-更多变量和一些算术"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习7:更多变量和一些算术.html"}},[t._v("2024.04.03-练习 7:更多变量和一些算术")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-03-练习-8-大小和数组"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-03-练习-8-大小和数组"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习8:大小和数组.html"}},[t._v("2024.04.03-练习 8:大小和数组")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-03-练习-9-数组和字符串"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-03-练习-9-数组和字符串"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习9:数组和字符串.html"}},[t._v("2024.04.03-练习 9:数组和字符串")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-04-练习-10-字符串数组和循环"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-04-练习-10-字符串数组和循环"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.04-练习10:字符串数组和循环.html"}},[t._v("2024.04.04-练习 10:字符串数组和循环")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-05-练习-11-while-循环和布尔表达式"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-05-练习-11-while-循环和布尔表达式"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习11:While循环和布尔表达式.html"}},[t._v("2024.04.05-练习 11:While 循环和布尔表达式")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-05-练习-12-if-else-if-else"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-05-练习-12-if-else-if-else"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习12:If,Else If,Else.html"}},[t._v("2024.04.05-练习 12:If,Else If,Else")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-05-练习-13-switch-语句"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-05-练习-13-switch-语句"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习13:Switch语句.html"}},[t._v("2024.04.05-练习 13:Switch 语句")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-05-练习-14-编写并使用函数"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-05-练习-14-编写并使用函数"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习14:编写并使用函数.html"}},[t._v("2024.04.05-练习 14:编写并使用函数")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-05-练习-15-指针-可怕的指针"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-05-练习-15-指针-可怕的指针"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习15:指针,可怕的指针.html"}},[t._v("2024.04.05-练习 15:指针,可怕的指针")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-05-练习-16-结构体和指向它们的指针"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-05-练习-16-结构体和指向它们的指针"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习16:结构体和指向它们的指针.html"}},[t._v("2024.04.05-练习 16:结构体和指向它们的指针")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-08-练习-17-堆和栈的内存分配"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-08-练习-17-堆和栈的内存分配"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.08-练习17:堆和栈的内存分配.html"}},[t._v("2024.04.08-练习 17:堆和栈的内存分配")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-10-练习-18-函数指针"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-10-练习-18-函数指针"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.10-练习18:函数指针.html"}},[t._v("2024.04.10-练习 18:函数指针")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-10-练习-32-双向链表"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-10-练习-32-双向链表"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.10-练习32:双向链表.html"}},[t._v("2024.04.10-练习 32:双向链表")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-11-练习-33-链表算法"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-11-练习-33-链表算法"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.11-练习33:链表算法.html"}},[t._v("2024.04.11-练习 33:链表算法")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-11-练习-42-栈和队列"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-11-练习-42-栈和队列"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.11-练习42:栈和队列.html"}},[t._v("2024.04.11-练习 42:栈和队列")])],1),t._v(" "),a("h2",{attrs:{id:"_2024-04-12-练习-44-环形缓冲区"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-12-练习-44-环形缓冲区"}},[t._v("#")]),t._v(" "),a("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.12-练习44:环形缓冲区.html"}},[t._v("2024.04.12-练习 44:环形缓冲区")])],1)])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/7.21716967.js b/assets/js/7.21716967.js new file mode 100644 index 0000000..bc689de --- /dev/null +++ b/assets/js/7.21716967.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[7],{383:function(t,e,s){"use strict";s.r(e);const o=["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."];var n={methods:{getMsg:()=>o[Math.floor(Math.random()*o.length)]}},h=s(14),i=Object(h.a)(n,(function(){var t=this._self._c;return t("div",{staticClass:"theme-container"},[t("div",{staticClass:"theme-default-content"},[t("h1",[this._v("404")]),this._v(" "),t("blockquote",[this._v(this._s(this.getMsg()))]),this._v(" "),t("RouterLink",{attrs:{to:"/"}},[this._v("\n Take me home.\n ")])],1)])}),[],!1,null,null,null);e.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/70.bbf0c841.js b/assets/js/70.bbf0c841.js new file mode 100644 index 0000000..bda555d --- /dev/null +++ b/assets/js/70.bbf0c841.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[70],{414:function(t,a,s){"use strict";s.r(a);var v=s(14),_=Object(v.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"_2024-04-02-练习3-格式化输出"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-02-练习3-格式化输出"}},[t._v("#")]),t._v(" 2024.04.02-练习3:格式化输出")]),t._v(" "),a("h2",{attrs:{id:"_1-printf"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-printf"}},[t._v("#")]),t._v(" 1. printf")]),t._v(" "),a("div",{staticClass:"language-c extra-class"},[a("pre",{pre:!0,attrs:{class:"language-c"}},[a("code",[a("span",{pre:!0,attrs:{class:"token macro property"}},[a("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),a("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" age "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" height "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("72")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"I am %d years old.\\n"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"I am %d inches tall.\\n"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("这个练习的代码量很小,但是信息量很大,所以让我们逐行分析一下:")]),t._v(" "),a("ul",[a("li",[t._v("首先你包含了另一个头文件叫做"),a("code",[t._v("stdio.h")]),t._v("。这告诉了编译器你要使用“标准的输入/输出函数”。它们之一就是"),a("code",[t._v("printf")]),t._v("。")]),t._v(" "),a("li",[t._v("然后你使用了一个叫"),a("code",[t._v("age")]),t._v("的变量并且将它设置为10。")]),t._v(" "),a("li",[t._v("接着你使用了一个叫"),a("code",[t._v("height")]),t._v("的变量并且设置为72。")]),t._v(" "),a("li",[t._v("再然后你使用"),a("code",[t._v("printf")]),t._v("函数来打印这个星球上最高的十岁的人的年龄和高度。")]),t._v(" "),a("li",[t._v("在"),a("code",[t._v("printf")]),t._v("中你会注意到你传入了一个字符串,这就是格式字符串,和其它语言中一样。")]),t._v(" "),a("li",[t._v("在格式字符串之后,你传入了一些变量,它们应该被"),a("code",[t._v("printf")]),t._v("“替换”进格式字符串中。")])]),t._v(" "),a("p",[t._v("这些语句的结果就是你用"),a("code",[t._v("printf")]),t._v("处理了一些变量,并且它会构造出一个新的字符串,之后将它打印在终端上。")]),t._v(" "),a("h2",{attrs:{id:"_2-附加题"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-附加题"}},[t._v("#")]),t._v(" 2. 附加题")]),t._v(" "),a("h3",{attrs:{id:"_2-1-占位符和转移字符"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-占位符和转移字符"}},[t._v("#")]),t._v(" 2.1 %占位符和转移字符")]),t._v(" "),a("p",[a("strong",[t._v("常用的")]),a("code",[t._v("%")]),a("strong",[t._v("占位符")])]),t._v(" "),a("ul",[a("li",[a("code",[t._v("%d")]),t._v(" 或 "),a("code",[t._v("%i")]),t._v(":用于输出"),a("code",[t._v("int")]),t._v("类型的整数。")]),t._v(" "),a("li",[a("code",[t._v("%u")]),t._v(":用于输出无符号整型"),a("code",[t._v("unsigned int")]),t._v("。")]),t._v(" "),a("li",[a("code",[t._v("%f")]),t._v(":用于输出单精度浮点数或双精度浮点数("),a("code",[t._v("float")]),t._v("或"),a("code",[t._v("double")]),t._v("),默认情况下显示六位小数。")]),t._v(" "),a("li",[a("code",[t._v("%lf")]),t._v(":用于输出双精度浮点数("),a("code",[t._v("double")]),t._v("),虽然"),a("code",[t._v("%f")]),t._v("也可以用于"),a("code",[t._v("double")]),t._v(",但在某些情况下使用"),a("code",[t._v("%lf")]),t._v("更加明确。")]),t._v(" "),a("li",[a("code",[t._v("%e")]),t._v(" 或 "),a("code",[t._v("%E")]),t._v(":用科学记数法输出浮点数。")]),t._v(" "),a("li",[a("code",[t._v("%g")]),t._v(" 或 "),a("code",[t._v("%G")]),t._v(":自动选择"),a("code",[t._v("%f")]),t._v("或"),a("code",[t._v("%e")]),t._v("("),a("code",[t._v("%E")]),t._v(")中较短的一种输出浮点数。")]),t._v(" "),a("li",[a("code",[t._v("%c")]),t._v(":输出单个字符。")]),t._v(" "),a("li",[a("code",[t._v("%s")]),t._v(":输出字符串。")]),t._v(" "),a("li",[a("code",[t._v("%p")]),t._v(":输出指针的地址。")]),t._v(" "),a("li",[a("code",[t._v("%x")]),t._v(" 或 "),a("code",[t._v("%X")]),t._v(":以十六进制形式输出无符号整数,"),a("code",[t._v("%x")]),t._v("产生小写字母,而"),a("code",[t._v("%X")]),t._v("产生大写字母。")]),t._v(" "),a("li",[a("code",[t._v("%%")]),t._v(":输出"),a("code",[t._v("%")]),t._v("字符本身。")])]),t._v(" "),a("p",[a("strong",[t._v("转义字符")])]),t._v(" "),a("p",[t._v("转义字符用于表示那些不能直接在源代码中表示的字符,或者具有特殊意义的字符。以下是一些常用的转义字符:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("\\n")]),t._v(":换行符,移动到下一行的开头。")]),t._v(" "),a("li",[a("code",[t._v("\\t")]),t._v(":水平制表符,常用于输出中的对齐。")]),t._v(" "),a("li",[a("code",[t._v("\\\\")]),t._v(":表示一个反斜杠字符"),a("code",[t._v("\\")]),t._v("。")]),t._v(" "),a("li",[a("code",[t._v('\\"')]),t._v(":表示双引号字符"),a("code",[t._v('"')]),t._v(",允许在字符串常量中使用双引号。")]),t._v(" "),a("li",[a("code",[t._v("\\'")]),t._v(":表示单引号字符"),a("code",[t._v("'")]),t._v("(在字符常量中使用)。")]),t._v(" "),a("li",[a("code",[t._v("\\r")]),t._v(":回车符,将光标移动到当前行的开头。")]),t._v(" "),a("li",[a("code",[t._v("\\b")]),t._v(":退格符,将光标向左移动一个位置。")]),t._v(" "),a("li",[a("code",[t._v("\\0")]),t._v(":空字符,字符串的结束标志。")])]),t._v(" "),a("p",[a("strong",[t._v("对于浮点数:")])]),t._v(" "),a("ul",[a("li",[a("code",[t._v("%.*f")]),t._v(":对于"),a("code",[t._v("float")]),t._v("和"),a("code",[t._v("double")]),t._v("类型,"),a("code",[t._v(".*")]),t._v("允许你通过参数指定小数点后的位数。例如,"),a("code",[t._v('printf("%.*f", 3, 3.14159)')]),t._v("会输出"),a("code",[t._v("3.142")]),t._v("。")]),t._v(" "),a("li",[a("code",[t._v("%.*e")]),t._v(" 或 "),a("code",[t._v("%.*E")]),t._v(":以科学记数法格式输出浮点数,其中"),a("code",[t._v(".*")]),t._v("指定小数点后的位数。")]),t._v(" "),a("li",[a("code",[t._v("%.*g")]),t._v(" 或 "),a("code",[t._v("%.*G")]),t._v(":自动选择"),a("code",[t._v("%f")]),t._v("或"),a("code",[t._v("%e")]),t._v("("),a("code",[t._v("%E")]),t._v(")中较短的一种输出浮点数,"),a("code",[t._v(".*")]),t._v("指定有效数字的最大位数。")])]),t._v(" "),a("p",[a("strong",[t._v("对于整数:")])]),t._v(" "),a("ul",[a("li",[a("code",[t._v("%.*d")]),t._v(" 或 "),a("code",[t._v("%.*i")]),t._v(":虽然通常用于指定最小宽度,但通过指定精度,可以使得输出的整数在前面用零填充到指定的长度。例如,"),a("code",[t._v('printf("%.*d", 5, 123)')]),t._v("会输出"),a("code",[t._v("00123")]),t._v("。")])]),t._v(" "),a("p",[a("strong",[t._v("对于字符串:")])]),t._v(" "),a("ul",[a("li",[a("code",[t._v("%.*s")]),t._v(":指定字符串的最大输出长度。这对于输出字符串的一个子串非常有用。例如,"),a("code",[t._v('printf("%.*s", 3, "abcdef")')]),t._v("会输出"),a("code",[t._v("abc")]),t._v("。")])]),t._v(" "),a("h3",{attrs:{id:"_2-2-makefile"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-makefile"}},[t._v("#")]),t._v(" 2.2 Makefile")]),t._v(" "),a("div",{staticClass:"language-makefile extra-class"},[a("pre",{pre:!0,attrs:{class:"language-makefile"}},[a("code",[t._v("CC"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("gcc\nCFLAGS"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("-Wall -g\n\nTARGET"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("ex3\n\n"),a("span",{pre:!0,attrs:{class:"token target symbol"}},[t._v("all")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("TARGET"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token target symbol"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$")]),t._v("(TARGET)")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("TARGET"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(".o\n\t"),a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CC"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CFLAGS"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$^")]),t._v(" -o "),a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$@")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token target symbol"}},[a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$")]),t._v("(TARGET).o")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("TARGET"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(".c\n\t"),a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CC"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CFLAGS"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" -c "),a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$^")]),t._v(" -o "),a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$@")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token target symbol"}},[t._v("clean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n\trm -f "),a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("TARGET"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("TARGET"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(".o\n\n"),a("span",{pre:!0,attrs:{class:"token builtin-target builtin"}},[t._v(".PHONY")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" all clean\n")])])])])}),[],!1,null,null,null);a.default=_.exports}}]); \ No newline at end of file diff --git a/assets/js/71.2da9347c.js b/assets/js/71.2da9347c.js new file mode 100644 index 0000000..fd3f44a --- /dev/null +++ b/assets/js/71.2da9347c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[71],{415:function(t,a,s){"use strict";s.r(a);var n=s(14),r=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"_2024-04-03-练习4-valgrind-介绍"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-03-练习4-valgrind-介绍"}},[t._v("#")]),t._v(" 2024.04.03-练习4:Valgrind 介绍")]),t._v(" "),a("h2",{attrs:{id:"_1-intro"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-intro"}},[t._v("#")]),t._v(" 1. Intro")]),t._v(" "),a("p",[t._v("Valgrind是一个编程工具,用于内存调试、内存泄漏检测,以及性能分析。它主要用于帮助开发者找出程序中的内存管理和线程使用错误,是Linux和macOS下常用的工具之一。Valgrind通过一个核心,提供了多种不同的工具,其中最著名的是Memcheck。Memcheck可以检测以下问题:")]),t._v(" "),a("ul",[a("li",[t._v("访问未初始化的内存")]),t._v(" "),a("li",[t._v("访问已经释放的内存")]),t._v(" "),a("li",[t._v("访问申请后未释放的内存(内存泄漏)")]),t._v(" "),a("li",[t._v("不当的堆栈使用")]),t._v(" "),a("li",[t._v("对"),a("code",[t._v("malloc")]),t._v("和"),a("code",[t._v("free")]),t._v("等堆管理函数的误用")])]),t._v(" "),a("p",[a("strong",[t._v("使用方法")])]),t._v(" "),a("p",[t._v("使用Valgrind的基本语法很简单。首先,确保你的程序是用调试信息编译的(通常是使用"),a("code",[t._v("gcc")]),t._v("的"),a("code",[t._v("-g")]),t._v("选项)。然后,使用下面的命令行格式运行Valgrind:")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[t._v("valgrind "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("options"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" your_program "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("program_options"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),a("p",[t._v("其中,"),a("code",[t._v("[options]")]),t._v("是传递给Valgrind的选项(例如,选择不同的工具),"),a("code",[t._v("your_program")]),t._v("是你的程序的路径,"),a("code",[t._v("[program_options]")]),t._v("是传递给你的程序的任何选项。")]),t._v(" "),a("p",[a("strong",[t._v("示例:使用Memcheck检测内存泄漏")])]),t._v(" "),a("p",[t._v("假设你的可执行文件名为"),a("code",[t._v("my_program")]),t._v(",要使用Memcheck工具(Valgrind的默认工具),可以这样做:")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[t._v("valgrind --leak-check"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("full ./my_program\n")])])]),a("ul",[a("li",[a("code",[t._v("-leak-check=full")]),t._v("选项告诉Memcheck提供每个内存泄漏的详细信息。")])]),t._v(" "),a("p",[t._v("Valgrind运行后,会在终端输出报告,其中包含了内存泄漏的信息、未初始化变量的使用等问题。")]),t._v(" "),a("h2",{attrs:{id:"_2-example"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-example"}},[t._v("#")]),t._v(" 2. Example")]),t._v(" "),a("div",{staticClass:"language-c extra-class"},[a("pre",{pre:!0,attrs:{class:"language-c"}},[a("code",[a("span",{pre:!0,attrs:{class:"token macro property"}},[a("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),a("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Warning: This program is wrong on purpose. */")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" age "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" height"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"I am %d years old.\\n"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"I am %d inches tall.\\n"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" height"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("使用 valgrind 运行,结果如下")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Memcheck, a memory error detector\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Copyright "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("C"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2002")]),t._v("-2017, and GNU GPL'd, by Julian Seward et al.\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Using Valgrind-3.18.1 and LibVEX"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" rerun with "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-h")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" copyright info\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Command: ./ex4\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" \n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Conditional jump or move depends on uninitialised value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" at 0x48EAAD6: __vfprintf_internal "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("vfprintf-internal.c:1516"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" by 0x48D479E: "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("printf")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("printf.c:33"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" by 0x109188: main "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ex4.c:8"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Uninitialised value was created by a stack allocation\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" at 0x109149: main "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ex4.c:3"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" \n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Use of uninitialised value of size "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" at 0x48CE2EB: _itoa_word "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_itoa.c:177"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" by 0x48E9ABD: __vfprintf_internal "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("vfprintf-internal.c:1516"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" by 0x48D479E: "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("printf")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("printf.c:33"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" by 0x109188: main "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ex4.c:8"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Uninitialised value was created by a stack allocation\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" at 0x109149: main "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ex4.c:3"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" \n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Conditional jump or move depends on uninitialised value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" at 0x48CE2FC: _itoa_word "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_itoa.c:177"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" by 0x48E9ABD: __vfprintf_internal "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("vfprintf-internal.c:1516"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" by 0x48D479E: "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("printf")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("printf.c:33"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" by 0x109188: main "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ex4.c:8"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Uninitialised value was created by a stack allocation\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" at 0x109149: main "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ex4.c:3"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" \n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Conditional jump or move depends on uninitialised value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" at 0x48EA5C3: __vfprintf_internal "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("vfprintf-internal.c:1516"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" by 0x48D479E: "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("printf")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("printf.c:33"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" by 0x109188: main "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ex4.c:8"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Uninitialised value was created by a stack allocation\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" at 0x109149: main "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ex4.c:3"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" \n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Conditional jump or move depends on uninitialised value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" at 0x48E9C05: __vfprintf_internal "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("vfprintf-internal.c:1516"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" by 0x48D479E: "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("printf")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("printf.c:33"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" by 0x109188: main "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ex4.c:8"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" Uninitialised value was created by a stack allocation\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" at 0x109149: main "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ex4.c:3"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" \nI am "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-16778360")]),t._v(" years old.\nI am "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" inches tall.\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" \n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" HEAP SUMMARY:\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" use at exit: "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" bytes "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" blocks\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" total heap usage: "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" allocs, "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" frees, "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4,096")]),t._v(" bytes allocated\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" \n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" All heap blocks were freed -- no leaks are possible\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" \n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" For lists of detected and suppressed errors, rerun with: "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-s")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("431815")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" ERROR SUMMARY: "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),t._v(" errors from "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),t._v(" contexts "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("suppressed: "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" from "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("by 0x109188: main (ex4.c:8):第八行 "),a("code",[t._v('printf("I am %d inches tall.\\n", height);')]),t._v(" 中有未初始化的量")]),t._v(" "),a("h2",{attrs:{id:"_3-附加题"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-附加题"}},[t._v("#")]),t._v(" 3. 附加题")])])}),[],!1,null,null,null);a.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/72.43af9dd4.js b/assets/js/72.43af9dd4.js new file mode 100644 index 0000000..63192f8 --- /dev/null +++ b/assets/js/72.43af9dd4.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[72],{417:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-03-练习5-一个c程序的结构"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-03-练习5-一个c程序的结构"}},[t._v("#")]),t._v(" 2024.04.03-练习5:一个C程序的结构")]),t._v(" "),s("h2",{attrs:{id:"_1-printf"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-printf"}},[t._v("#")]),t._v(" 1. printf")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* This is a comment. */")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" distance "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this is also a comment")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"You are %d miles away.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" distance"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/73.973c695f.js b/assets/js/73.973c695f.js new file mode 100644 index 0000000..1de92d2 --- /dev/null +++ b/assets/js/73.973c695f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[73],{418:function(s,t,a){"use strict";a.r(t);var n=a(14),r=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h1",{attrs:{id:"_2024-04-03-练习6-变量类型"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-03-练习6-变量类型"}},[s._v("#")]),s._v(" 2024.04.03-练习6:变量类型")]),s._v(" "),t("h2",{attrs:{id:"_1-变量"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-变量"}},[s._v("#")]),s._v(" 1. 变量")]),s._v(" "),t("div",{staticClass:"language-c extra-class"},[t("pre",{pre:!0,attrs:{class:"language-c"}},[t("code",[s._v("include "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),s._v("stdio"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("h"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("int")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("main")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("int")]),s._v(" argc"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("char")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),s._v("argv"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("int")]),s._v(" distance "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("100")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("float")]),s._v(" power "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("2.345f")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("double")]),s._v(" super_power "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("56789.4532")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("char")]),s._v(" initial "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token char"}},[s._v("'A'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("char")]),s._v(" first_name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Zed"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("char")]),s._v(" last_name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Shaw"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("printf")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"You are %d miles away.\\n"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" distance"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("printf")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"You have %f levels of power.\\n"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" power"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("printf")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"You have %f awesome super powers.\\n"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" super_power"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("printf")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"I have an initial %c.\\n"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" initial"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("printf")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"I have a first name %s.\\n"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" first_name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("printf")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"I have a last name %s.\\n"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" last_name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("printf")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"My whole name is %s %c. %s.\\n"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n first_name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" initial"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" last_name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("整数:使用"),t("code",[s._v("int")]),s._v("声明,使用"),t("code",[s._v("%d")]),s._v("来打印。")]),s._v(" "),t("p",[s._v("浮点:使用"),t("code",[s._v("float")]),s._v("或"),t("code",[s._v("double")]),s._v("声明,使用"),t("code",[s._v("%f")]),s._v("来打印。")]),s._v(" "),t("p",[s._v("字符:使用"),t("code",[s._v("char")]),s._v("来声明,以周围带有"),t("code",[s._v("'")]),s._v("(单引号)的单个字符来表示,使用"),t("code",[s._v("%c")]),s._v("来打印。")]),s._v(" "),t("p",[s._v("字符串(字符数组):使用"),t("code",[s._v("char name[]")]),s._v("来声明,以周围带有"),t("code",[s._v('"')]),s._v("的一些字符来表示,使用"),t("code",[s._v("%s")]),s._v("来打印。 你会注意到C语言中区分单引号的"),t("code",[s._v("char")]),s._v("和双引号的"),t("code",[s._v("char[]")]),s._v("或字符串。")]),s._v(" "),t("h2",{attrs:{id:"_2-如何使它崩溃"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2-如何使它崩溃"}},[s._v("#")]),s._v(" 2. 如何使它崩溃")]),s._v(" "),t("p",[s._v("你可以通过向"),t("code",[s._v("printf")]),s._v("传递错误的参数来轻易使这个程序崩溃。例如,如果你找到打印我的名字的那行,把"),t("code",[s._v("initial")]),s._v("放到"),t("code",[s._v("first_name")]),s._v("前面,你就制造了一个bug。执行上述修改编译器就会向你报错,之后运行的时候你可能会得到一个“段错误”,就像这样:")]),s._v(" "),t("div",{staticClass:"language-bash extra-class"},[t("pre",{pre:!0,attrs:{class:"language-bash"}},[t("code",[t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" Memcheck, a memory error detector\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" Copyright "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("C"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("2002")]),s._v("-2017, and GNU GPL"),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'d, by Julian Seward et al.\n==453551== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info\n==453551== Command: ./ex6\n==453551== \n==453551== Invalid read of size 1\n==453551== at 0x484ED16: strlen (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)\n==453551== by 0x48EAD30: __vfprintf_internal (vfprintf-internal.c:1517)\n==453551== by 0x48D479E: printf (printf.c:33)\n==453551== by 0x109290: main (ex6.c:18)\n==453551== Address 0x41 is not stack'")]),s._v("d, malloc"),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'d or (recently) free'")]),s._v("d\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" \n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" \n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" Process terminating with default action of signal "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("11")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("SIGSEGV"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" Access not within mapped region at address 0x41\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" at 0x484ED16: strlen "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" by 0x48EAD30: __vfprintf_internal "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("vfprintf-internal.c:1517"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" by 0x48D479E: "),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("printf")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("printf.c:33"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" by 0x109290: main "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ex6.c:18"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" If you believe this happened as a result of a stack\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" overflow "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" your program's main thread "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("unlikely but\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" possible"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(", you can try to increase the size of the\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" main thread stack using the --main-stacksize"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" flag.\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" The main thread stack size used "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" this run was "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("8388608")]),s._v(".\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" \n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" HEAP SUMMARY:\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" use at exit: "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("4,096")]),s._v(" bytes "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" blocks\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" total heap usage: "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" allocs, "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" frees, "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("4,096")]),s._v(" bytes allocated\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" \n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" LEAK SUMMARY:\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" definitely lost: "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" bytes "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" blocks\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" indirectly lost: "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" bytes "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" blocks\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" possibly lost: "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" bytes "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" blocks\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" still reachable: "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("4,096")]),s._v(" bytes "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" blocks\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" suppressed: "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" bytes "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("in")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" blocks\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" Rerun with --leak-check"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v("full to see details of leaked memory\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" \n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" For lists of detected and suppressed errors, rerun with: "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-s")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("453551")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" ERROR SUMMARY: "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" errors from "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" contexts "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("suppressed: "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" from "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])])]),t("p",[t("code",[s._v("by 0x109290: main (ex6.c:18)")]),s._v(" 显示 "),t("code",[s._v('printf("My whole name is %s %c. %s.\\n",')]),s._v(" 这一行有问题")]),s._v(" "),t("h2",{attrs:{id:"_3-附加题"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_3-附加题"}},[s._v("#")]),s._v(" 3. 附加题")]),s._v(" "),t("h3",{attrs:{id:"试着打印空字符串-即"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#试着打印空字符串-即"}},[s._v("#")]),s._v(" 试着打印空字符串,即"),t("code",[s._v('""')])]),s._v(" "),t("div",{staticClass:"language-c extra-class"},[t("pre",{pre:!0,attrs:{class:"language-c"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("char")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("*")]),s._v("null "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('""')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("printf")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"null is \\"%s\\"\\n"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" null"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])])])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/74.c2b70d6c.js b/assets/js/74.c2b70d6c.js new file mode 100644 index 0000000..329d015 --- /dev/null +++ b/assets/js/74.c2b70d6c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[74],{423:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-05-练习11-while循环和布尔表达式"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-05-练习11-while循环和布尔表达式"}},[t._v("#")]),t._v(" 2024.04.05-练习11:While循环和布尔表达式")]),t._v(" "),s("h2",{attrs:{id:"_1-while"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-while"}},[t._v("#")]),t._v(" 1. "),s("code",[t._v("while")])]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// go through each string in argv")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"arg %d: %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// let's make our own array of strings")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"California"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Oregon"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Washington"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Texas"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" num_states "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// watch for this")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" num_states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"state %d: %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"_2-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-附加题"}},[t._v("#")]),t._v(" 2. 附加题")]),t._v(" "),s("h3",{attrs:{id:"_2-1-循环倒序执行"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-循环倒序执行"}},[t._v("#")]),t._v(" 2.1 循环倒序执行")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"arg %d: %s\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"_2-2-使用while循环将argv中的值复制到states"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-使用while循环将argv中的值复制到states"}},[t._v("#")]),t._v(" 2.2 使用"),s("code",[t._v("while")]),t._v("循环将"),s("code",[t._v("argv")]),t._v("中的值复制到"),s("code",[t._v("states")])]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"California"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Oregon"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Washington"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Texas"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" num_states "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// watch for this")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 让这个复制循环不会执行失败,即使argv之中有很多元素也不会全部放进states。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" num_states "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n states"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"_2-3-是否真正复制了这些字符串"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-是否真正复制了这些字符串"}},[t._v("#")]),t._v(" 2.3 是否真正复制了这些字符串?")]),t._v(" "),s("p",[t._v("当在C语言中将一个字符串数组(例如"),s("code",[t._v("argv")]),t._v("或"),s("code",[t._v("states")]),t._v(")的元素赋值给另一个数组的元素时,你实际上并没有复制字符串的内容。相反,你只是复制了字符串的指针,这意味着两个数组中的对应元素现在共享同一个字符串实例(即指向同一个内存地址)。这是因为在C中,字符串是通过字符指针表示的,赋值操作只涉及指针的复制,而非指针所指向的数据(字符串内容)的复制。")])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/75.a359e09d.js b/assets/js/75.a359e09d.js new file mode 100644 index 0000000..8be6e8a --- /dev/null +++ b/assets/js/75.a359e09d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[75],{424:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-05-练习12-if-else-if-else"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-05-练习12-if-else-if-else"}},[t._v("#")]),t._v(" 2024.04.05-练习12:If,Else If,Else")]),t._v(" "),s("h2",{attrs:{id:"_1-if-else-if-else"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-if-else-if-else"}},[t._v("#")]),t._v(" 1. i"),s("strong",[t._v("f,else if,else")])]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"You only have one argument. You suck.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Here\'s your arguments:\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%s "')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"You have too many arguments. You suck.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"_2-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-附加题"}},[t._v("#")]),t._v(" 2. 附加题")]),t._v(" "),s("h3",{attrs:{id:"_2-1-布尔运算符"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-布尔运算符"}},[t._v("#")]),t._v(" 2.1 布尔运算符")]),t._v(" "),s("p",[t._v('在C语言中,常用的布尔运算符包括"与"('),s("code",[t._v("&&")]),t._v(')、"或"('),s("code",[t._v("||")]),t._v(')和"非"('),s("code",[t._v("!")]),t._v(")。这些运算符用于构建逻辑表达式,从而控制程序流程如条件语句和循环。"),s("code",[t._v("&&")]),t._v("运算符用于判断两个条件是否同时满足,"),s("code",[t._v("||")]),t._v("检查至少一个条件是否满足,而"),s("code",[t._v("!")]),t._v("用于反转一个条件的布尔值。由于C语言中没有内置的布尔类型,在使用这些运算符时,非零值被视为真("),s("code",[t._v("true")]),t._v("),而零值被视为假("),s("code",[t._v("false")]),t._v(")。")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/76.c39b2efa.js b/assets/js/76.c39b2efa.js new file mode 100644 index 0000000..779c2a3 --- /dev/null +++ b/assets/js/76.c39b2efa.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[76],{425:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-05-练习13-switch语句"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-05-练习13-switch语句"}},[t._v("#")]),t._v(" 2024.04.05-练习13:Switch语句")]),t._v(" "),s("h2",{attrs:{id:"_1-switch"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-switch"}},[t._v("#")]),t._v(" 1. s"),s("strong",[t._v("witch")])]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ERROR: You need one argument.\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this is how you abort a program")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" letter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("switch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("letter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'a'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'A'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"%d: 'A'\\n\"")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'e'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'E'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"%d: 'E'\\n\"")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'i'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'I'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"%d: 'I'\\n\"")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'o'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'O'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"%d: 'O'\\n\"")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'u'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'U'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"%d: 'U'\\n\"")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'y'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'Y'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// it's only sometimes Y")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"%d: 'Y'\\n\"")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("break")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"%d: %c is not a vowel\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" letter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("在这个程序中我们接受了单一的命令行参数,并且用一种极其复杂的方式打印出所有原因,来向你演示"),s("code",[t._v("switch")]),t._v("语句。下面是"),s("code",[t._v("swicth")]),t._v("语句的工作原理:")]),t._v(" "),s("ul",[s("li",[t._v("编译器会标记"),s("code",[t._v("swicth")]),t._v("语句的顶端,我们先把它记为地址Y。")]),t._v(" "),s("li",[t._v("接着对"),s("code",[t._v("switch")]),t._v("中的表达式求值,产生一个数字。在上面的例子中,数字为"),s("code",[t._v("argv[1]")]),t._v("中字母的原始的ASCLL码。")]),t._v(" "),s("li",[t._v("编译器也会把每个类似"),s("code",[t._v("case 'A'")]),t._v("的"),s("code",[t._v("case")]),t._v("代码块翻译成这个程序中距离语句顶端的地址,所以"),s("code",[t._v("case 'A'")]),t._v("就在"),s("code",[t._v("Y + 'A'")]),t._v("处。")]),t._v(" "),s("li",[t._v("接着计算是否"),s("code",[t._v("Y+letter")]),t._v("位于"),s("code",[t._v("switch")]),t._v("语句中,如果距离太远则会将其调整为"),s("code",[t._v("Y+Default")]),t._v("。")]),t._v(" "),s("li",[t._v("一旦计算出了地址,程序就会“跳”到代码的那个位置并继续执行。这就是一些"),s("code",[t._v("case")]),t._v("代码块中有"),s("code",[t._v("break")]),t._v("而另外一些没有的原因。")]),t._v(" "),s("li",[t._v("如果输出了"),s("code",[t._v("'a'")]),t._v(",那它就会跳到"),s("code",[t._v("case 'a'")]),t._v(",它里面没有"),s("code",[t._v("break")]),t._v("语句,所以它会贯穿执行底下带有代码和"),s("code",[t._v("break")]),t._v("的"),s("code",[t._v("case 'A'")]),t._v("。")]),t._v(" "),s("li",[t._v("最后它执行这段代码,执行"),s("code",[t._v("break")]),t._v("完全跳出"),s("code",[t._v("switch")]),t._v("语句块。")])]),t._v(" "),s("p",[t._v("更常见的情况是,gcc会在空白处单独构建一张跳转表,各个偏移处存放对应的"),s("code",[t._v("case")]),t._v("语句的地址。Y不是"),s("code",[t._v("switch")]),t._v("语句的起始地址,而是这张表的起始地址。程序会跳转到"),s("code",[t._v("*(Y + 'A')")]),t._v("而不是"),s("code",[t._v("Y + 'A'")]),t._v("处。")]),t._v(" "),s("h2",{attrs:{id:"_2-如何崩溃"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-如何崩溃"}},[t._v("#")]),t._v(" 2. 如何崩溃")]),t._v(" "),s("h3",{attrs:{id:"_2-1-忘记写default"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-忘记写default"}},[t._v("#")]),t._v(" 2.1 忘记写"),s("code",[t._v("default")])]),t._v(" "),s("p",[t._v("在C语言中,如果"),s("code",[t._v("switch")]),t._v("语句中没有写"),s("code",[t._v("default")]),t._v("子句,那么当没有任何"),s("code",[t._v("case")]),t._v("标签与"),s("code",[t._v("switch")]),t._v("表达式的值匹配时,程序将跳过整个"),s("code",[t._v("switch")]),t._v("块,继续执行"),s("code",[t._v("switch")]),t._v("语句之后的代码。简而言之,没有匹配的"),s("code",[t._v("case")]),t._v("且缺少"),s("code",[t._v("default")]),t._v("时,"),s("code",[t._v("switch")]),t._v("语句不执行任何操作。")]),t._v(" "),s("h3",{attrs:{id:"_2-2-无意中将一些带有预料之外的值的变量放入switch中"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-无意中将一些带有预料之外的值的变量放入switch中"}},[t._v("#")]),t._v(" 2.2 无意中将一些带有预料之外的值的变量放入"),s("code",[t._v("switch")]),t._v("中")]),t._v(" "),s("p",[t._v("这个值如果没有在任何"),s("code",[t._v("case")]),t._v("标签中明确匹配到,且没有"),s("code",[t._v("default")]),t._v("分支处理这种情况,"),s("code",[t._v("switch")]),t._v("语句将不会执行任何操作,程序将跳过整个"),s("code",[t._v("switch")]),t._v("块,继续执行下面的代码。")]),t._v(" "),s("h2",{attrs:{id:"_3-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-附加题"}},[t._v("#")]),t._v(" 3. 附加题")]),t._v(" "),s("h3",{attrs:{id:"_3-1-编写另一个程序-在字母上做算术运算将它们转换为小写-并且在switch中移除所有额外的大写字母"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-编写另一个程序-在字母上做算术运算将它们转换为小写-并且在switch中移除所有额外的大写字母"}},[t._v("#")]),t._v(" 3.1 编写另一个程序,在字母上做算术运算将它们转换为小写,并且在"),s("code",[t._v("switch")]),t._v("中移除所有额外的大写字母")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("letter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'A'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" letter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'Z'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n letter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("32")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Convert to lowercase")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/77.89cd0c9b.js b/assets/js/77.89cd0c9b.js new file mode 100644 index 0000000..0c73826 --- /dev/null +++ b/assets/js/77.89cd0c9b.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[77],{426:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-05-练习14-编写并使用函数"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-05-练习14-编写并使用函数"}},[t._v("#")]),t._v(" 2024.04.05-练习14:编写并使用函数")]),t._v(" "),s("h2",{attrs:{id:"_1-函数"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-函数"}},[t._v("#")]),t._v(" 1. 函数")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// forward declarations")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("can_print_it")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" ch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("print_letters")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("print_arguments")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("print_letters")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("print_letters")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'\\0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" ch "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" arg"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("can_print_it")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("\"'%c' == %d \"")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"\\n"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 属于“字母”和“空白”的字符")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("can_print_it")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" ch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isalpha")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isblank")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("print_arguments")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("argc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" argv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"_2-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-附加题"}},[t._v("#")]),t._v(" 2. 附加题")]),t._v(" "),s("h3",{attrs:{id:"_2-1-使用strlen函数"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-使用strlen函数"}},[t._v("#")]),t._v(" 2.1 使用"),s("code",[t._v("strlen")]),t._v("函数")]),t._v(" "),s("h3",{attrs:{id:"_2-2-ctype-h"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-ctype-h"}},[t._v("#")]),t._v(" 2.2 "),s("strong",[t._v("")])]),t._v(" "),s("p",[s("code",[t._v("isdigit()")]),t._v("用于检查字符是否为数字(0-9),"),s("code",[t._v("isspace()")]),t._v("用于检查空白字符(如空格、制表符、换行符),"),s("code",[t._v("islower()")]),t._v("和"),s("code",[t._v("isupper()")]),t._v("分别用于检查字符是否为小写或大写字母,"),s("code",[t._v("isalnum()")]),t._v("用于检查字符是否为字母或数字。")])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/78.01e91259.js b/assets/js/78.01e91259.js new file mode 100644 index 0000000..4b6f0ab --- /dev/null +++ b/assets/js/78.01e91259.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[78],{431:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-10-练习32-双向链表"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-10-练习32-双向链表"}},[t._v("#")]),t._v(" 2024.04.10-练习32:双向链表")]),t._v(" "),s("h2",{attrs:{id:"_1-program"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-program"}},[t._v("#")]),t._v(" 1. program")]),t._v(" "),s("h3",{attrs:{id:"_1-1-定义"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-定义"}},[t._v("#")]),t._v(" 1.1 定义")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("ifndef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("lcthw_List_h")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name"}},[t._v("lcthw_List_h")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ListNode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typedef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ListNode")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ListNode")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ListNode")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("prev"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" ListNode"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("typedef")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_clear")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_clear_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("List_first")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("List_last")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("A"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_pop")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_unshift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_shift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_remove")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("LIST_FOREACH")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("L"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" S"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" M"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" V"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("_node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("\\")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("V "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("\\")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("V "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" _node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" L"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("S"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" _node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" V "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" _node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" _node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("M"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("endif")])]),t._v("\n")])])]),s("h3",{attrs:{id:"_1-2-实现"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-实现"}},[t._v("#")]),t._v(" 1.2 实现")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("include")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("")])]),t._v("\n\nList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("calloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("LIST_FOREACH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_clear")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("LIST_FOREACH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_clear_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_clear")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("calloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ListNode"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check_mem")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nerror"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_pop")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_remove")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_unshift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("calloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ListNode"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check_mem")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nerror"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_shift")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_remove")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_remove")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"List is empty."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"node can\'t be NULL"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Invalid list, somehow got a first that is NULL."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Invalid list, somehow got a next that is NULL."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("after "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("before "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n after"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" before"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n before"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" after"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nerror"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"_1-3-calloc"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-calloc"}},[t._v("#")]),t._v(" 1.3 "),s("code",[t._v("calloc")])]),t._v(" "),s("p",[s("code",[t._v("calloc")]),t._v("(Contiguous Allocation,连续分配)和"),s("code",[t._v("malloc")]),t._v("(Memory Allocation,内存分配)都是C语言标准库中用于动态内存分配的函数,但它们之间有一些关键的区别:")]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("初始化")])])]),t._v(" "),s("ul",[s("li",[s("strong",[s("code",[t._v("malloc")])]),t._v(" 分配的内存块内容是未初始化的。这意味着分配后的内存块中的数据是不确定的,可能包含垃圾值。使用"),s("code",[t._v("malloc")]),t._v("分配内存后,通常需要手动初始化内存块,以避免潜在的安全问题或逻辑错误。")]),t._v(" "),s("li",[s("strong",[s("code",[t._v("calloc")])]),t._v(" 分配的内存块会自动初始化为零。这意味着分配后的内存块中的每个字节都被设置为"),s("code",[t._v("0")]),t._v(",这可以直接用于程序中而无需额外的初始化步骤。")])]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[s("strong",[t._v("参数")])])]),t._v(" "),s("ul",[s("li",[s("strong",[s("code",[t._v("malloc")])]),t._v(" 只需要一个参数,即所需分配的字节数。")]),t._v(" "),s("li",[s("strong",[s("code",[t._v("calloc")])]),t._v(" 需要两个参数:需要分配的元素数量和每个元素的大小。"),s("code",[t._v("calloc")]),t._v("会计算总共需要的字节数(两个参数的乘积),并分配相应的内存。")])]),t._v(" "),s("ol",{attrs:{start:"3"}},[s("li",[s("strong",[t._v("用途")])])]),t._v(" "),s("ul",[s("li",[t._v("选择"),s("code",[t._v("malloc")]),t._v("或"),s("code",[t._v("calloc")]),t._v("通常取决于是否需要自动将内存初始化为零。如果程序逻辑要求新分配的内存必须全部为零,那么"),s("code",[t._v("calloc")]),t._v("是一个更好的选择,因为它可以保证这一点并简化代码。如果不需要初始化,或者分配后会立即被其他值覆盖,那么使用"),s("code",[t._v("malloc")]),t._v("可能更有效率,因为它避免了额外的初始化开销。")])]),t._v(" "),s("ol",{attrs:{start:"4"}},[s("li",[s("strong",[t._v("性能")])])]),t._v(" "),s("ul",[s("li",[t._v("由于"),s("code",[t._v("calloc")]),t._v("会初始化内存,所以相比"),s("code",[t._v("malloc")]),t._v("可能有额外的性能开销。如果不需要内存内容初始化为零,直接使用"),s("code",[t._v("malloc")]),t._v("可能更加高效。")])]),t._v(" "),s("p",[s("strong",[t._v("示例")])]),t._v(" "),s("p",[t._v("使用"),s("code",[t._v("malloc")]),t._v("分配内存:")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("array "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("malloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 需要手动初始化")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n array"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("使用"),s("code",[t._v("calloc")]),t._v("分配内存:")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("array "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("calloc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sizeof")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 已经自动初始化为零,无需手动初始化")]),t._v("\n")])])]),s("p",[t._v("总之,选择"),s("code",[t._v("malloc")]),t._v("还是"),s("code",[t._v("calloc")]),t._v("主要取决于是否需要自动初始化内存和对性能的考虑。在某些情况下,显式地使用"),s("code",[t._v("malloc")]),t._v("和手动初始化可能更能清晰地表达程序员的意图,尤其是在初始化为非零值时。然而,"),s("code",[t._v("calloc")]),t._v("提供了一个方便的方式来确保新分配的内存区域安全地初始化为零。")]),t._v(" "),s("h3",{attrs:{id:"_1-4-list-foreach"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-4-list-foreach"}},[t._v("#")]),t._v(" 1.4 LIST_FOREACH")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token macro property"}},[s("span",{pre:!0,attrs:{class:"token directive-hash"}},[t._v("#")]),s("span",{pre:!0,attrs:{class:"token directive keyword"}},[t._v("define")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro-name function"}},[t._v("LIST_FOREACH")]),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("L"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" S"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" M"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" V"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("\\")]),t._v("\n\t\t"),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("_node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("\\")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("V "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("\\")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token expression"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("V "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" _node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" L"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("S"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" _node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" V "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" _node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" _node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("M"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])])]),t._v("\n")])])]),s("p",[t._v("这个宏"),s("code",[t._v("LIST_FOREACH")]),t._v("是一个用于遍历链表的宏,设计得非常巧妙。它利用了C语言宏的能力,提供了一个通用的、易于阅读的方式来遍历任何类型的链表。这个宏的参数有四个:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("L")]),t._v(":指向链表的指针。")]),t._v(" "),s("li",[s("code",[t._v("S")]),t._v(":链表中的起始节点。")]),t._v(" "),s("li",[s("code",[t._v("M")]),t._v(":节点中指向下一个节点的成员的名称。")]),t._v(" "),s("li",[s("code",[t._v("V")]),t._v(":在遍历过程中用于引用当前节点的变量。")])]),t._v(" "),s("p",[t._v("这个宏定义了两个局部变量("),s("code",[t._v("_node")]),t._v("和"),s("code",[t._v("V")]),t._v("),并初始化一个"),s("code",[t._v("for")]),t._v("循环,用于遍历链表。以下是该宏各部分的详细解释:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("ListNode *_node = NULL;")]),t._v(" 定义了一个名为"),s("code",[t._v("_node")]),t._v("的局部变量,类型为"),s("code",[t._v("ListNode*")]),t._v(",并将其初始化为"),s("code",[t._v("NULL")]),t._v("。这个变量用于在循环中跟踪当前节点。")]),t._v(" "),s("li",[s("code",[t._v("ListNode *V = NULL;")]),t._v(" 定义了一个名为"),s("code",[t._v("V")]),t._v("的局部变量("),s("code",[t._v("V")]),t._v("是宏的参数之一),类型为"),s("code",[t._v("ListNode*")]),t._v(",并将其初始化为"),s("code",[t._v("NULL")]),t._v("。这个变量用于在循环体中引用当前节点,让使用者能够访问或操作当前的链表节点。")]),t._v(" "),s("li",[s("code",[t._v("for(V = _node = L->S; _node != NULL; V = _node = _node->M)")]),t._v(" 初始化一个"),s("code",[t._v("for")]),t._v("循环,开始于链表的起始节点("),s("code",[t._v("L->S")]),t._v("),并持续到链表的末尾("),s("code",[t._v("_node != NULL")]),t._v(")。循环的每一步都将"),s("code",[t._v("_node")]),t._v("移动到下一个节点("),s("code",[t._v("_node->M")]),t._v("),同时也将"),s("code",[t._v("V")]),t._v("设置为当前节点,以便于使用。")])]),t._v(" "),s("p",[t._v("这个宏的设计允许在不知道链表具体实现细节的情况下,通过一个简洁的方式遍历链表。举个例子,如果你有一个链表"),s("code",[t._v("list")]),t._v(",它的起始节点为"),s("code",[t._v("head")]),t._v(",每个节点都有一个名为"),s("code",[t._v("next")]),t._v("的指针指向下一个节点,你可以使用"),s("code",[t._v("LIST_FOREACH")]),t._v("宏来遍历这个链表,如下所示:")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("LIST_FOREACH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" head"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在这里可以访问 cur 来操作当前节点")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("这里,"),s("code",[t._v("cur")]),t._v("就是循环中用来引用当前节点的变量,你可以通过它访问或修改当前节点的数据。")]),t._v(" "),s("p",[t._v("需要注意的是,这种宏的使用方式可能在某些编译器或代码分析工具中导致警告,因为它在宏内部定义了局部变量。此外,由于它使用了宏,调试可能会比较困难,错误信息可能不会直接指向问题的根源。不过,这种方式在提高代码可读性和减少重复代码方面是非常有效的。")]),t._v(" "),s("h3",{attrs:{id:"_1-5-void类型指针"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-5-void类型指针"}},[t._v("#")]),t._v(" 1.5 void类型指针")]),t._v(" "),s("p",[s("code",[t._v("void")]),t._v("类型的指针在C语言中扮演着非常重要的角色。"),s("code",[t._v("void")]),t._v("指针可以指向任何类型的数据,这使得它成为一种非常灵活的工具,特别是在需要处理多种数据类型但又不想在编码时指定具体类型的情况下。以下是"),s("code",[t._v("void")]),t._v("指针的一些主要用途:")]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("泛型编程")])])]),t._v(" "),s("p",[s("code",[t._v("void")]),t._v("指针的一个主要用途是实现泛型编程。由于"),s("code",[t._v("void")]),t._v("指针可以指向任何类型的数据,它可以用来编写可以处理多种数据类型的函数和数据结构。例如,标准库函数"),s("code",[t._v("qsort")]),t._v("就使用"),s("code",[t._v("void")]),t._v("指针来排序各种不同类型的数组。")]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[s("strong",[t._v("内存操作函数")])])]),t._v(" "),s("p",[t._v("C语言的标准库中有几个用于内存操作的函数,如"),s("code",[t._v("malloc")]),t._v("、"),s("code",[t._v("calloc")]),t._v("、"),s("code",[t._v("realloc")]),t._v("和"),s("code",[t._v("free")]),t._v(",这些函数都使用"),s("code",[t._v("void")]),t._v("指针。这使得它们可以用于分配和释放任何类型的数据的内存空间。")]),t._v(" "),s("ol",{attrs:{start:"3"}},[s("li",[s("strong",[t._v("回调函数")])])]),t._v(" "),s("p",[t._v("在使用回调函数时,"),s("code",[t._v("void")]),t._v("指针常被用来传递用户自定义的数据给回调函数。这些数据可以是任何类型,使用者在回调函数中可以根据需要将"),s("code",[t._v("void")]),t._v("指针转换回原始类型的指针来使用。")]),t._v(" "),s("ol",{attrs:{start:"4"}},[s("li",[s("strong",[t._v("接口和抽象层")])])]),t._v(" "),s("p",[t._v("在设计需要抽象化处理的接口时,"),s("code",[t._v("void")]),t._v("指针提供了一种方便的方式来隐藏具体的实现细节。这种方式常见于各种库的设计中,特别是那些需要处理多种数据类型或提供高度抽象化的库。")]),t._v(" "),s("p",[s("strong",[t._v("注意事项")])]),t._v(" "),s("p",[t._v("虽然"),s("code",[t._v("void")]),t._v("指针非常灵活和有用,但使用它们时也需要格外小心:")]),t._v(" "),s("ul",[s("li",[t._v("在解引用"),s("code",[t._v("void")]),t._v("指针之前,必须将它转换为合适的类型的指针。"),s("code",[t._v("void")]),t._v("指针本身不能直接被解引用,因为编译器不知道它指向的对象的类型和大小。")]),t._v(" "),s("li",[t._v("转换"),s("code",[t._v("void")]),t._v("指针时需要确保转换的目标类型正确,错误的类型转换可能导致未定义行为。")]),t._v(" "),s("li",[t._v("在某些情况下,过度依赖"),s("code",[t._v("void")]),t._v("指针可能会降低代码的可读性和安全性。尽可能使用具体的类型可以帮助编译器更好地进行类型检查。")])]),t._v(" "),s("p",[t._v("综上所述,"),s("code",[t._v("void")]),t._v("类型的指针是C语言中一个非常强大的特性,它为编程提供了极大的灵活性,但也需要谨慎使用。")]),t._v(" "),s("h2",{attrs:{id:"_2-附加题"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-附加题"}},[t._v("#")]),t._v(" 2. 附加题")]),t._v(" "),s("h3",{attrs:{id:"_2-0-改进list-clear-destroy"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-改进list-clear-destroy"}},[t._v("#")]),t._v(" 2.0 改进"),s("code",[t._v("List_clear_destroy")])]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_clear_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"List is NULL."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("LIST_FOREACH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// printf("freeing: %s\\n", (char *)cur->value);')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nerror"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"_2-1-单向与双向链表"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-单向与双向链表"}},[t._v("#")]),t._v(" 2.1 单向与双向链表")]),t._v(" "),s("p",[t._v("双向链表和单向链表是两种基本的数据结构,它们在数据组织和操作上各有特点。理解它们的优势和劣势可以帮助在特定场景下做出更合适的选择。")]),t._v(" "),s("h3",{attrs:{id:"单向链表"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#单向链表"}},[t._v("#")]),t._v(" 单向链表")]),t._v(" "),s("p",[t._v("单向链表是由一系列节点组成的链表,每个节点都包含数据部分和一个指向下一个节点的指针。它的特点和优势包括:")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("简单")]),t._v(":数据结构相对简单,易于实现和理解。")]),t._v(" "),s("li",[s("strong",[t._v("动态大小")]),t._v(":链表可以根据需要动态增长和收缩。")]),t._v(" "),s("li",[s("strong",[t._v("高效的插入和删除")]),t._v(":在链表头部或已知节点后插入和删除操作效率高,时间复杂度为O(1)。")]),t._v(" "),s("li",[s("strong",[t._v("内存利用率")]),t._v(":只要有足够的内存碎片,就可以分配新节点,无需连续的内存空间。")])]),t._v(" "),s("p",[t._v("单向链表的主要劣势是:")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("单向遍历")]),t._v(":只能从头到尾遍历,找到特定节点或者在尾部插入新节点的效率较低,特别是在链表较长时。")]),t._v(" "),s("li",[s("strong",[t._v("无法直接访问前一个节点")]),t._v(":这限制了某些操作的效率,比如删除当前节点(需要访问前一个节点的指针)。")])]),t._v(" "),s("h3",{attrs:{id:"双向链表"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#双向链表"}},[t._v("#")]),t._v(" 双向链表")]),t._v(" "),s("p",[t._v("双向链表中的每个节点除了包含数据部分和指向下一个节点的指针外,还包含一个指向前一个节点的指针。它的优势包括:")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("双向遍历")]),t._v(":可以从头到尾,也可以从尾到头遍历链表,提供了更大的灵活性。")]),t._v(" "),s("li",[s("strong",[t._v("高效的节点操作")]),t._v(":在已知节点的情况下,插入和删除操作效率高,无需遍历链表就可以直接删除节点或在任意位置插入新节点,因为可以直接访问前一个节点。")])]),t._v(" "),s("p",[t._v("双向链表的主要劣势是:")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("更高的内存消耗")]),t._v(":每个节点需要额外存储一个指向前一个节点的指针。")]),t._v(" "),s("li",[s("strong",[t._v("复杂性")]),t._v(":在进行插入和删除操作时,需要更新更多的指针,增加了实现的复杂度。")])]),t._v(" "),s("h3",{attrs:{id:"选择依据"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#选择依据"}},[t._v("#")]),t._v(" 选择依据")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("空间还是时间")]),t._v(":如果内存空间非常宝贵,且不需要频繁地进行插入、删除或反向遍历等操作,单向链表可能更合适。双向链表虽然在某些操作上更高效,但代价是更高的内存消耗。")]),t._v(" "),s("li",[s("strong",[t._v("操作的类型")]),t._v(":如果需要频繁地在链表中间插入或删除节点,或者需要从两个方向遍历链表,双向链表提供了更好的性能和灵活性。")]),t._v(" "),s("li",[s("strong",[t._v("实现的复杂度")]),t._v(":如果希望保持数据结构的简单性,以简化代码的维护和调试,单向链表可能是更好的选择。")])]),t._v(" "),s("p",[t._v("总的来说,没有绝对的“最佳”选择,只有最适合特定需求和场景的选择。理解双向链表和单向链表的优缺点可以帮助你根据实际情况做出明智的决策。")]),t._v(" "),s("h3",{attrs:{id:"_2-2-双向链表的限制"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-双向链表的限制"}},[t._v("#")]),t._v(" 2.2 双向链表的限制")]),t._v(" "),s("p",[t._v("双向链表确实提供了在节点的插入和删除操作上的高效性,特别是在你已经定位到目标节点的情况下。这种数据结构允许每个节点直接链接到其前后节点,从而使得添加或移除节点成为相对简单的操作。然而,双向链表并非没有限制,以下是它们的一些主要限制和缺点:")]),t._v(" "),s("h3",{attrs:{id:"_1-遍历速度"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-遍历速度"}},[t._v("#")]),t._v(" 1. "),s("strong",[t._v("遍历速度")])]),t._v(" "),s("ul",[s("li",[t._v("尽管双向链表允许从两个方向进行遍历,但遍历本身相比于数组和其他连续存储的数据结构通常较慢。这是因为链表中的元素在内存中可能分布不连续,这使得CPU缓存的利用效率较低,导致缓存利用率低下。")])]),t._v(" "),s("h3",{attrs:{id:"_2-访问特定元素"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-访问特定元素"}},[t._v("#")]),t._v(" 2. "),s("strong",[t._v("访问特定元素")])]),t._v(" "),s("ul",[s("li",[t._v("访问链表中的特定元素(特别是随机访问)比数组慢得多。在数组中,随机访问的时间复杂度为O(1),而在双向链表中,即使是使用最优的路径,时间复杂度也为O(n),因为可能需要从头或尾开始遍历链表来找到目标元素。")])]),t._v(" "),s("h3",{attrs:{id:"_3-内存开销"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-内存开销"}},[t._v("#")]),t._v(" 3. "),s("strong",[t._v("内存开销")])]),t._v(" "),s("ul",[s("li",[t._v("双向链表的每个节点都需要额外的内存空间来存储前驱和后继节点的指针,这意味着与单向链表相比,它们消耗更多的内存。对于内存敏感的应用,这可能成为一个问题。")])]),t._v(" "),s("h3",{attrs:{id:"_4-实现复杂性"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-实现复杂性"}},[t._v("#")]),t._v(" 4. "),s("strong",[t._v("实现复杂性")])]),t._v(" "),s("ul",[s("li",[t._v("相比于单向链表,双向链表的插入和删除操作需要更新更多的指针(前驱和后继),这增加了实现的复杂性和出错的可能性。")])]),t._v(" "),s("h3",{attrs:{id:"_2-3-实现复制、连接、分割"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-实现复制、连接、分割"}},[t._v("#")]),t._v(" 2.3 实现复制、连接、分割")]),t._v(" "),s("p",[t._v("使用strdup初始化字符串而不是直接赋值(这样可以free,而不是const)")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[t._v("test1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strdup")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test1 data"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ntest2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strdup")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test2 data"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\ntest3 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strdup")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test3 data"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("实现新功能源代码:")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_copy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"List is NULL."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("new_list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check_mem")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("new_list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("LIST_FOREACH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 复制字符串。注意:strdup在内存分配失败时返回NULL")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("copy_of_value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("strdup")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("copy_of_value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 处理内存分配失败的情况")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("new_list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("new_list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" copy_of_value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 如果当前节点的value为NULL,也可以选择将NULL推入新列表")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("new_list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" new_list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nerror"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_join")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("second"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" second"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"One of the lists is NULL."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("second"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 第二个链表为空,无需操作。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" second"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 连接两个链表。")]),t._v("\n second"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" second"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 如果第一个链表为空,直接设置首尾指针。")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" second"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" second"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nerror"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nList "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_split")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"List or node is NULL."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n List "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("new_list "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("check_mem")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("new_list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("cur "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("new_list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" cur"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("prev"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("free")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cur"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n cur "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("count"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("last"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("count "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" new_list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nerror"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("测试代码:")]),t._v(" "),s("div",{staticClass:"language-c extra-class"},[s("pre",{pre:!0,attrs:{class:"language-c"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_copy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 保证有数据")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" test1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" test2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" test3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list_copy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_copy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list_copy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Failed to copy list."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list_copy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Copy list has wrong count."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_clear_destroy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list_copy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_join")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n list_second "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list_second"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" test3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" count1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_join")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" list_second"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" count2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list_second"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("count1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" count2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Join list has wrong count."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_last")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" test3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Joined list has wrong last element."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("test_split")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ListNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" list"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("first"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("next"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test2")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" count1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n list_split "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_split")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Original list has wrong count after split."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list_split"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" count1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"New list has wrong count after split."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mu_assert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("List_first")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("list_split"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" test2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Split list has wrong first element."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("NULL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/79.7cd9d8f4.js b/assets/js/79.7cd9d8f4.js new file mode 100644 index 0000000..7773c1d --- /dev/null +++ b/assets/js/79.7cd9d8f4.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[79],{435:function(t,e,s){"use strict";s.r(e);var r=s(14),i=Object(r.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"the-missing-semester"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#the-missing-semester"}},[t._v("#")]),t._v(" The Missing Semester")]),t._v(" "),e("h2",{attrs:{id:"_2024-03-14-1-the-shell"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-14-1-the-shell"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.14-1.The Shell.html"}},[t._v("2024.03.14-1. The Shell")])],1),t._v(" "),e("h2",{attrs:{id:"_2024-03-19-2-script"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-19-2-script"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.19-2.Script.html"}},[t._v("2024.03.19-2. Script")])],1),t._v(" "),e("h2",{attrs:{id:"_2024-03-20-3-vim"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-20-3-vim"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.20-3.Vim.html"}},[t._v("2024.03.20-3. Vim")])],1),t._v(" "),e("h2",{attrs:{id:"_2024-03-21-4-data-wrangling"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-21-4-data-wrangling"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.21-4.Data Wrangling.html"}},[t._v("2024.03.21-4. Data Wrangling")])],1),t._v(" "),e("h2",{attrs:{id:"_2024-03-21-5-command-line-interface"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-21-5-command-line-interface"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.21-5.Command Line Interface.html"}},[t._v("2024.03.21-5. Command Line Interface")])],1),t._v(" "),e("h2",{attrs:{id:"_2024-03-25-6-version-control-git"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-25-6-version-control-git"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.25-6.Version Control (Git).html"}},[t._v("2024.03.25-6. Version Control (Git)")])],1)])}),[],!1,null,null,null);e.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/80.a67aaeeb.js b/assets/js/80.a67aaeeb.js new file mode 100644 index 0000000..81d82e6 --- /dev/null +++ b/assets/js/80.a67aaeeb.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[80],{436:function(s,a,t){"use strict";t.r(a);var e=t(14),r=Object(e.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h1",{attrs:{id:"_2024-03-14-1-the-shell"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-14-1-the-shell"}},[s._v("#")]),s._v(" 2024.03.14-1. The Shell")]),s._v(" "),a("h2",{attrs:{id:"_1-echo"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-echo"}},[s._v("#")]),s._v(" 1. echo")]),s._v(" "),a("p",[a("code",[s._v("echo")]),s._v("  程序将该参数打印出来。 shell 基于空格分割命令并进行解析,然后执行第一个单词代表的程序,并将后续的单词作为程序可以访问的参数。如果您希望传递的参数中包含空格(例如一个名为 My Photos 的文件夹),您要么用使用单引号,双引号将其包裹起来,要么使用转义符号  "),a("code",[s._v("\\")]),s._v("  进行处理("),a("code",[s._v("My\\ Photos")]),s._v(")。")]),s._v(" "),a("h2",{attrs:{id:"_2-cd"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-cd"}},[s._v("#")]),s._v(" 2. cd")]),s._v(" "),a("p",[s._v("切换到上次访问的目录:使用  cd -  可以切换到上次访问的目录。")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("cd")]),s._v(" -\n")])])]),a("h2",{attrs:{id:"_3-在程序间创建连接"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-在程序间创建连接"}},[s._v("#")]),s._v(" 3. 在程序间创建连接")]),s._v(" "),a("p",[s._v("在 shell 中,程序有两个主要的“流”:它们的输入流和输出流。 当程序尝试读取信息时,它们会从输入流中进行读取,当程序打印信息时,它们会将信息输出到输出流中。 通常,一个程序的输入输出流都是您的终端。也就是,您的键盘作为输入,显示器作为输出。 但是,我们也可以重定向这些流!")]),s._v(" "),a("p",[s._v("最简单的重定向是  "),a("code",[s._v("< file")]),s._v("  和  "),a("code",[s._v("> file")]),s._v("。这两个命令可以将程序的输入输出流分别重定向到文件:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("missing:~$ "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" hello "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" hello.txt\nmissing:~$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" hello.txt\nhello\nmissing:~$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),s._v(" hello.txt\nhello\nmissing:~$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),s._v(" hello.txt "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" hello2.txt\nmissing:~$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" hello2.txt\nhello\n")])])]),a("p",[s._v("您还可以使用  "),a("code",[s._v(">>")]),s._v("  来向一个文件追加内容。")]),s._v(" "),a("p",[s._v("使用管道( "),a("em",[s._v("pipes")]),s._v(" ),我们能够更好的利用文件重定向。 "),a("code",[s._v("|")]),s._v("  操作符允许我们将一个程序的输出和另外一个程序的输入连接起来:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("missing:~$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ls")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-l")]),s._v(" / "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("tail")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-n1")]),s._v("\ndrwxr-xr-x "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" root root "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("4096")]),s._v(" Jun "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("20")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2019")]),s._v(" var\nmissing:~$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("curl")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("--head")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("--silent")]),s._v(" google.com "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" --ignore-case content-length "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cut")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("--delimiter")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("' '")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-f2")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("219")]),s._v("\n")])])]),a("h2",{attrs:{id:"_4-clear"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_4-clear"}},[s._v("#")]),s._v(" 4. clear")]),s._v(" "),a("p",[s._v("ctrl+L")]),s._v(" "),a("h2",{attrs:{id:"_5-权限"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5-权限"}},[s._v("#")]),s._v(" 5. 权限")]),s._v(" "),a("p",[s._v("例如,您笔记本电脑的屏幕亮度写在  "),a("code",[s._v("brightness")]),s._v("  文件中,它位于 "),a("code",[s._v("/sys/class/backlight")])]),s._v(" "),a("p",[s._v("通过将数值写入该文件,我们可以改变屏幕的亮度。现在,蹦到您脑袋里的第一个想法可能是:")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sudo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("find")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-L")]),s._v(" /sys/class/backlight "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-maxdepth")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-name")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'*brightness*'")]),s._v("\n/sys/class/backlight/thinkpad_screen/brightness\n$ "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("cd")]),s._v(" /sys/class/backlight/thinkpad_screen\n$ "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sudo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("3")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" brightness\nAn error occurred "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("while")]),s._v(" redirecting "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("file")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v("'brightness'")]),s._v("\nopen: Permission denied\n")])])]),a("p",[s._v("出乎意料的是,我们还是得到了一个错误信息。毕竟,我们已经使用了  "),a("code",[s._v("sudo")]),s._v("  命令!关于 shell,有件事我们必须要知道。"),a("code",[s._v("|")]),s._v("、"),a("code",[s._v(">")]),s._v("、和  "),a("code",[s._v("<")]),s._v("  是通过 shell 执行的,而不是被各个程序单独执行。 "),a("code",[s._v("echo")]),s._v("  等程序并不知道  "),a("code",[s._v("|")]),s._v("  的存在,它们只知道从自己的输入输出流中进行读写。 对于上面这种情况,"),a("em",[s._v("shell")]),s._v(" (权限为您的当前用户) 在设置  "),a("code",[s._v("sudo echo")]),s._v("  前尝试打开 brightness 文件并写入,但是系统拒绝了 shell 的操作因为此时 shell 不是根用户。")]),s._v(" "),a("p",[s._v("明白这一点后,我们可以这样操作:")]),s._v(" "),a("p",[a("code",[s._v("$ echo 3 | sudo tee brightness")])]),s._v(" "),a("p",[s._v("因为打开  "),a("code",[s._v("/sys")]),s._v("  文件的是  "),a("code",[s._v("tee")]),s._v("  这个程序,并且该程序以  "),a("code",[s._v("root")]),s._v("  权限在运行,因此操作可以进行。 这样您就可以在  "),a("code",[s._v("/sys")]),s._v("  中愉快地玩耍了,例如修改系统中各种 LED 的状态(路径可能会有所不同):")]),s._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("$ "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("sudo")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("tee")]),s._v(" /sys/class/leds/input6::scrolllock/brightness\n")])])]),a("h2",{attrs:{id:"_6-单引号与双引号"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_6-单引号与双引号"}},[s._v("#")]),s._v(" 6. 单引号与双引号")]),s._v(" "),a("p",[s._v("单引号是全引用,被单引号括起的内容不管是常量还是变量都不会发生替换。")]),s._v(" "),a("p",[s._v("也就是说单引号定义字符串所见即所得,将单引号内的内容输出,看到的是什么就会输出什么。")]),s._v(" "),a("p",[s._v("双引号引用的内容,如果内容中有命令、变量等,会先把变量、命令解析出结果,然后在输出最终内容。双引号是部分引用,被双引号括起的内容常量还是常量,变量则会发生替换,替换成变量内容。")])])}),[],!1,null,null,null);a.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/81.2a1f580e.js b/assets/js/81.2a1f580e.js new file mode 100644 index 0000000..1c6fc2f --- /dev/null +++ b/assets/js/81.2a1f580e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[81],{439:function(_,v,e){"use strict";e.r(v);var r=e(14),t=Object(r.a)({},(function(){var _=this,v=_._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":_.$parent.slotKey}},[v("h1",{attrs:{id:"_2024-03-20-3-vim"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-20-3-vim"}},[_._v("#")]),_._v(" 2024.03.20-3. Vim")]),_._v(" "),v("h1",{attrs:{id:"_1-编辑模式"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_1-编辑模式"}},[_._v("#")]),_._v(" 1. 编辑模式")]),_._v(" "),v("p",[_._v("Vim 的设计以大多数时间都花在阅读、浏览和进行少量编辑改动为基础,因此它具有多种操作模式:")]),_._v(" "),v("ul",[v("li",[_._v("正常模式:在文件中四处移动光标进行修改")]),_._v(" "),v("li",[_._v("插入模式:插入文本")]),_._v(" "),v("li",[_._v("替换模式:替换文本")]),_._v(" "),v("li",[_._v("可视化模式(一般,行,块):选中文本块")]),_._v(" "),v("li",[_._v("命令模式:用于执行命令")])]),_._v(" "),v("p",[_._v("在不同的操作模式下,键盘敲击的含义也不同。比如,"),v("code",[_._v("x")]),_._v("  在插入模式会插入字母  "),v("code",[_._v("x")]),_._v(",但是在正常模式 会删除当前光标所在的字母,在可视模式下则会删除选中文块。")]),_._v(" "),v("p",[_._v("在默认设置下,Vim 会在左下角显示当前的模式。Vim 启动时的默认模式是正常模式。通常你会把大部分 时间花在正常模式和插入模式。")]),_._v(" "),v("p",[_._v("你可以按下  "),v("code",[_._v("")]),_._v("(退出键)从任何其他模式返回正常模式。在正常模式,键入  "),v("code",[_._v("i")]),_._v("  进入插入 模式,"),v("code",[_._v("R")]),_._v("  进入替换模式,"),v("code",[_._v("v")]),_._v("  进入可视(一般)模式,"),v("code",[_._v("V")]),_._v("  进入可视(行)模式,"),v("code",[_._v("")]),_._v(" (Ctrl-V, 有时也写作  "),v("code",[_._v("^V")]),_._v(")进入可视(块)模式,"),v("code",[_._v(":")]),_._v("  进入命令模式。")]),_._v(" "),v("p",[_._v("因为你会在使用 Vim 时大量使用  "),v("code",[_._v("")]),_._v("  键,所以可以考虑把大小写锁定键重定义成  "),v("code",[_._v("")]),_._v("  键("),v("a",{attrs:{href:"https://vim.fandom.com/wiki/Map_caps_lock_to_escape_in_macOS",target:"_blank",rel:"noopener noreferrer"}},[_._v("MacOS 教程"),v("OutboundLink")],1),_._v(")。")]),_._v(" "),v("h1",{attrs:{id:"_2-基本操作"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_2-基本操作"}},[_._v("#")]),_._v(" 2. 基本操作")]),_._v(" "),v("h2",{attrs:{id:"_2-1-插入文本"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-插入文本"}},[_._v("#")]),_._v(" 2.1 插入文本")]),_._v(" "),v("p",[_._v("在正常模式,键入  "),v("code",[_._v("i")]),_._v("  进入插入模式。现在 Vim 跟很多其他的编辑器一样,直到你键入  "),v("code",[_._v("")]),_._v("  返回正常模式。你只需要掌握这一点和上面介绍的所有基础知识就可以使用 Vim 来编辑文件了 (虽然如果你一直停留在插入模式内不一定高效)。")]),_._v(" "),v("h2",{attrs:{id:"_2-2-缓存-标签页-窗口"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-缓存-标签页-窗口"}},[_._v("#")]),_._v(" 2.2 缓存, 标签页, 窗口")]),_._v(" "),v("p",[_._v("Vim 会维护一系列打开的文件,称为“缓存”。一个 Vim 会话包含一系列标签页,每个标签页包含 一系列窗口(分隔面板)。每个窗口显示一个缓存。跟网页浏览器等其他你熟悉的程序不一样的是, 缓存和窗口不是一一对应的关系;窗口只是视角。一个缓存可以在"),v("em",[_._v("多个")]),_._v("窗口打开,甚至在同一 个标签页内的多个窗口打开。这个功能其实很好用,比如在查看同一个文件的不同部分的时候。")]),_._v(" "),v("p",[_._v("Vim 默认打开一个标签页,这个标签也包含一个窗口。")]),_._v(" "),v("h2",{attrs:{id:"_2-3-命令行"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-命令行"}},[_._v("#")]),_._v(" 2.3 命令行")]),_._v(" "),v("p",[_._v("在正常模式下键入  "),v("code",[_._v(":")]),_._v("  进入命令行模式。 在键入  "),v("code",[_._v(":")]),_._v("  后,你的光标会立即跳到屏幕下方的命令行。 这个模式有很多功能,包括打开,保存,关闭文件,以及  "),v("a",{attrs:{href:"https://twitter.com/iamdevloper/status/435555976687923200",target:"_blank",rel:"noopener noreferrer"}},[_._v("退出 Vim"),v("OutboundLink")],1),_._v("。")]),_._v(" "),v("ul",[v("li",[v("code",[_._v(":q")]),_._v("  退出(关闭窗口)")]),_._v(" "),v("li",[v("code",[_._v(":w")]),_._v("  保存(写)")]),_._v(" "),v("li",[v("code",[_._v(":wq")]),_._v("  保存然后退出")]),_._v(" "),v("li",[v("code",[_._v(":e {文件名}")]),_._v("  打开要编辑的文件")]),_._v(" "),v("li",[v("code",[_._v(":ls")]),_._v("  显示打开的缓存")]),_._v(" "),v("li",[v("code",[_._v(":help {标题}")]),_._v("  打开帮助文档\n"),v("ul",[v("li",[v("code",[_._v(":help :w")]),_._v("  打开  "),v("code",[_._v(":w")]),_._v("  命令的帮助文档")]),_._v(" "),v("li",[v("code",[_._v(":help w")]),_._v("  打开  "),v("code",[_._v("w")]),_._v("  移动的帮助文档")])])])]),_._v(" "),v("h1",{attrs:{id:"_3-vim-的接口其实是一种编程语言"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_3-vim-的接口其实是一种编程语言"}},[_._v("#")]),_._v(" 3. Vim 的接口其实是一种编程语言")]),_._v(" "),v("h2",{attrs:{id:"_3-1-移动"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-移动"}},[_._v("#")]),_._v(" 3.1 移动")]),_._v(" "),v("p",[_._v("多数时候你会在正常模式下,使用移动命令在缓存中导航。在 Vim 里面移动也被称为 “名词”, 因为它们指向文字块。")]),_._v(" "),v("ul",[v("li",[_._v("基本移动: "),v("code",[_._v("hjkl")]),_._v(" (左, 下, 上, 右)")]),_._v(" "),v("li",[_._v("词: "),v("code",[_._v("w")]),_._v(" (下一个词), "),v("code",[_._v("b")]),_._v(" (词初), "),v("code",[_._v("e")]),_._v(" (词尾)")]),_._v(" "),v("li",[_._v("行: "),v("code",[_._v("0")]),_._v(" (行初), "),v("code",[_._v("^")]),_._v(" (第一个非空格字符), "),v("code",[_._v("$")]),_._v(" (行尾)")]),_._v(" "),v("li",[_._v("屏幕: "),v("code",[_._v("H")]),_._v(" (屏幕首行), "),v("code",[_._v("M")]),_._v(" (屏幕中间), "),v("code",[_._v("L")]),_._v(" (屏幕底部)")]),_._v(" "),v("li",[_._v("翻页: "),v("code",[_._v("Ctrl-u")]),_._v(" (上翻), "),v("code",[_._v("Ctrl-d")]),_._v(" (下翻)")]),_._v(" "),v("li",[_._v("文件: "),v("code",[_._v("gg")]),_._v(" (文件头), "),v("code",[_._v("G")]),_._v(" (文件尾)")]),_._v(" "),v("li",[_._v("行数: "),v("code",[_._v(":{行数}")]),_._v("  或者  "),v("code",[_._v("{行数}G")]),_._v(" ({行数}为行数)")]),_._v(" "),v("li",[_._v("杂项: "),v("code",[_._v("%")]),_._v(" (找到配对,比如括号或者 /* */ 之类的注释对)")]),_._v(" "),v("li",[_._v("查找: "),v("code",[_._v("f{字符}")]),_._v(", "),v("code",[_._v("t{字符}")]),_._v(", "),v("code",[_._v("F{字符}")]),_._v(", "),v("code",[_._v("T{字符}")]),_._v(" "),v("ul",[v("li",[_._v("查找/到 向前/向后 在本行的{字符}")]),_._v(" "),v("li",[v("code",[_._v(",")]),_._v(" / "),v("code",[_._v(";")]),_._v("  用于导航匹配")])])]),_._v(" "),v("li",[_._v("搜索: "),v("code",[_._v("/{正则表达式}")]),_._v(", "),v("code",[_._v("n")]),_._v(" / "),v("code",[_._v("N")]),_._v("  用于导航匹配")])]),_._v(" "),v("h2",{attrs:{id:"_3-2-编辑"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-编辑"}},[_._v("#")]),_._v(" 3.2 编辑")]),_._v(" "),v("p",[_._v("所有你需要用鼠标做的事, 你现在都可以用键盘:采用编辑命令和移动命令的组合来完成。 这就是 Vim 的界面开始看起来像一个程序语言的时候。Vim 的编辑命令也被称为 “动词”, 因为动词可以施动于名词。")]),_._v(" "),v("ul",[v("li",[v("code",[_._v("i")]),_._v("  进入插入模式\n"),v("ul",[v("li",[_._v("但是对于操纵/编辑文本,不单想用退格键完成")])])]),_._v(" "),v("li",[v("code",[_._v("O")]),_._v(" / "),v("code",[_._v("o")]),_._v("  在之上/之下插入行")]),_._v(" "),v("li",[v("code",[_._v("d{移动命令}")]),_._v("  删除 {移动命令}\n"),v("ul",[v("li",[_._v("例如,"),v("code",[_._v("dw")]),_._v("  删除词, "),v("code",[_._v("d$")]),_._v("  删除到行尾, "),v("code",[_._v("d0")]),_._v("  删除到行头。")])])]),_._v(" "),v("li",[v("code",[_._v("c{移动命令}")]),_._v("  改变 {移动命令}\n"),v("ul",[v("li",[_._v("例如,"),v("code",[_._v("cw")]),_._v("  改变词")]),_._v(" "),v("li",[_._v("比如  "),v("code",[_._v("d{移动命令}")]),_._v("  再  "),v("code",[_._v("i")])])])]),_._v(" "),v("li",[v("code",[_._v("x")]),_._v("  删除字符(等同于  "),v("code",[_._v("dl")]),_._v(")")]),_._v(" "),v("li",[v("code",[_._v("s")]),_._v("  替换字符(等同于  "),v("code",[_._v("xi")]),_._v(")")]),_._v(" "),v("li",[_._v("可视化模式 + 操作\n"),v("ul",[v("li",[_._v("选中文字, "),v("code",[_._v("d")]),_._v("  删除 或者  "),v("code",[_._v("c")]),_._v("  改变")])])]),_._v(" "),v("li",[v("code",[_._v("u")]),_._v("  撤销, "),v("code",[_._v("")]),_._v("  重做")]),_._v(" "),v("li",[v("code",[_._v("y")]),_._v("  复制 / “yank” (其他一些命令比如  "),v("code",[_._v("d")]),_._v("  也会复制)"),v("code",[_._v("yy")]),_._v(" 复制一行")]),_._v(" "),v("li",[v("code",[_._v("p")]),_._v("  粘贴")]),_._v(" "),v("li",[_._v("更多值得学习的: 比如  "),v("code",[_._v("~")]),_._v("  改变字符的大小写")])]),_._v(" "),v("h2",{attrs:{id:"_3-3-计数"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-计数"}},[_._v("#")]),_._v(" 3.3 计数")]),_._v(" "),v("p",[_._v("你可以用一个计数来结合“名词”和“动词”,这会执行指定操作若干次。")]),_._v(" "),v("ul",[v("li",[v("code",[_._v("3w")]),_._v("  向后移动三个词")]),_._v(" "),v("li",[v("code",[_._v("5j")]),_._v("  向下移动 5 行")]),_._v(" "),v("li",[v("code",[_._v("7dw")]),_._v("  删除 7 个词")])]),_._v(" "),v("h2",{attrs:{id:"_3-4-修饰语"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-修饰语"}},[_._v("#")]),_._v(" 3.4 修饰语")]),_._v(" "),v("p",[_._v("你可以用修饰语改变“名词”的意义。修饰语有  "),v("code",[_._v("i")]),_._v(",表示“内部”或者“在内”,和  "),v("code",[_._v("a")]),_._v(", 表示“周围”。")]),_._v(" "),v("ul",[v("li",[v("code",[_._v("ci(")]),_._v("  改变当前括号内的内容")]),_._v(" "),v("li",[v("code",[_._v("ci[")]),_._v("  改变当前方括号内的内容")]),_._v(" "),v("li",[v("code",[_._v("da'")]),_._v("  删除一个单引号字符串, 包括周围的单引号")])]),_._v(" "),v("h1",{attrs:{id:"_4-自定义-vim"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_4-自定义-vim"}},[_._v("#")]),_._v(" 4. 自定义 Vim")]),_._v(" "),v("p",[_._v("Vim 由一个位于  "),v("code",[_._v("~/.vimrc")]),_._v("  的文本配置文件(包含 Vim 脚本命令)。你可能会启用很多基本 设置。")]),_._v(" "),v("p",[_._v("我们提供一个文档详细的基本设置,你可以用它当作你的初始设置。我们推荐使用这个设置因为 它修复了一些 Vim 默认设置奇怪行为。  在"),v("a",{attrs:{href:"https://missing-semester-cn.github.io/2020/files/vimrc",target:"_blank",rel:"noopener noreferrer"}},[_._v("这儿"),v("OutboundLink")],1),_._v("  下载我们的设置,然后将它保存成  "),v("code",[_._v("~/.vimrc")]),_._v(".")]),_._v(" "),v("p",[_._v("Vim 能够被重度自定义,花时间探索自定义选项是值得的。你可以参考其他人的在 GitHub 上共享的设置文件,比如,你的授课人的 Vim 设置 ("),v("a",{attrs:{href:"https://github.com/anishathalye/dotfiles/blob/master/vimrc",target:"_blank",rel:"noopener noreferrer"}},[_._v("Anish"),v("OutboundLink")],1),_._v(", "),v("a",{attrs:{href:"https://github.com/jonhoo/configs/blob/master/editor/.config/nvim/init.vim",target:"_blank",rel:"noopener noreferrer"}},[_._v("Jon"),v("OutboundLink")],1),_._v(" (uses "),v("a",{attrs:{href:"https://neovim.io/",target:"_blank",rel:"noopener noreferrer"}},[_._v("neovim"),v("OutboundLink")],1),_._v("), "),v("a",{attrs:{href:"https://github.com/JJGO/dotfiles/blob/master/vim/.vimrc",target:"_blank",rel:"noopener noreferrer"}},[_._v("Jose"),v("OutboundLink")],1),_._v(")。 有很多好的博客文章也聊到了这个话题。尽量不要复制粘贴别人的整个设置文件, 而是阅读和理解它,然后采用对你有用的部分。")]),_._v(" "),v("h1",{attrs:{id:"_5-扩展-vim"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_5-扩展-vim"}},[_._v("#")]),_._v(" 5. 扩展 Vim")]),_._v(" "),v("p",[_._v("Vim 有很多扩展插件。跟很多互联网上已经过时的建议相反,你"),v("em",[_._v("不")]),_._v("需要在 Vim 使用一个插件 管理器(从 Vim 8.0 开始)。你可以使用内置的插件管理系统。只需要创建一个  "),v("code",[_._v("~/.vim/pack/vendor/start/")]),_._v("  的文件夹,然后把插件放到这里(比如通过  "),v("code",[_._v("git clone")]),_._v(")。")]),_._v(" "),v("p",[_._v("以下是一些我们最爱的插件:")]),_._v(" "),v("ul",[v("li",[v("a",{attrs:{href:"https://github.com/ctrlpvim/ctrlp.vim",target:"_blank",rel:"noopener noreferrer"}},[_._v("ctrlp.vim"),v("OutboundLink")],1),_._v(": 模糊文件查找")]),_._v(" "),v("li",[v("a",{attrs:{href:"https://github.com/mileszs/ack.vim",target:"_blank",rel:"noopener noreferrer"}},[_._v("ack.vim"),v("OutboundLink")],1),_._v(": 代码搜索")]),_._v(" "),v("li",[v("a",{attrs:{href:"https://github.com/scrooloose/nerdtree",target:"_blank",rel:"noopener noreferrer"}},[_._v("nerdtree"),v("OutboundLink")],1),_._v(": 文件浏览器")]),_._v(" "),v("li",[v("a",{attrs:{href:"https://github.com/easymotion/vim-easymotion",target:"_blank",rel:"noopener noreferrer"}},[_._v("vim-easymotion"),v("OutboundLink")],1),_._v(": 魔术操作")])]),_._v(" "),v("p",[_._v("我们尽量避免在这里提供一份冗长的插件列表。你可以查看讲师们的开源的配置文件 ("),v("a",{attrs:{href:"https://github.com/anishathalye/dotfiles",target:"_blank",rel:"noopener noreferrer"}},[_._v("Anish"),v("OutboundLink")],1),_._v(", "),v("a",{attrs:{href:"https://github.com/jonhoo/configs",target:"_blank",rel:"noopener noreferrer"}},[_._v("Jon"),v("OutboundLink")],1),_._v(", "),v("a",{attrs:{href:"https://github.com/JJGO/dotfiles",target:"_blank",rel:"noopener noreferrer"}},[_._v("Jose"),v("OutboundLink")],1),_._v(") 来看看我们使用的其他插件。 浏览  "),v("a",{attrs:{href:"https://vimawesome.com/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Vim Awesome"),v("OutboundLink")],1),_._v("  来了解一些很棒的插件。 这个话题也有很多博客文章:搜索 “best Vim plugins”。")]),_._v(" "),v("h1",{attrs:{id:"_6-vim-进阶"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_6-vim-进阶"}},[_._v("#")]),_._v(" 6. Vim 进阶")]),_._v(" "),v("p",[_._v("这里我们提供了一些展示这个编辑器能力的例子。我们无法把所有的这样的事情都教给你,但是你可以在使用中学习。一个好的对策是: 当你在使用你的编辑器的时候感觉 “一定有更好的方法来做这个”, 那么很可能真的有:上网搜寻一下。")]),_._v(" "),v("h2",{attrs:{id:"_6-1-搜索和替换"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_6-1-搜索和替换"}},[_._v("#")]),_._v(" 6.1 搜索和替换")]),_._v(" "),v("p",[v("code",[_._v(":s")]),_._v(" (替换)命令("),v("a",{attrs:{href:"http://vim.wikia.com/wiki/Search_and_replace",target:"_blank",rel:"noopener noreferrer"}},[_._v("文档"),v("OutboundLink")],1),_._v(")。")]),_._v(" "),v("ul",[v("li",[v("code",[_._v("%s/foo/bar/g")]),_._v(" "),v("ul",[v("li",[_._v("在整个文件中将 foo 全局替换成 bar")])])]),_._v(" "),v("li",[v("code",[_._v("%s/\\[.*\\](\\(.*\\))/\\1/g")]),_._v(" "),v("ul",[v("li",[_._v("将有命名的 Markdown 链接替换成简单 URLs")])])])]),_._v(" "),v("h2",{attrs:{id:"_6-2-多窗口"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_6-2-多窗口"}},[_._v("#")]),_._v(" 6.2 多窗口")]),_._v(" "),v("ul",[v("li",[_._v("用  "),v("code",[_._v(":sp")]),_._v(" / "),v("code",[_._v(":vsp")]),_._v("  来分割窗口")]),_._v(" "),v("li",[_._v("同一个缓存可以在多个窗口中显示。")])]),_._v(" "),v("h2",{attrs:{id:"_6-3-宏"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_6-3-宏"}},[_._v("#")]),_._v(" 6.3 宏")]),_._v(" "),v("ul",[v("li",[v("code",[_._v("q{字符}")]),_._v("  来开始在寄存器"),v("code",[_._v("{字符}")]),_._v("中录制宏")]),_._v(" "),v("li",[v("code",[_._v("q")]),_._v("停止录制")]),_._v(" "),v("li",[v("code",[_._v("@{字符}")]),_._v("  重放宏")]),_._v(" "),v("li",[_._v("宏的执行遇错误会停止")]),_._v(" "),v("li",[v("code",[_._v("{计数}@{字符}")]),_._v("执行一个宏{计数}次")]),_._v(" "),v("li",[_._v("宏可以递归\n"),v("ul",[v("li",[_._v("首先用"),v("code",[_._v("q{字符}q")]),_._v("清除宏")]),_._v(" "),v("li",[_._v("录制该宏,用  "),v("code",[_._v("@{字符}")]),_._v("  来递归调用该宏 (在录制完成之前不会有任何操作)")])])]),_._v(" "),v("li",[_._v("例子:将 xml 转成 json ("),v("a",{attrs:{href:"https://missing-semester-cn.github.io/2020/files/example-data.xml",target:"_blank",rel:"noopener noreferrer"}},[_._v("file"),v("OutboundLink")],1),_._v(")\n"),v("ul",[v("li",[_._v("一个有 “name” / “email” 键对象的数组")]),_._v(" "),v("li",[_._v("用一个 Python 程序?")]),_._v(" "),v("li",[_._v("用 sed / 正则表达式\n"),v("ul",[v("li",[v("code",[_._v("g/people/d")])]),_._v(" "),v("li",[v("code",[_._v("%s//{/g")])]),_._v(" "),v("li",[v("code",[_._v('%s/\\(.*\\)<\\/name>/"name": "\\1",/g')])]),_._v(" "),v("li",[_._v("…")])])]),_._v(" "),v("li",[_._v("Vim 命令 / 宏\n"),v("ul",[v("li",[v("code",[_._v("ggdd")]),_._v(", "),v("code",[_._v("Gdd")]),_._v("  删除第一行和最后一行")]),_._v(" "),v("li",[_._v("格式化最后一个元素的宏 (寄存器  "),v("code",[_._v("e")]),_._v(")\n"),v("ul",[v("li",[_._v("跳转到有  "),v("code",[_._v("")]),_._v("  的行")]),_._v(" "),v("li",[v("code",[_._v('qe^r"f>s": "fq')])])])]),_._v(" "),v("li",[_._v("格式化一个的宏\n"),v("ul",[v("li",[_._v("跳转到有  "),v("code",[_._v("")]),_._v("  的行")]),_._v(" "),v("li",[v("code",[_._v("qpS{j@eA,j@ejS},q")])])])]),_._v(" "),v("li",[_._v("格式化一个标签然后转到另外一个的宏\n"),v("ul",[v("li",[_._v("跳转到有  "),v("code",[_._v("")]),_._v("  的行")]),_._v(" "),v("li",[v("code",[_._v("qq@pjq")])])])]),_._v(" "),v("li",[_._v("执行宏到文件尾\n"),v("ul",[v("li",[v("code",[_._v("999@q")])])])]),_._v(" "),v("li",[_._v("手动移除最后的  "),v("code",[_._v(",")]),_._v("  然后加上  "),v("code",[_._v("[")]),_._v("  和  "),v("code",[_._v("]")]),_._v("  分隔符")])])])])])]),_._v(" "),v("h1",{attrs:{id:"_7-扩展资料"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#_7-扩展资料"}},[_._v("#")]),_._v(" 7. 扩展资料")]),_._v(" "),v("ul",[v("li",[v("code",[_._v("vimtutor")]),_._v("  是一个 Vim 安装时自带的教程")]),_._v(" "),v("li",[v("a",{attrs:{href:"https://vim-adventures.com/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Vim Adventures"),v("OutboundLink")],1),_._v("  是一个学习使用 Vim 的游戏")]),_._v(" "),v("li",[v("a",{attrs:{href:"http://vim.wikia.com/wiki/Vim_Tips_Wiki",target:"_blank",rel:"noopener noreferrer"}},[_._v("Vim Tips Wiki"),v("OutboundLink")],1)]),_._v(" "),v("li",[v("a",{attrs:{href:"https://vimways.org/2019/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Vim Advent Calendar"),v("OutboundLink")],1),_._v("  有很多 Vim 小技巧")]),_._v(" "),v("li",[v("a",{attrs:{href:"http://www.vimgolf.com/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Vim Golf"),v("OutboundLink")],1),_._v("  是用 Vim 的用户界面作为程序语言的  "),v("a",{attrs:{href:"https://en.wikipedia.org/wiki/Code_golf",target:"_blank",rel:"noopener noreferrer"}},[_._v("code golf"),v("OutboundLink")],1)]),_._v(" "),v("li",[v("a",{attrs:{href:"https://vi.stackexchange.com/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Vi/Vim Stack Exchange"),v("OutboundLink")],1)]),_._v(" "),v("li",[v("a",{attrs:{href:"http://vimcasts.org/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Vim Screencasts"),v("OutboundLink")],1)]),_._v(" "),v("li",[v("a",{attrs:{href:"https://pragprog.com/titles/dnvim2/",target:"_blank",rel:"noopener noreferrer"}},[_._v("Practical Vim"),v("OutboundLink")],1),_._v("(书籍)")])])])}),[],!1,null,null,null);v.default=t.exports}}]); \ No newline at end of file diff --git a/assets/js/82.ac16656d.js b/assets/js/82.ac16656d.js new file mode 100644 index 0000000..650e256 --- /dev/null +++ b/assets/js/82.ac16656d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[82],{441:function(t,s,r){"use strict";r.r(s);var a=r(14),e=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"soc-design"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#soc-design"}},[t._v("#")]),t._v(" SoC Design")]),t._v(" "),s("h2",{attrs:{id:"_1-一生一芯计划"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-一生一芯计划"}},[t._v("#")]),t._v(" "),s("RouterLink",{attrs:{to:"/Chip/Chip/1. 一生一芯计划.html"}},[t._v("1. 一生一芯计划")])],1),t._v(" "),s("h2",{attrs:{id:"_2-2024-02-21-chisel"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-2024-02-21-chisel"}},[t._v("#")]),t._v(" "),s("RouterLink",{attrs:{to:"/Chip/Chip/2. 2024.02.21-Chisel.html"}},[t._v("2. 2024.02.21-Chisel")])],1),t._v(" "),s("h2",{attrs:{id:"_3-2023-11-07-verilog语法"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-2023-11-07-verilog语法"}},[t._v("#")]),t._v(" "),s("RouterLink",{attrs:{to:"/Chip/Chip/3. 2023.11.07-Verilog语法.html"}},[t._v("3. 2023.11.07-Verilog语法")])],1)])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/83.84ac68fa.js b/assets/js/83.84ac68fa.js new file mode 100644 index 0000000..e7b3b43 --- /dev/null +++ b/assets/js/83.84ac68fa.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[83],{440:function(t,s,e){"use strict";e.r(s);var a=e(14),r=Object(a.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"_2024-02-22-bfs"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-22-bfs"}},[this._v("#")]),this._v(" 2024.02.22-BFS")]),this._v(" "),t("h2",{attrs:{id:"_2024-02-22-752-打开转盘锁-bfs"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-22-752-打开转盘锁-bfs"}},[this._v("#")]),this._v(" "),t("RouterLink",{attrs:{to:"/LeetCode/LeetCode/2024.02.22-BFS/2024.02.22-752.打开转盘锁(BFS).html"}},[this._v("2024.02.22-752.打开转盘锁(BFS)")])],1)])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/84.0ecacc6f.js b/assets/js/84.0ecacc6f.js new file mode 100644 index 0000000..d1c1108 --- /dev/null +++ b/assets/js/84.0ecacc6f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[84],{444:function(t,s,n){"use strict";n.r(s);var a=n(14),p=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-02-22-752-打开转盘锁-bfs"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-22-752-打开转盘锁-bfs"}},[t._v("#")]),t._v(" 2024.02.22-752.打开转盘锁(BFS)")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('/*\n * @lc app=leetcode.cn id=752 lang=cpp\n *\n * [752] 打开转盘锁\n *\n * https://leetcode.cn/problems/open-the-lock/description/\n *\n * algorithms\n * Medium (52.77%)\n * Likes: 653\n * Dislikes: 0\n * Total Accepted: 128.3K\n * Total Submissions: 243.1K\n * Testcase Example: \'["0201","0101","0102","1212","2002"]\\n"0202"\'\n *\n * 你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字: \'0\', \'1\', \'2\', \'3\', \'4\', \'5\', \'6\', \'7\', \'8\',\n * \'9\' 。每个拨轮可以自由旋转:例如把 \'9\' 变为 \'0\',\'0\' 变为 \'9\' 。每次旋转都只能旋转一个拨轮的一位数字。\n *\n * 锁的初始数字为 \'0000\' ,一个代表四个拨轮的数字的字符串。\n *\n * 列表 deadends 包含了一组死亡数字,一旦拨轮的数字和列表里的任何一个元素相同,这个锁将会被永久锁定,无法再被旋转。\n *\n * 字符串 target 代表可以解锁的数字,你需要给出解锁需要的最小旋转次数,如果无论如何不能解锁,返回 -1 。\n *\n *\n *\n * 示例 1:\n *\n *\n * 输入:deadends = ["0201","0101","0102","1212","2002"], target = "0202"\n * 输出:6\n * 解释:\n * 可能的移动序列为 "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202"。\n * 注意 "0000" -> "0001" -> "0002" -> "0102" -> "0202" 这样的序列是不能解锁的,\n * 因为当拨动到 "0102" 时这个锁就会被锁定。\n *\n *\n * 示例 2:\n *\n *\n * 输入: deadends = ["8888"], target = "0009"\n * 输出:1\n * 解释:把最后一位反向旋转一次即可 "0000" -> "0009"。\n *\n *\n * 示例 3:\n *\n *\n * 输入: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"],\n * target = "8888"\n * 输出:-1\n * 解释:无法旋转到目标数字且不被锁定。\n *\n *\n *\n *\n * 提示:\n *\n *\n * 1 <= deadends.length <= 500\n * deadends[i].length == 4\n * target.length == 4\n * target 不在 deadends 之中\n * target 和 deadends[i] 仅由若干位数字组成\n *\n *\n */')]),t._v("\n")])])]),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Solution")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("openLock")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("string"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("deadends"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" string target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" num "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n queue"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("string"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" q"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n set"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("string"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("visited")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("deadends"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("begin")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" deadends"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("end")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("visited"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0000"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" visited"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("end")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n q"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0000"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n visited"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("insert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0000"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("q"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("empty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" ssize "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" q"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" ssize"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" i"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n string str "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" q"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("front")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n q"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pop")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// if (visited.find(str) != visited.end())")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// continue;")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("str "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" num"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" j "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" j "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n string up "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("turnUp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n string down "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("turnDown")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("visited"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("up"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" visited"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("end")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n q"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("up"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n visited"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("insert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("up"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("visited"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("down"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" visited"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("end")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n q"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("down"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n visited"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("insert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("down"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n num"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n string "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("turnUp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("string str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" old "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" nnew "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("old "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'9'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("old "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n string newString "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n newString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" nnew"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" newString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n string "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("turnDown")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("string str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" old "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" nnew "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("old "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("old "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token char"}},[t._v("'9'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n string newString "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n newString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("index"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" nnew"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" newString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"hint"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#hint"}},[t._v("#")]),t._v(" Hint:")]),t._v(" "),s("ol",[s("li",[t._v("修改"),s("code",[t._v("string")]),t._v("的某一个字符直接使用"),s("code",[t._v("[]")]),t._v("索引修改即可")]),t._v(" "),s("li",[t._v("字符’0‘到’1‘直接加一")]),t._v(" "),s("li",[s("code",[t._v("deadends")]),t._v("中的字符串以及已经访问过的字符串应该在尝试加入队列之前就被过滤掉,以防止它们被进一步处理。而不是从队列中拿出来的时候检查是不是在"),s("code",[t._v("visited")]),t._v("中")]),t._v(" "),s("li",[t._v("起始的"),s("code",[t._v("“0000”")]),t._v("也要检查")]),t._v(" "),s("li",[t._v("使用双向 BFS 可以加快速度,但是 queue 修改为 set,如下:")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("openLock")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("string"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("deadends"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" string target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n unordered_set"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("string"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dead")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("deadends"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("begin")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" deadends"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("end")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n unordered_set"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("string"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" begin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" end"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("set1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("set2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("dead"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0000"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" dead"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("end")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" dead"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" dead"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("end")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" step "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n begin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("insert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0000"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n end"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("insert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("begin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("empty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("end"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("empty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 优化搜索,总是从较小的集合开始扩展")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("begin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" end"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n set1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("end"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n set2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("begin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n set1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("begin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n set2 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("end"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n unordered_set"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("string"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" temp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("auto")]),t._v(" it "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" set1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("begin")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" it "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" set1"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("end")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),t._v("it"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n string str "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("it"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("set2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" set2"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("end")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("dead"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" dead"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("end")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("continue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n dead"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("insert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 标记为已访问")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" j "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" j "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),t._v("j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n string up "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("turnUp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n string down "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("turnDown")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("str"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("dead"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("up"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" dead"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("end")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n temp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("insert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("up"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("dead"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("down"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" dead"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("end")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n temp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("insert")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("down"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n step"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("set1 "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" temp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 更新当前正在扩展的集合")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 如果没有找到有效路径")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ol",[s("li",[t._v("创建一个临时集合("),s("code",[t._v("temp")]),t._v(")的原因是在每一轮搜索中,我们需要更新当前层次的节点。由于在遍历当前层次的节点时不能直接修改正在遍历的集合(这会影响迭代器的有效性),因此我们先将新发现的节点存储在一个临时集合中。在当前层次的所有节点都遍历完毕后,我们再用这个临时集合来更新主集合,为下一轮搜索做准备。")])])])}),[],!1,null,null,null);s.default=p.exports}}]); \ No newline at end of file diff --git a/assets/js/85.8fdb2913.js b/assets/js/85.8fdb2913.js new file mode 100644 index 0000000..301ecc7 --- /dev/null +++ b/assets/js/85.8fdb2913.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[85],{447:function(t,e,a){"use strict";a.r(e);var r=a(14),s=Object(r.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"_2024-03-05-二叉树"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-05-二叉树"}},[t._v("#")]),t._v(" 2024.03.05-二叉树")]),t._v(" "),e("h2",{attrs:{id:"_2024-03-05-104-二叉树的最大深度"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-05-104-二叉树的最大深度"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/LeetCode/LeetCode/2024.03.05-二叉树/2024.03.05-104.二叉树的最大深度.html"}},[t._v("2024.03.05-104.二叉树的最大深度")])],1),t._v(" "),e("h2",{attrs:{id:"_2024-03-05-144-二叉树的前序遍历"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-05-144-二叉树的前序遍历"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/LeetCode/LeetCode/2024.03.05-二叉树/2024.03.05-144.二叉树的前序遍历.html"}},[t._v("2024.03.05-144.二叉树的前序遍历")])],1),t._v(" "),e("h2",{attrs:{id:"_2024-03-05-543-二叉树的直径"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-05-543-二叉树的直径"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/LeetCode/LeetCode/2024.03.05-二叉树/2024.03.05-543.二叉树的直径.html"}},[t._v("2024.03.05-543.二叉树的直径")])],1)])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/86.c690cc84.js b/assets/js/86.c690cc84.js new file mode 100644 index 0000000..69b81eb --- /dev/null +++ b/assets/js/86.c690cc84.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[86],{445:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-03-05-104-二叉树的最大深度"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-05-104-二叉树的最大深度"}},[t._v("#")]),t._v(" 2024.03.05-104.二叉树的最大深度")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*\n * @lc app=leetcode.cn id=104 lang=cpp\n *\n * [104] 二叉树的最大深度\n *\n * https://leetcode.cn/problems/maximum-depth-of-binary-tree/description/\n *\n * algorithms\n * Easy (77.10%)\n * Likes: 1786\n * Dislikes: 0\n * Total Accepted: 1.2M\n * Total Submissions: 1.6M\n * Testcase Example: '[3,9,20,null,null,15,7]'\n *\n * 给定一个二叉树 root ,返回其最大深度。\n *\n * 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。\n *\n *\n *\n * 示例 1:\n *\n *\n *\n *\n *\n *\n * 输入:root = [3,9,20,null,null,15,7]\n * 输出:3\n *\n *\n * 示例 2:\n *\n *\n * 输入:root = [1,null,2]\n * 输出:2\n *\n *\n *\n *\n * 提示:\n *\n *\n * 树中节点的数量在 [0, 10^4] 区间内。\n * -100 <= Node.val <= 100\n *\n *\n */")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=start")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" Definition "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" a binary tree node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TreeNode")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" TreeNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" TreeNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("TreeNode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("val")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("left")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("nullptr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("right")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("nullptr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("TreeNode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("val")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("left")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("nullptr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("right")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("nullptr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("TreeNode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" TreeNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" TreeNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("val")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("left")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("right")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=end")]),t._v("\n")])])]),s("ol",[s("li",[t._v("递归:分解成左右子树")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Solution")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("maxDepth")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("TreeNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("root"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("root "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("nullptr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" tempLeft "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("maxDepth")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("root"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" tempRight "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("maxDepth")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("root"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("max")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tempLeft"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" tempRight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"2"}},[s("li",[t._v("遍历:进入节点(前序)加深度,离开节点(后序)减深度,叶子结点处更新结果")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Solution")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" temp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("maxDepth")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("TreeNode"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" root"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("traverse")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("root"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("traverse")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("TreeNode"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" node"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("nullptr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("max")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("temp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n temp"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("traverse")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("traverse")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n temp"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/87.46382599.js b/assets/js/87.46382599.js new file mode 100644 index 0000000..6dfdd22 --- /dev/null +++ b/assets/js/87.46382599.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[87],{446:function(t,s,n){"use strict";n.r(s);var a=n(14),r=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-03-05-144-二叉树的前序遍历"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-05-144-二叉树的前序遍历"}},[t._v("#")]),t._v(" 2024.03.05-144.二叉树的前序遍历")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*\n * @lc app=leetcode.cn id=144 lang=cpp\n *\n * [144] 二叉树的前序遍历\n *\n * https://leetcode.cn/problems/binary-tree-preorder-traversal/description/\n *\n * algorithms\n * Easy (71.71%)\n * Likes: 1230\n * Dislikes: 0\n * Total Accepted: 1M\n * Total Submissions: 1.4M\n * Testcase Example: '[1,null,2,3]'\n *\n * 给你二叉树的根节点 root ,返回它节点值的 前序 遍历。\n * \n * \n * \n * 示例 1:\n * \n * \n * 输入:root = [1,null,2,3]\n * 输出:[1,2,3]\n * \n * \n * 示例 2:\n * \n * \n * 输入:root = []\n * 输出:[]\n * \n * \n * 示例 3:\n * \n * \n * 输入:root = [1]\n * 输出:[1]\n * \n * \n * 示例 4:\n * \n * \n * 输入:root = [1,2]\n * 输出:[1,2]\n * \n * \n * 示例 5:\n * \n * \n * 输入:root = [1,null,2]\n * 输出:[1,2]\n * \n * \n * \n * \n * 提示:\n * \n * \n * 树中节点数目在范围 [0, 100] 内\n * -100 \n * \n * \n * \n * \n * 进阶:递归算法很简单,你可以通过迭代算法完成吗?\n * \n */")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=start")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/**\n * Definition for a binary tree node.\n * struct TreeNode {\n * int val;\n * TreeNode *left;\n * TreeNode *right;\n * TreeNode() : val(0), left(nullptr), right(nullptr) {}\n * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}\n * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}\n * };\n */")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=end")]),t._v("\n")])])]),s("ol",[s("li",[t._v("递归")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Solution")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("preorderTraversal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("TreeNode"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" root"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("root "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("nullptr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_back")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("root"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("preorderTraversal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("root"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("preorderTraversal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("root"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ol",{attrs:{start:"2"}},[s("li",[t._v("迭代(使用栈)")])]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Solution")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("preorderTraversal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("TreeNode"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" root"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("root "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("nullptr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n stack"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("TreeNode"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" stk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n stk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("root"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("stk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("empty")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n TreeNode"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" node "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" stk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("top")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n stk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pop")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_back")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("nullptr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n stk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 先压入右子树")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("nullptr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n stk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 再压入左子树")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/88.fe5b99b5.js b/assets/js/88.fe5b99b5.js new file mode 100644 index 0000000..911cf62 --- /dev/null +++ b/assets/js/88.fe5b99b5.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[88],{448:function(t,n,s){"use strict";s.r(n);var a=s(14),e=Object(a.a)({},(function(){var t=this,n=t._self._c;return n("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[n("h1",{attrs:{id:"_2024-03-05-543-二叉树的直径"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-05-543-二叉树的直径"}},[t._v("#")]),t._v(" 2024.03.05-543.二叉树的直径")]),t._v(" "),n("div",{staticClass:"language-cpp extra-class"},[n("pre",{pre:!0,attrs:{class:"language-cpp"}},[n("code",[n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*\n * @lc app=leetcode.cn id=543 lang=cpp\n *\n * [543] 二叉树的直径\n *\n * https://leetcode.cn/problems/diameter-of-binary-tree/description/\n *\n * algorithms\n * Easy (59.72%)\n * Likes: 1495\n * Dislikes: 0\n * Total Accepted: 387.9K\n * Total Submissions: 649.5K\n * Testcase Example: '[1,2,3,4,5]'\n *\n * 给你一棵二叉树的根节点,返回该树的 直径 。\n *\n * 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。\n *\n * 两节点之间路径的 长度 由它们之间边数表示。\n *\n *\n *\n * 示例 1:\n *\n *\n * 输入:root = [1,2,3,4,5]\n * 输出:3\n * 解释:3 ,取路径 [4,2,1,3] 或 [5,2,1,3] 的长度。\n *\n *\n * 示例 2:\n *\n *\n * 输入:root = [1,2]\n * 输出:1\n *\n *\n *\n *\n * 提示:\n *\n *\n * 树中节点数目在范围 [1, 10^4] 内\n * -100 <= Node.val <= 100\n *\n *\n */")]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=start")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Definition for a binary tree node.\n * struct TreeNode {\n * int val;\n * TreeNode *left;\n * TreeNode *right;\n * TreeNode() : val(0), left(nullptr), right(nullptr) {}\n * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}\n * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}\n * };\n */")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Solution")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" res "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("diameterOfBinaryTree")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("TreeNode"),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" root"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("traverse")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("root"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("res"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" res"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// cal the maxDepth")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("traverse")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("TreeNode"),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" node"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" res"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("nullptr")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" leftMax "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("traverse")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node"),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("left"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("res"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" rightMax "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("traverse")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("node"),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v("right"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("res"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" nodeMax "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("max")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("leftMax"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("rightMax"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),n("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n res "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("max")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("leftMax"),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v("rightMax"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" nodeMax"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=end")]),t._v("\n")])])])])}),[],!1,null,null,null);n.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/89.6d0df84a.js b/assets/js/89.6d0df84a.js new file mode 100644 index 0000000..52f5033 --- /dev/null +++ b/assets/js/89.6d0df84a.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[89],{449:function(t,e,a){"use strict";a.r(e);var r=a(14),s=Object(r.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"_2024-03-11-二分搜索"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-11-二分搜索"}},[t._v("#")]),t._v(" 2024.03.11-二分搜索")]),t._v(" "),e("h2",{attrs:{id:"_2024-03-11-704-二分搜索"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-11-704-二分搜索"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/LeetCode/LeetCode/2024.03.11-二分搜索/2024.03.11-704.二分搜索.html"}},[t._v("2024.03.11-704.二分搜索")])],1),t._v(" "),e("h2",{attrs:{id:"_2024-03-11-34-在排序数组中查找元素的第一个和最后一个位置"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-11-34-在排序数组中查找元素的第一个和最后一个位置"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/LeetCode/LeetCode/2024.03.11-二分搜索/2024.03.11-34.在排序数组中查找元素的第一个和最后一个位置.html"}},[t._v("2024.03.11-34.在排序数组中查找元素的第一个和最后一个位置")])],1)])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/90.54b36191.js b/assets/js/90.54b36191.js new file mode 100644 index 0000000..d294745 --- /dev/null +++ b/assets/js/90.54b36191.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[90],{450:function(t,s,a){"use strict";a.r(s);var n=a(14),r=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-03-11-34-在排序数组中查找元素的第一个和最后一个位置"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-11-34-在排序数组中查找元素的第一个和最后一个位置"}},[t._v("#")]),t._v(" 2024.03.11-34.在排序数组中查找元素的第一个和最后一个位置")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*\n * @lc app=leetcode.cn id=34 lang=cpp\n *\n * [34] 在排序数组中查找元素的第一个和最后一个位置\n *\n * https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/description/\n *\n * algorithms\n * Medium (43.05%)\n * Likes: 2636\n * Dislikes: 0\n * Total Accepted: 936.9K\n * Total Submissions: 2.2M\n * Testcase Example: '[5,7,7,8,8,10]\\n8'\n *\n * 给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。\n *\n * 如果数组中不存在目标值 target,返回 [-1, -1]。\n *\n * 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。\n *\n *\n *\n * 示例 1:\n *\n *\n * 输入:nums = [5,7,7,8,8,10], target = 8\n * 输出:[3,4]\n *\n * 示例 2:\n *\n *\n * 输入:nums = [5,7,7,8,8,10], target = 6\n * 输出:[-1,-1]\n *\n * 示例 3:\n *\n *\n * 输入:nums = [], target = 0\n * 输出:[-1,-1]\n *\n *\n *\n * 提示:\n *\n *\n * 0 <= nums.length <= 10^5\n * -10^9 <= nums[i] <= 10^9\n * nums 是一个非递减数组\n * -10^9 <= target <= 10^9\n *\n *\n */")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=start")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Solution")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("searchRange")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("leftRange")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("rightRange")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("leftRange")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" mid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("rightRange")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" mid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/91.3005b9ed.js b/assets/js/91.3005b9ed.js new file mode 100644 index 0000000..00ba374 --- /dev/null +++ b/assets/js/91.3005b9ed.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[91],{451:function(t,s,n){"use strict";n.r(s);var a=n(14),e=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-03-11-704-二分搜索"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-11-704-二分搜索"}},[t._v("#")]),t._v(" 2024.03.11-704.二分搜索")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*\n * @lc app=leetcode.cn id=704 lang=cpp\n *\n * [704] 二分查找\n *\n * https://leetcode.cn/problems/binary-search/description/\n *\n * algorithms\n * Easy (55.07%)\n * Likes: 1541\n * Dislikes: 0\n * Total Accepted: 1.2M\n * Total Submissions: 2.1M\n * Testcase Example: '[-1,0,3,5,9,12]\\n9'\n *\n * 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的\n * target,如果目标值存在返回下标,否则返回 -1。\n * \n * \n * 示例 1:\n * \n * 输入: nums = [-1,0,3,5,9,12], target = 9\n * 输出: 4\n * 解释: 9 出现在 nums 中并且下标为 4\n * \n * \n * 示例 2:\n * \n * 输入: nums = [-1,0,3,5,9,12], target = 2\n * 输出: -1\n * 解释: 2 不存在 nums 中因此返回 -1\n * \n * \n * \n * \n * 提示:\n * \n * \n * 你可以假设 nums 中的所有元素是不重复的。\n * n 将在 [1, 10000]之间。\n * nums 的每个元素都将在 [-9999, 9999]之间。\n * \n * \n */")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=start")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Solution")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("search")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v(" nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<=")]),t._v(" right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" mid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" mid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("nums"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" mid "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=end")]),t._v("\n")])])]),s("ol",[s("li",[t._v("注意 "),s("code",[t._v("int right = nums.size() - 1")]),t._v(";")]),t._v(" "),s("li",[s("code",[t._v("left ≤ right")]),t._v(",有个等号。即当while中那个区间为空的时候就该跳出while了")]),t._v(" "),s("li",[s("code",[t._v("left + (right - left) / 2")]),t._v(" 的目的是避免溢出,而不是直接 "),s("code",[t._v("left + right / 2")])]),t._v(" "),s("li",[s("code",[t._v("left = mid + 1")]),t._v("; 由于闭区间,所以更新边界的时候要考虑到不能包含原来的边界值")])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/92.8353cc7c.js b/assets/js/92.8353cc7c.js new file mode 100644 index 0000000..1d23933 --- /dev/null +++ b/assets/js/92.8353cc7c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[92],{453:function(t,e,a){"use strict";a.r(e);var r=a(14),s=Object(r.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"_2024-03-18-滑动窗口"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-18-滑动窗口"}},[t._v("#")]),t._v(" 2024.03.18-滑动窗口")]),t._v(" "),e("h2",{attrs:{id:"_2024-03-18-76-最小覆盖子串"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-18-76-最小覆盖子串"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/LeetCode/LeetCode/2024.03.18-滑动窗口/2024.03.18-76.最小覆盖子串.html"}},[t._v("2024.03.18-76.最小覆盖子串")])],1),t._v(" "),e("h2",{attrs:{id:"_2024-04-02-567-字符串的排列"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-02-567-字符串的排列"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/LeetCode/LeetCode/2024.03.18-滑动窗口/2024.04.02-567.字符串的排列.html"}},[t._v("2024.04.02-567.字符串的排列")])],1),t._v(" "),e("h2",{attrs:{id:"_2024-04-02-438-找到字符串中所有字母异位词"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-02-438-找到字符串中所有字母异位词"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/LeetCode/LeetCode/2024.03.18-滑动窗口/2024.04.02-438.找到字符串中所有字母异位词.html"}},[t._v("2024.04.02-438.找到字符串中所有字母异位词")])],1),t._v(" "),e("h2",{attrs:{id:"_2024-04-02-3-无重复字符的最长子串"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-02-3-无重复字符的最长子串"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/LeetCode/LeetCode/2024.03.18-滑动窗口/2024.04.02-3.无重复字符的最长子串.html"}},[t._v("2024.04.02-3.无重复字符的最长子串")])],1)])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/93.15e3069e.js b/assets/js/93.15e3069e.js new file mode 100644 index 0000000..d02bfd6 --- /dev/null +++ b/assets/js/93.15e3069e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[93],{452:function(t,s,n){"use strict";n.r(s);var a=n(14),r=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-03-18-76-最小覆盖子串"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-18-76-最小覆盖子串"}},[t._v("#")]),t._v(" 2024.03.18-76.最小覆盖子串")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('/*\n * @lc app=leetcode.cn id=76 lang=cpp\n *\n * [76] 最小覆盖子串\n *\n * https://leetcode.cn/problems/minimum-window-substring/description/\n *\n * algorithms\n * Hard (45.57%)\n * Likes: 2847\n * Dislikes: 0\n * Total Accepted: 534.5K\n * Total Submissions: 1.2M\n * Testcase Example: \'"ADOBECODEBANC"\\n"ABC"\'\n *\n * 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""\n * 。\n *\n *\n *\n * 注意:\n *\n *\n * 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。\n * 如果 s 中存在这样的子串,我们保证它是唯一的答案。\n *\n *\n *\n *\n * 示例 1:\n *\n *\n * 输入:s = "ADOBECODEBANC", t = "ABC"\n * 输出:"BANC"\n * 解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 \'A\'、\'B\' 和 \'C\'。\n *\n *\n * 示例 2:\n *\n *\n * 输入:s = "a", t = "a"\n * 输出:"a"\n * 解释:整个字符串 s 是最小覆盖子串。\n *\n *\n * 示例 3:\n *\n *\n * 输入: s = "a", t = "aa"\n * 输出: ""\n * 解释: t 中两个字符 \'a\' 均应包含在 s 的子串中,\n * 因此没有符合条件的子字符串,返回空字符串。\n *\n *\n *\n * 提示:\n *\n *\n * ^m == s.length\n * ^n == t.length\n * 1 <= m, n <= 10^5\n * s 和 t 由英文字母组成\n *\n *\n *\n * 进阶:你能设计一个在 o(m+n) 时间内解决此问题的算法吗?\n */')]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=start")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Solution")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n string "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("minWindow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("string s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" string t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 左闭右开区间 [left, right)")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n unordered_map"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" t"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" hit "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" resStart "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" resLen "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" INT_MAX"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n right"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n hit "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("hit "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n left"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" resLen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n resStart "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n resLen "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n hit "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" resLen "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" INT_MAX "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("substr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resStart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" resLen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=end")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/94.c492d022.js b/assets/js/94.c492d022.js new file mode 100644 index 0000000..015010b --- /dev/null +++ b/assets/js/94.c492d022.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[94],{454:function(t,n,s){"use strict";s.r(n);var a=s(14),e=Object(a.a)({},(function(){var t=this,n=t._self._c;return n("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[n("h1",{attrs:{id:"_2024-04-02-3-无重复字符的最长子串"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-02-3-无重复字符的最长子串"}},[t._v("#")]),t._v(" 2024.04.02-3.无重复字符的最长子串")]),t._v(" "),n("div",{staticClass:"language-cpp extra-class"},[n("pre",{pre:!0,attrs:{class:"language-cpp"}},[n("code",[n("span",{pre:!0,attrs:{class:"token comment"}},[t._v('/*\n * @lc app=leetcode.cn id=3 lang=cpp\n *\n * [3] 无重复字符的最长子串\n *\n * https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/\n *\n * algorithms\n * Medium (39.02%)\n * Likes: 8247\n * Dislikes: 0\n * Total Accepted: 2M\n * Total Submissions: 5.2M\n * Testcase Example: \'"abcabcbb"\'\n *\n * 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。\n *\n *\n *\n * 示例 1:\n *\n *\n * 输入: s = "abcabcbb"\n * 输出: 3\n * 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。\n *\n *\n * 示例 2:\n *\n *\n * 输入: s = "bbbbb"\n * 输出: 1\n * 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。\n *\n *\n * 示例 3:\n *\n *\n * 输入: s = "pwwkew"\n * 输出: 3\n * 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。\n * 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。\n *\n *\n *\n *\n * 提示:\n *\n *\n * 0 <= s.length <= 5 * 10^4\n * s 由英文字母、数字、符号和空格组成\n *\n *\n */')]),t._v("\n\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=start")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// class Solution")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// {")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// public:")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// int lengthOfLongestSubstring(string s)")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// {")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// int result = 0;")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// unordered_map num;")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// int l = 0;")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// for (int r = 0; r < s.length(); ++r)")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// {")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// num[s[r]]++;")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// while (num[s[r]] >= 2)")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// {")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// num[s[l++]]--;")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// }")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// result = max(r - l + 1, result);")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// }")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// return result;")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// }")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// };")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Solution")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("lengthOfLongestSubstring")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("string s"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n unordered_map"),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" window"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" left "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" right "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" res "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" s"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" in "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" s"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("right"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n right"),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n window"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("in"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("window"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("in"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" out "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" s"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("left"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n left"),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n window"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("out"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n res "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{pre:!0,attrs:{class:"token function"}},[t._v("max")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" right "),n("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" left"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" res"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),n("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),n("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=end")]),t._v("\n")])])])])}),[],!1,null,null,null);n.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/95.7faaf930.js b/assets/js/95.7faaf930.js new file mode 100644 index 0000000..0a40dce --- /dev/null +++ b/assets/js/95.7faaf930.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[95],{455:function(t,s,n){"use strict";n.r(s);var a=n(14),p=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-02-438-找到字符串中所有字母异位词"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-02-438-找到字符串中所有字母异位词"}},[t._v("#")]),t._v(" 2024.04.02-438.找到字符串中所有字母异位词")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('/*\n * @lc app=leetcode.cn id=438 lang=cpp\n *\n * [438] 找到字符串中所有字母异位词\n *\n * https://leetcode.cn/problems/find-all-anagrams-in-a-string/description/\n *\n * algorithms\n * Medium (53.57%)\n * Likes: 1413\n * Dislikes: 0\n * Total Accepted: 407.9K\n * Total Submissions: 761.5K\n * Testcase Example: \'"cbaebabacd"\\n"abc"\'\n *\n * 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。\n * \n * 异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。\n * \n * \n * \n * 示例 1:\n * \n * \n * 输入: s = "cbaebabacd", p = "abc"\n * 输出: [0,6]\n * 解释:\n * 起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。\n * 起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。\n * \n * \n * 示例 2:\n * \n * \n * 输入: s = "abab", p = "ab"\n * 输出: [0,1,2]\n * 解释:\n * 起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。\n * 起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。\n * 起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。\n * \n * \n * \n * \n * 提示:\n * \n * \n * 1 <= s.length, p.length <= 3 * 10^4\n * s 和 p 仅包含小写字母\n * \n * \n */')]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=start")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Solution")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("findAnagrams")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("string s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" string p"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n unordered_map"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" p"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" hit "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n vector"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n right"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n hit"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("hit "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" p"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("push_back")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" s"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n left"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n hit"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=end")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=p.exports}}]); \ No newline at end of file diff --git a/assets/js/96.d8b18168.js b/assets/js/96.d8b18168.js new file mode 100644 index 0000000..114f6bf --- /dev/null +++ b/assets/js/96.d8b18168.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[96],{456:function(t,s,n){"use strict";n.r(s);var a=n(14),p=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"_2024-04-02-567-字符串的排列"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2024-04-02-567-字符串的排列"}},[t._v("#")]),t._v(" 2024.04.02-567.字符串的排列")]),t._v(" "),s("div",{staticClass:"language-cpp extra-class"},[s("pre",{pre:!0,attrs:{class:"language-cpp"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('/*\n * @lc app=leetcode.cn id=567 lang=cpp\n *\n * [567] 字符串的排列\n *\n * https://leetcode.cn/problems/permutation-in-string/description/\n *\n * algorithms\n * Medium (44.96%)\n * Likes: 996\n * Dislikes: 0\n * Total Accepted: 286.4K\n * Total Submissions: 637.1K\n * Testcase Example: \'"ab"\\n"eidbaooo"\'\n *\n * 给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。\n *\n * 换句话说,s1 的排列之一是 s2 的 子串 。\n *\n *\n *\n * 示例 1:\n *\n *\n * 输入:s1 = "ab" s2 = "eidbaooo"\n * 输出:true\n * 解释:s2 包含 s1 的排列之一 ("ba").\n *\n *\n * 示例 2:\n *\n *\n * 输入:s1= "ab" s2 = "eidboaoo"\n * 输出:false\n *\n *\n *\n *\n * 提示:\n *\n *\n * 1 <= s1.length, s2.length <= 10^4\n * s1 和 s2 仅包含小写字母\n *\n *\n */')]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=start")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Solution")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("bool")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("checkInclusion")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("string s1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" string s2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n unordered_map"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" c "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" s1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" left "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" hit "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" s2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" in "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" s2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("right"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n right"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("in"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n hit"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("hit "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("right "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" s1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("size")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("char")]),t._v(" out "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" s2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("left"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n left"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("count")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" target"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n hit"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// @lc code=end")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=p.exports}}]); \ No newline at end of file diff --git a/assets/js/97.4e7ad107.js b/assets/js/97.4e7ad107.js new file mode 100644 index 0000000..0398c75 --- /dev/null +++ b/assets/js/97.4e7ad107.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[97],{457:function(t,e,a){"use strict";a.r(e);var s=a(14),r=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"leetcode"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#leetcode"}},[t._v("#")]),t._v(" LeetCode")]),t._v(" "),e("h2",{attrs:{id:"_2024-02-22-bfs"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-02-22-bfs"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/LeetCode/LeetCode/2024.02.22-BFS.html"}},[t._v("2024.02.22-BFS")])],1),t._v(" "),e("h2",{attrs:{id:"_2024-03-05-二叉树"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-05-二叉树"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/LeetCode/LeetCode/2024.03.05-二叉树.html"}},[t._v("2024.03.05-二叉树")])],1),t._v(" "),e("h2",{attrs:{id:"_2024-03-10-滑动窗口"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2024-03-10-滑动窗口"}},[t._v("#")]),t._v(" "),e("RouterLink",{attrs:{to:"/LeetCode/LeetCode/2024.03.10-滑动窗口.html"}},[t._v("2024.03.10-滑动窗口")])],1)])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/98.48e1bcd8.js b/assets/js/98.48e1bcd8.js new file mode 100644 index 0000000..8e12d7d --- /dev/null +++ b/assets/js/98.48e1bcd8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[98],{458:function(t,n,s){"use strict";s.r(n);var e=s(14),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/99.b5bdbb44.js b/assets/js/99.b5bdbb44.js new file mode 100644 index 0000000..ba5d40a --- /dev/null +++ b/assets/js/99.b5bdbb44.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[99],{460:function(e,t,a){"use strict";a.r(t);var r=a(14),f=Object(r.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"research"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#research"}},[e._v("#")]),e._v(" Research")]),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023-Geant4 945b483bffdc4c51beb68f87b0cd2434.html"}},[e._v("2023-Geant4")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 02 14-HPC Usage(以未名一号为例) 43e9534849b24815beecbb4fc013abd4.html"}},[e._v("2023.02.14-HPC Usage(以未名一号为例)")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 08 22-Git的使用 d310b2bc534b493caf8d7e181ae3cd6d.html"}},[e._v("2023.08.22-Git的使用")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 08 23-Linux基本命令 9965ddff4081441ab5cd153f8eb38627.html"}},[e._v("2023.08.23-Linux基本命令")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 08 24-Linux用户和权限 a14c965dd7644069b674289740142cb1.html"}},[e._v("2023.08.24-Linux用户和权限")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 08 24-Linux常用工具 fc65197d16aa4a6bbb52357bdf370287.html"}},[e._v("2023.08.24-Linux常用工具")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 08 24-Vim 73603861053040d68dbffaeeb72b943f.html"}},[e._v("2023.08.24-Vim")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 08 25-Linux中的C语言编译器GCC 4a7355e74306484393407ebdeb191492.html"}},[e._v("2023.08.25-Linux中的C语言编译器GCC")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 08 25-Linux中调试程序 0cf6ed4636c0413aa44e5fb934668354.html"}},[e._v("2023.08.25-Linux中调试程序")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 08 25-make工具 c1605b8f5e2747ef977111ca447ebe70.html"}},[e._v("2023.08.25-make工具")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 08 25-CMakeLists txt 语法 f8bb0481f6764595a1d03cf5863a08d0.html"}},[e._v("2023.08.25-CMakeLists.txt 语法")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 09 04-GCC基本使用 b03830c10a5f4bf3855a46a0c956178c.html"}},[e._v("2023.09.04-GCC基本使用")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 10 15-Transformer 22da59aa72344dc786793967f054180c.html"}},[e._v("2023.10.15-Transformer")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 10 24-numpy c1dfa01a93134c1bb0b9453dc24698c3.html"}},[e._v("2023.10.24-numpy")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 10 24-Tensor与Autograd ecc0ab96c5ee4d0f99834cf14f0951cb.html"}},[e._v("2023.10.24-Tensor与Autograd")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 10 24-Pandas f6e050e8b22e4062a22316c2ef598fae.html"}},[e._v("2023.10.24-Pandas")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 10 25-深度学习模型的构建框架 af92295e6c144f89b34bf7ea4d5a83a9.html"}},[e._v("2023.10.25-深度学习模型的构建框架")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 10 26-Pytorch实现线性回归 dc0e9bffdb3b4370b80fc3cdb772a5a6.html"}},[e._v("2023.10.26-Pytorch实现线性回归")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 10 26-torch nn Module bc73b61cb24e44829553a4d7c7cbafdb.html"}},[e._v("2023.10.26-torch.nn.Module")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 10 26-Jupyter Notebook 4004412fe7034eb5bb267574cf732a16.html"}},[e._v("2023.10.26-Jupyter Notebook")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 10 30-Pytorch面试例题 fcf6c0ea64764770ba4fbc4a3f501804.html"}},[e._v("2023.10.30-Pytorch面试例题")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 11 01-图神经网络(GNN)模型 dc23395e26614dc49de7f8712a9750e4.html"}},[e._v("2023.11.01-图神经网络(GNN)模型")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 11 01-AI4Science面试准备 dc353f520cbc43b38a33df3eee83b79b.html"}},[e._v("2023.11.01-AI4Science面试准备")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 11 29-正则表达式 d7e945b2e7d34d06acbfc6e51922861f.html"}},[e._v("2023.11.29-正则表达式")])],1),e._v(" "),t("p",[t("RouterLink",{attrs:{to:"/Research/Research 55793f133d904f8298fb3e4b1227d790/2023 12 12-Docker 6fc5ec79556c4d79960776b3a8f83968.html"}},[e._v("2023.12.12-Docker")])],1)])}),[],!1,null,null,null);t.default=f.exports}}]); \ No newline at end of file diff --git a/assets/js/app.ad00963f.js b/assets/js/app.ad00963f.js new file mode 100644 index 0000000..ebeda43 --- /dev/null +++ b/assets/js/app.ad00963f.js @@ -0,0 +1,16 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[]]);!function(e){function t(t){for(var n,o,l=t[0],s=t[1],h=t[2],u=0,E=[];u
'};function i(e,t,r){return er?r:e}function a(e){return 100*(-1+e)}r.configure=function(e){var t,r;for(t in e)void 0!==(r=e[t])&&e.hasOwnProperty(t)&&(n[t]=r);return this},r.status=null,r.set=function(e){var t=r.isStarted();e=i(e,n.minimum,1),r.status=1===e?null:e;var s=r.render(!t),h=s.querySelector(n.barSelector),c=n.speed,u=n.easing;return s.offsetWidth,o((function(t){""===n.positionUsing&&(n.positionUsing=r.getPositioningCSS()),l(h,function(e,t,r){var i;return(i="translate3d"===n.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===n.positionUsing?{transform:"translate("+a(e)+"%,0)"}:{"margin-left":a(e)+"%"}).transition="all "+t+"ms "+r,i}(e,c,u)),1===e?(l(s,{transition:"none",opacity:1}),s.offsetWidth,setTimeout((function(){l(s,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){r.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},r.isStarted=function(){return"number"==typeof r.status},r.start=function(){r.status||r.set(0);var e=function(){setTimeout((function(){r.status&&(r.trickle(),e())}),n.trickleSpeed)};return n.trickle&&e(),this},r.done=function(e){return e||r.status?r.inc(.3+.5*Math.random()).set(1):this},r.inc=function(e){var t=r.status;return t?("number"!=typeof e&&(e=(1-t)*i(Math.random()*t,.1,.95)),t=i(t+e,0,.994),r.set(t)):r.start()},r.trickle=function(){return r.inc(Math.random()*n.trickleRate)},e=0,t=0,r.promise=function(n){return n&&"resolved"!==n.state()?(0===t&&r.start(),e++,t++,n.always((function(){0==--t?(e=0,r.done()):r.set((e-t)/e)})),this):this},r.render=function(e){if(r.isRendered())return document.getElementById("nprogress");h(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=n.template;var i,o=t.querySelector(n.barSelector),s=e?"-100":a(r.status||0),c=document.querySelector(n.parent);return l(o,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),n.showSpinner||(i=t.querySelector(n.spinnerSelector))&&E(i),c!=document.body&&h(c,"nprogress-custom-parent"),c.appendChild(t),t},r.remove=function(){c(document.documentElement,"nprogress-busy"),c(document.querySelector(n.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&E(e)},r.isRendered=function(){return!!document.getElementById("nprogress")},r.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var o=function(){var e=[];function t(){var r=e.shift();r&&r(t)}return function(r){e.push(r),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function r(r){return r=r.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()})),t[r]||(t[r]=function(t){var r=document.body.style;if(t in r)return t;for(var n,i=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);i--;)if((n=e[i]+a)in r)return n;return t}(r))}function n(e,t,n){t=r(t),e.style[t]=n}return function(e,t){var r,i,a=arguments;if(2==a.length)for(r in t)void 0!==(i=t[r])&&t.hasOwnProperty(r)&&n(e,r,i);else n(e,a[1],a[2])}}();function s(e,t){return("string"==typeof e?e:u(e)).indexOf(" "+t+" ")>=0}function h(e,t){var r=u(e),n=r+t;s(r,t)||(e.className=n.substring(1))}function c(e,t){var r,n=u(e);s(e,t)&&(r=n.replace(" "+t+" "," "),e.className=r.substring(1,r.length-1))}function u(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function E(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return r})?n.call(t,r,t,e):n)||(e.exports=i)},function(e,t,r){"use strict";var n=r(0),i=r(46).f,a=r(12),o=r(91),l=r(32),s=r(61),h=r(119);e.exports=function(e,t){var r,c,u,E,p,f=e.target,d=e.global,A=e.stat;if(r=d?n:A?n[f]||l(f,{}):n[f]&&n[f].prototype)for(c in t){if(E=t[c],u=e.dontCallGetSet?(p=i(r,c))&&p.value:r[c],!h(d?c:f+(A?".":"#")+c,e.forced)&&void 0!==u){if(typeof E==typeof u)continue;s(E,u)}(e.sham||u&&u.sham)&&a(E,"sham",!0),o(r,c,E,e)}}},function(e,t,r){"use strict";var n=r(25),i=Function.prototype.call;e.exports=n?i.bind(i):function(){return i.apply(i,arguments)}},function(e,t,r){"use strict";var n=r(3);e.exports=!n((function(){var e=function(){}.bind();return"function"!=typeof e||e.hasOwnProperty("prototype")}))},function(e,t,r){"use strict";e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,r){"use strict";var n=r(47),i=r(48);e.exports=function(e){return n(i(e))}},function(e,t,r){"use strict";var n=r(0),i=r(1),a=function(e){return i(e)?e:void 0};e.exports=function(e,t){return arguments.length<2?a(n[e]):n[e]&&n[e][t]}},function(e,t,r){"use strict";var n=r(1),i=r(101),a=TypeError;e.exports=function(e){if(n(e))return e;throw new a(i(e)+" is not a function")}},function(e,t,r){"use strict";var n=r(0),i=r(56),a=r(8),o=r(58),l=r(54),s=r(53),h=n.Symbol,c=i("wks"),u=s?h.for||h:h&&h.withoutSetter||o;e.exports=function(e){return a(c,e)||(c[e]=l&&a(h,e)?h[e]:u("Symbol."+e)),c[e]}},function(e,t,r){"use strict";var n=r(57),i=r(0),a=r(32),o=e.exports=i["__core-js_shared__"]||a("__core-js_shared__",{});(o.versions||(o.versions=[])).push({version:"3.36.0",mode:n?"pure":"global",copyright:"© 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.36.0/LICENSE",source:"https://github.com/zloirock/core-js"})},function(e,t,r){"use strict";var n=r(0),i=Object.defineProperty;e.exports=function(e,t){try{i(n,e,{value:t,configurable:!0,writable:!0})}catch(r){n[e]=t}return t}},function(e,t,r){"use strict";var n=r(48),i=Object;e.exports=function(e){return i(n(e))}},function(e,t,r){"use strict";var n=r(7),i=String,a=TypeError;e.exports=function(e){if(n(e))return e;throw new a(i(e)+" is not an object")}},function(e,t,r){"use strict";var n=r(116);e.exports=function(e){return n(e.length)}},function(e,t,r){var n=r(143),i=r(10),a=Object.prototype,o=a.hasOwnProperty,l=a.propertyIsEnumerable,s=n(function(){return arguments}())?n:function(e){return i(e)&&o.call(e,"callee")&&!l.call(e,"callee")};e.exports=s},function(e,t,r){var n=r(9)(r(6),"Map");e.exports=n},function(e,t){e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},function(e,t,r){var n=r(163),i=r(170),a=r(172),o=r(173),l=r(174);function s(e){var t=-1,r=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e<=9007199254740991}},function(e,t,r){var n=r(4),i=r(43),a=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,o=/^\w*$/;e.exports=function(e,t){if(n(e))return!1;var r=typeof e;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=e&&!i(e))||(o.test(e)||!a.test(e)||null!=t&&e in Object(t))}},function(e,t,r){var n=r(11),i=r(10);e.exports=function(e){return"symbol"==typeof e||i(e)&&"[object Symbol]"==n(e)}},function(e,t){e.exports=function(e){return e}},function(e,t,r){"use strict";var n=r(23),i=r(33),a=r(35),o=r(138),l=r(140);n({target:"Array",proto:!0,arity:1,forced:r(3)((function(){return 4294967297!==[].push.call({length:4294967296},1)}))||!function(){try{Object.defineProperty([],"length",{writable:!1}).push()}catch(e){return e instanceof TypeError}}()},{push:function(e){var t=i(this),r=a(t),n=arguments.length;l(r+n);for(var s=0;s0&&n[0]<4?1:+(n[0]+n[1])),!i&&o&&(!(n=o.match(/Edge\/(\d+)/))||n[1]>=74)&&(n=o.match(/Chrome\/(\d+)/))&&(i=+n[1]),e.exports=i},function(e,t,r){"use strict";var n=r(31);e.exports=function(e,t){return n[e]||(n[e]=t||{})}},function(e,t,r){"use strict";e.exports=!1},function(e,t,r){"use strict";var n=r(2),i=0,a=Math.random(),o=n(1..toString);e.exports=function(e){return"Symbol("+(void 0===e?"":e)+")_"+o(++i+a,36)}},function(e,t,r){"use strict";var n=r(5),i=r(3),a=r(103);e.exports=!n&&!i((function(){return 7!==Object.defineProperty(a("div"),"a",{get:function(){return 7}}).a}))},function(e,t,r){"use strict";e.exports={}},function(e,t,r){"use strict";var n=r(8),i=r(110),a=r(46),o=r(15);e.exports=function(e,t,r){for(var l=i(t),s=o.f,h=a.f,c=0;cc))return!1;var E=s.get(e),p=s.get(t);if(E&&p)return E==t&&p==e;var f=-1,d=!0,A=2&r?new n:void 0;for(s.set(e,t),s.set(t,e);++f-1&&e%1==0&&e]/;e.exports=function(e){var t,r=""+e,i=n.exec(r);if(!i)return r;var a="",o=0,l=0;for(o=i.index;o=t||r<0||A&&e-h>=a}function g(){var e=p();if(B(e))return y(e);l=setTimeout(g,function(e){var r=t-(e-s);return A?E(r,a-(e-h)):r}(e))}function y(e){return l=void 0,v&&n?m(e):(n=i=void 0,o)}function b(){var e=p(),r=B(e);if(n=arguments,i=this,s=e,r){if(void 0===l)return C(s);if(A)return l=setTimeout(g,t),m(s)}return void 0===l&&(l=setTimeout(g,t)),o}return t=d(t)||0,f(r)&&(c=!!r.leading,a=(A="maxWait"in r)?u(d(r.maxWait)||0,t):a,v="trailing"in r?!!r.trailing:v),b.cancel=function(){void 0!==l&&clearTimeout(l),h=0,n=s=i=l=void 0},b.flush=function(){return void 0===l?o:y(p())},b}},function(e,t){e.exports=function(e){var t=null==e?0:e.length;return t?e[t-1]:void 0}},function(e,t,r){"use strict";var n=r(1),i=r(15),a=r(93),o=r(32);e.exports=function(e,t,r,l){l||(l={});var s=l.enumerable,h=void 0!==l.name?l.name:t;if(n(r)&&a(r,h,l),l.global)s?e[t]=r:o(t,r);else{try{l.unsafe?e[t]&&(s=!0):delete e[t]}catch(e){}s?e[t]=r:i.f(e,t,{value:r,enumerable:!1,configurable:!l.nonConfigurable,writable:!l.nonWritable})}return e}},function(e,t,r){"use strict";var n=r(132),i=String;e.exports=function(e){if("Symbol"===n(e))throw new TypeError("Cannot convert a Symbol value to a string");return i(e)}},function(e,t,r){"use strict";var n=r(2),i=r(3),a=r(1),o=r(8),l=r(5),s=r(105).CONFIGURABLE,h=r(106),c=r(107),u=c.enforce,E=c.get,p=String,f=Object.defineProperty,d=n("".slice),A=n("".replace),v=n([].join),m=l&&!i((function(){return 8!==f((function(){}),"length",{value:8}).length})),C=String(String).split("String"),B=e.exports=function(e,t,r){"Symbol("===d(p(t),0,7)&&(t="["+A(p(t),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),r&&r.getter&&(t="get "+t),r&&r.setter&&(t="set "+t),(!o(e,"name")||s&&e.name!==t)&&(l?f(e,"name",{value:t,configurable:!0}):e.name=t),m&&r&&o(r,"arity")&&e.length!==r.arity&&f(e,"length",{value:r.arity});try{r&&o(r,"constructor")&&r.constructor?l&&f(e,"prototype",{writable:!1}):e.prototype&&(e.prototype=void 0)}catch(e){}var n=u(e);return o(n,"source")||(n.source=v(C,"string"==typeof t?t:"")),e};Function.prototype.toString=B((function(){return a(this)&&E(this).source||h(this)}),"toString")},function(e,t,r){var n=r(83);e.exports=function(e,t,r){var i=null==e?void 0:n(e,t);return void 0===i?r:i}},function(e,t,r){e.exports=r(240)},function(e,t,r){"use strict";var n=r(23),i=r(120).left,a=r(121),o=r(55);n({target:"Array",proto:!0,forced:!r(122)&&o>79&&o<83||!a("reduce")},{reduce:function(e){var t=arguments.length;return i(this,e,t,t>1?arguments[1]:void 0)}})},function(e,t,r){"use strict";var n={}.propertyIsEnumerable,i=Object.getOwnPropertyDescriptor,a=i&&!n.call({1:2},1);t.f=a?function(e){var t=i(this,e);return!!t&&t.enumerable}:n},function(e,t,r){"use strict";var n=r(24),i=r(7),a=r(51),o=r(100),l=r(102),s=r(30),h=TypeError,c=s("toPrimitive");e.exports=function(e,t){if(!i(e)||a(e))return e;var r,s=o(e,c);if(s){if(void 0===t&&(t="default"),r=n(s,e,t),!i(r)||a(r))return r;throw new h("Can't convert object to primitive value")}return void 0===t&&(t="number"),l(e,t)}},function(e,t,r){"use strict";e.exports="undefined"!=typeof navigator&&String(navigator.userAgent)||""},function(e,t,r){"use strict";var n=r(29),i=r(49);e.exports=function(e,t){var r=e[t];return i(r)?void 0:n(r)}},function(e,t,r){"use strict";var n=String;e.exports=function(e){try{return n(e)}catch(e){return"Object"}}},function(e,t,r){"use strict";var n=r(24),i=r(1),a=r(7),o=TypeError;e.exports=function(e,t){var r,l;if("string"===t&&i(r=e.toString)&&!a(l=n(r,e)))return l;if(i(r=e.valueOf)&&!a(l=n(r,e)))return l;if("string"!==t&&i(r=e.toString)&&!a(l=n(r,e)))return l;throw new o("Can't convert object to primitive value")}},function(e,t,r){"use strict";var n=r(0),i=r(7),a=n.document,o=i(a)&&i(a.createElement);e.exports=function(e){return o?a.createElement(e):{}}},function(e,t,r){"use strict";var n=r(5),i=r(3);e.exports=n&&i((function(){return 42!==Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype}))},function(e,t,r){"use strict";var n=r(5),i=r(8),a=Function.prototype,o=n&&Object.getOwnPropertyDescriptor,l=i(a,"name"),s=l&&"something"===function(){}.name,h=l&&(!n||n&&o(a,"name").configurable);e.exports={EXISTS:l,PROPER:s,CONFIGURABLE:h}},function(e,t,r){"use strict";var n=r(2),i=r(1),a=r(31),o=n(Function.toString);i(a.inspectSource)||(a.inspectSource=function(e){return o(e)}),e.exports=a.inspectSource},function(e,t,r){"use strict";var n,i,a,o=r(108),l=r(0),s=r(7),h=r(12),c=r(8),u=r(31),E=r(109),p=r(60),f=l.TypeError,d=l.WeakMap;if(o||u.state){var A=u.state||(u.state=new d);A.get=A.get,A.has=A.has,A.set=A.set,n=function(e,t){if(A.has(e))throw new f("Object already initialized");return t.facade=e,A.set(e,t),t},i=function(e){return A.get(e)||{}},a=function(e){return A.has(e)}}else{var v=E("state");p[v]=!0,n=function(e,t){if(c(e,v))throw new f("Object already initialized");return t.facade=e,h(e,v,t),t},i=function(e){return c(e,v)?e[v]:{}},a=function(e){return c(e,v)}}e.exports={set:n,get:i,has:a,enforce:function(e){return a(e)?i(e):n(e,{})},getterFor:function(e){return function(t){var r;if(!s(t)||(r=i(t)).type!==e)throw new f("Incompatible receiver, "+e+" required");return r}}}},function(e,t,r){"use strict";var n=r(0),i=r(1),a=n.WeakMap;e.exports=i(a)&&/native code/.test(String(a))},function(e,t,r){"use strict";var n=r(56),i=r(58),a=n("keys");e.exports=function(e){return a[e]||(a[e]=i(e))}},function(e,t,r){"use strict";var n=r(28),i=r(2),a=r(111),o=r(118),l=r(34),s=i([].concat);e.exports=n("Reflect","ownKeys")||function(e){var t=a.f(l(e)),r=o.f;return r?s(t,r(e)):t}},function(e,t,r){"use strict";var n=r(112),i=r(117).concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return n(e,i)}},function(e,t,r){"use strict";var n=r(2),i=r(8),a=r(27),o=r(113).indexOf,l=r(60),s=n([].push);e.exports=function(e,t){var r,n=a(e),h=0,c=[];for(r in n)!i(l,r)&&i(n,r)&&s(c,r);for(;t.length>h;)i(n,r=t[h++])&&(~o(c,r)||s(c,r));return c}},function(e,t,r){"use strict";var n=r(27),i=r(114),a=r(35),o=function(e){return function(t,r,o){var l=n(t),s=a(l);if(0===s)return!e&&-1;var h,c=i(o,s);if(e&&r!=r){for(;s>c;)if((h=l[c++])!=h)return!0}else for(;s>c;c++)if((e||c in l)&&l[c]===r)return e||c||0;return!e&&-1}};e.exports={includes:o(!0),indexOf:o(!1)}},function(e,t,r){"use strict";var n=r(62),i=Math.max,a=Math.min;e.exports=function(e,t){var r=n(e);return r<0?i(r+t,0):a(r,t)}},function(e,t,r){"use strict";var n=Math.ceil,i=Math.floor;e.exports=Math.trunc||function(e){var t=+e;return(t>0?i:n)(t)}},function(e,t,r){"use strict";var n=r(62),i=Math.min;e.exports=function(e){var t=n(e);return t>0?i(t,9007199254740991):0}},function(e,t,r){"use strict";e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},function(e,t,r){"use strict";t.f=Object.getOwnPropertySymbols},function(e,t,r){"use strict";var n=r(3),i=r(1),a=/#|\.prototype\./,o=function(e,t){var r=s[l(e)];return r===c||r!==h&&(i(t)?n(t):!!t)},l=o.normalize=function(e){return String(e).replace(a,".").toLowerCase()},s=o.data={},h=o.NATIVE="N",c=o.POLYFILL="P";e.exports=o},function(e,t,r){"use strict";var n=r(29),i=r(33),a=r(47),o=r(35),l=TypeError,s="Reduce of empty array with no initial value",h=function(e){return function(t,r,h,c){var u=i(t),E=a(u),p=o(u);if(n(r),0===p&&h<2)throw new l(s);var f=e?p-1:0,d=e?-1:1;if(h<2)for(;;){if(f in E){c=E[f],f+=d;break}if(f+=d,e?f<0:p<=f)throw new l(s)}for(;e?f>=0:p>f;f+=d)f in E&&(c=r(c,E[f],f,u));return c}};e.exports={left:h(!1),right:h(!0)}},function(e,t,r){"use strict";var n=r(3);e.exports=function(e,t){var r=[][e];return!!r&&n((function(){r.call(null,t||function(){return 1},1)}))}},function(e,t,r){"use strict";var n=r(0),i=r(16);e.exports="process"===i(n.process)},function(e,t,r){"use strict";var n=r(23),i=r(0),a=r(124),o=r(125),l=i.WebAssembly,s=7!==new Error("e",{cause:7}).cause,h=function(e,t){var r={};r[e]=o(e,t,s),n({global:!0,constructor:!0,arity:1,forced:s},r)},c=function(e,t){if(l&&l[e]){var r={};r[e]=o("WebAssembly."+e,t,s),n({target:"WebAssembly",stat:!0,constructor:!0,arity:1,forced:s},r)}};h("Error",(function(e){return function(t){return a(e,this,arguments)}})),h("EvalError",(function(e){return function(t){return a(e,this,arguments)}})),h("RangeError",(function(e){return function(t){return a(e,this,arguments)}})),h("ReferenceError",(function(e){return function(t){return a(e,this,arguments)}})),h("SyntaxError",(function(e){return function(t){return a(e,this,arguments)}})),h("TypeError",(function(e){return function(t){return a(e,this,arguments)}})),h("URIError",(function(e){return function(t){return a(e,this,arguments)}})),c("CompileError",(function(e){return function(t){return a(e,this,arguments)}})),c("LinkError",(function(e){return function(t){return a(e,this,arguments)}})),c("RuntimeError",(function(e){return function(t){return a(e,this,arguments)}}))},function(e,t,r){"use strict";var n=r(25),i=Function.prototype,a=i.apply,o=i.call;e.exports="object"==typeof Reflect&&Reflect.apply||(n?o.bind(a):function(){return o.apply(a,arguments)})},function(e,t,r){"use strict";var n=r(28),i=r(8),a=r(12),o=r(52),l=r(63),s=r(61),h=r(129),c=r(130),u=r(131),E=r(134),p=r(135),f=r(5),d=r(57);e.exports=function(e,t,r,A){var v=A?2:1,m=e.split("."),C=m[m.length-1],B=n.apply(null,m);if(B){var g=B.prototype;if(!d&&i(g,"cause")&&delete g.cause,!r)return B;var y=n("Error"),b=t((function(e,t){var r=u(A?t:e,void 0),n=A?new B(e):new B;return void 0!==r&&a(n,"message",r),p(n,b,n.stack,2),this&&o(g,this)&&c(n,this,b),arguments.length>v&&E(n,arguments[v]),n}));if(b.prototype=g,"Error"!==C?l?l(b,y):s(b,y,{name:!0}):f&&"stackTraceLimit"in B&&(h(b,B,"stackTraceLimit"),h(b,B,"prepareStackTrace")),s(b,B),!d)try{g.name!==C&&a(g,"name",C),g.constructor=b}catch(e){}return b}}},function(e,t,r){"use strict";var n=r(2),i=r(29);e.exports=function(e,t,r){try{return n(i(Object.getOwnPropertyDescriptor(e,t)[r]))}catch(e){}}},function(e,t,r){"use strict";var n=r(128),i=String,a=TypeError;e.exports=function(e){if(n(e))return e;throw new a("Can't set "+i(e)+" as a prototype")}},function(e,t,r){"use strict";var n=r(7);e.exports=function(e){return n(e)||null===e}},function(e,t,r){"use strict";var n=r(15).f;e.exports=function(e,t,r){r in e||n(e,r,{configurable:!0,get:function(){return t[r]},set:function(e){t[r]=e}})}},function(e,t,r){"use strict";var n=r(1),i=r(7),a=r(63);e.exports=function(e,t,r){var o,l;return a&&n(o=t.constructor)&&o!==r&&i(l=o.prototype)&&l!==r.prototype&&a(e,l),e}},function(e,t,r){"use strict";var n=r(92);e.exports=function(e,t){return void 0===e?arguments.length<2?"":t:n(e)}},function(e,t,r){"use strict";var n=r(133),i=r(1),a=r(16),o=r(30)("toStringTag"),l=Object,s="Arguments"===a(function(){return arguments}());e.exports=n?a:function(e){var t,r,n;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(r=function(e,t){try{return e[t]}catch(e){}}(t=l(e),o))?r:s?a(t):"Object"===(n=a(t))&&i(t.callee)?"Arguments":n}},function(e,t,r){"use strict";var n={};n[r(30)("toStringTag")]="z",e.exports="[object z]"===String(n)},function(e,t,r){"use strict";var n=r(7),i=r(12);e.exports=function(e,t){n(t)&&"cause"in t&&i(e,"cause",t.cause)}},function(e,t,r){"use strict";var n=r(12),i=r(136),a=r(137),o=Error.captureStackTrace;e.exports=function(e,t,r,l){a&&(o?o(e,t):n(e,"stack",i(r,l)))}},function(e,t,r){"use strict";var n=r(2),i=Error,a=n("".replace),o=String(new i("zxcasd").stack),l=/\n\s*at [^:]*:[^\n]*/,s=l.test(o);e.exports=function(e,t){if(s&&"string"==typeof e&&!i.prepareStackTrace)for(;t--;)e=a(e,l,"");return e}},function(e,t,r){"use strict";var n=r(3),i=r(26);e.exports=!n((function(){var e=new Error("a");return!("stack"in e)||(Object.defineProperty(e,"stack",i(1,7)),7!==e.stack)}))},function(e,t,r){"use strict";var n=r(5),i=r(139),a=TypeError,o=Object.getOwnPropertyDescriptor,l=n&&!function(){if(void 0!==this)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(e){return e instanceof TypeError}}();e.exports=l?function(e,t){if(i(e)&&!o(e,"length").writable)throw new a("Cannot set read only .length");return e.length=t}:function(e,t){return e.length=t}},function(e,t,r){"use strict";var n=r(16);e.exports=Array.isArray||function(e){return"Array"===n(e)}},function(e,t,r){"use strict";var n=TypeError;e.exports=function(e){if(e>9007199254740991)throw n("Maximum allowed index exceeded");return e}},function(e,t,r){var n=r(64),i=r(142);e.exports=function e(t,r,a,o,l){var s=-1,h=t.length;for(a||(a=i),l||(l=[]);++s0&&a(c)?r>1?e(c,r-1,a,o,l):n(l,c):o||(l[l.length]=c)}return l}},function(e,t,r){var n=r(13),i=r(36),a=r(4),o=n?n.isConcatSpreadable:void 0;e.exports=function(e){return a(e)||i(e)||!!(o&&e&&e[o])}},function(e,t,r){var n=r(11),i=r(10);e.exports=function(e){return i(e)&&"[object Arguments]"==n(e)}},function(e,t,r){var n=r(13),i=Object.prototype,a=i.hasOwnProperty,o=i.toString,l=n?n.toStringTag:void 0;e.exports=function(e){var t=a.call(e,l),r=e[l];try{e[l]=void 0;var n=!0}catch(e){}var i=o.call(e);return n&&(t?e[l]=r:delete e[l]),i}},function(e,t){var r=Object.prototype.toString;e.exports=function(e){return r.call(e)}},function(e,t,r){var n=r(147),i=r(203),a=r(44),o=r(4),l=r(213);e.exports=function(e){return"function"==typeof e?e:null==e?a:"object"==typeof e?o(e)?i(e[0],e[1]):n(e):l(e)}},function(e,t,r){var n=r(148),i=r(202),a=r(82);e.exports=function(e){var t=i(e);return 1==t.length&&t[0][2]?a(t[0][0],t[0][1]):function(r){return r===e||n(r,e,t)}}},function(e,t,r){var n=r(66),i=r(70);e.exports=function(e,t,r,a){var o=r.length,l=o,s=!a;if(null==e)return!l;for(e=Object(e);o--;){var h=r[o];if(s&&h[2]?h[1]!==e[h[0]]:!(h[0]in e))return!1}for(;++o-1}},function(e,t,r){var n=r(18);e.exports=function(e,t){var r=this.__data__,i=n(r,e);return i<0?(++this.size,r.push([e,t])):r[i][1]=t,this}},function(e,t,r){var n=r(17);e.exports=function(){this.__data__=new n,this.size=0}},function(e,t){e.exports=function(e){var t=this.__data__,r=t.delete(e);return this.size=t.size,r}},function(e,t){e.exports=function(e){return this.__data__.get(e)}},function(e,t){e.exports=function(e){return this.__data__.has(e)}},function(e,t,r){var n=r(17),i=r(37),a=r(39);e.exports=function(e,t){var r=this.__data__;if(r instanceof n){var o=r.__data__;if(!i||o.length<199)return o.push([e,t]),this.size=++r.size,this;r=this.__data__=new a(o)}return r.set(e,t),this.size=r.size,this}},function(e,t,r){var n=r(68),i=r(160),a=r(38),o=r(69),l=/^\[object .+?Constructor\]$/,s=Function.prototype,h=Object.prototype,c=s.toString,u=h.hasOwnProperty,E=RegExp("^"+c.call(u).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");e.exports=function(e){return!(!a(e)||i(e))&&(n(e)?E:l).test(o(e))}},function(e,t,r){var n,i=r(161),a=(n=/[^.]+$/.exec(i&&i.keys&&i.keys.IE_PROTO||""))?"Symbol(src)_1."+n:"";e.exports=function(e){return!!a&&a in e}},function(e,t,r){var n=r(6)["__core-js_shared__"];e.exports=n},function(e,t){e.exports=function(e,t){return null==e?void 0:e[t]}},function(e,t,r){var n=r(164),i=r(17),a=r(37);e.exports=function(){this.size=0,this.__data__={hash:new n,map:new(a||i),string:new n}}},function(e,t,r){var n=r(165),i=r(166),a=r(167),o=r(168),l=r(169);function s(e){var t=-1,r=null==e?0:e.length;for(this.clear();++t0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}},function(e,t,r){var n=r(72),i=r(225),a=r(230),o=r(73),l=r(231),s=r(40);e.exports=function(e,t,r){var h=-1,c=i,u=e.length,E=!0,p=[],f=p;if(r)E=!1,c=a;else if(u>=200){var d=t?null:l(e);if(d)return s(d);E=!1,c=o,f=new n}else f=t?[]:p;e:for(;++h-1}},function(e,t,r){var n=r(227),i=r(228),a=r(229);e.exports=function(e,t,r){return t==t?a(e,t,r):n(e,i,r)}},function(e,t){e.exports=function(e,t,r,n){for(var i=e.length,a=r+(n?1:-1);n?a--:++a=0&&Math.floor(t)===t&&isFinite(e)}function d(e){return o(e)&&"function"==typeof e.then&&"function"==typeof e.catch}function A(e){return null==e?"":Array.isArray(e)||E(e)&&e.toString===u?JSON.stringify(e,v,2):String(e)}function v(e,t){return t&&t.__v_isRef?t.value:t}function m(e){var t=parseFloat(e);return isNaN(t)?e:t}function C(e,t){for(var r=Object.create(null),n=e.split(","),i=0;i-1)return e.splice(n,1)}}var y=Object.prototype.hasOwnProperty;function b(e,t){return y.call(e,t)}function _(e){var t=Object.create(null);return function(r){return t[r]||(t[r]=e(r))}}var F=/-(\w)/g,w=_((function(e){return e.replace(F,(function(e,t){return t?t.toUpperCase():""}))})),L=_((function(e){return e.charAt(0).toUpperCase()+e.slice(1)})),D=/\B([A-Z])/g,x=_((function(e){return e.replace(D,"-$1").toLowerCase()}));var k=Function.prototype.bind?function(e,t){return e.bind(t)}:function(e,t){function r(r){var n=arguments.length;return n?n>1?e.apply(t,arguments):e.call(t,r):e.call(t)}return r._length=e.length,r};function S(e,t){t=t||0;for(var r=e.length-t,n=new Array(r);r--;)n[r]=e[r+t];return n}function P(e,t){for(var r in t)e[r]=t[r];return e}function R(e){for(var t={},r=0;r0,Q=J&&J.indexOf("edge/")>0;J&&J.indexOf("android");var ee=J&&/iphone|ipad|ipod|ios/.test(J);J&&/chrome\/\d+/.test(J),J&&/phantomjs/.test(J);var te,re=J&&J.match(/firefox\/(\d+)/),ne={}.watch,ie=!1;if(X)try{var ae={};Object.defineProperty(ae,"passive",{get:function(){ie=!0}}),window.addEventListener("test-passive",null,ae)}catch(e){}var oe=function(){return void 0===te&&(te=!X&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),te},le=X&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function se(e){return"function"==typeof e&&/native code/.test(e.toString())}var he,ce="undefined"!=typeof Symbol&&se(Symbol)&&"undefined"!=typeof Reflect&&se(Reflect.ownKeys);he="undefined"!=typeof Set&&se(Set)?Set:function(){function e(){this.set=Object.create(null)}return e.prototype.has=function(e){return!0===this.set[e]},e.prototype.add=function(e){this.set[e]=!0},e.prototype.clear=function(){this.set=Object.create(null)},e}();var ue=null;function Ee(e){void 0===e&&(e=null),e||ue&&ue._scope.off(),ue=e,e&&e._scope.on()}var pe=function(){function e(e,t,r,n,i,a,o,l){this.tag=e,this.data=t,this.children=r,this.text=n,this.elm=i,this.ns=void 0,this.context=a,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=t&&t.key,this.componentOptions=o,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=l,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(e.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),e}(),fe=function(e){void 0===e&&(e="");var t=new pe;return t.text=e,t.isComment=!0,t};function de(e){return new pe(void 0,void 0,void 0,String(e))}function Ae(e){var t=new pe(e.tag,e.data,e.children&&e.children.slice(),e.text,e.elm,e.context,e.componentOptions,e.asyncFactory);return t.ns=e.ns,t.isStatic=e.isStatic,t.key=e.key,t.isComment=e.isComment,t.fnContext=e.fnContext,t.fnOptions=e.fnOptions,t.fnScopeId=e.fnScopeId,t.asyncMeta=e.asyncMeta,t.isCloned=!0,t}"function"==typeof SuppressedError&&SuppressedError;var ve=0,me=[],Ce=function(){function e(){this._pending=!1,this.id=ve++,this.subs=[]}return e.prototype.addSub=function(e){this.subs.push(e)},e.prototype.removeSub=function(e){this.subs[this.subs.indexOf(e)]=null,this._pending||(this._pending=!0,me.push(this))},e.prototype.depend=function(t){e.target&&e.target.addDep(this)},e.prototype.notify=function(e){var t=this.subs.filter((function(e){return e}));for(var r=0,n=t.length;r0&&(Je((h=e(h,"".concat(r||"","_").concat(n)))[0])&&Je(u)&&(E[c]=de(u.text+h[0].text),h.shift()),E.push.apply(E,h)):s(h)?Je(u)?E[c]=de(u.text+h):""!==h&&E.push(de(h)):Je(h)&&Je(u)?E[c]=de(u.text+h.text):(l(t._isVList)&&o(h.tag)&&a(h.key)&&o(r)&&(h.key="__vlist".concat(r,"_").concat(n,"__")),E.push(h)));return E}(e):void 0}function Je(e){return o(e)&&o(e.text)&&!1===e.isComment}function Ye(e,t){var r,n,a,l,s=null;if(i(e)||"string"==typeof e)for(s=new Array(e.length),r=0,n=e.length;r0,l=t?!!t.$stable:!o,s=t&&t.$key;if(t){if(t._normalized)return t._normalized;if(l&&i&&i!==n&&s===i.$key&&!o&&!i.$hasNormal)return i;for(var h in a={},t)t[h]&&"$"!==h[0]&&(a[h]=At(e,r,h,t[h]))}else a={};for(var c in r)c in a||(a[c]=vt(r,c));return t&&Object.isExtensible(t)&&(t._normalized=a),H(a,"$stable",l),H(a,"$key",s),H(a,"$hasNormal",o),a}function At(e,t,r,n){var a=function(){var t=ue;Ee(e);var r=arguments.length?n.apply(null,arguments):n({}),a=(r=r&&"object"==typeof r&&!i(r)?[r]:Xe(r))&&r[0];return Ee(t),r&&(!a||1===r.length&&a.isComment&&!ft(a))?void 0:r};return n.proxy&&Object.defineProperty(t,r,{get:a,enumerable:!0,configurable:!0}),a}function vt(e,t){return function(){return e[t]}}function mt(e){return{get attrs(){if(!e._attrsProxy){var t=e._attrsProxy={};H(t,"_v_attr_proxy",!0),Ct(t,e.$attrs,n,e,"$attrs")}return e._attrsProxy},get listeners(){e._listenersProxy||Ct(e._listenersProxy={},e.$listeners,n,e,"$listeners");return e._listenersProxy},get slots(){return function(e){e._slotsProxy||gt(e._slotsProxy={},e.$scopedSlots);return e._slotsProxy}(e)},emit:k(e.$emit,e),expose:function(t){t&&Object.keys(t).forEach((function(r){return Ie(e,t,r)}))}}}function Ct(e,t,r,n,i){var a=!1;for(var o in t)o in e?t[o]!==r[o]&&(a=!0):(a=!0,Bt(e,o,n,i));for(var o in e)o in t||(a=!0,delete e[o]);return a}function Bt(e,t,r,n){Object.defineProperty(e,t,{enumerable:!0,configurable:!0,get:function(){return r[n][t]}})}function gt(e,t){for(var r in t)e[r]=t[r];for(var r in e)r in t||delete e[r]}var yt=null;function bt(e,t){return(e.__esModule||ce&&"Module"===e[Symbol.toStringTag])&&(e=e.default),c(e)?t.extend(e):e}function _t(e){if(i(e))for(var t=0;tdocument.createEvent("Event").timeStamp&&(sr=function(){return hr.now()})}var cr=function(e,t){if(e.post){if(!t.post)return 1}else if(t.post)return-1;return e.id-t.id};function ur(){var e,t;for(lr=sr(),ar=!0,tr.sort(cr),or=0;oror&&tr[r].id>e.id;)r--;tr.splice(r+1,0,e)}else tr.push(e);ir||(ir=!0,Vt(ur))}}function pr(e,t){if(e){for(var r=Object.create(null),n=ce?Reflect.ownKeys(e):Object.keys(e),i=0;i-1)if(a&&!b(i,"default"))o=!1;else if(""===o||o===x(e)){var s=Or(String,i.type);(s<0||l-1:"string"==typeof e?e.split(",").indexOf(t)>-1:!!p(e)&&e.test(t)}function Jr(e,t){var r=e.cache,n=e.keys,i=e._vnode,a=e.$vnode;for(var o in r){var l=r[o];if(l){var s=l.name;s&&!t(s)&&Yr(r,o,n,i)}}a.componentOptions.children=void 0}function Yr(e,t,r,n){var i=e[t];!i||n&&i.tag===n.tag||i.componentInstance.$destroy(),e[t]=null,g(r,t)}Hr.prototype._init=function(e){var t=this;t._uid=zr++,t._isVue=!0,t.__v_skip=!0,t._scope=new Ne(!0),t._scope.parent=void 0,t._scope._vm=!0,e&&e._isComponent?function(e,t){var r=e.$options=Object.create(e.constructor.options),n=t._parentVnode;r.parent=t.parent,r._parentVnode=n;var i=n.componentOptions;r.propsData=i.propsData,r._parentListeners=i.listeners,r._renderChildren=i.children,r._componentTag=i.tag,t.render&&(r.render=t.render,r.staticRenderFns=t.staticRenderFns)}(t,e):t.$options=xr(qr(t.constructor),e||{},t),t._renderProxy=t,t._self=t,function(e){var t=e.$options,r=t.parent;if(r&&!t.abstract){for(;r.$options.abstract&&r.$parent;)r=r.$parent;r.$children.push(e)}e.$parent=r,e.$root=r?r.$root:e,e.$children=[],e.$refs={},e._provided=r?r._provided:Object.create(null),e._watcher=null,e._inactive=null,e._directInactive=!1,e._isMounted=!1,e._isDestroyed=!1,e._isBeingDestroyed=!1}(t),function(e){e._events=Object.create(null),e._hasHookEvent=!1;var t=e.$options._parentListeners;t&&Xt(e,t)}(t),function(e){e._vnode=null,e._staticTrees=null;var t=e.$options,r=e.$vnode=t._parentVnode,i=r&&r.context;e.$slots=Et(t._renderChildren,i),e.$scopedSlots=r?dt(e.$parent,r.data.scopedSlots,e.$slots):n,e._c=function(t,r,n,i){return Ft(e,t,r,n,i,!1)},e.$createElement=function(t,r,n,i){return Ft(e,t,r,n,i,!0)};var a=r&&r.data;Pe(e,"$attrs",a&&a.attrs||n,null,!0),Pe(e,"$listeners",t._parentListeners||n,null,!0)}(t),er(t,"beforeCreate",void 0,!1),function(e){var t=pr(e.$options.inject,e);t&&(De(!1),Object.keys(t).forEach((function(r){Pe(e,r,t[r])})),De(!0))}(t),Mr(t),function(e){var t=e.$options.provide;if(t){var r=h(t)?t.call(e):t;if(!c(r))return;for(var n=Ue(e),i=ce?Reflect.ownKeys(r):Object.keys(r),a=0;a1?S(r):r;for(var n=S(arguments,1),i='event handler for "'.concat(e,'"'),a=0,o=r.length;aparseInt(this.max)&&Yr(e,t[0],t,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var e in this.cache)Yr(this.cache,e,this.keys)},mounted:function(){var e=this;this.cacheVNode(),this.$watch("include",(function(t){Jr(e,(function(e){return Xr(t,e)}))})),this.$watch("exclude",(function(t){Jr(e,(function(e){return!Xr(t,e)}))}))},updated:function(){this.cacheVNode()},render:function(){var e=this.$slots.default,t=_t(e),r=t&&t.componentOptions;if(r){var n=Kr(r),i=this.include,a=this.exclude;if(i&&(!n||!Xr(i,n))||a&&n&&Xr(a,n))return t;var o=this.cache,l=this.keys,s=null==t.key?r.Ctor.cid+(r.tag?"::".concat(r.tag):""):t.key;o[s]?(t.componentInstance=o[s].componentInstance,g(l,s),l.push(s)):(this.vnodeToCache=t,this.keyToCache=s),t.data.keepAlive=!0}return t||e&&e[0]}}};!function(e){var t={get:function(){return U}};Object.defineProperty(e,"config",t),e.util={warn:yr,extend:P,mergeOptions:xr,defineReactive:Pe},e.set=Re,e.delete=Te,e.nextTick=Vt,e.observable=function(e){return Se(e),e},e.options=Object.create(null),G.forEach((function(t){e.options[t+"s"]=Object.create(null)})),e.options._base=e,P(e.options.components,Qr),function(e){e.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(t.indexOf(e)>-1)return this;var r=S(arguments,1);return r.unshift(this),h(e.install)?e.install.apply(e,r):h(e)&&e.apply(null,r),t.push(e),this}}(e),function(e){e.mixin=function(e){return this.options=xr(this.options,e),this}}(e),Wr(e),function(e){G.forEach((function(t){e[t]=function(e,r){return r?("component"===t&&E(r)&&(r.name=r.name||e,r=this.options._base.extend(r)),"directive"===t&&h(r)&&(r={bind:r,update:r}),this.options[t+"s"][e]=r,r):this.options[t+"s"][e]}}))}(e)}(Hr),Object.defineProperty(Hr.prototype,"$isServer",{get:oe}),Object.defineProperty(Hr.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Hr,"FunctionalRenderContext",{value:fr}),Hr.version="2.7.16";var en=C("style,class"),tn=C("input,textarea,option,select,progress"),rn=C("contenteditable,draggable,spellcheck"),nn=C("events,caret,typing,plaintext-only"),an=C("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),on="http://www.w3.org/1999/xlink",ln=function(e){return":"===e.charAt(5)&&"xlink"===e.slice(0,5)},sn=function(e){return ln(e)?e.slice(6,e.length):""},hn=function(e){return null==e||!1===e};function cn(e){for(var t=e.data,r=e,n=e;o(n.componentInstance);)(n=n.componentInstance._vnode)&&n.data&&(t=un(n.data,t));for(;o(r=r.parent);)r&&r.data&&(t=un(t,r.data));return function(e,t){if(o(e)||o(t))return En(e,pn(t));return""}(t.staticClass,t.class)}function un(e,t){return{staticClass:En(e.staticClass,t.staticClass),class:o(e.class)?[e.class,t.class]:t.class}}function En(e,t){return e?t?e+" "+t:e:t||""}function pn(e){return Array.isArray(e)?function(e){for(var t,r="",n=0,i=e.length;n-1?$n(e,t,r):an(t)?hn(r)?e.removeAttribute(t):(r="allowfullscreen"===t&&"EMBED"===e.tagName?"true":t,e.setAttribute(t,r)):rn(t)?e.setAttribute(t,function(e,t){return hn(t)||"false"===t?"false":"contenteditable"===e&&nn(t)?t:"true"}(t,r)):ln(t)?hn(r)?e.removeAttributeNS(on,sn(t)):e.setAttributeNS(on,t,r):$n(e,t,r)}function $n(e,t,r){if(hn(r))e.removeAttribute(t);else{if(Y&&!Z&&"TEXTAREA"===e.tagName&&"placeholder"===t&&""!==r&&!e.__ieph){var n=function(t){t.stopImmediatePropagation(),e.removeEventListener("input",n)};e.addEventListener("input",n),e.__ieph=!0}e.setAttribute(t,r)}}var Mn={create:On,update:On};function Vn(e,t){var r=t.elm,n=t.data,i=e.data;if(!(a(n.staticClass)&&a(n.class)&&(a(i)||a(i.staticClass)&&a(i.class)))){var l=cn(t),s=r._transitionClasses;o(s)&&(l=En(l,pn(s))),l!==r._prevClass&&(r.setAttribute("class",l),r._prevClass=l)}}var In,Gn={create:Vn,update:Vn};function Nn(e,t,r){var n=In;return function i(){var a=t.apply(null,arguments);null!==a&&qn(e,i,r,n)}}var Un=St&&!(re&&Number(re[1])<=53);function zn(e,t,r,n){if(Un){var i=lr,a=t;t=a._wrapper=function(e){if(e.target===e.currentTarget||e.timeStamp>=i||e.timeStamp<=0||e.target.ownerDocument!==document)return a.apply(this,arguments)}}In.addEventListener(e,t,ie?{capture:r,passive:n}:r)}function qn(e,t,r,n){(n||In).removeEventListener(e,t._wrapper||t,r)}function Hn(e,t){if(!a(e.data.on)||!a(t.data.on)){var r=t.data.on||{},n=e.data.on||{};In=t.elm||e.elm,function(e){if(o(e.__r)){var t=Y?"change":"input";e[t]=[].concat(e.__r,e[t]||[]),delete e.__r}o(e.__c)&&(e.change=[].concat(e.__c,e.change||[]),delete e.__c)}(r),He(r,n,zn,qn,Nn,t.context),In=void 0}}var Wn,Kn={create:Hn,update:Hn,destroy:function(e){return Hn(e,_n)}};function Xn(e,t){if(!a(e.data.domProps)||!a(t.data.domProps)){var r,n,i=t.elm,s=e.data.domProps||{},h=t.data.domProps||{};for(r in(o(h.__ob__)||l(h._v_attr_proxy))&&(h=t.data.domProps=P({},h)),s)r in h||(i[r]="");for(r in h){if(n=h[r],"textContent"===r||"innerHTML"===r){if(t.children&&(t.children.length=0),n===s[r])continue;1===i.childNodes.length&&i.removeChild(i.childNodes[0])}if("value"===r&&"PROGRESS"!==i.tagName){i._value=n;var c=a(n)?"":String(n);Jn(i,c)&&(i.value=c)}else if("innerHTML"===r&&An(i.tagName)&&a(i.innerHTML)){(Wn=Wn||document.createElement("div")).innerHTML="".concat(n,"");for(var u=Wn.firstChild;i.firstChild;)i.removeChild(i.firstChild);for(;u.firstChild;)i.appendChild(u.firstChild)}else if(n!==s[r])try{i[r]=n}catch(e){}}}}function Jn(e,t){return!e.composing&&("OPTION"===e.tagName||function(e,t){var r=!0;try{r=document.activeElement!==e}catch(e){}return r&&e.value!==t}(e,t)||function(e,t){var r=e.value,n=e._vModifiers;if(o(n)){if(n.number)return m(r)!==m(t);if(n.trim)return r.trim()!==t.trim()}return r!==t}(e,t))}var Yn={create:Xn,update:Xn},Zn=_((function(e){var t={},r=/:(.+)/;return e.split(/;(?![^(]*\))/g).forEach((function(e){if(e){var n=e.split(r);n.length>1&&(t[n[0].trim()]=n[1].trim())}})),t}));function Qn(e){var t=ei(e.style);return e.staticStyle?P(e.staticStyle,t):t}function ei(e){return Array.isArray(e)?R(e):"string"==typeof e?Zn(e):e}var ti,ri=/^--/,ni=/\s*!important$/,ii=function(e,t,r){if(ri.test(t))e.style.setProperty(t,r);else if(ni.test(r))e.style.setProperty(x(t),r.replace(ni,""),"important");else{var n=oi(t);if(Array.isArray(r))for(var i=0,a=r.length;i-1?t.split(hi).forEach((function(t){return e.classList.add(t)})):e.classList.add(t);else{var r=" ".concat(e.getAttribute("class")||""," ");r.indexOf(" "+t+" ")<0&&e.setAttribute("class",(r+t).trim())}}function ui(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split(hi).forEach((function(t){return e.classList.remove(t)})):e.classList.remove(t),e.classList.length||e.removeAttribute("class");else{for(var r=" ".concat(e.getAttribute("class")||""," "),n=" "+t+" ";r.indexOf(n)>=0;)r=r.replace(n," ");(r=r.trim())?e.setAttribute("class",r):e.removeAttribute("class")}}function Ei(e){if(e){if("object"==typeof e){var t={};return!1!==e.css&&P(t,pi(e.name||"v")),P(t,e),t}return"string"==typeof e?pi(e):void 0}}var pi=_((function(e){return{enterClass:"".concat(e,"-enter"),enterToClass:"".concat(e,"-enter-to"),enterActiveClass:"".concat(e,"-enter-active"),leaveClass:"".concat(e,"-leave"),leaveToClass:"".concat(e,"-leave-to"),leaveActiveClass:"".concat(e,"-leave-active")}})),fi=X&&!Z,di="transition",Ai="transitionend",vi="animation",mi="animationend";fi&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(di="WebkitTransition",Ai="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(vi="WebkitAnimation",mi="webkitAnimationEnd"));var Ci=X?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(e){return e()};function Bi(e){Ci((function(){Ci(e)}))}function gi(e,t){var r=e._transitionClasses||(e._transitionClasses=[]);r.indexOf(t)<0&&(r.push(t),ci(e,t))}function yi(e,t){e._transitionClasses&&g(e._transitionClasses,t),ui(e,t)}function bi(e,t,r){var n=Fi(e,t),i=n.type,a=n.timeout,o=n.propCount;if(!i)return r();var l="transition"===i?Ai:mi,s=0,h=function(){e.removeEventListener(l,c),r()},c=function(t){t.target===e&&++s>=o&&h()};setTimeout((function(){s0&&(r="transition",c=o,u=a.length):"animation"===t?h>0&&(r="animation",c=h,u=s.length):u=(r=(c=Math.max(o,h))>0?o>h?"transition":"animation":null)?"transition"===r?a.length:s.length:0,{type:r,timeout:c,propCount:u,hasTransform:"transition"===r&&_i.test(n[di+"Property"])}}function wi(e,t){for(;e.length1}function Pi(e,t){!0!==t.data.show&&Di(t)}var Ri=function(e){var t,r,n={},h=e.modules,c=e.nodeOps;for(t=0;tf?B(e,a(r[v+1])?null:r[v+1].elm,r,p,v,n):p>v&&y(t,u,f)}(u,d,v,r,h):o(v)?(o(e.text)&&c.setTextContent(u,""),B(u,null,v,0,v.length-1,r)):o(d)?y(d,0,d.length-1):o(e.text)&&c.setTextContent(u,""):e.text!==t.text&&c.setTextContent(u,t.text),o(f)&&o(p=f.hook)&&o(p=p.postpatch)&&p(e,t)}}}function w(e,t,r){if(l(r)&&o(e.parent))e.parent.data.pendingInsert=t;else for(var n=0;n-1,o.selected!==a&&(o.selected=a);else if($(Mi(o),n))return void(e.selectedIndex!==l&&(e.selectedIndex=l));i||(e.selectedIndex=-1)}}function $i(e,t){return t.every((function(t){return!$(t,e)}))}function Mi(e){return"_value"in e?e._value:e.value}function Vi(e){e.target.composing=!0}function Ii(e){e.target.composing&&(e.target.composing=!1,Gi(e.target,"input"))}function Gi(e,t){var r=document.createEvent("HTMLEvents");r.initEvent(t,!0,!0),e.dispatchEvent(r)}function Ni(e){return!e.componentInstance||e.data&&e.data.transition?e:Ni(e.componentInstance._vnode)}var Ui={model:Ti,show:{bind:function(e,t,r){var n=t.value,i=(r=Ni(r)).data&&r.data.transition,a=e.__vOriginalDisplay="none"===e.style.display?"":e.style.display;n&&i?(r.data.show=!0,Di(r,(function(){e.style.display=a}))):e.style.display=n?a:"none"},update:function(e,t,r){var n=t.value;!n!=!t.oldValue&&((r=Ni(r)).data&&r.data.transition?(r.data.show=!0,n?Di(r,(function(){e.style.display=e.__vOriginalDisplay})):xi(r,(function(){e.style.display="none"}))):e.style.display=n?e.__vOriginalDisplay:"none")},unbind:function(e,t,r,n,i){i||(e.style.display=e.__vOriginalDisplay)}}},zi={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function qi(e){var t=e&&e.componentOptions;return t&&t.Ctor.options.abstract?qi(_t(t.children)):e}function Hi(e){var t={},r=e.$options;for(var n in r.propsData)t[n]=e[n];var i=r._parentListeners;for(var n in i)t[w(n)]=i[n];return t}function Wi(e,t){if(/\d-keep-alive$/.test(t.tag))return e("keep-alive",{props:t.componentOptions.propsData})}var Ki=function(e){return e.tag||ft(e)},Xi=function(e){return"show"===e.name},Ji={name:"transition",props:zi,abstract:!0,render:function(e){var t=this,r=this.$slots.default;if(r&&(r=r.filter(Ki)).length){0;var n=this.mode;0;var i=r[0];if(function(e){for(;e=e.parent;)if(e.data.transition)return!0}(this.$vnode))return i;var a=qi(i);if(!a)return i;if(this._leaving)return Wi(e,i);var o="__transition-".concat(this._uid,"-");a.key=null==a.key?a.isComment?o+"comment":o+a.tag:s(a.key)?0===String(a.key).indexOf(o)?a.key:o+a.key:a.key;var l=(a.data||(a.data={})).transition=Hi(this),h=this._vnode,c=qi(h);if(a.data.directives&&a.data.directives.some(Xi)&&(a.data.show=!0),c&&c.data&&!function(e,t){return t.key===e.key&&t.tag===e.tag}(a,c)&&!ft(c)&&(!c.componentInstance||!c.componentInstance._vnode.isComment)){var u=c.data.transition=P({},l);if("out-in"===n)return this._leaving=!0,We(u,"afterLeave",(function(){t._leaving=!1,t.$forceUpdate()})),Wi(e,i);if("in-out"===n){if(ft(a))return h;var E,p=function(){E()};We(l,"afterEnter",p),We(l,"enterCancelled",p),We(u,"delayLeave",(function(e){E=e}))}}return i}}},Yi=P({tag:String,moveClass:String},zi);function Zi(e){e.elm._moveCb&&e.elm._moveCb(),e.elm._enterCb&&e.elm._enterCb()}function Qi(e){e.data.newPos=e.elm.getBoundingClientRect()}function ea(e){var t=e.data.pos,r=e.data.newPos,n=t.left-r.left,i=t.top-r.top;if(n||i){e.data.moved=!0;var a=e.elm.style;a.transform=a.WebkitTransform="translate(".concat(n,"px,").concat(i,"px)"),a.transitionDuration="0s"}}delete Yi.mode;var ta={Transition:Ji,TransitionGroup:{props:Yi,beforeMount:function(){var e=this,t=this._update;this._update=function(r,n){var i=Yt(e);e.__patch__(e._vnode,e.kept,!1,!0),e._vnode=e.kept,i(),t.call(e,r,n)}},render:function(e){for(var t=this.tag||this.$vnode.data.tag||"span",r=Object.create(null),n=this.prevChildren=this.children,i=this.$slots.default||[],a=this.children=[],o=Hi(this),l=0;l-1?mn[e]=t.constructor===window.HTMLUnknownElement||t.constructor===window.HTMLElement:mn[e]=/HTMLUnknownElement/.test(t.toString())},P(Hr.options.directives,Ui),P(Hr.options.components,ta),Hr.prototype.__patch__=X?Ri:T,Hr.prototype.$mount=function(e,t){return function(e,t,r){var n;e.$el=t,e.$options.render||(e.$options.render=fe),er(e,"beforeMount"),n=function(){e._update(e._render(),r)},new qt(e,n,T,{before:function(){e._isMounted&&!e._isDestroyed&&er(e,"beforeUpdate")}},!0),r=!1;var i=e._preWatchers;if(i)for(var a=0;a=0&&(t=e.slice(n),e=e.slice(0,n));var i=e.indexOf("?");return i>=0&&(r=e.slice(i+1),e=e.slice(0,i)),{path:e,query:r,hash:t}}(i.path||""),h=t&&t.path||"/",c=s.path?ya(s.path,h,r||i.append):h,u=function(e,t,r){void 0===t&&(t={});var n,i=r||ha;try{n=i(e||"")}catch(e){n={}}for(var a in t){var o=t[a];n[a]=Array.isArray(o)?o.map(sa):sa(o)}return n}(s.query,i.query,n&&n.options.parseQuery),E=i.hash||s.hash;return E&&"#"!==E.charAt(0)&&(E="#"+E),{_normalized:!0,path:c,query:u,hash:E}}var Ua,za=function(){},qa={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},custom:Boolean,exact:Boolean,exactPath:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,ariaCurrentValue:{type:String,default:"page"},event:{type:[String,Array],default:"click"}},render:function(e){var t=this,r=this.$router,n=this.$route,i=r.resolve(this.to,n,this.append),a=i.location,o=i.route,l=i.href,s={},h=r.options.linkActiveClass,c=r.options.linkExactActiveClass,u=null==h?"router-link-active":h,E=null==c?"router-link-exact-active":c,p=null==this.activeClass?u:this.activeClass,f=null==this.exactActiveClass?E:this.exactActiveClass,d=o.redirectedFrom?Ea(null,Na(o.redirectedFrom),null,r):o;s[f]=va(n,d,this.exactPath),s[p]=this.exact||this.exactPath?s[f]:function(e,t){return 0===e.path.replace(ua,"/").indexOf(t.path.replace(ua,"/"))&&(!t.hash||e.hash===t.hash)&&function(e,t){for(var r in t)if(!(r in e))return!1;return!0}(e.query,t.query)}(n,d);var A=s[f]?this.ariaCurrentValue:null,v=function(e){Ha(e)&&(t.replace?r.replace(a,za):r.push(a,za))},m={click:Ha};Array.isArray(this.event)?this.event.forEach((function(e){m[e]=v})):m[this.event]=v;var C={class:s},B=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:l,route:o,navigate:v,isActive:s[p],isExactActive:s[f]});if(B){if(1===B.length)return B[0];if(B.length>1||!B.length)return 0===B.length?e():e("span",{},B)}if("a"===this.tag)C.on=m,C.attrs={href:l,"aria-current":A};else{var g=function e(t){var r;if(t)for(var n=0;n-1&&(l.params[E]=r.params[E]);return l.path=Ga(c.path,l.params),s(c,l,o)}if(l.path){l.params={};for(var p=0;p-1}function _o(e,t){return bo(e)&&e._isRouter&&(null==t||e.type===t)}function Fo(e,t,r){var n=function(i){i>=e.length?r():e[i]?t(e[i],(function(){n(i+1)})):n(i+1)};n(0)}function wo(e){return function(t,r,n){var i=!1,a=0,o=null;Lo(e,(function(e,t,r,l){if("function"==typeof e&&void 0===e.cid){i=!0,a++;var s,h=ko((function(t){var i;((i=t).__esModule||xo&&"Module"===i[Symbol.toStringTag])&&(t=t.default),e.resolved="function"==typeof t?t:Ua.extend(t),r.components[l]=t,--a<=0&&n()})),c=ko((function(e){var t="Failed to resolve async component "+l+": "+e;o||(o=bo(e)?e:new Error(t),n(o))}));try{s=e(h,c)}catch(e){c(e)}if(s)if("function"==typeof s.then)s.then(h,c);else{var u=s.component;u&&"function"==typeof u.then&&u.then(h,c)}}})),i||n()}}function Lo(e,t){return Do(e.map((function(e){return Object.keys(e.components).map((function(r){return t(e.components[r],e.instances[r],e,r)}))})))}function Do(e){return Array.prototype.concat.apply([],e)}var xo="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function ko(e){var t=!1;return function(){for(var r=[],n=arguments.length;n--;)r[n]=arguments[n];if(!t)return t=!0,e.apply(this,r)}}var So=function(e,t){this.router=e,this.base=function(e){if(!e)if(Wa){var t=document.querySelector("base");e=(e=t&&t.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else e="/";"/"!==e.charAt(0)&&(e="/"+e);return e.replace(/\/$/,"")}(t),this.current=fa,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function Po(e,t,r,n){var i=Lo(e,(function(e,n,i,a){var o=function(e,t){"function"!=typeof e&&(e=Ua.extend(e));return e.options[t]}(e,t);if(o)return Array.isArray(o)?o.map((function(e){return r(e,n,i,a)})):r(o,n,i,a)}));return Do(n?i.reverse():i)}function Ro(e,t){if(t)return function(){return e.apply(t,arguments)}}So.prototype.listen=function(e){this.cb=e},So.prototype.onReady=function(e,t){this.ready?e():(this.readyCbs.push(e),t&&this.readyErrorCbs.push(t))},So.prototype.onError=function(e){this.errorCbs.push(e)},So.prototype.transitionTo=function(e,t,r){var n,i=this;try{n=this.router.match(e,this.current)}catch(e){throw this.errorCbs.forEach((function(t){t(e)})),e}var a=this.current;this.confirmTransition(n,(function(){i.updateRoute(n),t&&t(n),i.ensureURL(),i.router.afterHooks.forEach((function(e){e&&e(n,a)})),i.ready||(i.ready=!0,i.readyCbs.forEach((function(e){e(n)})))}),(function(e){r&&r(e),e&&!i.ready&&(_o(e,mo.redirected)&&a===fa||(i.ready=!0,i.readyErrorCbs.forEach((function(t){t(e)}))))}))},So.prototype.confirmTransition=function(e,t,r){var n=this,i=this.current;this.pending=e;var a,o,l=function(e){!_o(e)&&bo(e)&&(n.errorCbs.length?n.errorCbs.forEach((function(t){t(e)})):console.error(e)),r&&r(e)},s=e.matched.length-1,h=i.matched.length-1;if(va(e,i)&&s===h&&e.matched[s]===i.matched[h])return this.ensureURL(),e.hash&&ao(this.router,i,e,!1),l(((o=go(a=i,e,mo.duplicated,'Avoided redundant navigation to current location: "'+a.fullPath+'".')).name="NavigationDuplicated",o));var c=function(e,t){var r,n=Math.max(e.length,t.length);for(r=0;r0)){var t=this.router,r=t.options.scrollBehavior,n=fo&&r;n&&this.listeners.push(io());var i=function(){var r=e.current,i=Oo(e.base);e.current===fa&&i===e._startLocation||e.transitionTo(i,(function(e){n&&ao(t,e,r,!0)}))};window.addEventListener("popstate",i),this.listeners.push((function(){window.removeEventListener("popstate",i)}))}},t.prototype.go=function(e){window.history.go(e)},t.prototype.push=function(e,t,r){var n=this,i=this.current;this.transitionTo(e,(function(e){Ao(ba(n.base+e.fullPath)),ao(n.router,e,i,!1),t&&t(e)}),r)},t.prototype.replace=function(e,t,r){var n=this,i=this.current;this.transitionTo(e,(function(e){vo(ba(n.base+e.fullPath)),ao(n.router,e,i,!1),t&&t(e)}),r)},t.prototype.ensureURL=function(e){if(Oo(this.base)!==this.current.fullPath){var t=ba(this.base+this.current.fullPath);e?Ao(t):vo(t)}},t.prototype.getCurrentLocation=function(){return Oo(this.base)},t}(So);function Oo(e){var t=window.location.pathname,r=t.toLowerCase(),n=e.toLowerCase();return!e||r!==n&&0!==r.indexOf(ba(n+"/"))||(t=t.slice(e.length)),(t||"/")+window.location.search+window.location.hash}var jo=function(e){function t(t,r,n){e.call(this,t,r),n&&function(e){var t=Oo(e);if(!/^\/#/.test(t))return window.location.replace(ba(e+"/#"+t)),!0}(this.base)||$o()}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.setupListeners=function(){var e=this;if(!(this.listeners.length>0)){var t=this.router.options.scrollBehavior,r=fo&&t;r&&this.listeners.push(io());var n=function(){var t=e.current;$o()&&e.transitionTo(Mo(),(function(n){r&&ao(e.router,n,t,!0),fo||Go(n.fullPath)}))},i=fo?"popstate":"hashchange";window.addEventListener(i,n),this.listeners.push((function(){window.removeEventListener(i,n)}))}},t.prototype.push=function(e,t,r){var n=this,i=this.current;this.transitionTo(e,(function(e){Io(e.fullPath),ao(n.router,e,i,!1),t&&t(e)}),r)},t.prototype.replace=function(e,t,r){var n=this,i=this.current;this.transitionTo(e,(function(e){Go(e.fullPath),ao(n.router,e,i,!1),t&&t(e)}),r)},t.prototype.go=function(e){window.history.go(e)},t.prototype.ensureURL=function(e){var t=this.current.fullPath;Mo()!==t&&(e?Io(t):Go(t))},t.prototype.getCurrentLocation=function(){return Mo()},t}(So);function $o(){var e=Mo();return"/"===e.charAt(0)||(Go("/"+e),!1)}function Mo(){var e=window.location.href,t=e.indexOf("#");return t<0?"":e=e.slice(t+1)}function Vo(e){var t=window.location.href,r=t.indexOf("#");return(r>=0?t.slice(0,r):t)+"#"+e}function Io(e){fo?Ao(Vo(e)):window.location.hash=e}function Go(e){fo?vo(Vo(e)):window.location.replace(Vo(e))}var No=function(e){function t(t,r){e.call(this,t,r),this.stack=[],this.index=-1}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.push=function(e,t,r){var n=this;this.transitionTo(e,(function(e){n.stack=n.stack.slice(0,n.index+1).concat(e),n.index++,t&&t(e)}),r)},t.prototype.replace=function(e,t,r){var n=this;this.transitionTo(e,(function(e){n.stack=n.stack.slice(0,n.index).concat(e),t&&t(e)}),r)},t.prototype.go=function(e){var t=this,r=this.index+e;if(!(r<0||r>=this.stack.length)){var n=this.stack[r];this.confirmTransition(n,(function(){var e=t.current;t.index=r,t.updateRoute(n),t.router.afterHooks.forEach((function(t){t&&t(n,e)}))}),(function(e){_o(e,mo.duplicated)&&(t.index=r)}))}},t.prototype.getCurrentLocation=function(){var e=this.stack[this.stack.length-1];return e?e.fullPath:"/"},t.prototype.ensureURL=function(){},t}(So),Uo=function(e){void 0===e&&(e={}),this.app=null,this.apps=[],this.options=e,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Ja(e.routes||[],this);var t=e.mode||"hash";switch(this.fallback="history"===t&&!fo&&!1!==e.fallback,this.fallback&&(t="hash"),Wa||(t="abstract"),this.mode=t,t){case"history":this.history=new To(this,e.base);break;case"hash":this.history=new jo(this,e.base,this.fallback);break;case"abstract":this.history=new No(this,e.base);break;default:0}},zo={currentRoute:{configurable:!0}};Uo.prototype.match=function(e,t,r){return this.matcher.match(e,t,r)},zo.currentRoute.get=function(){return this.history&&this.history.current},Uo.prototype.init=function(e){var t=this;if(this.apps.push(e),e.$once("hook:destroyed",(function(){var r=t.apps.indexOf(e);r>-1&&t.apps.splice(r,1),t.app===e&&(t.app=t.apps[0]||null),t.app||t.history.teardown()})),!this.app){this.app=e;var r=this.history;if(r instanceof To||r instanceof jo){var n=function(e){r.setupListeners(),function(e){var n=r.current,i=t.options.scrollBehavior;fo&&i&&"fullPath"in e&&ao(t,e,n,!1)}(e)};r.transitionTo(r.getCurrentLocation(),n,n)}r.listen((function(e){t.apps.forEach((function(t){t._route=e}))}))}},Uo.prototype.beforeEach=function(e){return Ho(this.beforeHooks,e)},Uo.prototype.beforeResolve=function(e){return Ho(this.resolveHooks,e)},Uo.prototype.afterEach=function(e){return Ho(this.afterHooks,e)},Uo.prototype.onReady=function(e,t){this.history.onReady(e,t)},Uo.prototype.onError=function(e){this.history.onError(e)},Uo.prototype.push=function(e,t,r){var n=this;if(!t&&!r&&"undefined"!=typeof Promise)return new Promise((function(t,r){n.history.push(e,t,r)}));this.history.push(e,t,r)},Uo.prototype.replace=function(e,t,r){var n=this;if(!t&&!r&&"undefined"!=typeof Promise)return new Promise((function(t,r){n.history.replace(e,t,r)}));this.history.replace(e,t,r)},Uo.prototype.go=function(e){this.history.go(e)},Uo.prototype.back=function(){this.go(-1)},Uo.prototype.forward=function(){this.go(1)},Uo.prototype.getMatchedComponents=function(e){var t=e?e.matched?e:this.resolve(e).route:this.currentRoute;return t?[].concat.apply([],t.matched.map((function(e){return Object.keys(e.components).map((function(t){return e.components[t]}))}))):[]},Uo.prototype.resolve=function(e,t,r){var n=Na(e,t=t||this.history.current,r,this),i=this.match(n,t),a=i.redirectedFrom||i.fullPath;return{location:n,route:i,href:function(e,t,r){var n="hash"===r?"#"+t:t;return e?ba(e+"/"+n):n}(this.history.base,a,this.mode),normalizedTo:n,resolved:i}},Uo.prototype.getRoutes=function(){return this.matcher.getRoutes()},Uo.prototype.addRoute=function(e,t){this.matcher.addRoute(e,t),this.history.current!==fa&&this.history.transitionTo(this.history.getCurrentLocation())},Uo.prototype.addRoutes=function(e){this.matcher.addRoutes(e),this.history.current!==fa&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(Uo.prototype,zo);var qo=Uo;function Ho(e,t){return e.push(t),function(){var r=e.indexOf(t);r>-1&&e.splice(r,1)}}Uo.install=function e(t){if(!e.installed||Ua!==t){e.installed=!0,Ua=t;var r=function(e){return void 0!==e},n=function(e,t){var n=e.$options._parentVnode;r(n)&&r(n=n.data)&&r(n=n.registerRouteInstance)&&n(e,t)};t.mixin({beforeCreate:function(){r(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),t.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,n(this,this)},destroyed:function(){n(this)}}),Object.defineProperty(t.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(t.prototype,"$route",{get:function(){return this._routerRoot._route}}),t.component("RouterView",Ba),t.component("RouterLink",qa);var i=t.config.optionMergeStrategies;i.beforeRouteEnter=i.beforeRouteLeave=i.beforeRouteUpdate=i.created}},Uo.version="3.6.5",Uo.isNavigationFailure=_o,Uo.NavigationFailureType=mo,Uo.START_LOCATION=fa,Wa&&window.Vue&&window.Vue.use(Uo);r(96);r(123),r(45);var Wo={"components/AlgoliaSearchBox":()=>Promise.all([r.e(0),r.e(14)]).then(r.bind(null,380)),"components/DropdownLink":()=>Promise.all([r.e(0),r.e(15)]).then(r.bind(null,256)),"components/DropdownTransition":()=>Promise.all([r.e(0),r.e(30)]).then(r.bind(null,244)),"components/Home":()=>Promise.all([r.e(0),r.e(22)]).then(r.bind(null,282)),"components/Navbar":()=>Promise.all([r.e(0),r.e(1)]).then(r.bind(null,377)),"components/NavLink":()=>r.e(38).then(r.bind(null,243)),"components/NavLinks":()=>Promise.all([r.e(0),r.e(12)]).then(r.bind(null,267)),"components/Page":()=>Promise.all([r.e(0),r.e(11)]).then(r.bind(null,283)),"components/PageEdit":()=>Promise.all([r.e(0),r.e(23)]).then(r.bind(null,269)),"components/PageNav":()=>Promise.all([r.e(0),r.e(19)]).then(r.bind(null,270)),"components/Sidebar":()=>Promise.all([r.e(0),r.e(10)]).then(r.bind(null,284)),"components/SidebarButton":()=>Promise.all([r.e(0),r.e(31)]).then(r.bind(null,285)),"components/SidebarGroup":()=>Promise.all([r.e(0),r.e(3)]).then(r.bind(null,268)),"components/SidebarLink":()=>Promise.all([r.e(0),r.e(27)]).then(r.bind(null,257)),"components/SidebarLinks":()=>Promise.all([r.e(0),r.e(3)]).then(r.bind(null,255)),"global-components/Badge":()=>Promise.all([r.e(0),r.e(4)]).then(r.bind(null,385)),"global-components/CodeBlock":()=>Promise.all([r.e(0),r.e(5)]).then(r.bind(null,381)),"global-components/CodeGroup":()=>Promise.all([r.e(0),r.e(6)]).then(r.bind(null,382)),"layouts/404":()=>r.e(7).then(r.bind(null,383)),"layouts/Layout":()=>Promise.all([r.e(0),r.e(1),r.e(2)]).then(r.bind(null,384)),NotFound:()=>r.e(7).then(r.bind(null,383)),Layout:()=>Promise.all([r.e(0),r.e(1),r.e(2)]).then(r.bind(null,384))},Ko={"v-b24efa9a":()=>r.e(52).then(r.bind(null,386)),"v-73f1d486":()=>r.e(53).then(r.bind(null,387)),"v-1de65ad4":()=>r.e(54).then(r.bind(null,388)),"v-616a2bd1":()=>r.e(55).then(r.bind(null,389)),"v-1b5ef8cc":()=>r.e(56).then(r.bind(null,390)),"v-7b397256":()=>r.e(57).then(r.bind(null,391)),"v-0d8d83a2":()=>r.e(32).then(r.bind(null,392)),"v-a58f3c46":()=>r.e(39).then(r.bind(null,393)),"v-82f1c112":()=>r.e(59).then(r.bind(null,394)),"v-4a08a0ed":()=>r.e(60).then(r.bind(null,395)),"v-684930b0":()=>r.e(40).then(r.bind(null,396)),"v-42a60b32":()=>r.e(41).then(r.bind(null,397)),"v-5529e8e5":()=>r.e(58).then(r.bind(null,398)),"v-4e706958":()=>r.e(42).then(r.bind(null,399)),"v-35f865e3":()=>r.e(33).then(r.bind(null,400)),"v-c0256cdc":()=>r.e(43).then(r.bind(null,401)),"v-3d196975":()=>r.e(61).then(r.bind(null,402)),"v-4075f022":()=>r.e(44).then(r.bind(null,403)),"v-17521110":()=>r.e(62).then(r.bind(null,404)),"v-7c6e1710":()=>r.e(64).then(r.bind(null,405)),"v-5bcf313c":()=>r.e(63).then(r.bind(null,406)),"v-13f67663":()=>r.e(65).then(r.bind(null,407)),"v-0a8114b8":()=>r.e(45).then(r.bind(null,408)),"v-22b21eac":()=>r.e(67).then(r.bind(null,409)),"v-4d37d972":()=>r.e(68).then(r.bind(null,410)),"v-0d401e18":()=>r.e(66).then(r.bind(null,411)),"v-21624205":()=>r.e(69).then(r.bind(null,412)),"v-68aac09e":()=>r.e(24).then(r.bind(null,413)),"v-65603e35":()=>r.e(70).then(r.bind(null,414)),"v-3923ffea":()=>r.e(71).then(r.bind(null,415)),"v-554dcf2a":()=>r.e(46).then(r.bind(null,416)),"v-48c040f5":()=>r.e(72).then(r.bind(null,417)),"v-5c01da22":()=>r.e(73).then(r.bind(null,418)),"v-2f2496f9":()=>r.e(17).then(r.bind(null,419)),"v-ae29164a":()=>r.e(26).then(r.bind(null,420)),"v-31ab9aa4":()=>r.e(25).then(r.bind(null,421)),"v-75f1ac65":()=>r.e(47).then(r.bind(null,422)),"v-8b0f19d0":()=>r.e(74).then(r.bind(null,423)),"v-63e06dc9":()=>r.e(75).then(r.bind(null,424)),"v-29da66ba":()=>r.e(76).then(r.bind(null,425)),"v-e5986f3c":()=>r.e(77).then(r.bind(null,426)),"v-bae38342":()=>r.e(34).then(r.bind(null,427)),"v-3f5efb4a":()=>r.e(20).then(r.bind(null,428)),"v-197c9364":()=>r.e(21).then(r.bind(null,429)),"v-5dd420e2":()=>r.e(36).then(r.bind(null,430)),"v-d70fb904":()=>r.e(78).then(r.bind(null,431)),"v-0a451f79":()=>r.e(28).then(r.bind(null,432)),"v-7e47bbb5":()=>r.e(35).then(r.bind(null,433)),"v-46f32df9":()=>r.e(48).then(r.bind(null,434)),"v-44186d05":()=>r.e(79).then(r.bind(null,435)),"v-fd681622":()=>r.e(80).then(r.bind(null,436)),"v-ca90c390":()=>r.e(18).then(r.bind(null,437)),"v-425d935b":()=>r.e(29).then(r.bind(null,438)),"v-ae330e80":()=>r.e(81).then(r.bind(null,439)),"v-460e207e":()=>r.e(83).then(r.bind(null,440)),"v-5820d42c":()=>r.e(82).then(r.bind(null,441)),"v-78ff5d78":()=>r.e(37).then(r.bind(null,442)),"v-00c28682":()=>r.e(13).then(r.bind(null,443)),"v-e98c9f74":()=>r.e(84).then(r.bind(null,444)),"v-64cef05d":()=>r.e(86).then(r.bind(null,445)),"v-5f160c32":()=>r.e(87).then(r.bind(null,446)),"v-4f74fc89":()=>r.e(85).then(r.bind(null,447)),"v-261b3d28":()=>r.e(88).then(r.bind(null,448)),"v-9ea0bd9c":()=>r.e(89).then(r.bind(null,449)),"v-f4788b02":()=>r.e(90).then(r.bind(null,450)),"v-702763c5":()=>r.e(91).then(r.bind(null,451)),"v-deecd7d8":()=>r.e(93).then(r.bind(null,452)),"v-75e9fe08":()=>r.e(92).then(r.bind(null,453)),"v-2e6a317e":()=>r.e(94).then(r.bind(null,454)),"v-0a85ee78":()=>r.e(95).then(r.bind(null,455)),"v-6c9c2566":()=>r.e(96).then(r.bind(null,456)),"v-14b38dcc":()=>r.e(97).then(r.bind(null,457)),"v-2832db09":()=>r.e(98).then(r.bind(null,458)),"v-1454065a":()=>r.e(102).then(r.bind(null,459)),"v-60f1b38c":()=>r.e(99).then(r.bind(null,460)),"v-3325c5ea":()=>r.e(49).then(r.bind(null,461)),"v-60fcb6e3":()=>r.e(101).then(r.bind(null,462)),"v-4353bce0":()=>r.e(103).then(r.bind(null,463)),"v-de532b9a":()=>r.e(104).then(r.bind(null,464)),"v-0dd1e8ac":()=>r.e(105).then(r.bind(null,465)),"v-7b684336":()=>r.e(107).then(r.bind(null,466)),"v-435cf352":()=>r.e(108).then(r.bind(null,467)),"v-391322e8":()=>r.e(106).then(r.bind(null,468)),"v-740d92c0":()=>r.e(16).then(r.bind(null,469)),"v-2c2b6c90":()=>r.e(110).then(r.bind(null,470)),"v-952997da":()=>r.e(109).then(r.bind(null,471)),"v-29996ff7":()=>r.e(50).then(r.bind(null,472)),"v-ecf2f5e8":()=>r.e(111).then(r.bind(null,473)),"v-320d8845":()=>r.e(112).then(r.bind(null,474)),"v-83c37b1c":()=>r.e(100).then(r.bind(null,475)),"v-710cb2fd":()=>r.e(113).then(r.bind(null,476)),"v-047e1f3e":()=>r.e(114).then(r.bind(null,477)),"v-21c46276":()=>r.e(51).then(r.bind(null,478)),"v-2f1ebe3a":()=>r.e(115).then(r.bind(null,479))};function Xo(e){const t=Object.create(null);return function(r){return t[r]||(t[r]=e(r))}}const Jo=/-(\w)/g,Yo=Xo(e=>e.replace(Jo,(e,t)=>t?t.toUpperCase():"")),Zo=/\B([A-Z])/g,Qo=Xo(e=>e.replace(Zo,"-$1").toLowerCase()),el=Xo(e=>e.charAt(0).toUpperCase()+e.slice(1));function tl(e,t){if(!t)return;if(e(t))return e(t);return t.includes("-")?e(el(Yo(t))):e(el(t))||e(Qo(t))}const rl=Object.assign({},Wo,Ko),nl=e=>rl[e],il=e=>Ko[e],al=e=>Wo[e],ol=e=>Hr.component(e);function ll(e){return tl(il,e)}function sl(e){return tl(al,e)}function hl(e){return tl(nl,e)}function cl(e){return tl(ol,e)}function ul(...e){return Promise.all(e.filter(e=>e).map(async e=>{if(!cl(e)&&hl(e)){const t=await hl(e)();Hr.component(e,t.default)}}))}function El(e,t){"undefined"!=typeof window&&window.__VUEPRESS__&&(window.__VUEPRESS__[e]=t)}var pl=r(87),fl=r.n(pl),dl=r(88),Al=r.n(dl),vl={created(){if(this.siteMeta=this.$site.headTags.filter(([e])=>"meta"===e).map(([e,t])=>t),this.$ssrContext){const t=this.getMergedMetaTags();this.$ssrContext.title=this.$title,this.$ssrContext.lang=this.$lang,this.$ssrContext.pageMeta=(e=t)?e.map(e=>{let t="{t+=` ${r}="${Al()(e[r])}"`}),t+">"}).join("\n "):"",this.$ssrContext.canonicalLink=Cl(this.$canonicalUrl)}var e},mounted(){this.currentMetaTags=[...document.querySelectorAll("meta")],this.updateMeta(),this.updateCanonicalLink()},methods:{updateMeta(){document.title=this.$title,document.documentElement.lang=this.$lang;const e=this.getMergedMetaTags();this.currentMetaTags=Bl(e,this.currentMetaTags)},getMergedMetaTags(){const e=this.$page.frontmatter.meta||[];return fl()([{name:"description",content:this.$description}],e,this.siteMeta,gl)},updateCanonicalLink(){ml(),this.$canonicalUrl&&document.head.insertAdjacentHTML("beforeend",Cl(this.$canonicalUrl))}},watch:{$page(){this.updateMeta(),this.updateCanonicalLink()}},beforeDestroy(){Bl(null,this.currentMetaTags),ml()}};function ml(){const e=document.querySelector("link[rel='canonical']");e&&e.remove()}function Cl(e=""){return e?``:""}function Bl(e,t){if(t&&[...t].filter(e=>e.parentNode===document.head).forEach(e=>document.head.removeChild(e)),e)return e.map(e=>{const t=document.createElement("meta");return Object.keys(e).forEach(r=>{t.setAttribute(r,e[r])}),document.head.appendChild(t),t})}function gl(e){for(const t of["name","property","itemprop"])if(e.hasOwnProperty(t))return e[t]+t;return JSON.stringify(e)}var yl=r(89),bl={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:r.n(yl)()((function(){this.setActiveHash()}),300),setActiveHash(){const e=[].slice.call(document.querySelectorAll(".sidebar-link")),t=[].slice.call(document.querySelectorAll(".header-anchor")).filter(t=>e.some(e=>e.hash===t.hash)),r=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),n=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),i=window.innerHeight+r;for(let e=0;e=a.parentElement.offsetTop+10&&(!o||r{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},_l=r(22),Fl=r.n(_l),wl=[vl,bl,{mounted(){Fl.a.configure({showSpinner:!1}),this.$router.beforeEach((e,t,r)=>{e.path===t.path||Hr.component(e.name)||Fl.a.start(),r()}),this.$router.afterEach(()=>{Fl.a.done(),this.isSidebarOpen=!1})}}],Ll={name:"GlobalLayout",computed:{layout(){const e=this.getLayout();return El("layout",e),Hr.component(e)}},methods:{getLayout(){if(this.$page.path){const e=this.$page.frontmatter.layout;return e&&(this.$vuepress.getLayoutAsyncComponent(e)||this.$vuepress.getVueComponent(e))?e:"Layout"}return"NotFound"}}},Dl=r(14),xl=Object(Dl.a)(Ll,(function(){return(0,this._self._c)(this.layout,{tag:"component"})}),[],!1,null,null,null).exports;!function(e,t,r){switch(t){case"components":e[t]||(e[t]={}),Object.assign(e[t],r);break;case"mixins":e[t]||(e[t]=[]),e[t].push(...r);break;default:throw new Error("Unknown option name.")}}(xl,"mixins",wl);const kl=[{name:"v-b24efa9a",path:"/Chip/Chip/1.%20%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-b24efa9a").then(r)}},{path:"/Chip/Chip/1. 一生一芯计划.html",redirect:"/Chip/Chip/1.%20%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92.html"},{path:"/Chip/Chip/1. 一生一芯计划.html",redirect:"/Chip/Chip/1.%20%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92.html"},{name:"v-73f1d486",path:"/Chip/Chip/2.%202024.02.21-Chisel.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-73f1d486").then(r)}},{path:"/Chip/Chip/2. 2024.02.21-Chisel.html",redirect:"/Chip/Chip/2.%202024.02.21-Chisel.html"},{path:"/Chip/Chip/2. 2024.02.21-Chisel.html",redirect:"/Chip/Chip/2.%202024.02.21-Chisel.html"},{name:"v-1de65ad4",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/01.Verilog%20%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-1de65ad4").then(r)}},{path:"/Chip/Chip/2023.11.07-Verilog语法/01.Verilog 基础语法.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/01.Verilog%20%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95.html"},{path:"/Chip/Chip/2023.11.07-Verilog语法/01.Verilog 基础语法.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/01.Verilog%20%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95.html"},{name:"v-616a2bd1",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/02.Verilog%20%E6%95%B0%E5%80%BC%E8%A1%A8%E7%A4%BA.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-616a2bd1").then(r)}},{path:"/Chip/Chip/2023.11.07-Verilog语法/02.Verilog 数值表示.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/02.Verilog%20%E6%95%B0%E5%80%BC%E8%A1%A8%E7%A4%BA.html"},{path:"/Chip/Chip/2023.11.07-Verilog语法/02.Verilog 数值表示.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/02.Verilog%20%E6%95%B0%E5%80%BC%E8%A1%A8%E7%A4%BA.html"},{name:"v-1b5ef8cc",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/03.Verilog%20%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-1b5ef8cc").then(r)}},{path:"/Chip/Chip/2023.11.07-Verilog语法/03.Verilog 数据类型.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/03.Verilog%20%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.html"},{path:"/Chip/Chip/2023.11.07-Verilog语法/03.Verilog 数据类型.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/03.Verilog%20%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.html"},{name:"v-7b397256",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/04.Verilog%20%E8%A1%A8%E8%BE%BE%E5%BC%8F.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-7b397256").then(r)}},{path:"/Chip/Chip/2023.11.07-Verilog语法/04.Verilog 表达式.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/04.Verilog%20%E8%A1%A8%E8%BE%BE%E5%BC%8F.html"},{path:"/Chip/Chip/2023.11.07-Verilog语法/04.Verilog 表达式.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/04.Verilog%20%E8%A1%A8%E8%BE%BE%E5%BC%8F.html"},{name:"v-0d8d83a2",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/2023.11.15-Vivado.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-0d8d83a2").then(r)}},{path:"/Chip/Chip/2023.11.07-Verilog语法/2023.11.15-Vivado.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/2023.11.15-Vivado.html"},{path:"/Chip/Chip/2023.11.07-Verilog语法/2023.11.15-Vivado.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/2023.11.15-Vivado.html"},{name:"v-a58f3c46",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/10.Verilog%20%E5%A4%9A%E8%B7%AF%E5%88%86%E6%94%AF%E8%AF%AD%E5%8F%A5.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-a58f3c46").then(r)}},{path:"/Chip/Chip/2023.11.07-Verilog语法/10.Verilog 多路分支语句.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/10.Verilog%20%E5%A4%9A%E8%B7%AF%E5%88%86%E6%94%AF%E8%AF%AD%E5%8F%A5.html"},{path:"/Chip/Chip/2023.11.07-Verilog语法/10.Verilog 多路分支语句.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/10.Verilog%20%E5%A4%9A%E8%B7%AF%E5%88%86%E6%94%AF%E8%AF%AD%E5%8F%A5.html"},{name:"v-82f1c112",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.21-1%20Introduction%20to%20Scala.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-82f1c112").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.21-1 Introduction to Scala.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.21-1%20Introduction%20to%20Scala.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.21-1 Introduction to Scala.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.21-1%20Introduction%20to%20Scala.html"},{name:"v-4a08a0ed",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.23-2.1%20First%20Chisel%20Module.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-4a08a0ed").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.23-2.1 First Chisel Module.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.23-2.1%20First%20Chisel%20Module.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.23-2.1 First Chisel Module.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.23-2.1%20First%20Chisel%20Module.html"},{name:"v-684930b0",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.24-2.2%20Combinational%20Logic.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-684930b0").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.24-2.2 Combinational Logic.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.24-2.2%20Combinational%20Logic.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.24-2.2 Combinational Logic.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.24-2.2%20Combinational%20Logic.html"},{name:"v-42a60b32",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.25-2.3%20Control%20Flow.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-42a60b32").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.25-2.3 Control Flow.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.25-2.3%20Control%20Flow.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.25-2.3 Control Flow.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.25-2.3%20Control%20Flow.html"},{name:"v-5529e8e5",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-5529e8e5").then(r)}},{name:"v-4e706958",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.26-2.4%20Sequential%20Logic.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-4e706958").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.26-2.4 Sequential Logic.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.26-2.4%20Sequential%20Logic.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.26-2.4 Sequential Logic.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.26-2.4%20Sequential%20Logic.html"},{name:"v-35f865e3",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/2023.11.16-%E9%98%BB%E5%A1%9E%E4%B8%8E%E9%9D%9E%E9%98%BB%E5%A1%9E%E8%B5%8B%E5%80%BC.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-35f865e3").then(r)}},{path:"/Chip/Chip/2023.11.07-Verilog语法/2023.11.16-阻塞与非阻塞赋值.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/2023.11.16-%E9%98%BB%E5%A1%9E%E4%B8%8E%E9%9D%9E%E9%98%BB%E5%A1%9E%E8%B5%8B%E5%80%BC.html"},{path:"/Chip/Chip/2023.11.07-Verilog语法/2023.11.16-阻塞与非阻塞赋值.html",redirect:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/2023.11.16-%E9%98%BB%E5%A1%9E%E4%B8%8E%E9%9D%9E%E9%98%BB%E5%A1%9E%E8%B5%8B%E5%80%BC.html"},{name:"v-c0256cdc",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.28-2.5%20FIR%20Filter.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-c0256cdc").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.28-2.5 FIR Filter.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.28-2.5%20FIR%20Filter.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.28-2.5 FIR Filter.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.28-2.5%20FIR%20Filter.html"},{name:"v-3d196975",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.29-2.6%20More%20on%20ChiselTest.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-3d196975").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.29-2.6 More on ChiselTest.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.29-2.6%20More%20on%20ChiselTest.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.29-2.6 More on ChiselTest.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.29-2.6%20More%20on%20ChiselTest.html"},{name:"v-4075f022",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.01-3.1%20Generators%20Parameters.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-4075f022").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.01-3.1 Generators Parameters.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.01-3.1%20Generators%20Parameters.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.01-3.1 Generators Parameters.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.01-3.1%20Generators%20Parameters.html"},{name:"v-17521110",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.03-3.2%20Generators%20Collections.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-17521110").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.03-3.2 Generators Collections.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.03-3.2%20Generators%20Collections.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.03-3.2 Generators Collections.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.03-3.2%20Generators%20Collections.html"},{name:"v-7c6e1710",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.05-3.4%20Higher-Order%20Functions.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-7c6e1710").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.05-3.4 Higher-Order Functions.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.05-3.4%20Higher-Order%20Functions.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.05-3.4 Higher-Order Functions.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.05-3.4%20Higher-Order%20Functions.html"},{name:"v-5bcf313c",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.04-3.3%20Interlude%20Chisel%20Standard%20Library.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-5bcf313c").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.04-3.3 Interlude Chisel Standard Library.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.04-3.3%20Interlude%20Chisel%20Standard%20Library.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.04-3.3 Interlude Chisel Standard Library.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.04-3.3%20Interlude%20Chisel%20Standard%20Library.html"},{name:"v-13f67663",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.09-3.6%20Object%20Oriented%20Programming.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-13f67663").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.09-3.6 Object Oriented Programming.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.09-3.6%20Object%20Oriented%20Programming.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.09-3.6 Object Oriented Programming.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.09-3.6%20Object%20Oriented%20Programming.html"},{name:"v-0a8114b8",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.07-3.5%20Functional%20Programming.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-0a8114b8").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.07-3.5 Functional Programming.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.07-3.5%20Functional%20Programming.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.07-3.5 Functional Programming.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.07-3.5%20Functional%20Programming.html"},{name:"v-22b21eac",path:"/Chip/Chip/3.%202023.11.07-Verilog%E8%AF%AD%E6%B3%95.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-22b21eac").then(r)}},{path:"/Chip/Chip/3. 2023.11.07-Verilog语法.html",redirect:"/Chip/Chip/3.%202023.11.07-Verilog%E8%AF%AD%E6%B3%95.html"},{path:"/Chip/Chip/3. 2023.11.07-Verilog语法.html",redirect:"/Chip/Chip/3.%202023.11.07-Verilog%E8%AF%AD%E6%B3%95.html"},{name:"v-4d37d972",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-4d37d972").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5.html"},{name:"v-0d401e18",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.12-3.7%20Generators%20Types.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-0d401e18").then(r)}},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.12-3.7 Generators Types.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.12-3.7%20Generators%20Types.html"},{path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.12-3.7 Generators Types.html",redirect:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.12-3.7%20Generators%20Types.html"},{name:"v-21624205",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-21624205").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way.html"},{name:"v-68aac09e",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A01%EF%BC%9A%E5%90%AF%E7%94%A8%E7%BC%96%E8%AF%91%E5%99%A8.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-68aac09e").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.02-练习1:启用编译器.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A01%EF%BC%9A%E5%90%AF%E7%94%A8%E7%BC%96%E8%AF%91%E5%99%A8.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.02-练习1:启用编译器.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A01%EF%BC%9A%E5%90%AF%E7%94%A8%E7%BC%96%E8%AF%91%E5%99%A8.html"},{name:"v-65603e35",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A03%EF%BC%9A%E6%A0%BC%E5%BC%8F%E5%8C%96%E8%BE%93%E5%87%BA.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-65603e35").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.02-练习3:格式化输出.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A03%EF%BC%9A%E6%A0%BC%E5%BC%8F%E5%8C%96%E8%BE%93%E5%87%BA.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.02-练习3:格式化输出.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A03%EF%BC%9A%E6%A0%BC%E5%BC%8F%E5%8C%96%E8%BE%93%E5%87%BA.html"},{name:"v-3923ffea",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A04%EF%BC%9AValgrind%20%E4%BB%8B%E7%BB%8D.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-3923ffea").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习4:Valgrind 介绍.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A04%EF%BC%9AValgrind%20%E4%BB%8B%E7%BB%8D.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习4:Valgrind 介绍.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A04%EF%BC%9AValgrind%20%E4%BB%8B%E7%BB%8D.html"},{name:"v-554dcf2a",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A02%EF%BC%9A%E7%94%A8Make%E6%9D%A5%E4%BB%A3%E6%9B%BFPython.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-554dcf2a").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.02-练习2:用Make来代替Python.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A02%EF%BC%9A%E7%94%A8Make%E6%9D%A5%E4%BB%A3%E6%9B%BFPython.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.02-练习2:用Make来代替Python.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A02%EF%BC%9A%E7%94%A8Make%E6%9D%A5%E4%BB%A3%E6%9B%BFPython.html"},{name:"v-48c040f5",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A05%EF%BC%9A%E4%B8%80%E4%B8%AAC%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%BB%93%E6%9E%84.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-48c040f5").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习5:一个C程序的结构.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A05%EF%BC%9A%E4%B8%80%E4%B8%AAC%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%BB%93%E6%9E%84.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习5:一个C程序的结构.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A05%EF%BC%9A%E4%B8%80%E4%B8%AAC%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%BB%93%E6%9E%84.html"},{name:"v-5c01da22",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A06%EF%BC%9A%E5%8F%98%E9%87%8F%E7%B1%BB%E5%9E%8B.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-5c01da22").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习6:变量类型.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A06%EF%BC%9A%E5%8F%98%E9%87%8F%E7%B1%BB%E5%9E%8B.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习6:变量类型.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A06%EF%BC%9A%E5%8F%98%E9%87%8F%E7%B1%BB%E5%9E%8B.html"},{name:"v-2f2496f9",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A08%EF%BC%9A%E5%A4%A7%E5%B0%8F%E5%92%8C%E6%95%B0%E7%BB%84.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-2f2496f9").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习8:大小和数组.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A08%EF%BC%9A%E5%A4%A7%E5%B0%8F%E5%92%8C%E6%95%B0%E7%BB%84.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习8:大小和数组.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A08%EF%BC%9A%E5%A4%A7%E5%B0%8F%E5%92%8C%E6%95%B0%E7%BB%84.html"},{name:"v-ae29164a",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A09%EF%BC%9A%E6%95%B0%E7%BB%84%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-ae29164a").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习9:数组和字符串.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A09%EF%BC%9A%E6%95%B0%E7%BB%84%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习9:数组和字符串.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A09%EF%BC%9A%E6%95%B0%E7%BB%84%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2.html"},{name:"v-31ab9aa4",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A07%EF%BC%9A%E6%9B%B4%E5%A4%9A%E5%8F%98%E9%87%8F%E5%92%8C%E4%B8%80%E4%BA%9B%E7%AE%97%E6%9C%AF.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-31ab9aa4").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习7:更多变量和一些算术.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A07%EF%BC%9A%E6%9B%B4%E5%A4%9A%E5%8F%98%E9%87%8F%E5%92%8C%E4%B8%80%E4%BA%9B%E7%AE%97%E6%9C%AF.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习7:更多变量和一些算术.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A07%EF%BC%9A%E6%9B%B4%E5%A4%9A%E5%8F%98%E9%87%8F%E5%92%8C%E4%B8%80%E4%BA%9B%E7%AE%97%E6%9C%AF.html"},{name:"v-75f1ac65",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.04-%E7%BB%83%E4%B9%A010%EF%BC%9A%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%95%B0%E7%BB%84%E5%92%8C%E5%BE%AA%E7%8E%AF.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-75f1ac65").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.04-练习10:字符串数组和循环.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.04-%E7%BB%83%E4%B9%A010%EF%BC%9A%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%95%B0%E7%BB%84%E5%92%8C%E5%BE%AA%E7%8E%AF.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.04-练习10:字符串数组和循环.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.04-%E7%BB%83%E4%B9%A010%EF%BC%9A%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%95%B0%E7%BB%84%E5%92%8C%E5%BE%AA%E7%8E%AF.html"},{name:"v-8b0f19d0",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A011%EF%BC%9AWhile%E5%BE%AA%E7%8E%AF%E5%92%8C%E5%B8%83%E5%B0%94%E8%A1%A8%E8%BE%BE%E5%BC%8F.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-8b0f19d0").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习11:While循环和布尔表达式.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A011%EF%BC%9AWhile%E5%BE%AA%E7%8E%AF%E5%92%8C%E5%B8%83%E5%B0%94%E8%A1%A8%E8%BE%BE%E5%BC%8F.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习11:While循环和布尔表达式.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A011%EF%BC%9AWhile%E5%BE%AA%E7%8E%AF%E5%92%8C%E5%B8%83%E5%B0%94%E8%A1%A8%E8%BE%BE%E5%BC%8F.html"},{name:"v-63e06dc9",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A012%EF%BC%9AIf%EF%BC%8CElse%20If%EF%BC%8CElse.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-63e06dc9").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习12:If,Else If,Else.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A012%EF%BC%9AIf%EF%BC%8CElse%20If%EF%BC%8CElse.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习12:If,Else If,Else.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A012%EF%BC%9AIf%EF%BC%8CElse%20If%EF%BC%8CElse.html"},{name:"v-29da66ba",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A013%EF%BC%9ASwitch%E8%AF%AD%E5%8F%A5.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-29da66ba").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习13:Switch语句.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A013%EF%BC%9ASwitch%E8%AF%AD%E5%8F%A5.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习13:Switch语句.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A013%EF%BC%9ASwitch%E8%AF%AD%E5%8F%A5.html"},{name:"v-e5986f3c",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A014%EF%BC%9A%E7%BC%96%E5%86%99%E5%B9%B6%E4%BD%BF%E7%94%A8%E5%87%BD%E6%95%B0.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-e5986f3c").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习14:编写并使用函数.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A014%EF%BC%9A%E7%BC%96%E5%86%99%E5%B9%B6%E4%BD%BF%E7%94%A8%E5%87%BD%E6%95%B0.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习14:编写并使用函数.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A014%EF%BC%9A%E7%BC%96%E5%86%99%E5%B9%B6%E4%BD%BF%E7%94%A8%E5%87%BD%E6%95%B0.html"},{name:"v-bae38342",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A015%EF%BC%9A%E6%8C%87%E9%92%88%EF%BC%8C%E5%8F%AF%E6%80%95%E7%9A%84%E6%8C%87%E9%92%88.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-bae38342").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习15:指针,可怕的指针.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A015%EF%BC%9A%E6%8C%87%E9%92%88%EF%BC%8C%E5%8F%AF%E6%80%95%E7%9A%84%E6%8C%87%E9%92%88.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习15:指针,可怕的指针.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A015%EF%BC%9A%E6%8C%87%E9%92%88%EF%BC%8C%E5%8F%AF%E6%80%95%E7%9A%84%E6%8C%87%E9%92%88.html"},{name:"v-3f5efb4a",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A016%EF%BC%9A%E7%BB%93%E6%9E%84%E4%BD%93%E5%92%8C%E6%8C%87%E5%90%91%E5%AE%83%E4%BB%AC%E7%9A%84%E6%8C%87%E9%92%88.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-3f5efb4a").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习16:结构体和指向它们的指针.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A016%EF%BC%9A%E7%BB%93%E6%9E%84%E4%BD%93%E5%92%8C%E6%8C%87%E5%90%91%E5%AE%83%E4%BB%AC%E7%9A%84%E6%8C%87%E9%92%88.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习16:结构体和指向它们的指针.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A016%EF%BC%9A%E7%BB%93%E6%9E%84%E4%BD%93%E5%92%8C%E6%8C%87%E5%90%91%E5%AE%83%E4%BB%AC%E7%9A%84%E6%8C%87%E9%92%88.html"},{name:"v-197c9364",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.10-%E7%BB%83%E4%B9%A018%EF%BC%9A%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-197c9364").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.10-练习18:函数指针.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.10-%E7%BB%83%E4%B9%A018%EF%BC%9A%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.10-练习18:函数指针.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.10-%E7%BB%83%E4%B9%A018%EF%BC%9A%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88.html"},{name:"v-5dd420e2",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.11-%E7%BB%83%E4%B9%A042%EF%BC%9A%E6%A0%88%E5%92%8C%E9%98%9F%E5%88%97.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-5dd420e2").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.11-练习42:栈和队列.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.11-%E7%BB%83%E4%B9%A042%EF%BC%9A%E6%A0%88%E5%92%8C%E9%98%9F%E5%88%97.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.11-练习42:栈和队列.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.11-%E7%BB%83%E4%B9%A042%EF%BC%9A%E6%A0%88%E5%92%8C%E9%98%9F%E5%88%97.html"},{name:"v-d70fb904",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.10-%E7%BB%83%E4%B9%A032%EF%BC%9A%E5%8F%8C%E5%90%91%E9%93%BE%E8%A1%A8.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-d70fb904").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.10-练习32:双向链表.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.10-%E7%BB%83%E4%B9%A032%EF%BC%9A%E5%8F%8C%E5%90%91%E9%93%BE%E8%A1%A8.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.10-练习32:双向链表.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.10-%E7%BB%83%E4%B9%A032%EF%BC%9A%E5%8F%8C%E5%90%91%E9%93%BE%E8%A1%A8.html"},{name:"v-0a451f79",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.11-%E7%BB%83%E4%B9%A033%EF%BC%9A%E9%93%BE%E8%A1%A8%E7%AE%97%E6%B3%95.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-0a451f79").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.11-练习33:链表算法.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.11-%E7%BB%83%E4%B9%A033%EF%BC%9A%E9%93%BE%E8%A1%A8%E7%AE%97%E6%B3%95.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.11-练习33:链表算法.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.11-%E7%BB%83%E4%B9%A033%EF%BC%9A%E9%93%BE%E8%A1%A8%E7%AE%97%E6%B3%95.html"},{name:"v-7e47bbb5",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.08-%E7%BB%83%E4%B9%A017%EF%BC%9A%E5%A0%86%E5%92%8C%E6%A0%88%E7%9A%84%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-7e47bbb5").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.08-练习17:堆和栈的内存分配.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.08-%E7%BB%83%E4%B9%A017%EF%BC%9A%E5%A0%86%E5%92%8C%E6%A0%88%E7%9A%84%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.08-练习17:堆和栈的内存分配.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.08-%E7%BB%83%E4%B9%A017%EF%BC%9A%E5%A0%86%E5%92%8C%E6%A0%88%E7%9A%84%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D.html"},{name:"v-46f32df9",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.12-%E7%BB%83%E4%B9%A044%EF%BC%9A%E7%8E%AF%E5%BD%A2%E7%BC%93%E5%86%B2%E5%8C%BA.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-46f32df9").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.12-练习44:环形缓冲区.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.12-%E7%BB%83%E4%B9%A044%EF%BC%9A%E7%8E%AF%E5%BD%A2%E7%BC%93%E5%86%B2%E5%8C%BA.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.12-练习44:环形缓冲区.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.12-%E7%BB%83%E4%B9%A044%EF%BC%9A%E7%8E%AF%E5%BD%A2%E7%BC%93%E5%86%B2%E5%8C%BA.html"},{name:"v-44186d05",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-44186d05").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester.html"},{name:"v-fd681622",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.14-1.The%20Shell.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-fd681622").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.14-1.The Shell.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.14-1.The%20Shell.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.14-1.The Shell.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.14-1.The%20Shell.html"},{name:"v-ca90c390",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.19-2.Script.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-ca90c390").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.19-2.Script.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.19-2.Script.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.19-2.Script.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.19-2.Script.html"},{name:"v-425d935b",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.21-4.Data%20Wrangling.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-425d935b").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.21-4.Data Wrangling.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.21-4.Data%20Wrangling.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.21-4.Data Wrangling.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.21-4.Data%20Wrangling.html"},{name:"v-ae330e80",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.20-3.Vim.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-ae330e80").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.20-3.Vim.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.20-3.Vim.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.20-3.Vim.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.20-3.Vim.html"},{name:"v-460e207e",path:"/LeetCode/LeetCode/2024.02.22-BFS.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-460e207e").then(r)}},{name:"v-5820d42c",path:"/Chip/",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-5820d42c").then(r)}},{path:"/Chip/index.html",redirect:"/Chip/"},{name:"v-78ff5d78",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.21-5.Command%20Line%20Interface.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-78ff5d78").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.21-5.Command Line Interface.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.21-5.Command%20Line%20Interface.html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.21-5.Command Line Interface.html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.21-5.Command%20Line%20Interface.html"},{name:"v-00c28682",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.25-6.Version%20Control%20(Git).html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-00c28682").then(r)}},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.25-6.Version Control (Git).html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.25-6.Version%20Control%20(Git).html"},{path:"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.25-6.Version Control (Git).html",redirect:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.25-6.Version%20Control%20(Git).html"},{name:"v-e98c9f74",path:"/LeetCode/LeetCode/2024.02.22-BFS/2024.02.22-752.%E6%89%93%E5%BC%80%E8%BD%AC%E7%9B%98%E9%94%81%EF%BC%88BFS%EF%BC%89.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-e98c9f74").then(r)}},{path:"/LeetCode/LeetCode/2024.02.22-BFS/2024.02.22-752.打开转盘锁(BFS).html",redirect:"/LeetCode/LeetCode/2024.02.22-BFS/2024.02.22-752.%E6%89%93%E5%BC%80%E8%BD%AC%E7%9B%98%E9%94%81%EF%BC%88BFS%EF%BC%89.html"},{path:"/LeetCode/LeetCode/2024.02.22-BFS/2024.02.22-752.打开转盘锁(BFS).html",redirect:"/LeetCode/LeetCode/2024.02.22-BFS/2024.02.22-752.%E6%89%93%E5%BC%80%E8%BD%AC%E7%9B%98%E9%94%81%EF%BC%88BFS%EF%BC%89.html"},{name:"v-64cef05d",path:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-104.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-64cef05d").then(r)}},{path:"/LeetCode/LeetCode/2024.03.05-二叉树/2024.03.05-104.二叉树的最大深度.html",redirect:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-104.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6.html"},{path:"/LeetCode/LeetCode/2024.03.05-二叉树/2024.03.05-104.二叉树的最大深度.html",redirect:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-104.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6.html"},{name:"v-5f160c32",path:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-144.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%89%8D%E5%BA%8F%E9%81%8D%E5%8E%86.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-5f160c32").then(r)}},{path:"/LeetCode/LeetCode/2024.03.05-二叉树/2024.03.05-144.二叉树的前序遍历.html",redirect:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-144.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%89%8D%E5%BA%8F%E9%81%8D%E5%8E%86.html"},{path:"/LeetCode/LeetCode/2024.03.05-二叉树/2024.03.05-144.二叉树的前序遍历.html",redirect:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-144.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%89%8D%E5%BA%8F%E9%81%8D%E5%8E%86.html"},{name:"v-4f74fc89",path:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-4f74fc89").then(r)}},{path:"/LeetCode/LeetCode/2024.03.05-二叉树.html",redirect:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91.html"},{path:"/LeetCode/LeetCode/2024.03.05-二叉树.html",redirect:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91.html"},{name:"v-261b3d28",path:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-543.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E7%9B%B4%E5%BE%84.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-261b3d28").then(r)}},{path:"/LeetCode/LeetCode/2024.03.05-二叉树/2024.03.05-543.二叉树的直径.html",redirect:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-543.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E7%9B%B4%E5%BE%84.html"},{path:"/LeetCode/LeetCode/2024.03.05-二叉树/2024.03.05-543.二叉树的直径.html",redirect:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-543.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E7%9B%B4%E5%BE%84.html"},{name:"v-9ea0bd9c",path:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-9ea0bd9c").then(r)}},{path:"/LeetCode/LeetCode/2024.03.11-二分搜索.html",redirect:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2.html"},{path:"/LeetCode/LeetCode/2024.03.11-二分搜索.html",redirect:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2.html"},{name:"v-f4788b02",path:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2/2024.03.11-34.%E5%9C%A8%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E6%9F%A5%E6%89%BE%E5%85%83%E7%B4%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%92%8C%E6%9C%80%E5%90%8E%E4%B8%80%E4%B8%AA%E4%BD%8D%E7%BD%AE.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-f4788b02").then(r)}},{path:"/LeetCode/LeetCode/2024.03.11-二分搜索/2024.03.11-34.在排序数组中查找元素的第一个和最后一个位置.html",redirect:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2/2024.03.11-34.%E5%9C%A8%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E6%9F%A5%E6%89%BE%E5%85%83%E7%B4%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%92%8C%E6%9C%80%E5%90%8E%E4%B8%80%E4%B8%AA%E4%BD%8D%E7%BD%AE.html"},{path:"/LeetCode/LeetCode/2024.03.11-二分搜索/2024.03.11-34.在排序数组中查找元素的第一个和最后一个位置.html",redirect:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2/2024.03.11-34.%E5%9C%A8%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E6%9F%A5%E6%89%BE%E5%85%83%E7%B4%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%92%8C%E6%9C%80%E5%90%8E%E4%B8%80%E4%B8%AA%E4%BD%8D%E7%BD%AE.html"},{name:"v-702763c5",path:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2/2024.03.11-704.%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-702763c5").then(r)}},{path:"/LeetCode/LeetCode/2024.03.11-二分搜索/2024.03.11-704.二分搜索.html",redirect:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2/2024.03.11-704.%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2.html"},{path:"/LeetCode/LeetCode/2024.03.11-二分搜索/2024.03.11-704.二分搜索.html",redirect:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2/2024.03.11-704.%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2.html"},{name:"v-deecd7d8",path:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.03.18-76.%E6%9C%80%E5%B0%8F%E8%A6%86%E7%9B%96%E5%AD%90%E4%B8%B2.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-deecd7d8").then(r)}},{path:"/LeetCode/LeetCode/2024.03.18-滑动窗口/2024.03.18-76.最小覆盖子串.html",redirect:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.03.18-76.%E6%9C%80%E5%B0%8F%E8%A6%86%E7%9B%96%E5%AD%90%E4%B8%B2.html"},{path:"/LeetCode/LeetCode/2024.03.18-滑动窗口/2024.03.18-76.最小覆盖子串.html",redirect:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.03.18-76.%E6%9C%80%E5%B0%8F%E8%A6%86%E7%9B%96%E5%AD%90%E4%B8%B2.html"},{name:"v-75e9fe08",path:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-75e9fe08").then(r)}},{path:"/LeetCode/LeetCode/2024.03.18-滑动窗口.html",redirect:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3.html"},{path:"/LeetCode/LeetCode/2024.03.18-滑动窗口.html",redirect:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3.html"},{name:"v-2e6a317e",path:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-3.%E6%97%A0%E9%87%8D%E5%A4%8D%E5%AD%97%E7%AC%A6%E7%9A%84%E6%9C%80%E9%95%BF%E5%AD%90%E4%B8%B2.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-2e6a317e").then(r)}},{path:"/LeetCode/LeetCode/2024.03.18-滑动窗口/2024.04.02-3.无重复字符的最长子串.html",redirect:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-3.%E6%97%A0%E9%87%8D%E5%A4%8D%E5%AD%97%E7%AC%A6%E7%9A%84%E6%9C%80%E9%95%BF%E5%AD%90%E4%B8%B2.html"},{path:"/LeetCode/LeetCode/2024.03.18-滑动窗口/2024.04.02-3.无重复字符的最长子串.html",redirect:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-3.%E6%97%A0%E9%87%8D%E5%A4%8D%E5%AD%97%E7%AC%A6%E7%9A%84%E6%9C%80%E9%95%BF%E5%AD%90%E4%B8%B2.html"},{name:"v-0a85ee78",path:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-438.%E6%89%BE%E5%88%B0%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E6%89%80%E6%9C%89%E5%AD%97%E6%AF%8D%E5%BC%82%E4%BD%8D%E8%AF%8D.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-0a85ee78").then(r)}},{path:"/LeetCode/LeetCode/2024.03.18-滑动窗口/2024.04.02-438.找到字符串中所有字母异位词.html",redirect:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-438.%E6%89%BE%E5%88%B0%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E6%89%80%E6%9C%89%E5%AD%97%E6%AF%8D%E5%BC%82%E4%BD%8D%E8%AF%8D.html"},{path:"/LeetCode/LeetCode/2024.03.18-滑动窗口/2024.04.02-438.找到字符串中所有字母异位词.html",redirect:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-438.%E6%89%BE%E5%88%B0%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E6%89%80%E6%9C%89%E5%AD%97%E6%AF%8D%E5%BC%82%E4%BD%8D%E8%AF%8D.html"},{name:"v-6c9c2566",path:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-567.%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%8E%92%E5%88%97.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-6c9c2566").then(r)}},{path:"/LeetCode/LeetCode/2024.03.18-滑动窗口/2024.04.02-567.字符串的排列.html",redirect:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-567.%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%8E%92%E5%88%97.html"},{path:"/LeetCode/LeetCode/2024.03.18-滑动窗口/2024.04.02-567.字符串的排列.html",redirect:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-567.%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%8E%92%E5%88%97.html"},{name:"v-14b38dcc",path:"/LeetCode/",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-14b38dcc").then(r)}},{path:"/LeetCode/index.html",redirect:"/LeetCode/"},{name:"v-2832db09",path:"/",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-2832db09").then(r)}},{path:"/index.html",redirect:"/"},{name:"v-1454065a",path:"/Research/Research/2023-Geant4/2023.03.12-PKA%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-1454065a").then(r)}},{path:"/Research/Research/2023-Geant4/2023.03.12-PKA数据处理.html",redirect:"/Research/Research/2023-Geant4/2023.03.12-PKA%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86.html"},{path:"/Research/Research/2023-Geant4/2023.03.12-PKA数据处理.html",redirect:"/Research/Research/2023-Geant4/2023.03.12-PKA%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86.html"},{name:"v-60f1b38c",path:"/Research/",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-60f1b38c").then(r)}},{path:"/Research/index.html",redirect:"/Research/"},{name:"v-3325c5ea",path:"/Research/Research/2023-Geant4/2023.02.13-%E5%9C%A8%E8%B6%85%E7%AE%97%E4%B8%8A%E6%90%AD%E5%BB%BASingularity%E7%8E%AF%E5%A2%83%E5%B9%B6%E9%85%8D%E7%BD%AEGeant4.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-3325c5ea").then(r)}},{path:"/Research/Research/2023-Geant4/2023.02.13-在超算上搭建Singularity环境并配置Geant4.html",redirect:"/Research/Research/2023-Geant4/2023.02.13-%E5%9C%A8%E8%B6%85%E7%AE%97%E4%B8%8A%E6%90%AD%E5%BB%BASingularity%E7%8E%AF%E5%A2%83%E5%B9%B6%E9%85%8D%E7%BD%AEGeant4.html"},{path:"/Research/Research/2023-Geant4/2023.02.13-在超算上搭建Singularity环境并配置Geant4.html",redirect:"/Research/Research/2023-Geant4/2023.02.13-%E5%9C%A8%E8%B6%85%E7%AE%97%E4%B8%8A%E6%90%AD%E5%BB%BASingularity%E7%8E%AF%E5%A2%83%E5%B9%B6%E9%85%8D%E7%BD%AEGeant4.html"},{name:"v-60fcb6e3",path:"/Research/Research/2023-Geant4/2023.02.27-%E5%A4%84%E7%90%86Geant4%E8%8E%B7%E5%8F%96%E7%9A%84%E6%95%B0%E6%8D%AE.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-60fcb6e3").then(r)}},{path:"/Research/Research/2023-Geant4/2023.02.27-处理Geant4获取的数据.html",redirect:"/Research/Research/2023-Geant4/2023.02.27-%E5%A4%84%E7%90%86Geant4%E8%8E%B7%E5%8F%96%E7%9A%84%E6%95%B0%E6%8D%AE.html"},{path:"/Research/Research/2023-Geant4/2023.02.27-处理Geant4获取的数据.html",redirect:"/Research/Research/2023-Geant4/2023.02.27-%E5%A4%84%E7%90%86Geant4%E8%8E%B7%E5%8F%96%E7%9A%84%E6%95%B0%E6%8D%AE.html"},{name:"v-4353bce0",path:"/Research/Research/2023-Geant4/2023.05.23-Geant4%E5%A4%9A%E7%B2%92%E5%AD%90%E6%BA%90%E8%AE%BE%E7%BD%AE.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-4353bce0").then(r)}},{path:"/Research/Research/2023-Geant4/2023.05.23-Geant4多粒子源设置.html",redirect:"/Research/Research/2023-Geant4/2023.05.23-Geant4%E5%A4%9A%E7%B2%92%E5%AD%90%E6%BA%90%E8%AE%BE%E7%BD%AE.html"},{path:"/Research/Research/2023-Geant4/2023.05.23-Geant4多粒子源设置.html",redirect:"/Research/Research/2023-Geant4/2023.05.23-Geant4%E5%A4%9A%E7%B2%92%E5%AD%90%E6%BA%90%E8%AE%BE%E7%BD%AE.html"},{name:"v-de532b9a",path:"/Research/Research/2023-Geant4/2023.06.14-Geant4%E5%90%84%E7%89%88%E6%9C%AC%E7%9A%84%E5%AE%89%E8%A3%85.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-de532b9a").then(r)}},{path:"/Research/Research/2023-Geant4/2023.06.14-Geant4各版本的安装.html",redirect:"/Research/Research/2023-Geant4/2023.06.14-Geant4%E5%90%84%E7%89%88%E6%9C%AC%E7%9A%84%E5%AE%89%E8%A3%85.html"},{path:"/Research/Research/2023-Geant4/2023.06.14-Geant4各版本的安装.html",redirect:"/Research/Research/2023-Geant4/2023.06.14-Geant4%E5%90%84%E7%89%88%E6%9C%AC%E7%9A%84%E5%AE%89%E8%A3%85.html"},{name:"v-0dd1e8ac",path:"/Research/Research/2023-Geant4/2023.08.28-Geant4%E8%87%AA%E5%AE%9A%E4%B9%89PhysicsList.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-0dd1e8ac").then(r)}},{path:"/Research/Research/2023-Geant4/2023.08.28-Geant4自定义PhysicsList.html",redirect:"/Research/Research/2023-Geant4/2023.08.28-Geant4%E8%87%AA%E5%AE%9A%E4%B9%89PhysicsList.html"},{path:"/Research/Research/2023-Geant4/2023.08.28-Geant4自定义PhysicsList.html",redirect:"/Research/Research/2023-Geant4/2023.08.28-Geant4%E8%87%AA%E5%AE%9A%E4%B9%89PhysicsList.html"},{name:"v-7b684336",path:"/Research/Research/2023-Geant4/2023.12.18-Geant4%E8%87%AA%E5%8A%A8%E5%8C%96.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-7b684336").then(r)}},{path:"/Research/Research/2023-Geant4/2023.12.18-Geant4自动化.html",redirect:"/Research/Research/2023-Geant4/2023.12.18-Geant4%E8%87%AA%E5%8A%A8%E5%8C%96.html"},{path:"/Research/Research/2023-Geant4/2023.12.18-Geant4自动化.html",redirect:"/Research/Research/2023-Geant4/2023.12.18-Geant4%E8%87%AA%E5%8A%A8%E5%8C%96.html"},{name:"v-435cf352",path:"/Research/Research/2023.12.12-Docker.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-435cf352").then(r)}},{name:"v-391322e8",path:"/Research/Research/2023-Geant4/2023.09.05-C++%20Trim%E7%A8%8B%E5%BA%8F.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-391322e8").then(r)}},{path:"/Research/Research/2023-Geant4/2023.09.05-C++ Trim程序.html",redirect:"/Research/Research/2023-Geant4/2023.09.05-C++%20Trim%E7%A8%8B%E5%BA%8F.html"},{path:"/Research/Research/2023-Geant4/2023.09.05-C++ Trim程序.html",redirect:"/Research/Research/2023-Geant4/2023.09.05-C++%20Trim%E7%A8%8B%E5%BA%8F.html"},{name:"v-740d92c0",path:"/Research/Research/2023.12.12-Docker/01.Docker%20%E7%AE%80%E4%BB%8B%E5%92%8C%E5%AE%89%E8%A3%85.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-740d92c0").then(r)}},{path:"/Research/Research/2023.12.12-Docker/01.Docker 简介和安装.html",redirect:"/Research/Research/2023.12.12-Docker/01.Docker%20%E7%AE%80%E4%BB%8B%E5%92%8C%E5%AE%89%E8%A3%85.html"},{path:"/Research/Research/2023.12.12-Docker/01.Docker 简介和安装.html",redirect:"/Research/Research/2023.12.12-Docker/01.Docker%20%E7%AE%80%E4%BB%8B%E5%92%8C%E5%AE%89%E8%A3%85.html"},{name:"v-2c2b6c90",path:"/Research/Research/2023.12.12-Docker/03.%E5%88%B6%E4%BD%9C%E8%87%AA%E5%B7%B1%E7%9A%84%E9%95%9C%E5%83%8F.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-2c2b6c90").then(r)}},{path:"/Research/Research/2023.12.12-Docker/03.制作自己的镜像.html",redirect:"/Research/Research/2023.12.12-Docker/03.%E5%88%B6%E4%BD%9C%E8%87%AA%E5%B7%B1%E7%9A%84%E9%95%9C%E5%83%8F.html"},{path:"/Research/Research/2023.12.12-Docker/03.制作自己的镜像.html",redirect:"/Research/Research/2023.12.12-Docker/03.%E5%88%B6%E4%BD%9C%E8%87%AA%E5%B7%B1%E7%9A%84%E9%95%9C%E5%83%8F.html"},{name:"v-952997da",path:"/Research/Research/2023.12.12-Docker/02.Docker%20%E5%BF%AB%E9%80%9F%E5%AE%89%E8%A3%85%E8%BD%AF%E4%BB%B6.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-952997da").then(r)}},{path:"/Research/Research/2023.12.12-Docker/02.Docker 快速安装软件.html",redirect:"/Research/Research/2023.12.12-Docker/02.Docker%20%E5%BF%AB%E9%80%9F%E5%AE%89%E8%A3%85%E8%BD%AF%E4%BB%B6.html"},{path:"/Research/Research/2023.12.12-Docker/02.Docker 快速安装软件.html",redirect:"/Research/Research/2023.12.12-Docker/02.Docker%20%E5%BF%AB%E9%80%9F%E5%AE%89%E8%A3%85%E8%BD%AF%E4%BB%B6.html"},{name:"v-29996ff7",path:"/Research/Research/2023.12.12-Docker/04.%E7%9B%AE%E5%BD%95%E6%8C%82%E8%BD%BD.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-29996ff7").then(r)}},{path:"/Research/Research/2023.12.12-Docker/04.目录挂载.html",redirect:"/Research/Research/2023.12.12-Docker/04.%E7%9B%AE%E5%BD%95%E6%8C%82%E8%BD%BD.html"},{path:"/Research/Research/2023.12.12-Docker/04.目录挂载.html",redirect:"/Research/Research/2023.12.12-Docker/04.%E7%9B%AE%E5%BD%95%E6%8C%82%E8%BD%BD.html"},{name:"v-ecf2f5e8",path:"/Research/Research/2023.12.12-Docker/05.%E5%A4%9A%E5%AE%B9%E5%99%A8%E9%80%9A%E4%BF%A1.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-ecf2f5e8").then(r)}},{path:"/Research/Research/2023.12.12-Docker/05.多容器通信.html",redirect:"/Research/Research/2023.12.12-Docker/05.%E5%A4%9A%E5%AE%B9%E5%99%A8%E9%80%9A%E4%BF%A1.html"},{path:"/Research/Research/2023.12.12-Docker/05.多容器通信.html",redirect:"/Research/Research/2023.12.12-Docker/05.%E5%A4%9A%E5%AE%B9%E5%99%A8%E9%80%9A%E4%BF%A1.html"},{name:"v-320d8845",path:"/Research/Research/2023.12.12-Docker/06.Docker-Compose.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-320d8845").then(r)}},{name:"v-83c37b1c",path:"/Research/Research/2023-Geant4.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-83c37b1c").then(r)}},{name:"v-710cb2fd",path:"/Research/Research/2023.12.12-Docker/07.%E5%8F%91%E5%B8%83%E5%92%8C%E9%83%A8%E7%BD%B2.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-710cb2fd").then(r)}},{path:"/Research/Research/2023.12.12-Docker/07.发布和部署.html",redirect:"/Research/Research/2023.12.12-Docker/07.%E5%8F%91%E5%B8%83%E5%92%8C%E9%83%A8%E7%BD%B2.html"},{path:"/Research/Research/2023.12.12-Docker/07.发布和部署.html",redirect:"/Research/Research/2023.12.12-Docker/07.%E5%8F%91%E5%B8%83%E5%92%8C%E9%83%A8%E7%BD%B2.html"},{name:"v-047e1f3e",path:"/Research/Research/2023.12.12-Docker/08.%E5%A4%87%E4%BB%BD%E5%92%8C%E8%BF%81%E7%A7%BB%E6%95%B0%E6%8D%AE.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-047e1f3e").then(r)}},{path:"/Research/Research/2023.12.12-Docker/08.备份和迁移数据.html",redirect:"/Research/Research/2023.12.12-Docker/08.%E5%A4%87%E4%BB%BD%E5%92%8C%E8%BF%81%E7%A7%BB%E6%95%B0%E6%8D%AE.html"},{path:"/Research/Research/2023.12.12-Docker/08.备份和迁移数据.html",redirect:"/Research/Research/2023.12.12-Docker/08.%E5%A4%87%E4%BB%BD%E5%92%8C%E8%BF%81%E7%A7%BB%E6%95%B0%E6%8D%AE.html"},{name:"v-21c46276",path:"/Research/Research/2023.12.12-Docker/2023.12.12-%E5%88%B6%E4%BD%9C%E5%AE%9A%E5%88%B6%E9%95%9C%E5%83%8F.html",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-21c46276").then(r)}},{path:"/Research/Research/2023.12.12-Docker/2023.12.12-制作定制镜像.html",redirect:"/Research/Research/2023.12.12-Docker/2023.12.12-%E5%88%B6%E4%BD%9C%E5%AE%9A%E5%88%B6%E9%95%9C%E5%83%8F.html"},{path:"/Research/Research/2023.12.12-Docker/2023.12.12-制作定制镜像.html",redirect:"/Research/Research/2023.12.12-Docker/2023.12.12-%E5%88%B6%E4%BD%9C%E5%AE%9A%E5%88%B6%E9%95%9C%E5%83%8F.html"},{name:"v-2f1ebe3a",path:"/about/",component:xl,beforeEnter:(e,t,r)=>{ul("Layout","v-2f1ebe3a").then(r)}},{path:"/about/index.html",redirect:"/about/"},{path:"*",component:xl}],Sl={title:"Personal Blog --from Outis Li",description:"",base:"/Blog/",headTags:[],pages:[{title:"1. 一生一芯计划",frontmatter:{},regularPath:"/Chip/Chip/1.%20%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92.html",relativePath:"Chip/Chip/1. 一生一芯计划.md",key:"v-b24efa9a",path:"/Chip/Chip/1.%20%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92.html",headers:[{level:2,title:"预学习阶段",slug:"预学习阶段"}],createdTime:170977737e4},{title:"2. 2024.02.21-Chisel",frontmatter:{},regularPath:"/Chip/Chip/2.%202024.02.21-Chisel.html",relativePath:"Chip/Chip/2. 2024.02.21-Chisel.md",key:"v-73f1d486",path:"/Chip/Chip/2.%202024.02.21-Chisel.html",headers:[{level:2,title:"2024.02.21-Chisel Bootcamp",slug:"_2024-02-21-chisel-bootcamp"}],createdTime:170977737e4},{title:"1. Verilog 基础语法",frontmatter:{},regularPath:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/01.Verilog%20%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95.html",relativePath:"Chip/Chip/2023.11.07-Verilog语法/01.Verilog 基础语法.md",key:"v-1de65ad4",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/01.Verilog%20%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95.html",headers:[{level:2,title:"格式",slug:"格式"},{level:3,title:"不换行(不推荐)",slug:"不换行-不推荐"},{level:3,title:"换行(推荐)",slug:"换行-推荐"},{level:2,title:"注释",slug:"注释"},{level:2,title:"标识符与关键字",slug:"标识符与关键字"},{level:3,title:"实例",slug:"实例"}],createdTime:170977737e4},{title:"2. Verilog 数值表示",frontmatter:{},regularPath:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/02.Verilog%20%E6%95%B0%E5%80%BC%E8%A1%A8%E7%A4%BA.html",relativePath:"Chip/Chip/2023.11.07-Verilog语法/02.Verilog 数值表示.md",key:"v-616a2bd1",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/02.Verilog%20%E6%95%B0%E5%80%BC%E8%A1%A8%E7%A4%BA.html",headers:[{level:2,title:"数值种类",slug:"数值种类"},{level:2,title:"整数数值表示方法",slug:"整数数值表示方法"},{level:3,title:"指明位宽:",slug:"指明位宽"},{level:3,title:"不指明位宽:",slug:"不指明位宽"},{level:3,title:"负数表示",slug:"负数表示"},{level:2,title:"实数表示方法",slug:"实数表示方法"},{level:3,title:"十进制:",slug:"十进制"},{level:3,title:"科学计数法:",slug:"科学计数法"},{level:2,title:"字符串表示方法",slug:"字符串表示方法"}],createdTime:170977737e4},{title:"3. Verilog 数据类型",frontmatter:{},regularPath:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/03.Verilog%20%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.html",relativePath:"Chip/Chip/2023.11.07-Verilog语法/03.Verilog 数据类型.md",key:"v-1b5ef8cc",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/03.Verilog%20%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.html",headers:[{level:2,title:"线网(wire)",slug:"线网-wire"},{level:2,title:"寄存器(reg)",slug:"寄存器-reg"},{level:2,title:"向量",slug:"向量"},{level:2,title:"整数,实数,时间寄存器变量",slug:"整数-实数-时间寄存器变量"},{level:3,title:"整数(integer)",slug:"整数-integer"},{level:3,title:"实数(real)",slug:"实数-real"},{level:3,title:"时间(time)",slug:"时间-time"},{level:3,title:"数组",slug:"数组"},{level:2,title:"存储器",slug:"存储器"},{level:2,title:"参数",slug:"参数"},{level:2,title:"字符串",slug:"字符串"}],createdTime:170977737e4},{title:"4. Verilog 表达式",frontmatter:{},regularPath:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/04.Verilog%20%E8%A1%A8%E8%BE%BE%E5%BC%8F.html",relativePath:"Chip/Chip/2023.11.07-Verilog语法/04.Verilog 表达式.md",key:"v-7b397256",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/04.Verilog%20%E8%A1%A8%E8%BE%BE%E5%BC%8F.html",headers:[{level:3,title:"表达式",slug:"表达式"},{level:2,title:"实例",slug:"实例"},{level:3,title:"操作数",slug:"操作数"},{level:2,title:"实例",slug:"实例-2"},{level:3,title:"操作符",slug:"操作符"},{level:3,title:"算术操作符",slug:"算术操作符"},{level:2,title:"实例",slug:"实例-3"},{level:2,title:"实例",slug:"实例-4"},{level:2,title:"实例",slug:"实例-5"},{level:2,title:"实例",slug:"实例-6"},{level:3,title:"关系操作符",slug:"关系操作符"},{level:2,title:"实例",slug:"实例-7"},{level:3,title:"等价操作符",slug:"等价操作符"},{level:2,title:"实例",slug:"实例-8"},{level:3,title:"逻辑操作符",slug:"逻辑操作符"},{level:2,title:"实例",slug:"实例-9"},{level:3,title:"按位操作符",slug:"按位操作符"},{level:2,title:"实例",slug:"实例-10"},{level:3,title:"归约操作符",slug:"归约操作符"},{level:3,title:"移位操作符",slug:"移位操作符"},{level:2,title:"实例",slug:"实例-11"},{level:3,title:"拼接操作符",slug:"拼接操作符"},{level:2,title:"实例",slug:"实例-12"},{level:3,title:"条件操作符",slug:"条件操作符"},{level:2,title:"实例",slug:"实例-13"}],createdTime:170977737e4},{title:"2023.11.15-Vivado",frontmatter:{},regularPath:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/2023.11.15-Vivado.html",relativePath:"Chip/Chip/2023.11.07-Verilog语法/2023.11.15-Vivado.md",key:"v-0d8d83a2",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/2023.11.15-Vivado.html",headers:[{level:2,title:"1. RTL Schematic & Synthesis Schematic",slug:"_1-rtl-schematic-synthesis-schematic"},{level:2,title:"2. Project 汇总中的 LUT,FF,IO,BUFG",slug:"_2-project-汇总中的-lut-ff-io-bufg"},{level:2,title:"3. FPGA 的组成构造",slug:"_3-fpga-的组成构造"}],createdTime:170972353e4},{title:"10. Verilog 多路分支语句",frontmatter:{},regularPath:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/10.Verilog%20%E5%A4%9A%E8%B7%AF%E5%88%86%E6%94%AF%E8%AF%AD%E5%8F%A5.html",relativePath:"Chip/Chip/2023.11.07-Verilog语法/10.Verilog 多路分支语句.md",key:"v-a58f3c46",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/10.Verilog%20%E5%A4%9A%E8%B7%AF%E5%88%86%E6%94%AF%E8%AF%AD%E5%8F%A5.html",headers:[{level:3,title:"关键词:case,选择器",slug:"关键词-case-选择器"},{level:2,title:"case 语句",slug:"case-语句"},{level:3,title:"case 语句支持嵌套使用。",slug:"case-语句支持嵌套使用。"},{level:3,title:"实例",slug:"实例"},{level:3,title:"例如,对 4 路选择器的 case 语句进行扩展,举例如下:",slug:"例如-对-4-路选择器的-case-语句进行扩展-举例如下"},{level:2,title:"casex/casez 语句",slug:"casex-casez-语句"},{level:3,title:"例如用 casez 语句来实现一个 4bit 控制端的 4 路选择选择器。",slug:"例如用-casez-语句来实现一个-4bit-控制端的-4-路选择选择器。"}],createdTime:170972353e4},{title:"2024.02.21-1. Introduction to Scala",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.21-1%20Introduction%20to%20Scala.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.21-1 Introduction to Scala.md",key:"v-82f1c112",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.21-1%20Introduction%20to%20Scala.html",headers:[{level:2,title:"Variables and Constants - var and val",slug:"variables-and-constants-var-and-val"},{level:2,title:"Conditionals",slug:"conditionals"},{level:2,title:"Methods (Functions)",slug:"methods-functions"},{level:2,title:"Overloading Functions",slug:"overloading-functions"},{level:3,title:"Recursive and Nested Functions",slug:"recursive-and-nested-functions"},{level:3,title:"Named Parameters and Parameter Defaults",slug:"named-parameters-and-parameter-defaults"},{level:2,title:"Lists",slug:"lists"},{level:2,title:"for Statement",slug:"for-statement"},{level:2,title:"Packages and Imports",slug:"packages-and-imports"},{level:2,title:"Class",slug:"class"},{level:3,title:"Creating an Instance of a Class",slug:"creating-an-instance-of-a-class"},{level:2,title:"Code Blocks",slug:"code-blocks"},{level:3,title:"Parameterized Code Blocks",slug:"parameterized-code-blocks"}],createdTime:170977737e4},{title:"2024.02.23-2.1 First Chisel Module",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.23-2.1%20First%20Chisel%20Module.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.23-2.1 First Chisel Module.md",key:"v-4a08a0ed",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.23-2.1%20First%20Chisel%20Module.html",headers:[{level:2,title:"Setup",slug:"setup"},{level:2,title:"Example Module",slug:"example-module"},{level:3,title:"Generate Verilog",slug:"generate-verilog"},{level:3,title:"Generate Firrtl",slug:"generate-firrtl"},{level:2,title:"Example Tester",slug:"example-tester"},{level:2,title:'Appendix: A Note on "printf" Debugging',slug:"appendix-a-note-on-printf-debugging"}],createdTime:170977737e4},{title:"2024.02.24-2.2 Combinational Logic",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.24-2.2%20Combinational%20Logic.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.24-2.2 Combinational Logic.md",key:"v-684930b0",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.24-2.2%20Combinational%20Logic.html",headers:[{level:2,title:"Common Operators",slug:"common-operators"},{level:2,title:"Mux and Concatenation",slug:"mux-and-concatenation"},{level:2,title:"MAC: multiply accumulate function",slug:"mac-multiply-accumulate-function"},{level:2,title:"Arbiter",slug:"arbiter"},{level:2,title:"Parameterized Adder",slug:"parameterized-adder"}],createdTime:170977737e4},{title:"2024.02.25-2.3 Control Flow",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.25-2.3%20Control%20Flow.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.25-2.3 Control Flow.md",key:"v-42a60b32",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.25-2.3%20Control%20Flow.html",headers:[{level:2,title:"Last Connect Semantics",slug:"last-connect-semantics"},{level:2,title:"when, elsewhen, and otherwise",slug:"when-elsewhen-and-otherwise"},{level:2,title:"The Wire Construct",slug:"the-wire-construct"},{level:3,title:"Exercise: Polynomial",slug:"exercise-polynomial"},{level:3,title:"Exercise: Finite State Machine",slug:"exercise-finite-state-machine"}],createdTime:170977737e4},{title:"2024.02.21-Chisel BootCamp",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot.md",key:"v-5529e8e5",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot.html",headers:[{level:2,title:"2024.02.21-1. Introduction to Scala",slug:"_2024-02-21-1-introduction-to-scala"},{level:2,title:"2024.02.23-2.1 First Chisel Module",slug:"_2024-02-23-2-1-first-chisel-module"},{level:2,title:"2024.02.24-2.2 Combinational Logic",slug:"_2024-02-24-2-2-combinational-logic"},{level:2,title:"2024.02.25-2.3 Control Flow",slug:"_2024-02-25-2-3-control-flow"},{level:2,title:"2024.02.26-2.4 Sequential Logic",slug:"_2024-02-26-2-4-sequential-logic"},{level:2,title:"2024.02.28-2.5 FIR Filter",slug:"_2024-02-28-2-5-fir-filter"},{level:2,title:"2024.02.29-2.6 More on ChiselTest",slug:"_2024-02-29-2-6-more-on-chiseltest"},{level:2,title:"2024.03.01-3.1 Generators: Parameters",slug:"_2024-03-01-3-1-generators-parameters"},{level:2,title:"2024.03.03-3.2 Generators: Collections",slug:"_2024-03-03-3-2-generators-collections"},{level:2,title:"2024.03.04-3.3 Interlude: Chisel Standard Library",slug:"_2024-03-04-3-3-interlude-chisel-standard-library"},{level:2,title:"2024.03.05-3.4 Higher-Order Functions",slug:"_2024-03-05-3-4-higher-order-functions"},{level:2,title:"2024.03.07-3.5 Functional Programming",slug:"_2024-03-07-3-5-functional-programming"},{level:2,title:"2024.03.08-3.6 Object Oriented Programming",slug:"_2024-03-08-3-6-object-oriented-programming"},{level:2,title:"2024.03.12-3.7 Generator Types",slug:"_2024-03-12-3-7-generator-types"}],createdTime:170977737e4},{title:"2024.02.26-2.4 Sequential Logic",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.26-2.4%20Sequential%20Logic.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.26-2.4 Sequential Logic.md",key:"v-4e706958",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.26-2.4%20Sequential%20Logic.html",headers:[{level:2,title:"Registers",slug:"registers"},{level:3,title:"RegInit",slug:"reginit"},{level:3,title:"RegNext",slug:"regnext"},{level:2,title:"Shift Register",slug:"shift-register"},{level:3,title:"Parameterized Shift Register",slug:"parameterized-shift-register"},{level:2,title:"Appendix: Explicit clock and reset",slug:"appendix-explicit-clock-and-reset"},{level:3,title:"Example: Multi-Clock Module",slug:"example-multi-clock-module"}],createdTime:170977737e4},{title:"2023.11.16-阻塞与非阻塞赋值",frontmatter:{},regularPath:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/2023.11.16-%E9%98%BB%E5%A1%9E%E4%B8%8E%E9%9D%9E%E9%98%BB%E5%A1%9E%E8%B5%8B%E5%80%BC.html",relativePath:"Chip/Chip/2023.11.07-Verilog语法/2023.11.16-阻塞与非阻塞赋值.md",key:"v-35f865e3",path:"/Chip/Chip/2023.11.07-Verilog%E8%AF%AD%E6%B3%95/2023.11.16-%E9%98%BB%E5%A1%9E%E4%B8%8E%E9%9D%9E%E9%98%BB%E5%A1%9E%E8%B5%8B%E5%80%BC.html",headers:[{level:3,title:"阻塞赋值(Blocking Assignment)",slug:"阻塞赋值-blocking-assignment"},{level:3,title:"非阻塞赋值(Non-Blocking Assignment)",slug:"非阻塞赋值-non-blocking-assignment"}],createdTime:170972353e4},{title:"2024.02.28-2.5 FIR Filter",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.28-2.5%20FIR%20Filter.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.28-2.5 FIR Filter.md",key:"v-c0256cdc",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.28-2.5%20FIR%20Filter.html",headers:[{level:2,title:"FIR Filter Generator",slug:"fir-filter-generator"}],createdTime:170977737e4},{title:"2024.02.29-2.6 More on ChiselTest",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.29-2.6%20More%20on%20ChiselTest.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.29-2.6 More on ChiselTest.md",key:"v-3d196975",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.02.29-2.6%20More%20on%20ChiselTest.html",headers:[{level:2,title:"Modules with Decoupled Interfaces",slug:"modules-with-decoupled-interfaces"},{level:3,title:"EnqueueNow and expectDequeueNow",slug:"enqueuenow-and-expectdequeuenow"},{level:3,title:"EnqueueSeq and DequeueSeq",slug:"enqueueseq-and-dequeueseq"},{level:2,title:"Fork and Join",slug:"fork-and-join"}],createdTime:170977737e4},{title:"2024.03.01-3.1 Generators: Parameters",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.01-3.1%20Generators%20Parameters.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.01-3.1 Generators Parameters.md",key:"v-4075f022",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.01-3.1%20Generators%20Parameters.html",headers:[{level:2,title:"Parameter Passing",slug:"parameter-passing"},{level:3,title:"Example: Parameterized Scala Object",slug:"example-parameterized-scala-object"},{level:3,title:"Example: Parameterized Chisel Object",slug:"example-parameterized-chisel-object"},{level:3,title:"Example: Parameterized 4-input Sort",slug:"example-parameterized-4-input-sort"},{level:2,title:"Option and Defualt Arguments",slug:"option-and-defualt-arguments"},{level:3,title:"Options for Parameters with Defaults",slug:"options-for-parameters-with-defaults"},{level:2,title:"Match/Case Statements",slug:"match-case-statements"},{level:3,title:"Example: Value Matching",slug:"example-value-matching"},{level:3,title:"Example: Multiple Value Matching",slug:"example-multiple-value-matching"},{level:3,title:"Example: Type Matching",slug:"example-type-matching"},{level:3,title:"Example: Multiple Type Matching",slug:"example-multiple-type-matching"},{level:3,title:"Example: Type Matching and Erasure",slug:"example-type-matching-and-erasure"},{level:2,title:"IOs with Optional Fields",slug:"ios-with-optional-fields"},{level:3,title:"Example: Optional IO with Option",slug:"example-optional-io-with-option"},{level:3,title:"Example: Optional IO with Zero-Width Wires",slug:"example-optional-io-with-zero-width-wires"},{level:2,title:"Implicits",slug:"implicits"},{level:3,title:"Implicit Arguments",slug:"implicit-arguments"},{level:3,title:"Example: Implicit Cats",slug:"example-implicit-cats"},{level:3,title:"Example: Implicit Logging",slug:"example-implicit-logging"},{level:3,title:"Implicit Conversions",slug:"implicit-conversions"},{level:3,title:"Example: Implicit Conversion",slug:"example-implicit-conversion"}],createdTime:170977737e4},{title:"2024.03.03-3.2 Generators: Collections",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.03-3.2%20Generators%20Collections.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.03-3.2 Generators Collections.md",key:"v-17521110",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.03-3.2%20Generators%20Collections.html",headers:[{level:2,title:"Generators and Collections",slug:"generators-and-collections"},{level:3,title:"FIR Golden Model",slug:"fir-golden-model"},{level:3,title:"Seq",slug:"seq"},{level:3,title:"寄存器",slug:"寄存器"},{level:3,title:"Poke",slug:"poke"},{level:3,title:"更新寄存器",slug:"更新寄存器"},{level:3,title:"计算输出",slug:"计算输出"},{level:3,title:"Test circuit using the golden model",slug:"test-circuit-using-the-golden-model"},{level:3,title:"Example: Parameterized FIR Generator",slug:"example-parameterized-fir-generator"},{level:3,title:"Test a bunch of different sized FIR filters",slug:"test-a-bunch-of-different-sized-fir-filters"},{level:2,title:"Hardware Collections",slug:"hardware-collections"},{level:3,title:"Example: Add run-time configurable taps to our FIR",slug:"example-add-run-time-configurable-taps-to-our-fir"},{level:3,title:"Example: 32-bit RISC-V Processor",slug:"example-32-bit-risc-v-processor"}],createdTime:170977737e4},{title:"2024.03.05-3.4 Higher-Order Functions",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.05-3.4%20Higher-Order%20Functions.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.05-3.4 Higher-Order Functions.md",key:"v-7c6e1710",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.05-3.4%20Higher-Order%20Functions.html",headers:[{level:2,title:"Practice in Scala",slug:"practice-in-scala"},{level:3,title:"Example: map",slug:"example-map"},{level:3,title:"Example: zipWithIndex",slug:"example-zipwithindex"},{level:3,title:"Example: **reduce**",slug:"example-reduce"},{level:3,title:"Example: **fold**",slug:"example-fold"}],createdTime:170977737e4},{title:"2024.03.04-3.3 Interlude: Chisel Standard Library",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.04-3.3%20Interlude%20Chisel%20Standard%20Library.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.04-3.3 Interlude Chisel Standard Library.md",key:"v-5bcf313c",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.04-3.3%20Interlude%20Chisel%20Standard%20Library.html",headers:[{level:2,title:"Decoupled: A Standard Ready-Valid Interface",slug:"decoupled-a-standard-ready-valid-interface"},{level:3,title:"组件",slug:"组件"},{level:3,title:"数据传输",slug:"数据传输"},{level:3,title:"使用场景",slug:"使用场景"},{level:3,title:"代码示例",slug:"代码示例"},{level:2,title:"Queue",slug:"queue"},{level:2,title:"Arbiter",slug:"arbiter"},{level:2,title:"Misc Function Blocks",slug:"misc-function-blocks"},{level:3,title:"Bitwise Utilities",slug:"bitwise-utilities"},{level:3,title:"PopCount",slug:"popcount"},{level:3,title:"Reverse",slug:"reverse"},{level:3,title:"OneHot encoding utilities",slug:"onehot-encoding-utilities"},{level:3,title:"UIntToOH",slug:"uinttooh"},{level:3,title:"OHToUInt",slug:"ohtouint"},{level:3,title:"MUX",slug:"mux"},{level:3,title:"PriorityMux",slug:"prioritymux"},{level:3,title:"OneHot Mux: Mux1H",slug:"onehot-mux-mux1h"},{level:3,title:"Counter",slug:"counter"}],createdTime:170977737e4},{title:"2024.03.09-3.6 Object Oriented Programming",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.09-3.6%20Object%20Oriented%20Programming.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.09-3.6 Object Oriented Programming.md",key:"v-13f67663",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.09-3.6%20Object%20Oriented%20Programming.html",headers:[{level:2,title:"Abstract Classes",slug:"abstract-classes"},{level:3,title:"Example: Abstract Classes",slug:"example-abstract-classes"},{level:2,title:"Trait",slug:"trait"},{level:3,title:"Example: Trait and Multiple Inheritance",slug:"example-trait-and-multiple-inheritance"},{level:2,title:"Object",slug:"object"},{level:3,title:"Example: Object",slug:"example-object"},{level:2,title:"Companion Objects",slug:"companion-objects"},{level:3,title:"Example: Companion Object",slug:"example-companion-object"},{level:3,title:"构造器和工厂函数",slug:"构造器和工厂函数"},{level:2,title:"Case Classes",slug:"case-classes"},{level:2,title:"Module",slug:"module"},{level:3,title:"Example: Gray Encoder and Decoder",slug:"example-gray-encoder-and-decoder"},{level:3,title:"Test",slug:"test"}],createdTime:1712294936e3},{title:"2024.03.07-3.5 Functional Programming",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.07-3.5%20Functional%20Programming.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.07-3.5 Functional Programming.md",key:"v-0a8114b8",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.07-3.5%20Functional%20Programming.html",headers:[{level:2,title:"Example: Custom Functions",slug:"example-custom-functions"},{level:2,title:"Example: Function Objects",slug:"example-function-objects"},{level:3,title:"Hint:",slug:"hint"},{level:2,title:"Example: Higher-Order Functions",slug:"example-higher-order-functions"},{level:2,title:"Example: Functions vs. Objects",slug:"example-functions-vs-objects"},{level:2,title:"Example: Anonymous Functions",slug:"example-anonymous-functions"},{level:2,title:"Exercise: Sequence Manipulation",slug:"exercise-sequence-manipulation"},{level:2,title:"Exercise: FIR Filter",slug:"exercise-fir-filter"},{level:2,title:"Example: FIR Filter Tester",slug:"example-fir-filter-tester"},{level:2,title:"Exercise: Neural Network Neuron",slug:"exercise-neural-network-neuron"},{level:3,title:"Basic Multiply",slug:"basic-multiply"},{level:3,title:"Activation Functions",slug:"activation-functions"},{level:3,title:"Tester",slug:"tester"}],createdTime:1712294936e3},{title:"3. 2023.11.07-Verilog语法",frontmatter:{},regularPath:"/Chip/Chip/3.%202023.11.07-Verilog%E8%AF%AD%E6%B3%95.html",relativePath:"Chip/Chip/3. 2023.11.07-Verilog语法.md",key:"v-22b21eac",path:"/Chip/Chip/3.%202023.11.07-Verilog%E8%AF%AD%E6%B3%95.html",headers:[{level:2,title:"01. Verilog 基础语法",slug:"_01-verilog-基础语法"},{level:2,title:"02. Verilog 数值表示",slug:"_02-verilog-数值表示"},{level:2,title:"03. Verilog 数据类型",slug:"_03-verilog-数据类型"},{level:2,title:"04. Verilog 表达式",slug:"_04-verilog-表达式"},{level:2,title:"10. Verilog 多路分支语句",slug:"_10-verilog-多路分支语句"},{level:2,title:"2023.11.15-Vivado",slug:"_2023-11-15-vivado"},{level:2,title:"2023.11.16-阻塞与非阻塞赋值",slug:"_2023-11-16-阻塞与非阻塞赋值"}],createdTime:170977737e4},{title:"预学习阶段",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段.md",key:"v-4d37d972",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5.html",headers:[{level:2,title:"The Missing Semester",slug:"the-missing-semester"},{level:2,title:"Learn C the hard way",slug:"learn-c-the-hard-way"}],createdTime:170972353e4},{title:"2024.03.12-3.7 Generators: Types",frontmatter:{},regularPath:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.12-3.7%20Generators%20Types.html",relativePath:"Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.12-3.7 Generators Types.md",key:"v-0d401e18",path:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/2024.03.12-3.7%20Generators%20Types.html",headers:[{level:2,title:"Types in Scala",slug:"types-in-scala"},{level:2,title:"Scala vs. Chisel Types",slug:"scala-vs-chisel-types"},{level:2,title:"Scala Tye Coercion",slug:"scala-tye-coercion"},{level:3,title:"asInstanceOf",slug:"asinstanceof"},{level:3,title:"Type Casting in Chisel",slug:"type-casting-in-chisel"},{level:2,title:"Match Operator",slug:"match-operator"},{level:2,title:"Unapply",slug:"unapply"},{level:3,title:"SomeGeneratorParameters case 类",slug:"somegeneratorparameters-case-类"},{level:3,title:"delay 函数",slug:"delay-函数"},{level:3,title:"模式匹配的不同语法",slug:"模式匹配的不同语法"},{level:3,title:"手动定义 unapply 方法",slug:"手动定义-unapply-方法"},{level:2,title:"Partial Functions",slug:"partial-functions"},{level:2,title:"Chisel Type Hierarchy",slug:"chisel-type-hierarchy"},{level:3,title:"Example: Type Generic ShiftRegister",slug:"example-type-generic-shiftregister"},{level:2,title:"Type Generics with Typeclasses",slug:"type-generics-with-typeclasses"}],createdTime:1712294936e3},{title:"Learn C the hard way",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way.md",key:"v-21624205",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way.html",headers:[{level:2,title:"2024.04.02-练习 1:启用编译器",slug:"_2024-04-02-练习-1-启用编译器"},{level:2,title:"2024.04.02-练习 2:用 Make 来代替 Python",slug:"_2024-04-02-练习-2-用-make-来代替-python"},{level:2,title:"2024.04.02-练习 3:格式化输出",slug:"_2024-04-02-练习-3-格式化输出"},{level:2,title:"2024.04.03-练习 4:Valgrind 介绍",slug:"_2024-04-03-练习-4-valgrind-介绍"},{level:2,title:"2024.04.03-练习 5:一个 C 程序的结构",slug:"_2024-04-03-练习-5-一个-c-程序的结构"},{level:2,title:"2024.04.03-练习 6:变量类型",slug:"_2024-04-03-练习-6-变量类型"},{level:2,title:"2024.04.03-练习 7:更多变量和一些算术",slug:"_2024-04-03-练习-7-更多变量和一些算术"},{level:2,title:"2024.04.03-练习 8:大小和数组",slug:"_2024-04-03-练习-8-大小和数组"},{level:2,title:"2024.04.03-练习 9:数组和字符串",slug:"_2024-04-03-练习-9-数组和字符串"},{level:2,title:"2024.04.04-练习 10:字符串数组和循环",slug:"_2024-04-04-练习-10-字符串数组和循环"},{level:2,title:"2024.04.05-练习 11:While 循环和布尔表达式",slug:"_2024-04-05-练习-11-while-循环和布尔表达式"},{level:2,title:"2024.04.05-练习 12:If,Else If,Else",slug:"_2024-04-05-练习-12-if-else-if-else"},{level:2,title:"2024.04.05-练习 13:Switch 语句",slug:"_2024-04-05-练习-13-switch-语句"},{level:2,title:"2024.04.05-练习 14:编写并使用函数",slug:"_2024-04-05-练习-14-编写并使用函数"},{level:2,title:"2024.04.05-练习 15:指针,可怕的指针",slug:"_2024-04-05-练习-15-指针-可怕的指针"},{level:2,title:"2024.04.05-练习 16:结构体和指向它们的指针",slug:"_2024-04-05-练习-16-结构体和指向它们的指针"},{level:2,title:"2024.04.08-练习 17:堆和栈的内存分配",slug:"_2024-04-08-练习-17-堆和栈的内存分配"},{level:2,title:"2024.04.10-练习 18:函数指针",slug:"_2024-04-10-练习-18-函数指针"},{level:2,title:"2024.04.10-练习 32:双向链表",slug:"_2024-04-10-练习-32-双向链表"},{level:2,title:"2024.04.11-练习 33:链表算法",slug:"_2024-04-11-练习-33-链表算法"},{level:2,title:"2024.04.11-练习 42:栈和队列",slug:"_2024-04-11-练习-42-栈和队列"},{level:2,title:"2024.04.12-练习 44:环形缓冲区",slug:"_2024-04-12-练习-44-环形缓冲区"}],createdTime:1712918404e3},{title:"2024.04.02-练习 1:启用编译器",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A01%EF%BC%9A%E5%90%AF%E7%94%A8%E7%BC%96%E8%AF%91%E5%99%A8.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.02-练习1:启用编译器.md",key:"v-68aac09e",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A01%EF%BC%9A%E5%90%AF%E7%94%A8%E7%BC%96%E8%AF%91%E5%99%A8.html",headers:[{level:2,title:"1. make",slug:"_1-make"},{level:2,title:"2. 如何使它崩溃?",slug:"_2-如何使它崩溃"},{level:2,title:"3. 附加题 1",slug:"_3-附加题-1"},{level:2,title:"4. 附加题 2",slug:"_4-附加题-2"},{level:2,title:"5. 附加题 3",slug:"_5-附加题-3"}],createdTime:1712918404e3},{title:"2024.04.02-练习3:格式化输出",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A03%EF%BC%9A%E6%A0%BC%E5%BC%8F%E5%8C%96%E8%BE%93%E5%87%BA.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.02-练习3:格式化输出.md",key:"v-65603e35",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A03%EF%BC%9A%E6%A0%BC%E5%BC%8F%E5%8C%96%E8%BE%93%E5%87%BA.html",headers:[{level:2,title:"1. printf",slug:"_1-printf"},{level:2,title:"2. 附加题",slug:"_2-附加题"},{level:3,title:"2.1 %占位符和转移字符",slug:"_2-1-占位符和转移字符"},{level:3,title:"2.2 Makefile",slug:"_2-2-makefile"}],createdTime:1712918404e3},{title:"2024.04.03-练习4:Valgrind 介绍",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A04%EF%BC%9AValgrind%20%E4%BB%8B%E7%BB%8D.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习4:Valgrind 介绍.md",key:"v-3923ffea",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A04%EF%BC%9AValgrind%20%E4%BB%8B%E7%BB%8D.html",headers:[{level:2,title:"1. Intro",slug:"_1-intro"},{level:2,title:"2. Example",slug:"_2-example"},{level:2,title:"3. 附加题",slug:"_3-附加题"}],createdTime:1712918404e3},{title:"2024.04.02-练习 2:用 Make 来代替 Python",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A02%EF%BC%9A%E7%94%A8Make%E6%9D%A5%E4%BB%A3%E6%9B%BFPython.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.02-练习2:用Make来代替Python.md",key:"v-554dcf2a",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.02-%E7%BB%83%E4%B9%A02%EF%BC%9A%E7%94%A8Make%E6%9D%A5%E4%BB%A3%E6%9B%BFPython.html",headers:[{level:2,title:"1. 使用 Make",slug:"_1-使用-make"},{level:2,title:"2. Makefile",slug:"_2-makefile"},{level:3,title:"2.1 语法规则",slug:"_2-1-语法规则"},{level:3,title:"2.2 变量",slug:"_2-2-变量"},{level:3,title:"2.3 变量赋值",slug:"_2-3-变量赋值"},{level:3,title:"2.4 预定义变量",slug:"_2-4-预定义变量"},{level:3,title:"2.5 函数",slug:"_2-5-函数"},{level:3,title:"2.6 伪目标 .PHONY",slug:"_2-6-伪目标-phony"},{level:3,title:"2.7 其他常用功能",slug:"_2-7-其他常用功能"},{level:3,title:"2.8 嵌套执行 Makefile",slug:"_2-8-嵌套执行-makefile"},{level:3,title:"2.9 指定头文件路径",slug:"_2-9-指定头文件路径"},{level:2,title:"3. 附加题",slug:"_3-附加题"},{level:3,title:"3.1 创建目标all:ex1,可以以单个命令make构建ex1",slug:"_3-1-创建目标all-ex1-可以以单个命令make构建ex1"},{level:3,title:"3.2 阅读man cc来了解关于-Wall和-g行为的更多信息",slug:"_3-2-阅读man-cc来了解关于-wall和-g行为的更多信息"}],createdTime:1712918404e3},{title:"2024.04.03-练习5:一个C程序的结构",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A05%EF%BC%9A%E4%B8%80%E4%B8%AAC%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%BB%93%E6%9E%84.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习5:一个C程序的结构.md",key:"v-48c040f5",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A05%EF%BC%9A%E4%B8%80%E4%B8%AAC%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%BB%93%E6%9E%84.html",headers:[{level:2,title:"1. printf",slug:"_1-printf"}],createdTime:1712918404e3},{title:"2024.04.03-练习6:变量类型",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A06%EF%BC%9A%E5%8F%98%E9%87%8F%E7%B1%BB%E5%9E%8B.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习6:变量类型.md",key:"v-5c01da22",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A06%EF%BC%9A%E5%8F%98%E9%87%8F%E7%B1%BB%E5%9E%8B.html",headers:[{level:2,title:"1. 变量",slug:"_1-变量"},{level:2,title:"2. 如何使它崩溃",slug:"_2-如何使它崩溃"},{level:2,title:"3. 附加题",slug:"_3-附加题"},{level:3,title:'试着打印空字符串,即""',slug:"试着打印空字符串-即"}],createdTime:1712918404e3},{title:"2024.04.03-练习8:大小和数组",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A08%EF%BC%9A%E5%A4%A7%E5%B0%8F%E5%92%8C%E6%95%B0%E7%BB%84.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习8:大小和数组.md",key:"v-2f2496f9",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A08%EF%BC%9A%E5%A4%A7%E5%B0%8F%E5%92%8C%E6%95%B0%E7%BB%84.html",headers:[{level:2,title:"1. sizeof和数组",slug:"_1-sizeof和数组"},{level:2,title:"2. 如何使它崩溃",slug:"_2-如何使它崩溃"},{level:3,title:"2.1 将full_name最后的'\\0'去掉",slug:"_2-1-将full-name最后的-0-去掉"},{level:3,title:"2.2 将areas[0]改为areas[10]",slug:"_2-2-将areas-0-改为areas-10"},{level:2,title:"3. 附加题",slug:"_3-附加题"},{level:3,title:"3.1 对areas的元素赋值",slug:"_3-1-对areas的元素赋值"},{level:3,title:"3.2 对name的元素赋值",slug:"_3-2-对name的元素赋值"},{level:3,title:"3.3 将areas的一个元素赋值为name中的字符",slug:"_3-3-将areas的一个元素赋值为name中的字符"},{level:3,title:"3.4 C语言中不同的CPU上整数所占的不同大小",slug:"_3-4-c语言中不同的cpu上整数所占的不同大小"}],createdTime:1712918404e3},{title:"2024.04.03-练习9:数组和字符串",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A09%EF%BC%9A%E6%95%B0%E7%BB%84%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习9:数组和字符串.md",key:"v-ae29164a",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A09%EF%BC%9A%E6%95%B0%E7%BB%84%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2.html",headers:[{level:2,title:"1. 字符数组",slug:"_1-字符数组"},{level:2,title:"2. 使其崩溃",slug:"_2-使其崩溃"},{level:3,title:"2.1 删掉name的初始化表达式",slug:"_2-1-删掉name的初始化表达式"},{level:3,title:"2.2 设置name[3] = 'A'",slug:"_2-2-设置name-3-a"},{level:3,title:"2.3 初始化表达式设置为{'a','a','a','a'}",slug:"_2-3-初始化表达式设置为-a-a-a-a"},{level:2,title:"3. 附加题",slug:"_3-附加题"},{level:3,title:"3.1 字符赋给numbers的元素",slug:"_3-1-字符赋给numbers的元素"},{level:3,title:"3.2 把names当成int数组",slug:"_3-2-把names当成int数组"},{level:3,title:"3.3",slug:"_3-3"}],createdTime:1712918404e3},{title:"2024.04.03-练习7:更多变量和一些算术",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A07%EF%BC%9A%E6%9B%B4%E5%A4%9A%E5%8F%98%E9%87%8F%E5%92%8C%E4%B8%80%E4%BA%9B%E7%AE%97%E6%9C%AF.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.03-练习7:更多变量和一些算术.md",key:"v-31ab9aa4",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.03-%E7%BB%83%E4%B9%A07%EF%BC%9A%E6%9B%B4%E5%A4%9A%E5%8F%98%E9%87%8F%E5%92%8C%E4%B8%80%E4%BA%9B%E7%AE%97%E6%9C%AF.html",headers:[{level:2,title:"1. 基本算术操作",slug:"_1-基本算术操作"},{level:2,title:"2. 用%s打印\\0",slug:"_2-用-s打印-0"},{level:2,title:"3. 附加题",slug:"_3-附加题"},{level:3,title:"3.1 LONG_MAX",slug:"_3-1-long-max"},{level:3,title:"3.2 ULONG_MAX",slug:"_3-2-ulong-max"},{level:3,title:"3.3 char & int",slug:"_3-3-char-int"}],createdTime:1712918404e3},{title:"2024.04.04-练习10:字符串数组和循环",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.04-%E7%BB%83%E4%B9%A010%EF%BC%9A%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%95%B0%E7%BB%84%E5%92%8C%E5%BE%AA%E7%8E%AF.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.04-练习10:字符串数组和循环.md",key:"v-75f1ac65",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.04-%E7%BB%83%E4%B9%A010%EF%BC%9A%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%95%B0%E7%BB%84%E5%92%8C%E5%BE%AA%E7%8E%AF.html",headers:[{level:2,title:"1. 字符串数组",slug:"_1-字符串数组"},{level:2,title:"2. 附加题",slug:"_2-附加题"},{level:3,title:"2.1 在for循环的每一部分可以放置什么代码",slug:"_2-1-在for循环的每一部分可以放置什么代码"},{level:3,title:"2.2 for 循环中的逗号",slug:"_2-2-for-循环中的逗号"},{level:3,title:"2.3 NULL",slug:"_2-3-null"},{level:3,title:"2.4",slug:"_2-4"}],createdTime:1712918404e3},{title:"2024.04.05-练习11:While循环和布尔表达式",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A011%EF%BC%9AWhile%E5%BE%AA%E7%8E%AF%E5%92%8C%E5%B8%83%E5%B0%94%E8%A1%A8%E8%BE%BE%E5%BC%8F.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习11:While循环和布尔表达式.md",key:"v-8b0f19d0",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A011%EF%BC%9AWhile%E5%BE%AA%E7%8E%AF%E5%92%8C%E5%B8%83%E5%B0%94%E8%A1%A8%E8%BE%BE%E5%BC%8F.html",headers:[{level:2,title:"1. while",slug:"_1-while"},{level:2,title:"2. 附加题",slug:"_2-附加题"},{level:3,title:"2.1 循环倒序执行",slug:"_2-1-循环倒序执行"},{level:3,title:"2.2 使用while循环将argv中的值复制到states",slug:"_2-2-使用while循环将argv中的值复制到states"},{level:3,title:"2.3 是否真正复制了这些字符串?",slug:"_2-3-是否真正复制了这些字符串"}],createdTime:1712918404e3},{title:"2024.04.05-练习12:If,Else If,Else",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A012%EF%BC%9AIf%EF%BC%8CElse%20If%EF%BC%8CElse.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习12:If,Else If,Else.md",key:"v-63e06dc9",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A012%EF%BC%9AIf%EF%BC%8CElse%20If%EF%BC%8CElse.html",headers:[{level:2,title:"1. if,else if,else",slug:"_1-if-else-if-else"},{level:2,title:"2. 附加题",slug:"_2-附加题"},{level:3,title:"2.1 布尔运算符",slug:"_2-1-布尔运算符"}],createdTime:1712918404e3},{title:"2024.04.05-练习13:Switch语句",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A013%EF%BC%9ASwitch%E8%AF%AD%E5%8F%A5.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习13:Switch语句.md",key:"v-29da66ba",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A013%EF%BC%9ASwitch%E8%AF%AD%E5%8F%A5.html",headers:[{level:2,title:"1. switch",slug:"_1-switch"},{level:2,title:"2. 如何崩溃",slug:"_2-如何崩溃"},{level:3,title:"2.1 忘记写default",slug:"_2-1-忘记写default"},{level:3,title:"2.2 无意中将一些带有预料之外的值的变量放入switch中",slug:"_2-2-无意中将一些带有预料之外的值的变量放入switch中"},{level:2,title:"3. 附加题",slug:"_3-附加题"},{level:3,title:"3.1 编写另一个程序,在字母上做算术运算将它们转换为小写,并且在switch中移除所有额外的大写字母",slug:"_3-1-编写另一个程序-在字母上做算术运算将它们转换为小写-并且在switch中移除所有额外的大写字母"}],createdTime:1712918404e3},{title:"2024.04.05-练习14:编写并使用函数",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A014%EF%BC%9A%E7%BC%96%E5%86%99%E5%B9%B6%E4%BD%BF%E7%94%A8%E5%87%BD%E6%95%B0.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习14:编写并使用函数.md",key:"v-e5986f3c",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A014%EF%BC%9A%E7%BC%96%E5%86%99%E5%B9%B6%E4%BD%BF%E7%94%A8%E5%87%BD%E6%95%B0.html",headers:[{level:2,title:"1. 函数",slug:"_1-函数"},{level:2,title:"2. 附加题",slug:"_2-附加题"},{level:3,title:"2.1 使用strlen函数",slug:"_2-1-使用strlen函数"},{level:3,title:"2.2 **",slug:"_2-2-ctype-h"}],createdTime:1712918404e3},{title:"2024.04.05-练习15:指针,可怕的指针",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A015%EF%BC%9A%E6%8C%87%E9%92%88%EF%BC%8C%E5%8F%AF%E6%80%95%E7%9A%84%E6%8C%87%E9%92%88.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习15:指针,可怕的指针.md",key:"v-bae38342",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A015%EF%BC%9A%E6%8C%87%E9%92%88%EF%BC%8C%E5%8F%AF%E6%80%95%E7%9A%84%E6%8C%87%E9%92%88.html",headers:[{level:2,title:"1. 指针",slug:"_1-指针"},{level:2,title:"2. 实用的指针用法",slug:"_2-实用的指针用法"},{level:2,title:"3. 指针词库",slug:"_3-指针词库"},{level:2,title:"4. 指针并不是数组",slug:"_4-指针并不是数组"},{level:2,title:"5. 附加题",slug:"_5-附加题"},{level:2,title:"5.1 获取地址",slug:"_5-1-获取地址"},{level:3,title:"5.2 倒序遍历",slug:"_5-2-倒序遍历"}],createdTime:1712918404e3},{title:"2024.04.05-练习16:结构体和指向它们的指针",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A016%EF%BC%9A%E7%BB%93%E6%9E%84%E4%BD%93%E5%92%8C%E6%8C%87%E5%90%91%E5%AE%83%E4%BB%AC%E7%9A%84%E6%8C%87%E9%92%88.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.05-练习16:结构体和指向它们的指针.md",key:"v-3f5efb4a",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.05-%E7%BB%83%E4%B9%A016%EF%BC%9A%E7%BB%93%E6%9E%84%E4%BD%93%E5%92%8C%E6%8C%87%E5%90%91%E5%AE%83%E4%BB%AC%E7%9A%84%E6%8C%87%E9%92%88.html",headers:[{level:2,title:"1. struct",slug:"_1-struct"},{level:2,title:"2. 使它崩溃",slug:"_2-使它崩溃"},{level:3,title:"2.1 assert(who != NULL);",slug:"_2-1-assert-who-null"},{level:3,title:"2.2 内存泄漏",slug:"_2-2-内存泄漏"},{level:3,title:"2.3 单独释放结构体中的指针",slug:"_2-3-单独释放结构体中的指针"},{level:3,title:"2.4 获取NULL",slug:"_2-4-获取null"},{level:2,title:"3. 附加题",slug:"_3-附加题"},{level:3,title:"3.1 在栈上创建结构体",slug:"_3-1-在栈上创建结构体"}],createdTime:1712918404e3},{title:"2024.04.10-练习18:函数指针",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.10-%E7%BB%83%E4%B9%A018%EF%BC%9A%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.10-练习18:函数指针.md",key:"v-197c9364",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.10-%E7%BB%83%E4%B9%A018%EF%BC%9A%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88.html",headers:[{level:2,title:"1. 函数指针",slug:"_1-函数指针"},{level:2,title:"2. program",slug:"_2-program"},{level:2,title:"3. 函数指针汇编字节码",slug:"_3-函数指针汇编字节码"},{level:2,title:"4. 附加题",slug:"_4-附加题"},{level:3,title:"4.1 十六进制编辑器",slug:"_4-1-十六进制编辑器"},{level:3,title:"4.2 修改十六进制文件",slug:"_4-2-修改十六进制文件"},{level:3,title:"4.3 传递错误函数",slug:"_4-3-传递错误函数"},{level:3,title:"4.4 传递NULL到原函数指针位置",slug:"_4-4-传递null到原函数指针位置"},{level:3,title:"4.5 快速排序",slug:"_4-5-快速排序"}],createdTime:1712918404e3},{title:"2024.04.11-练习42:栈和队列",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.11-%E7%BB%83%E4%B9%A042%EF%BC%9A%E6%A0%88%E5%92%8C%E9%98%9F%E5%88%97.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.11-练习42:栈和队列.md",key:"v-5dd420e2",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.11-%E7%BB%83%E4%B9%A042%EF%BC%9A%E6%A0%88%E5%92%8C%E9%98%9F%E5%88%97.html",headers:[{level:2,title:"1. 栈",slug:"_1-栈"},{level:3,title:"1.1 头文件",slug:"_1-1-头文件"},{level:3,title:"1.2 单元测试",slug:"_1-2-单元测试"},{level:2,title:"2. 队列",slug:"_2-队列"},{level:3,title:"2.1 头文件",slug:"_2-1-头文件"},{level:3,title:"2.2 单元测试",slug:"_2-2-单元测试"}],createdTime:1712918404e3},{title:"2024.04.10-练习32:双向链表",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.10-%E7%BB%83%E4%B9%A032%EF%BC%9A%E5%8F%8C%E5%90%91%E9%93%BE%E8%A1%A8.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.10-练习32:双向链表.md",key:"v-d70fb904",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.10-%E7%BB%83%E4%B9%A032%EF%BC%9A%E5%8F%8C%E5%90%91%E9%93%BE%E8%A1%A8.html",headers:[{level:2,title:"1. program",slug:"_1-program"},{level:3,title:"1.1 定义",slug:"_1-1-定义"},{level:3,title:"1.2 实现",slug:"_1-2-实现"},{level:3,title:"1.3 calloc",slug:"_1-3-calloc"},{level:3,title:"1.4 LIST_FOREACH",slug:"_1-4-list-foreach"},{level:3,title:"1.5 void类型指针",slug:"_1-5-void类型指针"},{level:2,title:"2. 附加题",slug:"_2-附加题"},{level:3,title:"2.0 改进List_clear_destroy",slug:"_2-0-改进list-clear-destroy"},{level:3,title:"2.1 单向与双向链表",slug:"_2-1-单向与双向链表"},{level:3,title:"单向链表",slug:"单向链表"},{level:3,title:"双向链表",slug:"双向链表"},{level:3,title:"选择依据",slug:"选择依据"},{level:3,title:"2.2 双向链表的限制",slug:"_2-2-双向链表的限制"},{level:3,title:"1. 遍历速度",slug:"_1-遍历速度"},{level:3,title:"2. 访问特定元素",slug:"_2-访问特定元素"},{level:3,title:"3. 内存开销",slug:"_3-内存开销"},{level:3,title:"4. 实现复杂性",slug:"_4-实现复杂性"},{level:3,title:"2.3 实现复制、连接、分割",slug:"_2-3-实现复制、连接、分割"}],createdTime:1712918404e3},{title:"2024.04.11-练习33:链表算法",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.11-%E7%BB%83%E4%B9%A033%EF%BC%9A%E9%93%BE%E8%A1%A8%E7%AE%97%E6%B3%95.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.11-练习33:链表算法.md",key:"v-0a451f79",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.11-%E7%BB%83%E4%B9%A033%EF%BC%9A%E9%93%BE%E8%A1%A8%E7%AE%97%E6%B3%95.html",headers:[{level:2,title:"1. 归并排序",slug:"_1-归并排序"},{level:2,title:"2. 代码",slug:"_2-代码"},{level:3,title:"2.1 头文件",slug:"_2-1-头文件"},{level:3,title:"2.2 实现",slug:"_2-2-实现"},{level:3,title:"2.3 单元测试",slug:"_2-3-单元测试"},{level:3,title:"2.4 inline",slug:"_2-4-inline"},{level:3,title:"标准inline函数的使用",slug:"标准inline函数的使用"},{level:3,title:"使用static inline",slug:"使用static-inline"},{level:2,title:"3. 改进",slug:"_3-改进"},{level:2,title:"4. 附加题",slug:"_4-附加题"},{level:3,title:"4.1 程序运行时间",slug:"_4-1-程序运行时间"},{level:3,title:"4.2 List_insert_sorted",slug:"_4-2-list-insert-sorted"}],createdTime:1712918404e3},{title:"2024.04.08-练习17:堆和栈的内存分配",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.08-%E7%BB%83%E4%B9%A017%EF%BC%9A%E5%A0%86%E5%92%8C%E6%A0%88%E7%9A%84%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.08-练习17:堆和栈的内存分配.md",key:"v-7e47bbb5",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.08-%E7%BB%83%E4%B9%A017%EF%BC%9A%E5%A0%86%E5%92%8C%E6%A0%88%E7%9A%84%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D.html",headers:[{level:2,title:"1. Program",slug:"_1-program"},{level:2,title:"2. 堆和栈的内存分配",slug:"_2-堆和栈的内存分配"},{level:2,title:"3. 如何使它崩溃",slug:"_3-如何使它崩溃"},{level:3,title:"3.1 strncpy",slug:"_3-1-strncpy"},{level:2,title:"4. 附加题",slug:"_4-附加题"},{level:3,title:"4.1 报错时清理内存",slug:"_4-1-报错时清理内存"},{level:3,title:"4.2 创建任意大小的数据库",slug:"_4-2-创建任意大小的数据库"},{level:3,title:"4.3 添加find操作",slug:"_4-3-添加find操作"},{level:3,title:"4.4 C结构体存储方式",slug:"_4-4-c结构体存储方式"},{level:3,title:"4.5 栈数据结构",slug:"_4-5-栈数据结构"},{level:2,title:"5. 文件操作",slug:"_5-文件操作"},{level:3,title:"5.1 C",slug:"_5-1-c"},{level:3,title:"5.2 C++",slug:"_5-2-c"},{level:3,title:"ifstream(输入文件流)",slug:"ifstream-输入文件流"},{level:3,title:"ofstream(输出文件流)",slug:"ofstream-输出文件流"},{level:3,title:"fstream(文件流)",slug:"fstream-文件流"},{level:3,title:"文件打开模式",slug:"文件打开模式"}],createdTime:1712918404e3},{title:"2024.04.12-练习44:环形缓冲区",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.12-%E7%BB%83%E4%B9%A044%EF%BC%9A%E7%8E%AF%E5%BD%A2%E7%BC%93%E5%86%B2%E5%8C%BA.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/2024.04.12-练习44:环形缓冲区.md",key:"v-46f32df9",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/Learn%20C%20the%20hard%20way/2024.04.12-%E7%BB%83%E4%B9%A044%EF%BC%9A%E7%8E%AF%E5%BD%A2%E7%BC%93%E5%86%B2%E5%8C%BA.html",headers:[{level:2,title:"1. 头文件",slug:"_1-头文件"},{level:3,title:"头文件和宏定义",slug:"头文件和宏定义"},{level:3,title:"结构体定义",slug:"结构体定义"},{level:3,title:"函数原型",slug:"函数原型"},{level:3,title:"宏定义",slug:"宏定义"},{level:3,title:"提交数据的宏",slug:"提交数据的宏"},{level:2,title:"2. 源文件",slug:"_2-源文件"},{level:3,title:"RingBuffer_write函数签名",slug:"ringbuffer-write函数签名"},{level:3,title:"函数体",slug:"函数体"},{level:3,title:"确定起始位置",slug:"确定起始位置"},{level:3,title:"检查是否有足够空间",slug:"检查是否有足够空间"},{level:3,title:"数据复制",slug:"数据复制"},{level:3,title:"提交写操作",slug:"提交写操作"},{level:3,title:"成功返回",slug:"成功返回"},{level:3,title:"错误处理",slug:"错误处理"},{level:3,title:"RingBuffer_write总结",slug:"ringbuffer-write总结"},{level:3,title:"RingBuffer_read",slug:"ringbuffer-read"},{level:3,title:"RingBuffer_gets",slug:"ringbuffer-gets"},{level:3,title:"主要区别",slug:"主要区别"},{level:2,title:"3. 测试",slug:"_3-测试"},{level:2,title:"4. 一些修改",slug:"_4-一些修改"}],createdTime:1712918404e3},{title:"The Missing Semester",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester.md",key:"v-44186d05",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester.html",headers:[{level:2,title:"2024.03.14-1. The Shell",slug:"_2024-03-14-1-the-shell"},{level:2,title:"2024.03.19-2. Script",slug:"_2024-03-19-2-script"},{level:2,title:"2024.03.20-3. Vim",slug:"_2024-03-20-3-vim"},{level:2,title:"2024.03.21-4. Data Wrangling",slug:"_2024-03-21-4-data-wrangling"},{level:2,title:"2024.03.21-5. Command Line Interface",slug:"_2024-03-21-5-command-line-interface"},{level:2,title:"2024.03.25-6. Version Control (Git).md)",slug:"_2024-03-25-6-version-control-git"}],createdTime:1712294936e3},{title:"2024.03.14-1. The Shell",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.14-1.The%20Shell.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.14-1.The Shell.md",key:"v-fd681622",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.14-1.The%20Shell.html",headers:[{level:2,title:"1. echo",slug:"_1-echo"},{level:2,title:"2. cd",slug:"_2-cd"},{level:2,title:"3. 在程序间创建连接",slug:"_3-在程序间创建连接"},{level:2,title:"4. clear",slug:"_4-clear"},{level:2,title:"5. 权限",slug:"_5-权限"},{level:2,title:"6. 单引号与双引号",slug:"_6-单引号与双引号"}],createdTime:1712294936e3},{title:"2024.03.19-2. Script",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.19-2.Script.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.19-2.Script.md",key:"v-ca90c390",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.19-2.Script.html",headers:[{level:2,title:"1.1 变量赋值",slug:"_1-1-变量赋值"},{level:2,title:"1.2 函数",slug:"_1-2-函数"},{level:2,title:"1.3 返回码",slug:"_1-3-返回码"},{level:2,title:"1.4 通配",slug:"_1-4-通配"},{level:2,title:"1.5 shebang",slug:"_1-5-shebang"},{level:2,title:"1.6 shell 函数和脚本",slug:"_1-6-shell-函数和脚本"},{level:2,title:"1.7  shellcheck",slug:"_1-7-shellcheck"},{level:2,title:"2.1 查看命令如何使用",slug:"_2-1-查看命令如何使用"},{level:2,title:"2.2 查找文件",slug:"_2-2-查找文件"},{level:3,title:"fd 基本用法",slug:"fd-基本用法"},{level:3,title:"fd 高级用法",slug:"fd-高级用法"},{level:3,title:"fd 实用示例",slug:"fd-实用示例"},{level:2,title:"2.3 查找代码",slug:"_2-3-查找代码"},{level:2,title:"2.4 查找 shell 命令",slug:"_2-4-查找-shell-命令"},{level:2,title:"2.5 文件夹导航",slug:"_2-5-文件夹导航"},{level:2,title:"3.1 ls",slug:"_3-1-ls"},{level:2,title:"3.2 函数",slug:"_3-2-函数"},{level:2,title:"3.3 返回码",slug:"_3-3-返回码"},{level:2,title:"3.4 find",slug:"_3-4-find"},{level:2,title:"3.5 LRU",slug:"_3-5-lru"}],createdTime:1712294936e3},{title:"2024.03.21-4. Data Wrangling",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.21-4.Data%20Wrangling.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.21-4.Data Wrangling.md",key:"v-425d935b",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.21-4.Data%20Wrangling.html",headers:[{level:2,title:"1. journalctl",slug:"_1-journalctl"},{level:2,title:"2. 正则表达式",slug:"_2-正则表达式"},{level:3,title:"2.1 正则匹配基本知识及概念",slug:"_2-1-正则匹配基本知识及概念"},{level:3,title:"2.2 正则表达式-字符类",slug:"_2-2-正则表达式-字符类"},{level:3,title:"2.3 正则表达式-逻辑运算符",slug:"_2-3-正则表达式-逻辑运算符"},{level:3,title:"2.4 正则表达式-预定义字符",slug:"_2-4-正则表达式-预定义字符"},{level:3,title:"2.5 正则表达式-数量词",slug:"_2-5-正则表达式-数量词"},{level:2,title:"3. 数据整理",slug:"_3-数据整理"},{level:2,title:"4. awk – 另外一种编辑器",slug:"_4-awk-另外一种编辑器"},{level:2,title:"5. 分析数据",slug:"_5-分析数据"},{level:2,title:"6. Exercise",slug:"_6-exercise"},{level:3,title:"6.1 学习这篇简短的  交互式正则表达式教程",slug:"_6-1-学习这篇简短的-交互式正则表达式教程"},{level:3,title:"6.2 sed",slug:"_6-2-sed"},{level:3,title:"6.3 in-place",slug:"_6-3-in-place"},{level:3,title:"6.4 开机时间",slug:"_6-4-开机时间"},{level:3,title:"6.5 awk",slug:"_6-5-awk"}],createdTime:1712294936e3},{title:"2024.03.20-3. Vim",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.20-3.Vim.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.20-3.Vim.md",key:"v-ae330e80",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.20-3.Vim.html",headers:[{level:2,title:"2.1 插入文本",slug:"_2-1-插入文本"},{level:2,title:"2.2 缓存, 标签页, 窗口",slug:"_2-2-缓存-标签页-窗口"},{level:2,title:"2.3 命令行",slug:"_2-3-命令行"},{level:2,title:"3.1 移动",slug:"_3-1-移动"},{level:2,title:"3.2 编辑",slug:"_3-2-编辑"},{level:2,title:"3.3 计数",slug:"_3-3-计数"},{level:2,title:"3.4 修饰语",slug:"_3-4-修饰语"},{level:2,title:"6.1 搜索和替换",slug:"_6-1-搜索和替换"},{level:2,title:"6.2 多窗口",slug:"_6-2-多窗口"},{level:2,title:"6.3 宏",slug:"_6-3-宏"}],createdTime:1712294936e3},{title:"2024.02.22-BFS",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.02.22-BFS.html",relativePath:"LeetCode/LeetCode/2024.02.22-BFS.md",key:"v-460e207e",path:"/LeetCode/LeetCode/2024.02.22-BFS.html",headers:[{level:2,title:"2024.02.22-752.打开转盘锁(BFS)",slug:"_2024-02-22-752-打开转盘锁-bfs"}],createdTime:170977737e4},{title:"SoC Design",frontmatter:{},regularPath:"/Chip/",relativePath:"Chip/README.md",key:"v-5820d42c",path:"/Chip/",headers:[{level:2,title:"1. 一生一芯计划",slug:"_1-一生一芯计划"},{level:2,title:"2. 2024.02.21-Chisel",slug:"_2-2024-02-21-chisel"},{level:2,title:"3. 2023.11.07-Verilog语法",slug:"_3-2023-11-07-verilog语法"}],createdTime:170972353e4},{title:"2024.03.21-5. Command Line Interface",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.21-5.Command%20Line%20Interface.html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.21-5.Command Line Interface.md",key:"v-78ff5d78",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.21-5.Command%20Line%20Interface.html",headers:[{level:2,title:"1.1 结束进程",slug:"_1-1-结束进程"},{level:2,title:"1.2 暂停和后台执行进程",slug:"_1-2-暂停和后台执行进程"},{level:2,title:"4.1 可移植性",slug:"_4-1-可移植性"},{level:2,title:"5.1 执行命令",slug:"_5-1-执行命令"},{level:2,title:"5.2 SSH 密钥",slug:"_5-2-ssh-密钥"},{level:3,title:"5.2.1 密钥生成",slug:"_5-2-1-密钥生成"},{level:3,title:"5.2.2 基于密钥的认证机制",slug:"_5-2-2-基于密钥的认证机制"},{level:2,title:"5.3 通过 SSH 复制文件",slug:"_5-3-通过-ssh-复制文件"},{level:2,title:"5.4 端口转发",slug:"_5-4-端口转发"},{level:2,title:"5.5 SSH 配置",slug:"_5-5-ssh-配置"},{level:2,title:"6.1 任务控制",slug:"_6-1-任务控制"},{level:3,title:"6.1.1 pgrep & pkill",slug:"_6-1-1-pgrep-pkill"},{level:3,title:"6.1.2 pidwait",slug:"_6-1-2-pidwait"},{level:2,title:"6.2 配置文件",slug:"_6-2-配置文件"}],createdTime:1712294936e3},{title:"2024.03.25-6. Version Control (Git)",frontmatter:{},regularPath:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.25-6.Version%20Control%20(Git).html",relativePath:"Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/2024.03.25-6.Version Control (Git).md",key:"v-00c28682",path:"/Chip/Chip/%E4%B8%80%E7%94%9F%E4%B8%80%E8%8A%AF%E8%AE%A1%E5%88%92/%E9%A2%84%E5%AD%A6%E4%B9%A0%E9%98%B6%E6%AE%B5/The%20Missing%20Semester/2024.03.25-6.Version%20Control%20(Git).html",headers:[{level:2,title:"1. Git 的数据模型",slug:"_1-git-的数据模型"},{level:3,title:"1.1 快照",slug:"_1-1-快照"},{level:3,title:"1.2 历史记录建模:关联快照",slug:"_1-2-历史记录建模-关联快照"},{level:3,title:"1.3 数据模型及其伪代码表示",slug:"_1-3-数据模型及其伪代码表示"},{level:3,title:"1.4 对象和内存寻址",slug:"_1-4-对象和内存寻址"},{level:3,title:"1.5 引用",slug:"_1-5-引用"},{level:3,title:"1.6 仓库",slug:"_1-6-仓库"},{level:2,title:"2. 暂存区",slug:"_2-暂存区"},{level:2,title:"3. Git 的命令行接口",slug:"_3-git-的命令行接口"},{level:3,title:"3.1 基础",slug:"_3-1-基础"},{level:3,title:"3.2 分支和合并",slug:"_3-2-分支和合并"},{level:3,title:"3.3 远端操作",slug:"_3-3-远端操作"},{level:3,title:"3.4 撤销",slug:"_3-4-撤销"},{level:2,title:"4. Git 高级操作",slug:"_4-git-高级操作"},{level:2,title:"5. 杂项",slug:"_5-杂项"},{level:2,title:"6. 资源",slug:"_6-资源"},{level:2,title:"7. Exercise",slug:"_7-exercise"},{level:3,title:"7.1 Fork 本课程网站的仓库",slug:"_7-1-fork-本课程网站的仓库"},{level:3,title:"7.2 从 Git 历史中删除",slug:"_7-2-从-git-历史中删除"},{level:3,title:"7.3 git stash",slug:"_7-3-git-stash"},{level:3,title:"7.4 .gitconfig",slug:"_7-4-gitconfig"},{level:3,title:"7.5 .gitignore_global",slug:"_7-5-gitignore-global"}],createdTime:1712294936e3},{title:"2024.02.22-752.打开转盘锁(BFS)",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.02.22-BFS/2024.02.22-752.%E6%89%93%E5%BC%80%E8%BD%AC%E7%9B%98%E9%94%81%EF%BC%88BFS%EF%BC%89.html",relativePath:"LeetCode/LeetCode/2024.02.22-BFS/2024.02.22-752.打开转盘锁(BFS).md",key:"v-e98c9f74",path:"/LeetCode/LeetCode/2024.02.22-BFS/2024.02.22-752.%E6%89%93%E5%BC%80%E8%BD%AC%E7%9B%98%E9%94%81%EF%BC%88BFS%EF%BC%89.html",headers:[{level:2,title:"Hint:",slug:"hint"}],createdTime:1712294936e3},{title:"2024.03.05-104.二叉树的最大深度",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-104.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6.html",relativePath:"LeetCode/LeetCode/2024.03.05-二叉树/2024.03.05-104.二叉树的最大深度.md",key:"v-64cef05d",path:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-104.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6.html",createdTime:1712294936e3},{title:"2024.03.05-144.二叉树的前序遍历",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-144.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%89%8D%E5%BA%8F%E9%81%8D%E5%8E%86.html",relativePath:"LeetCode/LeetCode/2024.03.05-二叉树/2024.03.05-144.二叉树的前序遍历.md",key:"v-5f160c32",path:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-144.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%89%8D%E5%BA%8F%E9%81%8D%E5%8E%86.html",createdTime:1712294936e3},{title:"2024.03.05-二叉树",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91.html",relativePath:"LeetCode/LeetCode/2024.03.05-二叉树.md",key:"v-4f74fc89",path:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91.html",headers:[{level:2,title:"2024.03.05-104.二叉树的最大深度",slug:"_2024-03-05-104-二叉树的最大深度"},{level:2,title:"2024.03.05-144.二叉树的前序遍历",slug:"_2024-03-05-144-二叉树的前序遍历"},{level:2,title:"2024.03.05-543.二叉树的直径",slug:"_2024-03-05-543-二叉树的直径"}],createdTime:170977737e4},{title:"2024.03.05-543.二叉树的直径",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-543.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E7%9B%B4%E5%BE%84.html",relativePath:"LeetCode/LeetCode/2024.03.05-二叉树/2024.03.05-543.二叉树的直径.md",key:"v-261b3d28",path:"/LeetCode/LeetCode/2024.03.05-%E4%BA%8C%E5%8F%89%E6%A0%91/2024.03.05-543.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E7%9B%B4%E5%BE%84.html",createdTime:1712294936e3},{title:"2024.03.11-二分搜索",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2.html",relativePath:"LeetCode/LeetCode/2024.03.11-二分搜索.md",key:"v-9ea0bd9c",path:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2.html",headers:[{level:2,title:"2024.03.11-704.二分搜索",slug:"_2024-03-11-704-二分搜索"},{level:2,title:"2024.03.11-34.在排序数组中查找元素的第一个和最后一个位置",slug:"_2024-03-11-34-在排序数组中查找元素的第一个和最后一个位置"}],createdTime:1712294936e3},{title:"2024.03.11-34.在排序数组中查找元素的第一个和最后一个位置",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2/2024.03.11-34.%E5%9C%A8%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E6%9F%A5%E6%89%BE%E5%85%83%E7%B4%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%92%8C%E6%9C%80%E5%90%8E%E4%B8%80%E4%B8%AA%E4%BD%8D%E7%BD%AE.html",relativePath:"LeetCode/LeetCode/2024.03.11-二分搜索/2024.03.11-34.在排序数组中查找元素的第一个和最后一个位置.md",key:"v-f4788b02",path:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2/2024.03.11-34.%E5%9C%A8%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E6%9F%A5%E6%89%BE%E5%85%83%E7%B4%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%92%8C%E6%9C%80%E5%90%8E%E4%B8%80%E4%B8%AA%E4%BD%8D%E7%BD%AE.html",createdTime:1712294936e3},{title:"2024.03.11-704.二分搜索",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2/2024.03.11-704.%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2.html",relativePath:"LeetCode/LeetCode/2024.03.11-二分搜索/2024.03.11-704.二分搜索.md",key:"v-702763c5",path:"/LeetCode/LeetCode/2024.03.11-%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2/2024.03.11-704.%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2.html",createdTime:1712294936e3},{title:"2024.03.18-76.最小覆盖子串",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.03.18-76.%E6%9C%80%E5%B0%8F%E8%A6%86%E7%9B%96%E5%AD%90%E4%B8%B2.html",relativePath:"LeetCode/LeetCode/2024.03.18-滑动窗口/2024.03.18-76.最小覆盖子串.md",key:"v-deecd7d8",path:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.03.18-76.%E6%9C%80%E5%B0%8F%E8%A6%86%E7%9B%96%E5%AD%90%E4%B8%B2.html",createdTime:1712294936e3},{title:"2024.03.18-滑动窗口",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3.html",relativePath:"LeetCode/LeetCode/2024.03.18-滑动窗口.md",key:"v-75e9fe08",path:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3.html",headers:[{level:2,title:"2024.03.18-76.最小覆盖子串",slug:"_2024-03-18-76-最小覆盖子串"},{level:2,title:"2024.04.02-567.字符串的排列",slug:"_2024-04-02-567-字符串的排列"},{level:2,title:"2024.04.02-438.找到字符串中所有字母异位词",slug:"_2024-04-02-438-找到字符串中所有字母异位词"},{level:2,title:"2024.04.02-3.无重复字符的最长子串",slug:"_2024-04-02-3-无重复字符的最长子串"}],createdTime:1712294936e3},{title:"2024.04.02-3.无重复字符的最长子串",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-3.%E6%97%A0%E9%87%8D%E5%A4%8D%E5%AD%97%E7%AC%A6%E7%9A%84%E6%9C%80%E9%95%BF%E5%AD%90%E4%B8%B2.html",relativePath:"LeetCode/LeetCode/2024.03.18-滑动窗口/2024.04.02-3.无重复字符的最长子串.md",key:"v-2e6a317e",path:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-3.%E6%97%A0%E9%87%8D%E5%A4%8D%E5%AD%97%E7%AC%A6%E7%9A%84%E6%9C%80%E9%95%BF%E5%AD%90%E4%B8%B2.html",createdTime:1712294936e3},{title:"2024.04.02-438.找到字符串中所有字母异位词",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-438.%E6%89%BE%E5%88%B0%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E6%89%80%E6%9C%89%E5%AD%97%E6%AF%8D%E5%BC%82%E4%BD%8D%E8%AF%8D.html",relativePath:"LeetCode/LeetCode/2024.03.18-滑动窗口/2024.04.02-438.找到字符串中所有字母异位词.md",key:"v-0a85ee78",path:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-438.%E6%89%BE%E5%88%B0%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E6%89%80%E6%9C%89%E5%AD%97%E6%AF%8D%E5%BC%82%E4%BD%8D%E8%AF%8D.html",createdTime:1712294936e3},{title:"2024.04.02-567.字符串的排列",frontmatter:{},regularPath:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-567.%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%8E%92%E5%88%97.html",relativePath:"LeetCode/LeetCode/2024.03.18-滑动窗口/2024.04.02-567.字符串的排列.md",key:"v-6c9c2566",path:"/LeetCode/LeetCode/2024.03.18-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/2024.04.02-567.%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%8E%92%E5%88%97.html",createdTime:1712294936e3},{title:"LeetCode",frontmatter:{},regularPath:"/LeetCode/",relativePath:"LeetCode/README.md",key:"v-14b38dcc",path:"/LeetCode/",headers:[{level:2,title:"2024.02.22-BFS",slug:"_2024-02-22-bfs"},{level:2,title:"2024.03.05-二叉树",slug:"_2024-03-05-二叉树"},{level:2,title:"2024.03.10-滑动窗口",slug:"_2024-03-10-滑动窗口"}],createdTime:170972353e4},{title:"Home",frontmatter:{home:!0,heroText:"Outis Li",tagline:"Personal Blog",actionText:"预览 →",actionLink:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot.md",features:[{title:"Research",details:"用于记录科研中一些注意事项,小工具等等杂乱的东西"},{title:"LeetCode",details:"闲暇时分学习算法的一些记录,以及一些题解"},{title:"Chip",details:"记录自学芯片设计的过程"}],footer:"Licensed under Apache 2.0 | Copyright © 2023-Present Outis Li"},regularPath:"/",relativePath:"README.md",key:"v-2832db09",path:"/",createdTime:170972353e4},{title:"2023.03.12-PKA数据处理",frontmatter:{},regularPath:"/Research/Research/2023-Geant4/2023.03.12-PKA%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86.html",relativePath:"Research/Research/2023-Geant4/2023.03.12-PKA数据处理.md",key:"v-1454065a",path:"/Research/Research/2023-Geant4/2023.03.12-PKA%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86.html",createdTime:170977737e4},{title:"Research",frontmatter:{},regularPath:"/Research/",relativePath:"Research/README.md",key:"v-60f1b38c",path:"/Research/",createdTime:170977737e4},{title:"2023.02.13-在超算上搭建Singularity环境并配置Geant4",frontmatter:{},regularPath:"/Research/Research/2023-Geant4/2023.02.13-%E5%9C%A8%E8%B6%85%E7%AE%97%E4%B8%8A%E6%90%AD%E5%BB%BASingularity%E7%8E%AF%E5%A2%83%E5%B9%B6%E9%85%8D%E7%BD%AEGeant4.html",relativePath:"Research/Research/2023-Geant4/2023.02.13-在超算上搭建Singularity环境并配置Geant4.md",key:"v-3325c5ea",path:"/Research/Research/2023-Geant4/2023.02.13-%E5%9C%A8%E8%B6%85%E7%AE%97%E4%B8%8A%E6%90%AD%E5%BB%BASingularity%E7%8E%AF%E5%A2%83%E5%B9%B6%E9%85%8D%E7%BD%AEGeant4.html",headers:[{level:2,title:"I. 制作singularity包",slug:"i-制作singularity包"},{level:3,title:"1. 进入fakeroot节点",slug:"_1-进入fakeroot节点"},{level:3,title:"2. 制作并进入sandbox镜像",slug:"_2-制作并进入sandbox镜像"},{level:3,title:"3. 配置geant4环境",slug:"_3-配置geant4环境"},{level:3,title:"4. 打包",slug:"_4-打包"},{level:2,title:"II. 配置go&singularity",slug:"ii-配置go-singularity"},{level:3,title:"1. 配置go环境",slug:"_1-配置go环境"},{level:3,title:"2. 安装singularity",slug:"_2-安装singularity"},{level:3,title:"3. 环境变量",slug:"_3-环境变量"},{level:2,title:"III. 启用singularity",slug:"iii-启用singularity"},{level:3,title:"1. 将SIF镜像下载到常规节点",slug:"_1-将sif镜像下载到常规节点"},{level:3,title:"2. 转换成sandbox镜像并启用",slug:"_2-转换成sandbox镜像并启用"},{level:3,title:"3. 配置环境变量",slug:"_3-配置环境变量"},{level:2,title:"IV. 附录",slug:"iv-附录"},{level:3,title:"1. SIF容器与sandbox相互转换",slug:"_1-sif容器与sandbox相互转换"},{level:3,title:"2. 在fakeroot节点上删除sandbox镜像",slug:"_2-在fakeroot节点上删除sandbox镜像"}],createdTime:170977737e4},{title:"2023.02.27-处理Geant4获取的数据",frontmatter:{},regularPath:"/Research/Research/2023-Geant4/2023.02.27-%E5%A4%84%E7%90%86Geant4%E8%8E%B7%E5%8F%96%E7%9A%84%E6%95%B0%E6%8D%AE.html",relativePath:"Research/Research/2023-Geant4/2023.02.27-处理Geant4获取的数据.md",key:"v-60fcb6e3",path:"/Research/Research/2023-Geant4/2023.02.27-%E5%A4%84%E7%90%86Geant4%E8%8E%B7%E5%8F%96%E7%9A%84%E6%95%B0%E6%8D%AE.html",headers:[{level:2,title:"直方图 Histogram",slug:"直方图-histogram"},{level:2,title:"热力图 Heatmap",slug:"热力图-heatmap"}],createdTime:170977737e4},{title:"2023.05.23-Geant4多粒子源设置",frontmatter:{},regularPath:"/Research/Research/2023-Geant4/2023.05.23-Geant4%E5%A4%9A%E7%B2%92%E5%AD%90%E6%BA%90%E8%AE%BE%E7%BD%AE.html",relativePath:"Research/Research/2023-Geant4/2023.05.23-Geant4多粒子源设置.md",key:"v-4353bce0",path:"/Research/Research/2023-Geant4/2023.05.23-Geant4%E5%A4%9A%E7%B2%92%E5%AD%90%E6%BA%90%E8%AE%BE%E7%BD%AE.html",createdTime:170977737e4},{title:"2023.06.14-Geant4各版本的安装",frontmatter:{},regularPath:"/Research/Research/2023-Geant4/2023.06.14-Geant4%E5%90%84%E7%89%88%E6%9C%AC%E7%9A%84%E5%AE%89%E8%A3%85.html",relativePath:"Research/Research/2023-Geant4/2023.06.14-Geant4各版本的安装.md",key:"v-de532b9a",path:"/Research/Research/2023-Geant4/2023.06.14-Geant4%E5%90%84%E7%89%88%E6%9C%AC%E7%9A%84%E5%AE%89%E8%A3%85.html",headers:[{level:2,title:"安装依赖",slug:"安装依赖"},{level:2,title:"下载安装Geant4",slug:"下载安装geant4"}],createdTime:170977737e4},{title:"2023.08.28-Geant4 自定义 PhysicsList",frontmatter:{},regularPath:"/Research/Research/2023-Geant4/2023.08.28-Geant4%E8%87%AA%E5%AE%9A%E4%B9%89PhysicsList.html",relativePath:"Research/Research/2023-Geant4/2023.08.28-Geant4自定义PhysicsList.md",key:"v-0dd1e8ac",path:"/Research/Research/2023-Geant4/2023.08.28-Geant4%E8%87%AA%E5%AE%9A%E4%B9%89PhysicsList.html",headers:[{level:2,title:"一个最简单的例子",slug:"一个最简单的例子"},{level:3,title:"main:",slug:"main"},{level:2,title:"自定义物理列表类:",slug:"自定义物理列表类"},{level:2,title:"自定义碰撞过程类:",slug:"自定义碰撞过程类"},{level:2,title:"1. 关于必须重新定义的函数:",slug:"_1-关于必须重新定义的函数"},{level:2,title:"2. 关于 aParticleChange:",slug:"_2-关于-aparticlechange"},{level:2,title:"3. GetMeanFreePath 的作用",slug:"_3-getmeanfreepath-的作用"},{level:2,title:"4. 多物理过程情形",slug:"_4-多物理过程情形"},{level:3,title:"说明:",slug:"说明"},{level:3,title:"示例:",slug:"示例"}],createdTime:170977737e4},{title:"2023.12.18-Geant4自动化",frontmatter:{},regularPath:"/Research/Research/2023-Geant4/2023.12.18-Geant4%E8%87%AA%E5%8A%A8%E5%8C%96.html",relativePath:"Research/Research/2023-Geant4/2023.12.18-Geant4自动化.md",key:"v-7b684336",path:"/Research/Research/2023-Geant4/2023.12.18-Geant4%E8%87%AA%E5%8A%A8%E5%8C%96.html",headers:[{level:2,title:"1. CMakeLists.txt与run.mac的自动创建",slug:"_1-cmakelists-txt与run-mac的自动创建"},{level:3,title:"CMakeLists.txt中:",slug:"cmakelists-txt中"},{level:3,title:"run.mac中",slug:"run-mac中"},{level:2,title:"2. Docker自动化",slug:"_2-docker自动化"},{level:3,title:"Dockerfile:",slug:"dockerfile"},{level:3,title:"start.sh:",slug:"start-sh"}],createdTime:170977737e4},{title:"2023.12.12-Docker",frontmatter:{},regularPath:"/Research/Research/2023.12.12-Docker.html",relativePath:"Research/Research/2023.12.12-Docker.md",key:"v-435cf352",path:"/Research/Research/2023.12.12-Docker.html",headers:[{level:2,title:"01. 🎉 Docker 简介和安装",slug:"_01-🎉-docker-简介和安装"},{level:2,title:"02. 💻 Docker 快速安装软件",slug:"_02-💻-docker-快速安装软件"},{level:2,title:"03. 💽 制作自己的镜像",slug:"_03-💽-制作自己的镜像"},{level:2,title:"04. 🥙 目录挂载",slug:"_04-🥙-目录挂载"},{level:2,title:"05. 👨‍👦‍👦 多容器通信",slug:"_05-👨‍👦‍👦-多容器通信"},{level:2,title:"06. 🍁 Docker-Compose",slug:"_06-🍁-docker-compose"},{level:2,title:"07. 🚚 发布和部署",slug:"_07-🚚-发布和部署"},{level:2,title:"08. 🎯 备份和迁移数据",slug:"_08-🎯-备份和迁移数据"},{level:2,title:"2023.12.12-制作定制镜像",slug:"_2023-12-12-制作定制镜像"}],createdTime:1712294936e3},{title:"2023.09.05-C++ Trim 程序",frontmatter:{},regularPath:"/Research/Research/2023-Geant4/2023.09.05-C++%20Trim%E7%A8%8B%E5%BA%8F.html",relativePath:"Research/Research/2023-Geant4/2023.09.05-C++ Trim程序.md",key:"v-391322e8",path:"/Research/Research/2023-Geant4/2023.09.05-C++%20Trim%E7%A8%8B%E5%BA%8F.html",headers:[{level:2,title:"每个粒子端到端的计算",slug:"每个粒子端到端的计算"},{level:3,title:"InitialIon()",slug:"initialion"},{level:2,title:"具体计算",slug:"具体计算"},{level:3,title:"1. FreeLength()",slug:"_1-freelength"},{level:3,title:"使用到的变量:",slug:"使用到的变量"},{level:3,title:"输出(改变)的变量:",slug:"输出-改变-的变量"},{level:3,title:"2. ChoseCollisionAtom()",slug:"_2-chosecollisionatom"},{level:3,title:"使用到的变量:",slug:"使用到的变量-2"},{level:3,title:"改变的变量:",slug:"改变的变量"},{level:2,title:"3. EleEnergyLoss()",slug:"_3-eleenergyloss"},{level:3,title:"使用的变量:",slug:"使用的变量"},{level:3,title:"改变的变量:",slug:"改变的变量-2"},{level:2,title:"4. EmissionAngle()",slug:"_4-emissionangle"},{level:3,title:"使用的变量:",slug:"使用的变量-2"},{level:3,title:"改变的变量:",slug:"改变的变量-3"},{level:2,title:"5. IonNewCondition()",slug:"_5-ionnewcondition"},{level:3,title:"使用的变量:",slug:"使用的变量-3"},{level:3,title:"改变的变量:",slug:"改变的变量-4"},{level:2,title:"6. ProcessRecorder()",slug:"_6-processrecorder"},{level:3,title:"使用的变量:",slug:"使用的变量-4"},{level:3,title:"改变的变量:",slug:"改变的变量-5"},{level:2,title:"7. OutOrNot(int &Ionflag)",slug:"_7-outornot-int-ionflag"},{level:3,title:"使用的变量:",slug:"使用的变量-5"},{level:3,title:"改变的变量:",slug:"改变的变量-6"}],createdTime:170977737e4},{title:"01. 🎉 Docker 简介和安装",frontmatter:{},regularPath:"/Research/Research/2023.12.12-Docker/01.Docker%20%E7%AE%80%E4%BB%8B%E5%92%8C%E5%AE%89%E8%A3%85.html",relativePath:"Research/Research/2023.12.12-Docker/01.Docker 简介和安装.md",key:"v-740d92c0",path:"/Research/Research/2023.12.12-Docker/01.Docker%20%E7%AE%80%E4%BB%8B%E5%92%8C%E5%AE%89%E8%A3%85.html",headers:[{level:2,title:"Docker 是什么",slug:"docker-是什么"},{level:2,title:"跟普通虚拟机的对比",slug:"跟普通虚拟机的对比"},{level:2,title:"打包、分发、部署",slug:"打包、分发、部署"},{level:2,title:"Docker 部署的优势",slug:"docker-部署的优势"},{level:2,title:"Docker 通常用来做什么",slug:"docker-通常用来做什么"},{level:2,title:"重要概念:镜像、容器",slug:"重要概念-镜像、容器"},{level:2,title:"安装",slug:"安装"},{level:2,title:"启动报错解决",slug:"启动报错解决"},{level:2,title:"镜像加速源",slug:"镜像加速源"}],createdTime:1712294936e3},{title:"03. 💽 制作自己的镜像",frontmatter:{},regularPath:"/Research/Research/2023.12.12-Docker/03.%E5%88%B6%E4%BD%9C%E8%87%AA%E5%B7%B1%E7%9A%84%E9%95%9C%E5%83%8F.html",relativePath:"Research/Research/2023.12.12-Docker/03.制作自己的镜像.md",key:"v-2c2b6c90",path:"/Research/Research/2023.12.12-Docker/03.%E5%88%B6%E4%BD%9C%E8%87%AA%E5%B7%B1%E7%9A%84%E9%95%9C%E5%83%8F.html",headers:[{level:3,title:"为自己的 Web 项目构建镜像",slug:"为自己的-web-项目构建镜像"},{level:3,title:"编写 Dockerfile",slug:"编写-dockerfile"},{level:3,title:"Build 为镜像(安装包)和运行",slug:"build-为镜像-安装包-和运行"},{level:3,title:"更多相关命令",slug:"更多相关命令"}],createdTime:1712294936e3},{title:"02. 💻 Docker 快速安装软件",frontmatter:{},regularPath:"/Research/Research/2023.12.12-Docker/02.Docker%20%E5%BF%AB%E9%80%9F%E5%AE%89%E8%A3%85%E8%BD%AF%E4%BB%B6.html",relativePath:"Research/Research/2023.12.12-Docker/02.Docker 快速安装软件.md",key:"v-952997da",path:"/Research/Research/2023.12.12-Docker/02.Docker%20%E5%BF%AB%E9%80%9F%E5%AE%89%E8%A3%85%E8%BD%AF%E4%BB%B6.html",headers:[{level:3,title:"直接安装的缺点",slug:"直接安装的缺点"},{level:3,title:"Docker 安装的优点",slug:"docker-安装的优点"},{level:3,title:"演示 Docker 安装 Redis",slug:"演示-docker-安装-redis"},{level:3,title:"安装 Wordpress",slug:"安装-wordpress"},{level:3,title:"安装 ELK",slug:"安装-elk"},{level:3,title:"更多相关命令",slug:"更多相关命令"}],createdTime:1712294936e3},{title:"04. 🥙 目录挂载",frontmatter:{},regularPath:"/Research/Research/2023.12.12-Docker/04.%E7%9B%AE%E5%BD%95%E6%8C%82%E8%BD%BD.html",relativePath:"Research/Research/2023.12.12-Docker/04.目录挂载.md",key:"v-29996ff7",path:"/Research/Research/2023.12.12-Docker/04.%E7%9B%AE%E5%BD%95%E6%8C%82%E8%BD%BD.html",headers:[{level:3,title:"现存问题",slug:"现存问题"},{level:3,title:"几种挂载方式",slug:"几种挂载方式"},{level:3,title:"挂载演示",slug:"挂载演示"}],createdTime:1712294936e3},{title:"05. 👨‍👦‍👦 多容器通信",frontmatter:{},regularPath:"/Research/Research/2023.12.12-Docker/05.%E5%A4%9A%E5%AE%B9%E5%99%A8%E9%80%9A%E4%BF%A1.html",relativePath:"Research/Research/2023.12.12-Docker/05.多容器通信.md",key:"v-ecf2f5e8",path:"/Research/Research/2023.12.12-Docker/05.%E5%A4%9A%E5%AE%B9%E5%99%A8%E9%80%9A%E4%BF%A1.html",headers:[{level:3,title:"学习目标",slug:"学习目标"},{level:3,title:"创建虚拟网络",slug:"创建虚拟网络"},{level:3,title:"演示",slug:"演示"},{level:3,title:"创建一个名为test-net的网络:",slug:"创建一个名为test-net的网络"},{level:3,title:"运行 Redis 在 test-net 网络中,别名redis",slug:"运行-redis-在-test-net-网络中-别名redis"},{level:3,title:"修改代码中访问redis的地址为网络别名",slug:"修改代码中访问redis的地址为网络别名"},{level:3,title:"运行 Web 项目,使用同个网络",slug:"运行-web-项目-使用同个网络"},{level:3,title:"查看数据",slug:"查看数据"},{level:3,title:"更多相关命令",slug:"更多相关命令"}],createdTime:1712294936e3},{title:"06. 🍁 Docker-Compose",frontmatter:{},regularPath:"/Research/Research/2023.12.12-Docker/06.Docker-Compose.html",relativePath:"Research/Research/2023.12.12-Docker/06.Docker-Compose.md",key:"v-320d8845",path:"/Research/Research/2023.12.12-Docker/06.Docker-Compose.html",headers:[{level:3,title:"现存问题",slug:"现存问题"},{level:3,title:"安装 Docker Compose",slug:"安装-docker-compose"},{level:3,title:"编写脚本",slug:"编写脚本"},{level:3,title:"跑起来",slug:"跑起来"}],createdTime:1712294936e3},{title:"2023-Geant4",frontmatter:{},regularPath:"/Research/Research/2023-Geant4.html",relativePath:"Research/Research/2023-Geant4.md",key:"v-83c37b1c",path:"/Research/Research/2023-Geant4.html",headers:[{level:2,title:"2023.02.13-在超算上搭建Singularity环境并配置Geant4",slug:"_2023-02-13-在超算上搭建singularity环境并配置geant4"},{level:2,title:"2023.06.14-Geant4各版本的安装",slug:"_2023-06-14-geant4各版本的安装"},{level:2,title:"2023.02.27-处理Geant4获取的数据",slug:"_2023-02-27-处理geant4获取的数据"},{level:2,title:"2023.05.23-Geant4多粒子源设置",slug:"_2023-05-23-geant4多粒子源设置"},{level:2,title:"2023.03.12-PKA数据处理",slug:"_2023-03-12-pka数据处理"},{level:2,title:"2023.08.28-Geant4自定义PhysicsList",slug:"_2023-08-28-geant4自定义physicslist"},{level:2,title:"2023.09.05-C++ Trim程序",slug:"_2023-09-05-c-trim程序"},{level:2,title:"2023.12.18-Geant4自动化",slug:"_2023-12-18-geant4自动化"}],createdTime:170977737e4},{title:"07. 🚚 发布和部署",frontmatter:{},regularPath:"/Research/Research/2023.12.12-Docker/07.%E5%8F%91%E5%B8%83%E5%92%8C%E9%83%A8%E7%BD%B2.html",relativePath:"Research/Research/2023.12.12-Docker/07.发布和部署.md",key:"v-710cb2fd",path:"/Research/Research/2023.12.12-Docker/07.%E5%8F%91%E5%B8%83%E5%92%8C%E9%83%A8%E7%BD%B2.html",headers:[{level:3,title:"镜像仓库介绍",slug:"镜像仓库介绍"},{level:3,title:"上传我们的镜像",slug:"上传我们的镜像"},{level:3,title:"docker-compose 中也可以直接用这个镜像了",slug:"docker-compose-中也可以直接用这个镜像了"},{level:3,title:"阿里云容器托管",slug:"阿里云容器托管"}],createdTime:1712294936e3},{title:"08. 🎯 备份和迁移数据",frontmatter:{},regularPath:"/Research/Research/2023.12.12-Docker/08.%E5%A4%87%E4%BB%BD%E5%92%8C%E8%BF%81%E7%A7%BB%E6%95%B0%E6%8D%AE.html",relativePath:"Research/Research/2023.12.12-Docker/08.备份和迁移数据.md",key:"v-047e1f3e",path:"/Research/Research/2023.12.12-Docker/08.%E5%A4%87%E4%BB%BD%E5%92%8C%E8%BF%81%E7%A7%BB%E6%95%B0%E6%8D%AE.html",headers:[{level:3,title:"迁移方式介绍",slug:"迁移方式介绍"},{level:3,title:"备份和导入 Volume 的流程",slug:"备份和导入-volume-的流程"},{level:3,title:"备份 MongoDB 数据演示",slug:"备份-mongodb-数据演示"},{level:3,title:"恢复 Volume 数据演示",slug:"恢复-volume-数据演示"}],createdTime:1712294936e3},{title:"2023.12.12-制作定制镜像",frontmatter:{},regularPath:"/Research/Research/2023.12.12-Docker/2023.12.12-%E5%88%B6%E4%BD%9C%E5%AE%9A%E5%88%B6%E9%95%9C%E5%83%8F.html",relativePath:"Research/Research/2023.12.12-Docker/2023.12.12-制作定制镜像.md",key:"v-21c46276",path:"/Research/Research/2023.12.12-Docker/2023.12.12-%E5%88%B6%E4%BD%9C%E5%AE%9A%E5%88%B6%E9%95%9C%E5%83%8F.html",headers:[{level:2,title:"1. 获取Ubuntu系统",slug:"_1-获取ubuntu系统"},{level:2,title:"2. 在容器内配置容器",slug:"_2-在容器内配置容器"},{level:2,title:"3. 将容器打包成镜像",slug:"_3-将容器打包成镜像"},{level:2,title:"4. 将镜像实例化为容器并运行终端",slug:"_4-将镜像实例化为容器并运行终端"},{level:2,title:"1. 编写容器启动脚本start.sh",slug:"_1-编写容器启动脚本start-sh"},{level:2,title:"2. 编写Dockerfile",slug:"_2-编写dockerfile"},{level:2,title:"3. 构建镜像",slug:"_3-构建镜像"},{level:2,title:"4. 运行容器",slug:"_4-运行容器"}],createdTime:1712294936e3},{title:"Helloworld",frontmatter:{},regularPath:"/about/",relativePath:"about/README.md",key:"v-2f1ebe3a",path:"/about/",createdTime:170972353e4}],themeConfig:{logo:"/assets/img/good.png",sidebarDepth:2,nav:[{text:"Home",link:"/"},{text:"Research",items:[{text:"Geant4",link:"/Research/Research/2023-Geant4.md"},{text:"CS",items:[{text:"Docker",link:"/Research/Research/2023.12.12-Docker.md"},{text:"tbc",link:"/Chip/Chip/2.%202024.02.21-Chisel.md"}]},{text:"tbc",items:[{text:"tbc",link:"/Chip/Chip/3.%202023.11.07-Verilog语法.md"},{text:"tbc",link:"/Chip/Chip/3.%202023.11.07-Verilog语法.md"}]}]},{text:"LeetCode",items:[{text:"Basic",items:[{text:"BFS",link:"/LeetCode/Leetcode/2024.02.22-BFS.md"},{text:"二叉树",link:"/LeetCode/Leetcode/2024.03.05-二叉树.md"},{text:"二分搜索",link:"/LeetCode/Leetcode/2024.03.11-二分搜索.md"},{text:"滑动窗口",link:"/LeetCode/Leetcode/2024.03.18-滑动窗口.md"}]},{text:"tbc",items:[{text:"tbc",link:"/Chip/Chip/3.%202023.11.07-Verilog语法.md"},{text:"tbc",link:"/Chip/Chip/3.%202023.11.07-Verilog语法.md"}]}]},{text:"Chip",items:[{text:"一生一芯",items:[{text:"预学习",link:"/Chip/Chip/1.%20一生一芯计划.md"},{text:"B阶段",link:"/Chip/Chip/1.%20一生一芯计划.md"},{text:"A阶段",link:"/Chip/Chip/1.%20一生一芯计划.md"}]},{text:"Chisel",items:[{text:"Outline",link:"/Chip/Chip/2.%202024.02.21-Chisel.md"},{text:"Bootcamp",link:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot.md"}]},{text:"Verilog",items:[{text:"Outline",link:"/Chip/Chip/3.%202023.11.07-Verilog语法.md"},{text:"Basic",link:"/Chip/Chip/3.%202023.11.07-Verilog语法.md"}]}]},{text:"Others",items:[{text:"tbc",items:[{text:"tbc",link:"/Chip/Chip/1.%20一生一芯计划.md"},{text:"tbc",link:"/Chip/Chip/1.%20一生一芯计划.md"},{text:"tbc",link:"/Chip/Chip/1.%20一生一芯计划.md"}]},{text:"tbc",items:[{text:"tbc",link:"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot.md"},{text:"tbc",link:"/Chip/Chip/2.%202024.02.21-Chisel.md"}]},{text:"tbc",items:[{text:"tbc",link:"/Chip/Chip/3.%202023.11.07-Verilog语法.md"},{text:"tbc",link:"/Chip/Chip/3.%202023.11.07-Verilog语法.md"}]}]},{text:"External",link:"https://google.com"}],displayAllHeaders:!1,activeHeaderLinks:!0}};r(234);Hr.component("Badge",()=>Promise.all([r.e(0),r.e(4)]).then(r.bind(null,385))),Hr.component("CodeBlock",()=>Promise.all([r.e(0),r.e(5)]).then(r.bind(null,381))),Hr.component("CodeGroup",()=>Promise.all([r.e(0),r.e(6)]).then(r.bind(null,382)));r(235),r(236),r(237);var Pl=[{},({Vue:e})=>{e.mixin({computed:{$dataBlock(){return this.$options.__data__block__}}})},{},{},({siteData:e,options:t})=>{e.themeConfig.sidebar={"/Chip/Chip/2024.02.21-Chisel/2024.02.21-ChiselBoot/":[{title:"2024 02 21 Chisel Boot",collapsable:!1,sidebarDepth:2,children:["2024.02.21-1 Introduction to Scala","2024.02.23-2.1 First Chisel Module","2024.02.24-2.2 Combinational Logic","2024.02.25-2.3 Control Flow","2024.02.26-2.4 Sequential Logic","2024.02.28-2.5 FIR Filter","2024.02.29-2.6 More on ChiselTest","2024.03.01-3.1 Generators Parameters","2024.03.03-3.2 Generators Collections","2024.03.04-3.3 Interlude Chisel Standard Library","2024.03.05-3.4 Higher-Order Functions","2024.03.07-3.5 Functional Programming","2024.03.09-3.6 Object Oriented Programming","2024.03.12-3.7 Generators Types"]}],"/Chip/Chip/一生一芯计划/预学习阶段/Learn C the hard way/":[{title:"Learn C The Hard Way",collapsable:!1,sidebarDepth:2,children:["2024.04.02-练习1:启用编译器","2024.04.02-练习2:用Make来代替Python","2024.04.02-练习3:格式化输出","2024.04.03-练习4:Valgrind 介绍","2024.04.03-练习5:一个C程序的结构","2024.04.03-练习6:变量类型","2024.04.03-练习7:更多变量和一些算术","2024.04.03-练习8:大小和数组","2024.04.03-练习9:数组和字符串","2024.04.04-练习10:字符串数组和循环","2024.04.05-练习11:While循环和布尔表达式","2024.04.05-练习12:If,Else If,Else","2024.04.05-练习13:Switch语句","2024.04.05-练习14:编写并使用函数","2024.04.05-练习15:指针,可怕的指针","2024.04.05-练习16:结构体和指向它们的指针","2024.04.08-练习17:堆和栈的内存分配","2024.04.10-练习18:函数指针","2024.04.10-练习32:双向链表","2024.04.11-练习33:链表算法","2024.04.11-练习42:栈和队列","2024.04.12-练习44:环形缓冲区"]}],"/Chip/Chip/一生一芯计划/预学习阶段/The Missing Semester/":[{title:"The Missing Semester",collapsable:!1,sidebarDepth:2,children:["2024.03.14-1.The Shell","2024.03.19-2.Script","2024.03.20-3.Vim","2024.03.21-4.Data Wrangling","2024.03.21-5.Command Line Interface","2024.03.25-6.Version Control (Git)"]}],"/Research/Research/2023.12.12-Docker/":[{title:"2023 12 12 Docker",collapsable:!1,sidebarDepth:2,children:["01.Docker 简介和安装","02.Docker 快速安装软件","03.制作自己的镜像","04.目录挂载","05.多容器通信","06.Docker-Compose","07.发布和部署","08.备份和迁移数据","2023.12.12-制作定制镜像"]}],"/LeetCode/LeetCode/2024.03.11-二分搜索/":[{title:"2024.03.11-二分搜索",collapsable:!1,sidebarDepth:2,children:["2024.03.11-34.在排序数组中查找元素的第一个和最后一个位置","2024.03.11-704.二分搜索"]}],"/LeetCode/LeetCode/2024.03.18-滑动窗口/":[{title:"2024.03.18-滑动窗口",collapsable:!1,sidebarDepth:2,children:["2024.03.18-76.最小覆盖子串","2024.04.02-3.无重复字符的最长子串","2024.04.02-438.找到字符串中所有字母异位词","2024.04.02-567.字符串的排列"]}],"/LeetCode/LeetCode/2024.02.22-BFS/":[{title:"2024 02 22 BFS",collapsable:!1,sidebarDepth:2,children:["2024.02.22-752.打开转盘锁(BFS)"]}],"/LeetCode/LeetCode/2024.03.05-二叉树/":[{title:"2024.03.05-二叉树",collapsable:!1,sidebarDepth:2,children:["2024.03.05-104.二叉树的最大深度","2024.03.05-144.二叉树的前序遍历","2024.03.05-543.二叉树的直径"]}],"/Chip/Chip/2023.11.07-Verilog语法/":[{title:"2023.11.07-Verilog语法",collapsable:!1,sidebarDepth:2,children:["01.Verilog 基础语法","02.Verilog 数值表示","03.Verilog 数据类型","04.Verilog 表达式","10.Verilog 多路分支语句","2023.11.15-Vivado","2023.11.16-阻塞与非阻塞赋值"]}],"/Research/Research/2023-Geant4/":[{title:"2023 Geant4",collapsable:!1,sidebarDepth:2,children:["2023.02.13-在超算上搭建Singularity环境并配置Geant4","2023.02.27-处理Geant4获取的数据","2023.03.12-PKA数据处理","2023.05.23-Geant4多粒子源设置","2023.06.14-Geant4各版本的安装","2023.08.28-Geant4自定义PhysicsList","2023.09.05-C++ Trim程序","2023.12.18-Geant4自动化"]}],"/Chip/Chip/2024.02.21-Chisel/":[{title:"2024 02 21 Chisel",collapsable:!1,sidebarDepth:2,children:["2024.02.21-ChiselBoot"]}],"/Chip/Chip/一生一芯计划/预学习阶段/":[{title:"预学习阶段",collapsable:!1,sidebarDepth:2,children:["Learn C the hard way","The Missing Semester"]}],"/LeetCode/LeetCode/":[{title:"Leet Code",collapsable:!1,sidebarDepth:2,children:["2024.02.22-BFS","2024.03.05-二叉树","2024.03.11-二分搜索","2024.03.18-滑动窗口"]}],"/Research/Research/":[{title:"Research",collapsable:!1,sidebarDepth:2,children:["2023-Geant4","2023.12.12-Docker"]}],"/Chip/Chip/一生一芯计划/":[{title:"一生一芯计划",collapsable:!1,sidebarDepth:2,children:["预学习阶段"]}],"/Chip/Chip/":[{title:"Chip",collapsable:!1,sidebarDepth:2,children:["1. 一生一芯计划","2. 2024.02.21-Chisel","3. 2023.11.07-Verilog语法"]}],"/LeetCode/":[{title:"Leet Code",collapsable:!1,sidebarDepth:2,children:[""]}],"/Research/":[{title:"Research",collapsable:!1,sidebarDepth:2,children:[""]}],"/about/":[{title:"About",collapsable:!1,sidebarDepth:2,children:[""]}],"/Chip/":[{title:"Chip",collapsable:!1,sidebarDepth:2,children:[""]}]}},({Vue:e})=>{const{ignoredElements:t}=e.config;t.every(e=>"/^mjx-/"!==e.toString())&&t.push(/^mjx-/)}],Rl=[];class Tl extends class{constructor(){this.store=new Hr({data:{state:{}}})}$get(e){return this.store.state[e]}$set(e,t){Hr.set(this.store.state,e,t)}$emit(...e){this.store.$emit(...e)}$on(...e){this.store.$on(...e)}}{}Object.assign(Tl.prototype,{getPageAsyncComponent:ll,getLayoutAsyncComponent:sl,getAsyncComponent:hl,getVueComponent:cl});var Ol={install(e){const t=new Tl;e.$vuepress=t,e.prototype.$vuepress=t}};function jl(e,t){const r=t.toLowerCase();return e.options.routes.some(e=>e.path.toLowerCase()===r)}var $l={props:{pageKey:String,slotKey:{type:String,default:"default"}},render(e){const t=this.pageKey||this.$parent.$page.key;return El("pageKey",t),Hr.component(t)||Hr.component(t,ll(t)),Hr.component(t)?e(t):e("")}},Ml={functional:!0,props:{slotKey:String,required:!0},render:(e,{props:t,slots:r})=>e("div",{class:["content__"+t.slotKey]},r()[t.slotKey])},Vl={computed:{openInNewWindowTitle(){return this.$themeLocaleConfig.openNewWindowText||"(opens new window)"}}},Il=(r(238),r(239),Object(Dl.a)(Vl,(function(){var e=this._self._c;return e("span",[e("svg",{staticClass:"icon outbound",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"}},[e("path",{attrs:{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}}),this._v(" "),e("polygon",{attrs:{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"}})]),this._v(" "),e("span",{staticClass:"sr-only"},[this._v(this._s(this.openInNewWindowTitle))])])}),[],!1,null,null,null).exports),Gl={functional:!0,render(e,{parent:t,children:r}){if(t._isMounted)return r;t.$once("hook:mounted",()=>{t.$forceUpdate()})}};Hr.config.productionTip=!1,Hr.use(qo),Hr.use(Ol),Hr.mixin(function(e,t,r=Hr){!function(e){e.locales&&Object.keys(e.locales).forEach(t=>{e.locales[t].path=t});Object.freeze(e)}(t),r.$vuepress.$set("siteData",t);const n=new(e(r.$vuepress.$get("siteData"))),i=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(n)),a={};return Object.keys(i).reduce((e,t)=>(t.startsWith("$")&&(e[t]=i[t].get),e),a),{computed:a}}(e=>class{setPage(e){this.__page=e}get $site(){return e}get $themeConfig(){return this.$site.themeConfig}get $frontmatter(){return this.$page.frontmatter}get $localeConfig(){const{locales:e={}}=this.$site;let t,r;for(const n in e)"/"===n?r=e[n]:0===this.$page.path.indexOf(n)&&(t=e[n]);return t||r||{}}get $siteTitle(){return this.$localeConfig.title||this.$site.title||""}get $canonicalUrl(){const{canonicalUrl:e}=this.$page.frontmatter;return"string"==typeof e&&e}get $title(){const e=this.$page,{metaTitle:t}=this.$page.frontmatter;if("string"==typeof t)return t;const r=this.$siteTitle,n=e.frontmatter.home?null:e.frontmatter.title||e.title;return r?n?n+" | "+r:r:n||"VuePress"}get $description(){const e=function(e){if(e){const t=e.filter(e=>"description"===e.name)[0];if(t)return t.content}}(this.$page.frontmatter.meta);return e||(this.$page.frontmatter.description||this.$localeConfig.description||this.$site.description||"")}get $lang(){return this.$page.frontmatter.lang||this.$localeConfig.lang||"en-US"}get $localePath(){return this.$localeConfig.path||"/"}get $themeLocaleConfig(){return(this.$site.themeConfig.locales||{})[this.$localePath]||{}}get $page(){return this.__page?this.__page:function(e,t){for(let r=0;rr||(e.hash?!Hr.$vuepress.$get("disableScrollBehavior")&&{selector:decodeURIComponent(e.hash)}:{x:0,y:0})});!function(e){e.beforeEach((t,r,n)=>{if(jl(e,t.path))n();else if(/(\/|\.html)$/.test(t.path))if(/\/$/.test(t.path)){const r=t.path.replace(/\/$/,"")+".html";jl(e,r)?n(r):n()}else n();else{const r=t.path+"/",i=t.path+".html";jl(e,i)?n(i):jl(e,r)?n(r):n()}})}(r);const n={};try{await Promise.all(Pl.filter(e=>"function"==typeof e).map(t=>t({Vue:Hr,options:n,router:r,siteData:Sl,isServer:e})))}catch(e){console.error(e)}return{app:new Hr(Object.assign(n,{router:r,render:e=>e("div",{attrs:{id:"app"}},[e("RouterView",{ref:"layout"}),e("div",{class:"global-ui"},Rl.map(t=>e(t)))])})),router:r}}(!1).then(({app:e,router:t})=>{t.onReady(()=>{e.$mount("#app")})})}]); \ No newline at end of file diff --git a/assets/js/vendors~docsearch.3b28fe31.js b/assets/js/vendors~docsearch.3b28fe31.js new file mode 100644 index 0000000..014e1b7 --- /dev/null +++ b/assets/js/vendors~docsearch.3b28fe31.js @@ -0,0 +1,3 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[9],{378:function(t,e,n){ +/*! docsearch 2.6.3 | © Algolia | github.com/algolia/docsearch */ +var r;"undefined"!=typeof self&&self,r=function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=22)}([function(t,e,n){"use strict";var r,i=n(1);function s(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}t.exports={isArray:null,isFunction:null,isObject:null,bind:null,each:null,map:null,mixin:null,isMsie:function(t){if(void 0===t&&(t=navigator.userAgent),/(msie|trident)/i.test(t)){var e=t.match(/(msie |rv:)(\d+(.\d+)?)/i);if(e)return e[2]}return!1},escapeRegExChars:function(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isNumber:function(t){return"number"==typeof t},toStr:function(t){return null==t?"":t+""},cloneDeep:function(t){var e=this.mixin({},t),n=this;return this.each(e,(function(t,r){t&&(n.isArray(t)?e[r]=[].concat(t):n.isObject(t)&&(e[r]=n.cloneDeep(t)))})),e},error:function(t){throw new Error(t)},every:function(t,e){var n=!0;return t?(this.each(t,(function(r,i){n&&(n=e.call(null,r,i,t)&&n)})),!!n):n},any:function(t,e){var n=!1;return t?(this.each(t,(function(r,i){if(e.call(null,r,i,t))return n=!0,!1})),n):n},getUniqueId:(r=0,function(){return r++}),templatify:function(t){if(this.isFunction(t))return t;var e=i.element(t);return"SCRIPT"===e.prop("tagName")?function(){return e.text()}:function(){return String(t)}},defer:function(t){setTimeout(t,0)},noop:function(){},formatPrefix:function(t,e){return e?"":t+"-"},className:function(t,e,n){return(n?"":".")+t+e},escapeHighlightedString:function(t,e,n){e=e||"";var r=document.createElement("div");r.appendChild(document.createTextNode(e)),n=n||"";var i=document.createElement("div");i.appendChild(document.createTextNode(n));var o=document.createElement("div");return o.appendChild(document.createTextNode(t)),o.innerHTML.replace(RegExp(s(r.innerHTML),"g"),e).replace(RegExp(s(i.innerHTML),"g"),n)}}},function(t,e,n){"use strict";t.exports={element:null}},function(t,e){var n=Object.prototype.hasOwnProperty,r=Object.prototype.toString;t.exports=function(t,e,i){if("[object Function]"!==r.call(e))throw new TypeError("iterator must be a function");var s=t.length;if(s===+s)for(var o=0;o was loaded but did not call our provided callback"),JSONPScriptError:s("JSONPScriptError"," + +