weixing1531 发表于 2018-8-3 13:39:06

VB中Redim功能讨论

比如Redim Preserve比Fortran的
allocate功能强大,能保存数组之前的元素数值
Fortran如何实现类似功能?
链表?


pasuka 发表于 2018-8-3 13:53:59

对标C的realloc?
https://en.cppreference.com/w/c/memory/realloc
fortran当然有这项功能
https://docs.oracle.com/cd/E19205-01/819-5259/aetga/index.html
1.4.35 malloc, malloc64, realloc, free: Allocate/Reallocate/Deallocate Memory

fcode 发表于 2018-8-3 18:38:38

realloc 是 Sun 提供的函数,不是标准的。
不管是VB的 Redim Preserve,还是 C++ 容器类的 resize() 成员。其底层的实现本质,都是重新分配,然后复制原来的值。

Fortran需要自己去实现,而且由于Fortran没有模板类,所以每种类型都要写一遍,二维数组又要写一遍,三维还要写一遍。实际上,C++ 压根没有多维数组,VB Redim Preserve 也只能改变最后一维的大小,前面不能改变。
静态编程语言,改变大小都很难。想要自由编程,可以选 Python 或者 matlab 这种动态编程语言。想怎么加怎么加。

用预处理宏定义可以节省一点时间。

Program Main
Integer , allocatable :: x(:)
Real    , allocatable :: y(:)
allocate(x(4),y(4))
x = 3 ; y = 4
write(*,*) x
write(*,*) y
call ReallocateInt( x , 3 )
call ReallocateReal( y , 6 )
write(*,*) x
write(*,*) y

contains
#define TYPE_Integer
Subroutine ReallocateInt( x , n )
    TYPE_ , allocatable :: x(:) , t(:)
    integer :: n , s
    call move_alloc(x,t)
    allocate(x(n))
    s = min(size(t),n)
    x(:s) = t(:s)
    deallocate(t)
End Subroutine ReallocateInt
#define TYPE_Real
Subroutine ReallocateReal( x , n )
    TYPE_ , allocatable :: x(:) , t(:)
    integer :: n , s
    call move_alloc(x,t)
    allocate(x(n))
    s = min(size(t),n)
    x(:s) = t(:s)
    deallocate(t)
End Subroutine ReallocateReal

End Program Main

weixing1531 发表于 2018-8-3 19:25:49

曲线解决
运行时不确定数组元素个数
用Redim Preserve很方便的

weixing1531 发表于 2018-8-24 12:39:18

无限多态class(*)都无法实现模板?

pasuka 发表于 2018-8-24 15:28:26

weixing1531 发表于 2018-8-24 12:39
无限多态class(*)都无法实现模板?

这个问题很有意思,特地费点时间去查找了一下
简易模板
https://stackoverflow.com/questions/23706742/template-in-fortran
模板类库
https://github.com/robertrueger/ftl

weixing1531 发表于 2018-9-19 13:16:29

pasuka 发表于 2018-8-24 15:28
这个问题很有意思,特地费点时间去查找了一下
简易模板
https://stackoverflow.com/questions/23706742/t ...

看了源代码,作者几乎实现了STL所有功能
但是通过预处理实现的
模板类型T好象需要在预处理中修改

weixing1531 发表于 2019-5-8 01:54:33

本帖最后由 weixing1531 于 2019-5-8 02:09 编辑

f2008好像可以直接实现
program main
integer, parameter   :: ivp(*) =
integer, allocatable :: iv(:)
integer :: i, ios, unit
iv =
open(newunit = unit, file='test.txt')
do
    read(unit=unit,fmt=*,iostat=ios) i
    if(ios /= 0) exit
    iv =
enddo
close(unit)
if(all(iv==ivp)) print*, 'pass'
end program

vvt 发表于 2019-5-8 08:30:59

嗯,递延数组。F2008新增的功能,但是能不用尽量不用,特别是大数组,重新分配的资源消耗还是很头疼的。

weixing1531 发表于 2019-5-8 18:31:27

vvt 发表于 2019-5-8 08:30
嗯,递延数组。F2008新增的功能,但是能不用尽量不用,特别是大数组,重新分配的资源消耗还是很头疼的。 ...

试验了一下
递延数组在超大数组方面果然效率太差
比链表差多了
页: [1] 2
查看完整版本: VB中Redim功能讨论