sv标准研读第七章-聚合数据类型

书接上回:

sv标准研读第一章-综述

sv标准研读第二章-标准引用

sv标准研读第三章-设计和验证的building block

sv标准研读第四章-时间调度机制

sv标准研读第五章-词法

sv标准研读第六章-数据类型

7 聚合数据类型

7.1概览

  1. 结构体的定义和使用
  2. union的定义和使用
  3. packed/unpacked数组、动态数组、联合数组、队列的定义和使用
  4. 数组查询和操作的方法

7.2 结构体

结构体:可以作为整体引用,也可以通过名字引用结构体里的单个数据类型。

默认情况下,结构体是unpacked,里面可以包含任意数据类型。

结构体的声明:

7.2.1 packed 结构体

Packed结构体可以理解成:各个数据存储之间没有GAP,所有的数据可以看成一个vector。因此可以被算术运算符和逻辑运算符操作,可以对packed结构体指定符号,默认是unsigned类型。第一个成员是MSB。

举例:

如果是unpacked结构体,那么指定符号是非法的,例如:

如果packed结构体的所有成员都是2态的,那么整体就是一个2态的vector。

如果packed结构体有成员是4态的,那么整体就是4态的vector。如果里面也有2态的成员,那么在读结构体时,会隐式进行从4态到2态的转换,写结构体时,会隐式进行从4态到2态的转换。

可以对packed结构体进行bit-sel。例如:

在packed结构体里只允许存在packed数据类型和整型数据类型,见6.11描述。

举例:

7.2.2 结构体的赋值

结构体赋初值举例:

结构体的例化:

给结构体显式赋值:

如果unpacked结构体里有union,和packed结构体一样,不能单独给某个成员赋初始默认值。

当声明一个net数据类型但是没有用户自定义nettype时,表达式赋初值会被忽略。

7.3 Union

Union:union只存储一个元素,但是元素可以有多种表示方法,每种表示方法可以是不同的数据类型。Union内的成员公用同一存储空间,所以对其中一个成员赋值,其他成员也会相应变化,只是数据类型不同而已。因此一次也只能使用union中的一种数据类型。

默认情况下,union是unpacked的。

举例:

如果在声明unpacked union时没有赋初值,那么默认会给第一个成员赋它对应data type的默认值。

有一种特殊情况:当unpacked union包含若干个unpacked 结构体,且这些结构体共享一个公共的initial seq,那么允许检查这个公共part。如果两个结构体拥有equivalent的数据类型,那么他们共享这个公共seq。

7.3.1 packed unions

Packed union里面只允许有整型数据类型。Packed untagged union里的成员必须拥有相同的size。Unpacked union/packed tagged union里的成员可以有不同的size。因此,给union里的一个成员做写操作时,可以读union里的另一个成员。Packed union和unpacked union的区别在于前者应该看做是一个primary,一个单独的vector。

可以对packed union使用算术和逻辑操作符,行为受到符号的影响,默认packed union是无符号的。

还可以对packed union做bit select操作[n-1:0]

Packed union里只能出现packed数据类型和整型数据类型,见6.11小节的table6-8。

Packed union里面如果既有2态数据又有4态数据,那么整体就是4态的。当对packed union做读操作时,就隐式的包含一个4态转2态的过程,当做写操作时,就隐式的包含一个2态转4态的过程。

举例:

需要注意的是,对于packed union,对一个成员进行写操作和对另一个成员进行读操作和byte order无关,但是unpacked union里成员的地址是按照升序排列的。

7.3.2 tagged unions

Tagged union:type-checked union。

对于untagged union(默认),可以通过赋值(该值的类型是其中一个成员的数据类型)被update,并且也可以被read(读出的值的类型可以是另一个成员的数据类型),那么这就是一个潜在的类型漏洞。

因此,tagged union同时保存了成员的值和一个tag,这个tag代表了当前成员的名字。Tag和值只能通过11.9介绍的静态typed-check tagged union表达式被同时update。只有当成员的类型和当前tag的值(即成员名)匹配时,才能对该成员进行读操作。

