[SystemVerilog语法拾遗] 不同类型的数组作为方法参数时使用区别
我们在使用函数/任务时,参数列表中经常会出现数组类型,我们定义函数时需要指定数组的类型(形参),常用类型包括静态数组(数组深度固定)、动态数组(通过new来指定数组深度)和队列(队列是一种特殊的数组,他的数组深度随时可变),三种数组参数类型使用实例如下图所示。
三种数组参数类型的函数实例
具体使用哪种数组类型(实参)需要根据我们实际调用时传入的数组类型来决定。
1、实参为静态数组。
分别调用三种函数,使用实例如下图所示:
打印结果如下图所示:
由此可见,对于实参为静态数组的应用场景,形参为静态数组、动态数组、队列都可以正常接收。
2、实参为动态数组
这里我们故意把动态数组的大小(8)实例化为比以静态数组参数的数组大小(5)要大
实例代码如下图所示:
打印结果如下图所示:
形参为静态数组调用报错显示大小不匹配
形参为动态数组、队列的能够正常打印
由此可见当我们实参为动态数组时,我们的形参只能是动态数组或者队列,而不能是静态数组。
3、实参为队列
同理,静态数组作为参数的函数无法使用,代码实例如下:
打印结果如下:
由此可见当我们实参为队列时,我们的形参只能是动态数组或者队列,而不能是静态数组。
下面我们再讨论另外一种应用场景,即函数参数的数组作为输入输出类型时,包括inout和ref两种情况。
涉及到函数如下所示,函数内部对数组元素都做了放大一倍的处理:
4、实参为静态数组
根据我们上面1-3的讨论结果,这边我们打印统一都用动态数组作为形参的函数,保证打印结果的准备,仅仅是在调用double的函数参数有区别
实例代码如下图所示:
打印结果如下图所示:
可以看到,实参为静态数组时,形参是静态数组、动态数组、队列都可以操作inout类型数组参数对应的函数。
5、实参为动态数组或队列
分析方法类似于上面对于打印函数,形参为动态数组或队列的函数都可以正常使用。
对于将inout替换为ref的函数,使用上是完全一样的,这里就不展开分析了。
6、特殊实验
如果我们没有将队列参数声明为inout/ref类型,那么我们对队列的操作会产生什么结果呢?
以下面这个函数为例:
调用前后打印结果如下:
由此可见,函数内的操作并未带出到函数外,这其实跟数据结构的处理有关,这里我们就不深入讨论了,大家使用的时候一定要注意,如果需要将数组、队列的值带出的话,一定要声明为inout/ref类型,这一定跟C语言还不同,C语言数组作为参数我们传递数组名相当于传递的是数组的首地址指针,我们对数组的操作实际操作的都是数组对应的实际空间里的内容,对数组的修改也是可以完成的,而在sv中数组作为参数传递的是值类型,而不是指针类型,大家使用的时候一定要注意了。
7、总结
根据上面的分析,我们在使用函数/任务时,接口涉及到数组时,根据实际需要可以将形参声明为静态数组、动态数组、队列,其中静态数组的形参限制了实参必须也是静态数组,而动态数组或者队列作为形参时,实参的数组类型可以各种类型相互兼容,动态数组和队列作为形参/实参的不同点就在于两者操作的方法不同,队列有队列的操作方法(push_back、pop_front等),动态数组的创建则需要使用new函数。