Fortran Coder

查看: 366|回复: 6

[派生类型] 向派生数据类型中赋值出现奇怪的错误,谢谢各位高手

[复制链接]

4

帖子

1

主题

0

精华

入门

F 币
38 元
贡献
22 点

规矩勋章

发表于 2018-2-8 11:23:12 | 显示全部楼层 |阅读模式
各位高手中午好!先向各位问好!

我定义了一个type,用来存储一个特定的化学反应类型的各个数据,如下
[Fortran] 纯文本查看 复制代码
    type :: L2R2
        !===============================================================================
        ! a1*L1^CL1 + a2*L2^CL2 + e*E^(-1) <---> b1*R1^CR1 + b2*R2^CR2 , p = XXX V
        !
        ! for example:
        !
        ! No = 1
        ! idn= 'L2R2_001'
        ! Rx = 'O3 + 2 H^(+) + 2 e^(-) <---> O2 + H2O'   Pot = +2.075 V
        !
        ! a1 = 1 ; L1 = 'O3'  ; CL1 = 0
        ! a2 = 2 ; L2 = 'H'   ; CL1 = 1
        ! e  = 2 ;
        ! b1 = 1 ; R1 = 'O2'  ; CR1 = 0
        ! b2 = 1 ; R1 = 'H2O' ; CL1 = 0
        ! p  = 2.075
        !==============================================================================
        integer        :: No
        character(10)  :: idn
        character(100) :: Rx
        integer        :: a1
        character(20)  :: L1
        integer        :: CL1
        integer        :: a2
        character(20)  :: L2
        integer        :: CL2
        integer        :: e
        integer        :: b1
        character(20)  :: R1
        integer        :: CR1
        integer        :: b2
        character(20)  :: R2
        integer        :: CR2
        real           :: p        
    end type L2R2

然后,两种赋值方式
第一种:
[Fortran] 纯文本查看 复制代码
    type (L2R2) :: L2R2_003
        !==============================================================================
        ! No = 3   Rx = 'ZnO2^(2-) + 2 H2O + 2 e^(-) <---> Zn + 4 OH^(-)'   Pot = -1.285 V
        !==============================================================================
        L2R2_003%No   =  3
        L2R2_003%idn  =  'L2R2_003'
        L2R2_003%Rx   =  'ZnO2^(2-) + 2 H2O + 2 e^(-) <---> Zn + 4 OH^(-)'
        L2R2_003%a1   =  1
        L2R2_003%L1   =  'ZnO2'
        L2R2_003%CL1  =  -2
        L2R2_003%a2   =  2
        L2R2_003%L2   =  'H2O'
        L2R2_003%CL2  =  0
        L2R2_003%e    =  2
        L2R2_003%b1   =  1
        L2R2_003%R1   =  'Zn'
        L2R2_003%CR1  =  0
        L2R2_003%b2   =  4
        L2R2_003%R2   =  'OH'
        L2R2_003%CR2  =  -1
        L2R2_003%p    =  -1.285

这个没有任何问题。

问题是第二种,出错了:
[Fortran] 纯文本查看 复制代码
        L2R2_003 = (/ 3 , "L2R2_003" , "ZnO2^(2-) + 2 H2O + 2 e^(-) <---> Zn + 4 OH^(-)" , &
                      1 , "ZnO2" , -2 , 2 , "H2O" , 0 , 2 , 1 , "Zn" , 0 , 4 , "OH" , -1 , -1.285 /)