在untagged union里不能使用动态数据类型和chandle数据类型,但是在tagged union里可能可以用。

Tagged union里成员可以作为tagged表达式被引用,参见11.9

Tagged union还可以使用pattern matching,见12.6.

在tagged union里,允许type是void。举例:

11.9将详细介绍这种用法。

举例2:

11.9将详细介绍这种用法。

当对tagged union加上packed关键字后,其成员只能是packed数据类型,但是成员的size可以不一样。关于packed tagged union的标准介绍:

  1. Size=tag的bit位数+最大size的成员的size
  2. Tag的size是能够表示所有成员的最小bits(例如8位成员只需要3bit就可以了)
  3. Tag bits是左对齐的(朝向MSB)
  4. 成员 bits是右对齐的(朝向LSB)
  5. Tag和成员之间的bit怎么排列的没有定义。

举例:

这个Vint加上packed关键字后,它的bits是这样的:

举例2:

这个Instr加上packed关键字后,它的bits是这样的:

7.4 Packedunpacked 数组

Packed数组:维度在标识符之前

Unpacked数组:维度在标识符之后

举例:

一维的packed数组见6.9描述

Unpacked数组包括:

  1. 固定size的数组,详细描述见7.4.2
  2. 动态数组,详细描述见7.5
  3. 联合数组,详细描述见7.8
  4. 队列,详细描述见7.10

Unpacked数组可以包含任何数据类型,包括packed数组和unpacked数组

7.4.1 packed数组

Packed数组特点:是一组连续的bit位,可以看做是单个向量。

可以对packed数组加上signed关键字,表明这个packed数组是signed的。默认packed数组里的成员是unsigned的,但是可以加上signed关键字改变它的符号。如果要对packed数组做part-select操作,那么这个packed数组应该是unsigned的。

Packed数组的size最大不能超过65536 bits

Packed数组的单bit数据类型可以是bit/logic/reg/enum/其他packed数组和其他packed 结构体。

如果packed数组的类型是byte shortint  int  longint   integer  time等这些固定size的数据类型,那么他们和用[n:0]写法写成的packed数组是match的关系。举例:

7.4.2 unpacked数组

Unpacked数组的数据类型可以是任意的。Unpacked数组里的元素也可以是一个数组,此时unpacked数组就是多维数组。

一个很有用的unpacked数组应用场景是:可以使用net unpacked数组连接到generate循环结构体中,见27.4小节。

Unpacked数组的维度有两种表示方式:[size]或者[0:size-1]

举例:

上面两种表示方式是等效的。

地址范围的表示必须是整数表达式,常量的值可以是正数、负数和0,不能包含x或者z。最大的size为16777216。

7.4.3数组的操作

下面的一些操作适用于packed数组和unpacked数组:

  1. 读写操作;例如:A=B
  2. 读写数组的一个slice;例如:A[i:j]=B[i:j]
  3. 读写数组的一个带有变量的slice;A[x+:c]=B[y+:c]
  4. 读写数组的一个元素;例如:A[i]=B[i]
  5. 对数组或者数组的slice进行equality操作;例如:A==B,A[i:j]!=B[i:j]

下面的一些操作只能对packed数组操作,不能对unpacked数组操作:

  1. 给数组赋整数值,例如:A=8’b1111_1111;
  2. 在表达式中把数组当做整数处理,例如:A+3;

如果unpacked数组声明成signed,那么每个元素都是signed。7.6小节会详细介绍packed数组和unpacked数组的赋值。

7.4.4 memories

如果一维数组里的元素类型是reg/logic/bit,那么就可以称之为memory。

举例:

7.4.5 多维数组

举例:

举例2:

以v4为例,v4[x][y][z][k]这种表示方法中的x/y/z/k分别对应上图中的维度1/2/3/4.

可以使用typedef定义多维packed数组。举例:

可以使用typedef定义多维unpacked数组。举例:

Subarray举例:

当用逗号分隔声明两个数组时,它们的数据类型和packed维度是一样的,举例:

7.4.6 数组的索引和切片

举例:

数组的切片只能应用于一个维度,但表达式中的其他维度可以具有单个索引值。

