Verilog系列:动态数组
动态数组作为一种常用的数据结构,在数字电路设计中也经常使用,其主要特点是动态数组的大小是在仿真运行时动态指定的,因此,其所占用的空间也是在仿真运行时才确定的.那么如果未对其分配大小,那么该数组大小为0.动态数组的声明定义格式如下:
动态数组在声明时使用空的中括号[],其数组大小是在程序运行时通过new[]来分配空间的,中括号中间指定数组的深度,即该数组有多少个元素,当然,也可以不适用new[]来分配空间大小,可通过将已经分配空间大小的数组复制给未指定空间大小的数组,从而间接的实现并指定空间大小数组的构造,但是无论哪种方式,动态数组的大小都是在运行过程中动态指定的.这里需要注意,new[]中指定的数组深度,是数组***有多少个元素(其元素宽度可在为数组指定的类型名之后指定)其数目与new[]中括号中指定的一致,但是对数组有效引用的索引是new[]中指定数组深度减1,因为数组的索引与C语言中索引一致,都是从0开始的.例如,如果给动态数组"logic arr[]"指定数据深度为"arr =new[4]",那么arr中一共有4个元素,这4各元素分别是"arr[0],arr[1],arr[2],arr[3]",其中并没有arr[4],那么如果此时访问arr[4]仿真器并不会报错,只是得到的arr[4]值为对应数据类型的默认值.
【示例】
【仿真结果】
示例中,dyn_arry没有显式的进行空间大小分配,当使用size()获取该数组大小时,该数组的大小为0.但是当时用已经分配大小并且已经赋值的dyn_arr复制给dyn_arry后,dyn_arry中就具有了和dyn_arr一样的数据元素和大小.dyn_arr声明后,第6行对其分配了5个地址空间,随后对该数组进行了访问,但是此时并未对该数组进行初始化,访问该数组获取到的数值为该数组指定类型的默认值.17-21行,虽然对该数组进行了初始化,进行了6次赋值,但是因为该数组只分配了5个地址空间,虽然给超出5个地址空间的数组元素也分配了数值,但是第6次赋值实际上并没有给第6个元素分配数值,如果对该元素进行访问,可以观测到其中的数值为该数组数据类型的默认值.在示例中,使用了如下几个函数任务:
-
new[]用来分配或者改变数组的深度;
-
size()用来获取当前数组的大小,其原型为"functionitn size()",这里需要注意,size()返回的是数组的大小,但是实际数组有效索引的最大值为size()-1;
-
delete()用来清除当前数组占据的空间,使用该方法后,数组的大小即被清除为0,其原型为"functionvoid delete()";
【示例】
【仿真结果】
示例中dyn_arr在delete()之后,其大小变为0,此时如果对其进行访问,那么原数组中将没有任何元素,访问得到的值仅为该数组声明的数据类型的默认值.
【示例】
【仿真结果】
示例中,首先在第6行通过new给dyn_arr分配了5个地址空间,在7-10行对该5个地址空间进行了初始化.11行对dyn_arry进行了空间分配,分配的空间大小为dyn_arr空间大小的2倍,且dyn_arry空间的前5个元素与dyn_arr数值一致,因为后5个元素并没有进行初始化,所以其中的元素数值为0,即"dyn_arry=[dyn_arr.size()*2](dyn_arr)"还保留原有dyn_arr复制到dyn_arry的前5个元素,再分配了dyn_arr.size()个大小的空间给dyn_arry的后5个元素.由此可见,"dyn_arry=[dyn_arr.size()*2](dyn_arr)"先执行了中括号内的内容,再执行小括号内的内容.实际空间分配好后,先放入已分配空间起始地址的数据是小括号指定的数组的内容.
【示例】
【仿真结果】
示例中,当"dyn_arry=[ 2](dyn_arr)"执行时,分配给dyn_arry空间的大小小于dyn_arr,那么dyn_arry的实际分配大小就是2,且dyn_arr中超过两个元素之后的所有元素将被忽略,不会被复制到dyn_arry中.
最后,在使用动态数组时,一定要注意以下几点:
-
size()反悔的是数组的大小,但是该值比实际数组的最大索引值大1;
-
除了可以使用new[]分配数组空间外,还可以通过其他同类型数组以复制的方式复制给未显式调用new[]的数组分配空间;
-
数组在使用完后,可以使用delete()删除数组占用的空间,删除后的数组大小为0;
-
在使用new[number](arry_name)对新的数组记性初始化分配空间时,需要注意指定的数组空间的大小与将要复制的数组的大小,以免数据丢失;