编译时候的错误是
  1. Compiling ..\..\..\..\Desktop\ZZZ\hello.f90
  2. ..\..\..\..\Desktop\ZZZ\hello.f90:104.25:

  3.         L2R2_003 = (/ 3 , "L2R2_003" , "ZnO2^(2-) + 2 H2O + 2 e^(-) <---> Zn + 4 OH^(-)" , &
  4.                          1
  5. Error: Element in INTEGER(4) array constructor at (1) is CHARACTER(1)
  6. Error(E42): Last command making (build\hello.o) returned a bad status
  7. Error(E02): Make execution terminated

  8. * Failed *
复制代码

所用环境就是Simply Fortran 2.17 Build 1758
实在不能理解这个错误发生的原因,还请明示!十分感谢

我自己的理解是:( / ...... / )这种方式,实际上是先造一个数组或列表出来,然后依次对应到派生类型中的各个变量里。
而fortran不允许数组内各元素类型不同,他会去认第一个元素的类型,一看,是整形,3,于是整个数组开始被建立,是个整形的数组。但是读到第二个元素时,却变成了"L2R2_003",是字符串,好,报错!

像L2R2_003%No=3,L2R2_003%idn='L2R2_003'这样的赋值方式,太繁琐。那么,有什么好办法么?

啰嗦啰嗦写了这么多,谢谢您耐心看完,再次感谢所有提出意见的人!
回复

使用道具 举报

1230

帖子

12

主题

5

精华

论坛跑堂

Fcode跑堂伙计

F 币
711 元
贡献
323 点

新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

发表于 2018-2-8 12:29:14 | 显示全部楼层
(/  /) 只能构造一个数组。(实际上我建议用 [] 来构造 )

要构造 L2R2 的结构体,需要用  L2R2()

L2R2_003 = L2R2( 3 , "L2R2_003" , "ZnO2^(2-) + 2 H2O + 2 e^(-) <---> Zn + 4 OH^(-)" , &
              1 , "ZnO2" , -2 , 2 , "H2O" , 0 , 2 , 1 , "Zn" , 0 , 4 , "OH" , -1 , -1.285 )

4

帖子

1

主题

0

精华

入门

F 币
38 元
贡献
22 点

规矩勋章

 楼主| 发表于 2018-2-8 14:41:32 | 显示全部楼层
fcode 发表于 2018-2-8 12:29
(/  /) 只能构造一个数组。(实际上我建议用 [] 来构造 )

要构造 L2R2 的结构体,需要用  L2R2()

非常感谢您的回复!
另外,从您帮我修改的帖子格式来看,您太细心了。
顺便学会了mw_shl_code=fortran,这是您建站的时候自定义的吧?
再次感谢您的回答

437

帖子

2

主题

0

精华

大宗师

F 币
2932 元
贡献
1747 点

水王勋章元老勋章热心勋章

发表于 2018-2-8 15:17:52 | 显示全部楼层
需要用到面向对象编程的内容,类似于C++的构造函数
[Fortran] 纯文本查看 复制代码
module example
    implicit none
    type:: base
        integer:: nlen=2
        real, allocatable:: array(:)
    end type
    interface base
        module procedure new_base
        module procedure new_base_list
    end interface
    contains
            function new_base(nlen)
                implicit none
                integer, intent(in), optional:: nlen
                type(base):: new_base
                write(*, "('Call constructor: new_base(nlen)')")
                if (present(nlen)) then
                    if (0 < nlen) then
                        new_base%nlen = nlen
                        write(*, '(2x, "User defined length:", 1x, i4)') nlen
                    else
                        write(*, '(2x, "Negetive input and use default value 2")')
                    endif
                else
                    write(*, '(2x, "Default length: 2")')
                end if
                allocate(new_base%array(new_base%nlen))
            end function

            function new_base_list(array) result(new_base)
                implicit none
                real, intent(in):: array(:)
                type(base):: new_base
                write(*, "('Call constructor: new_base_list(array)')")
                new_base%nlen = size(array)
                allocate(new_base%array(new_base%nlen))
                new_base%array = array
                write(*, "(2x, 'Array:', *(f7.2))")new_base%array
            end function
end module

program oop
use example
implicit none
type(base):: a1, a2, a3, a4
a1 = base()
a2 = base(nlen=6)
a3 = base(-2)
a4 = base([1E1, 3E2, 5E0, 7E0, 9E1])
end program

1230

帖子

12

主题

5

精华

论坛跑堂

Fcode跑堂伙计

F 币
711 元
贡献
323 点

新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

发表于 2018-2-8 15:43:53 | 显示全部楼层
qdd 发表于 2018-2-8 14:41
非常感谢您的回复!
另外,从您帮我修改的帖子格式来看,您太细心了。
顺便学会了mw_shl_code=fortran,这 ...

嗯,我修改了一个代码高亮的插件,添加了fortran的高亮方案。

1230

帖子

12

主题

5

精华

论坛跑堂

Fcode跑堂伙计

F 币
711 元
贡献
323 点

新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

发表于 2018-2-8 15:54:29 | 显示全部楼层
pasuka 的方法也是极好的,对于不是每个成员都需要外部赋值的情况。

4

帖子

1

主题

0

精华

入门

F 币
38 元
贡献
22 点

规矩勋章

 楼主| 发表于 2018-2-8 17:02:35 | 显示全部楼层
pasuka 发表于 2018-2-8 15:17
需要用到面向对象编程的内容,类似于C++的构造函数
[mw_shl_code=fortran,true]module example
    implici ...

谢谢!十分感谢提供例子!
我这儿只是做一个静态的数据库,为其他子程序提供一些基础数据(其实就是常用电极的基础数据),所以不用class啦
再次感谢!
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

QQ|捐赠本站|Archiver|关于我们 About Us|群聊|Fcode

GMT+8, 2018-6-23 10:15

Powered by Discuz! X3.2

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表