如果索引表达式越界,或者索引表达式中有x或z位,则该索引无效。从具有无效索引的任何类型的unpacked数组中读取将返回表7-1中指定的值。写无效索引到数组将不会产生任何操作,除非对队列的写索引是[$+1],见7.10.1描述,或者除非对关联数组创建一个新的元素,见7.8.6描述。工具在实现上可能会报出warning。

如果访问packed数组的索引是无效的,那么见11.5.1小节的描述,更多详细的信息见11.5.1和11.5.2小节的描述。

7.5 动态数组

动态数组:unpacked数组,在编译时不指定大小没在run time时指定大小或者更改大小。动态数组未初始化的大小是0。动态数组的大小是通过new或者赋值来设置的,见7.5.1和7.6小节的描述。动态数组的数据类型可以是任意的。

在声明时,动态数组的维度用空的中括号[]表示。举例:

7.5.1 new[]

New构造器可以为动态数组设置size和对元素进行初始化。

格式:

上面[expression]这个操作数的类型是longint,所以如果写一个负数会报错,写0表示为空数组。

举例:

如果初始化时没有用new函数,那么会被初始化为对应data type的默认值。

用new赋值时,左右两边的类型必须是赋值兼容的。举例:

同时,左右两边的size可以不一样。当左边的size大于右边时,赋值时右边会被截断,当右边size大于左边时,会补0。举例:

这种机制能够很好的实现resize动态数组的目的。举例:

7.5.2 size()

作用:返回动态数组的size。

举例:

也可以通过系统函数求出动态数组的size:

7.5.2 delete()

作用:清空动态数组,最终动态数组的size将变成0.

举例:

7.6 数组赋值

在没有显示转换的条件下,packed 数组是不能被unpacked数组赋值的。

联合数组只能和联合数组赋值兼容,具体见7.9.9小节描述。

Unpacked数组、动态数组、队列以及它们的slice是和满足下面条件的数组或者slice赋值兼容的:

  1. Source和target的元素类型是equivalent关系;
  2. 如果target是固定size的数组或者slice,那么source数组的元素个数要一样

A[7:0]=B[1:8],就是将B[1]赋值给A[7]

如果target是队列或者动态数组,那么它的size会根据source的size而调整。

举例:

Wire类型的数组可以被var赋值,只要source和target的数据类型是赋值兼容的。

如果一个动态数组或者队列被一个固定size的数组赋值,那么source数组的大小直到run time才能确定。如果想复制一个动态数组或者队列给固定size的数组,但是二者的成员数量不一致,那么会报一个run time error,并且不会执行任何操作。举例:

举例2:

上面最后一行等于:

举例3:source数组可以是slice

最终,p的值是:

7.7 数组作为参数传递给子程序

数组在作为参数传递给子程序的过程中,会复制一份,无论是固定size的数组、动态数组、队列还是关联数组。

数组作为实参传递给形参的规则和数组作为source数组赋值给dest数组的规则一样,见7.6。如果形参数组是unsized,例如动态数组、队列,那么它的size将会和实参数组的size匹配。

举例:

假如定义了这样一个task:

调用该task时,传递的实参:

举例2:即使是动态数组或者队列,只要size能匹配,也可以作为参数传递

还可以将实参定义为动态数组或者队列:

7.8 联合数组

联合数组的索引可以是任意类型。

声明格式:

举例:

关联数组的元素是动态分配的。只有当使用时才会分配空间。每一个关联数组的元素是unpacked的。

7.8.1 通配符索引类型

举例:

特点:

  1. 数组可以被任意整数表达式索引。这个时候就会出现不同的整数表达式可能位宽不同的现象,这是允许存在的,sv会计算这些整数表达式的最小长度然后删除多余的前导0来解决这个问题。
  2. 非整数表达式的所有会报错。
  3. 4态索引包含了x/z也会报错。
  4. 索引会被认为是unsigned。
  5. 字符串文字索引会被转换为一个bit向量。
  6. 顺序是数字从小到大。
  7. 不能用在foreach循环(12.7.3)中使用,也不能用在需要返回数组值和索引值的数组方法中(7.12)

7.8.2 字符串索引

举例:

特点:

  1. 索引可以是任意长度的字符串文字
  2. “”空字符串也是允许的
  3. 顺序是字典序从小到大

7.8.3 class索引

举例:

特点:

  1. 索引可以是该class类型的对象
  2. Null索引也是允许的
  3. 顺序是确定但任意的??

7.8.4 整数索引

举例:

特点:

  1. 索引表达式会被转换为索引类型,但是real/shortreal类型是不允许的
  2. 4态索引如果包含了x/z是不允许的
  3. 顺序是数字顺序,符号可以是signed/unsigned,符号由索引类型决定

7.8.5 其他类型

举例:

特点:

  1. 索引类型必须能使用equality操作符,这就包括了动态类型。但是real/shortreal是不被允许的。
  2. 索引表达式中任何一个元素是或包含X或Z的索引表达式无效。
  3. 索引表达式为空或包含null或其中任何元素为空并不会使索引无效。
  4. 如果索引类型可以使用关系操作符,那么顺序是确定的,但是如果不能使用,那么在多次运行时,关联数组的任意两个元素的相对顺序可能会发生改变。

7.8.6 访问无效元素

假如读操作:

  1. 索引包含x/z
  2. 访问一个不存在的元素

那么会产生一个warning,并返回一个该数组类型的不存在元素值,见7.4.6表7-1。自定义类型默认不会产生warning且会返回值,见7.9.11

假如写操作过程中包含了无效的索引,那么该写操作将被忽略,并产生warning。

7.8.7 关联数组赋值

当一个不存在的关联数组元素被用作赋值的目标或实际用于通过引用传递的参数时,应分配该元素的表项。有些结构将读和写操作作为单个语句的一部分执行,例如使用增量操作。在这种情况下,在引用该元素之前,应该为不存在的元素分配其默认值或用户指定的初始值。例如:

A[1]会变成2

B[2].x会变成5,b[2].y会变成2

7.9 关联数组的方法

7.9.1 num()/size()

作用:返回关联数组元素的个数,如果数组为空,就返回0.

举例:

7.9.2 delete()

若有索引值,删掉指定索引元素;

若无索引值,删掉整个关联数组元素

举例:

7.9.3 exist()

作用:检查是否有该索引的元素,有返回1,否则返回0

举例:

7.9.4 first()

作用:将第一个索引的值赋值给指定索引的元素。

7.9.5 last()

作用:将最后一个索引的值赋值给指定索引的元素。

7.9.6 next()

作用:查找值大于给定索引参数的最小索引。如果有,返回1,如果没有,返回0.

7.9.7 prev()

作用:查找值小于给定索引参数的最大索引。如果有,返回1,如果没有,返回0.

7.9.8 索引截断

如果索引实参大于索引类型宽度,那么上述first()/last()/next()/prev()函数将返回-1

7.9.9 关联数组赋值

关联数组只能分配给具有相同索引类型的兼容类型的另一个关联数组。其他类型的数组不能赋值给关联数组,关联数组也不能赋值给其他类型的数组,无论是固定大小的还是动态的。

将一个关联数组赋值给另一个关联数组会清除目标数组中的所有现有条目,然后将源数组中的每个条目复制到目标数组中。

7.9.10 关联数组参数

关联数组只能作为参数传递给具有兼容类型和相同索引类型的关联数组。其他类型的数组,无论是固定大小的还是动态的,都不能传递给接受关联数组作为参数的子例程。同样,关联数组也不能传递给接受其他类型数组的子例程。按值传递关联数组将导致创建关联数组的本地副本。

7.9.10 关联数组字面量

字面量格式:

举例:

如果指定了默认值,则读取不存在的元素将产生指定的默认值,并且不会发出警告。否则,返回表7-1(见7.4.6)规定的值。定义默认值不会影响关联数组方法的操作(见7.9)。

7.10 队列

队列是同构元素可变大小的有序集合。队列支持对其所有元素的恒定时间访问,以及在队列开始或结束时的恒定时间插入删除。队列中的每个元素都由一个序数标识,该序数表示其在队列中的位置,其中0表示第一个$表示最后一个。队列类似于自动增长和收缩的一维未打包数组。因此,与数组一样,可以使用索引、连接、切片操作符语法和相等操作符来操作队列。

使用与unpacked数组相同的语法声明队列,但指定$作为数组大小。可以通过指定其可选的右边界(最后索引)来限制队列的最大大小。

可以使用赋值模式或unpacked数组连接来写入队列值(参见10.9,10.10)。

举例:

如果声明中没有提供初始值,则将队列变量初始化为空队列。空队列可以用空的unpacked数组连接{}表示,如10.10中所述。

7.10.1 队列的操作符

队列应支持可在unpacked数组上执行的相同操作。此外,队列应支持以下操作:

-队列应调整自身大小以适应写入的任何队列值,但其最大大小可能有7.10中所述的限制。

—在队列切片表达式(如Q[a:b])中,切片边界可以是任意整数表达式,特别是不需要是常量表达式。

-队列应支持7.10.2中描述的方法。

与数组不同,空队列{}是一个有效的队列,并且是某些队列操作的结果。以下规则约束队列操作符:

—Q[a: b]生成具有b - a + 1个元素的队列。

•如果a > b,则Q[a:b]产生空队列{}。

•Q[n: n]产生一个只有一个项目的队列,这个项目位于位置n。因此,Q[n: n] === {Q[n]}。

•如果n在Q的范围之外(n < 0或n > $),则Q[n:n]产生空队列{}。

•如果a或b是包含X或Z值的四状态表达式,则产生空队列{}。

—Q[a: b],其中a < 0与Q[0: b]相同。

—Q[a: b],其中b > $与Q[a: $]相同。

—一个无效的索引值(即一个包含一个或多个x或z位的4状态表达式,或者一个值在0…$之外)将导致读取操作返回一个适合于队列元素类型的不存在的数组条目的值(如7.4.6中的表7-1所述)。

—一个无效的索引(例如,一个包含X或Z的四状态表达式,或者一个值在0…$+1之外)将导致写操作被忽略,并发出运行时警告;然而,写Q[$+1]是合法的。—使用语法[$:N]声明有右边界的队列称为有界队列,其索引不得大于N(其大小不得超过N+1)。管理有界队列的其他规则将在7.10.5中描述。

7.10.2 队列的方法

举例:

7.10.2.1 size()

返回队列中的项数。如果队列为空,则返回0。

7.10.2.2 insert()

insert()方法将给定的项插入到指定的索引位置。

如果index参数有任何未知(x/z)值的位,或者为负值,或者大于队列的当前大小,则该方法调用将不会对队列产生影响,并可能导致发出警告。

7.10.2.3 delete()

如果未指定索引,则delete()方法删除队列中的所有元素,使队列为空。如果指定了索引,则delete()方法删除位于指定索引位置的项。如果index参数有任何未知(x/z)值的位,或者为负值,或者大于或等于队列的当前大小,则该方法调用将不会对队列产生影响,并可能导致发出警告。

7.10.2.4 pop_front()

pop_front()方法删除并返回队列的第一个元素。

如果在一个空队列上调用该方法:

-它的返回值将与尝试读取一个不存在的数组元素所获得的值相同,该数组元素的类型与队列元素的类型相同(如7.4.6中的表7-1所述);

-对队列没有任何影响,并可能导致发出警告。

7.10.2.5 pop_back()

pop_back()方法删除并返回队列的最后一个元素。

如果这个方法在一个空队列上被调用:

-它的返回值应该与尝试读取一个不存在的数组元素所获得的值相同,该数组元素的类型与队列元素的类型相同(如7.4.6中的表7-1所述);

-对排队没有任何影响,并可能导致发出警告。

7.10.2.6 push_front()

push_front()方法将给定的元素插入到队列的前面。

7.10.2.7 push_back()

push_back()方法将给定的元素插入到队列的后面。

7.10.3 队列元素引用

如13.5.2所述,可以将队列的元素通过引用传递给task,当在队列上执行其他操作时,该task继续持有该引用。对队列的某些操作将导致任何此类引用过时(如13.5.2中的定义)。本小节定义了对队列元素的引用过时的情况。

当7.10.2中描述的任何队列方法更新队列时,对未被该方法删除的任何现有元素的引用都不会过时。该方法从队列中删除的所有元素都将成为过时的引用。

当赋值的目标是整个队列时,对原始队列中任何元素的引用都将过时。

结果是,使用unpacked数组连接语法在队列中插入元素(如7.10.4中的示例所示)将导致对现有队列中任何元素的所有引用都过时。使用delete、pop_front和pop_back方法将使对已弹出或已删除元素的任何引用过时,但不会影响对队列中所有其他元素的引用。相比之下,在队列上使用insert、push_back和push_front方法永远不会产生过时的引用(除非在有界队列上使用insert 或push_front方法,如果队列的新大小超过队列的界限,则会导致删除队列中编号最高的元素)。

7.10.4 使用赋值和unpacked数组更新队列

如7.10所述,队列变量可以通过赋值来更新。在对队列变量执行操作时,与unpacked的数组连接一起,这为7.10.2中描述的队列方法提供了一个灵活的替代方案。

下面的示例展示了与队列方法类似的行为的队列赋值操作。在每种情况下,queue变量的结果值都应该与应用queue方法时相同,但是任何对queue元素的引用都会在赋值操作后过期(见7.10.3):

举例:

以下示例说明了一些不能作为单个队列方法调用实现的有用操作。与前面的示例一样,对队列变量的赋值比对其元素的任何引用都重要。

7.10.5 有界队列

有界队列不能有索引高于队列声明上界的元素。对有界队列的操作应该表现得与队列无界完全一样,除非在向有界队列变量写入任何操作之后,该变量有任何超出其边界的元素,那么所有这些超出边界的元素都将被丢弃并发出警告。

7.11数组查询函数

SystemVerilog提供返回数组信息的系统函数。它们是$left, $right, $low, $high, $increment, $size, $dimensions和$unpacked_dimensions。这些函数将在20.7中描述。

7.12 数组操作方法

SystemVerilog提供了几个内置方法来促进数组搜索、排序和约简。

语法:

可选的with子句接受用圆括号括起来的表达式。相反,randomize方法使用的with子句(见18.7)接受一组用大括号括起来的约束。

如果包含在with子句中的表达式包含任何副作用,则结果可能是不可预测的。

数组操作方法遍历数组元素,然后使用这些元素求值with子句指定的表达式。iterator_argument可选地指定with表达式在每次迭代时用来指定数组元素的变量名。如果未指定,则默认使用name项。iterator_argument的作用域是with表达式。指定iterator_argument而不指定with子句是非法的。

7.12.1 数组定位方法

数组定位器方法对任何unpacked数组(包括队列)进行操作,但它们的返回类型是队列。这些定位器方法允许在数组中搜索满足给定表达式的元素(或它们的索引)。数组定位器方法以未指定的顺序遍历数组。

索引定位器方法对于除关联数组外的所有数组返回int类型的队列,关联数组返回与关联索引类型相同类型的队列不允许使用指定通配符索引类型的关联数组。

如果没有元素满足给定表达式,或者数组为空(在队列或动态数组的情况下),则返回空队列。否则,这些方法返回一个包含满足表达式的所有项的队列。索引定位器方法返回一个包含满足表达式的所有项的索引的队列。with子句指定的可选表达式应计算为布尔值。

支持以下定位器方法(with子句是强制性的):

- find()返回满足给定表达式的所有元素。

- find_index()返回满足给定表达式的所有元素的索引。

- find_first()返回第一个满足给定表达式的元素。

- find_first_index()返回满足给定表达式的第一个元素的索引。

- find_last()返回最后一个满足给定表达式的元素。

- find_last_index()返回满足给定表达式的最后一个元素的索引。

第一个或最后一个元素被定义为分别最靠近最左或最右的索引元素,但关联数组除外,它应该使用最靠近关联数组索引类型的第一个或最后一个方法返回的索引的元素

对于以下定位器方法,如果为给定数组的元素类型定义了关系操作符(<,>,==),则可以省略with子句(及其表达式)。如果指定了with子句,则应该为表达式的类型定义关系操作符(<、>、==)。

- Min()返回具有最小值或其表达式求值为最小值的元素。

- max()返回具有最大值或其表达式求值为最大值的元素。

- unique()返回所有具有唯一值或其表达式求值为唯一值的元素。对于在数组中找到的每个值,返回的队列包含且仅包含一个条目。返回元素的顺序与原始数组的顺序无关。

- unique_index()返回具有唯一值或其表达式求值为唯一值的所有元素的索引。对于在数组中找到的每个值,返回的队列包含且仅包含一个条目。返回元素的顺序与原始数组的顺序无关。为重复值项返回的索引可能是其中一个重复项的索引。

举例:

7.12.2 数组排序方法

数组排序方法对任何unpacked数组(固定大小或动态大小)的元素重新排序,关联数组除外。

- reverse()反转数组中元素的顺序。指定with子句将是编译器错误。

- sort()按升序对数组进行排序,可选择使用with子句中的表达式。当为数组元素类型定义关系操作符(<、>、==)时,with子句(及其表达式)是可选的。如果指定了with子句,则应该为表达式的类型定义关系操作符(<、>、==)。

- rsort()按降序对数组进行排序,可选择使用with子句中的表达式。当为数组元素类型定义关系操作符(<、>、==)时,with子句(及其表达式)是可选的。如果指定了with子句,则应该为表达式的类型定义关系操作符(<、>、==)。

- shuffle()随机化数组中元素的顺序。指定with子句将是编译器错误。

举例:

7.12.3 数组缩减方法

数组简化方法可以应用于任何unpacked的整数值数组,以将数组简化为单个值。可选的with子句中的表达式用于指定要在约简中使用的值。对每个数组元素求值所产生的值将被约简方法使用。这与使用with子句作为选择标准的数组定位器方法(见7.12.1)形成对比。

该方法返回与数组元素类型相同类型的单个值,如果指定了,则返回与with子句中表达式类型相同的值。如果为数组元素类型定义了相应的算术或布尔约简操作,则可以省略with子句。如果指定了with子句,则应该为表达式的类型定义相应的算术或布尔约简操作。

包括:

- sum()返回所有数组元素的和,如果指定了with子句,则返回对每个数组元素的表达式求值所产生的值的和。

- product()返回所有数组元素的乘积,如果指定了with子句,则返回对每个数组元素的表达式求值所得值的乘积。

- and()返回所有数组元素的按位与(&),或者,如果指定了with子句,则返回通过计算每个数组元素的表达式产生的值的按位与。

- or()返回所有数组元素的按位或(|),或者,如果指定了with子句,则返回通过计算每个数组元素的表达式产生的值的按位或。

- xor()返回所有数组元素的按位异或(^),或者,如果指定了with子句,则返回通过计算每个数组元素的表达式产生的值的按位异或。

举例:

最后一个示例显示了如何将对单bit数组调用sum的结果强制为32位的数量。默认情况下,在本例中调用sum的结果为logic类型。将1024位的值相加可能会溢出结果。可以通过使用with子句来避免这种溢出。指定后,使用with子句确定结果的类型。在with子句中将item强制转换为int会导致数组元素在求和之前被扩展到32位。本例中调用sum的结果为32位,因为约简方法结果的宽度必须与with子句中表达式的宽度相同。

7.12.4 循环索引查询方法

数组操作方法使用的表达式有时在每次迭代时需要实际的数组下标,而不仅仅是数组元素。迭代器的index方法返回指定维度的索引值。索引法的原型如下:

数组的size按20.7中的定义编号。变化最慢的是维度1。变化速度越快,维数越高。如果未指定维度,则默认使用第一个维度。

对于除关联数组之外的所有数组迭代器项,index方法的返回类型都是int,关联数组返回与关联索引类型相同类型的索引。不允许使用指定通配符索引类型的关联数组。

举例:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值