Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在fortran中正确定义用户定义复数的算术运算符重载?_Fortran_Gfortran - Fatal编程技术网

如何在fortran中正确定义用户定义复数的算术运算符重载?

如何在fortran中正确定义用户定义复数的算术运算符重载?,fortran,gfortran,Fortran,Gfortran,我的IDE是:代码::Blocks 20.03(MinGW 9.2.0) 这是我的简单代码: module mod_kompleks use, intrinsic :: iso_c_binding, only : rp => c_double implicit none type, public :: kom_bro private real(rp) :: dio_rea real(rp) :: dio_img contains

我的IDE是:代码::Blocks 20.03(MinGW 9.2.0)

这是我的简单代码:

module mod_kompleks

  use, intrinsic :: iso_c_binding, only : rp => c_double

  implicit none

  type, public :: kom_bro

    private

    real(rp) :: dio_rea
    real(rp) :: dio_img

    contains

      procedure, private :: kom_bro_sab    ! 16 line

      generic, public :: operator(+) => kom_bro_sab  ! 18 line

  end type kom_bro

  interface kom_bro

    module procedure :: kom_bro_set

  end interface kom_bro

  contains

  ! procedure - kom_bro_set

    type(kom_bro) function kom_bro_set(rea_part, img_part) result(bro_c)

      real, intent(in) :: rea_part, img_part

      bro_c%dio_rea = rea_part
      bro_c%dio_img = img_part

    end function kom_bro_set

  ! procedure - kom_bro_sab

    function kom_bro_sab(bro_a, bro_b) result(bro_c)

      type(kom_bro), intent(in) :: bro_a
      type(kom_bro), intent(in) :: bro_b
      type(kom_bro)             :: bro_c

      bro_c%dio_rea = bro_a%dio_rea + bro_b%dio_rea
      bro_c%dio_img = bro_a%dio_img + bro_b%dio_img

    end function kom_bro_sab

end module mod_kompleks

program kompleksni_broj

  use, non_intrinsic :: mod_kompleks

  implicit none

  integer :: i

  type(kom_bro) :: broj_01(3)
  type(kom_bro) :: broj_02(3)
  type(kom_bro) :: broj_03(3)

  do i = 1, 3

    broj_01(i) = kom_bro(i + 2.2,i + 3.3)
    broj_02(i) = kom_bro(i + 4.4,i + 5.5)

    broj_03(i) = broj_01(i) + broj_02(i)

  end do

end program kompleksni_broj
我打算定义一个看起来像复数的用户类型,但也允许对两个复数进行加法运算。由于在我的示例中我对编程语言Fortran没有经验,因此遇到了一个问题,编译器向我报告以下错误:

| 16 |错误:“kom_bro_sab”的非多态传递对象伪参数
| 18 |错误:未定义特定绑定“kom_bro_sab”作为泛型“+”的目标
| |===生成失败:2个错误,0个警告(0分钟,0秒))=====

我在编程语言Fortran中的OOP知识不足以让我自己解决这个问题。
甚至可以定义这样一个用户定义的类型吗?

您有多个错误。最重要的是,运算符重载是错误的。请参见下面的示例实现

复数的派生数据类型(文件名
b.f90

模块模块模块
使用,内在::iso_c_绑定,仅:rp=>c_-double
隐式无
私有的
公墓
公共操作员(+)
kom_bro型
私有的
雷亚尔(rp):迪奥·雷亚
雷亚尔(rp):迪奥·伊姆
包含
过程::init=>kom_bro_init
程序::打印=>kom_bro_打印
端型
接口运算符(+)
模块程序kom_bro_sab
端接口
接口kom_bro
模块程序kom_bro_init2
端接口
包含
函数kom_bro_init2(rea_部分,img_部分)结果(bro)
真实(rp)、意图(in):真实部分
真实(rp),意图(in)::img\U部分
类型(kom_bro)::bro
呼叫兄弟%init(真实部分、模拟部分)
端函数
子程序kom_bro_init(此,rea_部分,img_部分)
等级(kom_bro),意图(out)::此
真实(rp)、意图(in):真实部分
真实(rp),意图(in)::img\U部分
此%dio_rea=rea_零件
此%dio\u img=img\u零件
结束子程序
子程序kom_bro_print(本)
类(kom_bro),意图(in)::本
打印*,此%dio\u rea,此%dio\u img
结束子程序
函数kom_bro_sab(bro_a,bro_b)结果(bro_c)
类型(kom_bro),意图(in)::bro_a
类型(kom_bro),意图(in)::bro_b
类型(kom_bro)::bro_c
兄弟c%dio\U rea=兄弟a%dio\U rea+兄弟b%dio\U rea
兄弟c%dio\U img=兄弟a%dio\U img+兄弟b%dio\U img
端函数
端模块
程序(文件名
a.f90

程序kompleksni_broj
使用mod_kompleks
使用,内在::iso_c_绑定,仅:rp=>c_-double
隐式无
整数::i
类型(kom_bro):broj_01(3)、broj_02(3)、broj_03(3)
i=1,3吗
呼叫broj_01(i)%init(i+2.2\u rp,i+3.3\u rp)!通过类型绑定例程初始化
broj_02(i)=kom_bro(i+4.4_rp,i+5.5_rp)!通过接口kom_bro(又名“类型构造函数”)初始化
broj_03(i)=broj_01(i)+broj_02(i)
致电broj_03(i)%print()
结束
结束程序
输出

$gfortran-g3-Wall-fcheck=所有b.f90 a.f90&./a.out
3.2000000000000002        5.4000000000000004        8.6000000000000014     
4.2000000000000002        6.4000000000000004        10.600000000000001     
5.2000000000000002        7.4000000000000004        12.600000000000001

您有多个错误。最重要的是,运算符重载是错误的。请参见下面的示例实现

复数的派生数据类型(文件名
b.f90

模块模块模块
使用,内在::iso_c_绑定,仅:rp=>c_-double
隐式无
私有的
公墓
公共操作员(+)
kom_bro型
私有的
雷亚尔(rp):迪奥·雷亚
雷亚尔(rp):迪奥·伊姆
包含
过程::init=>kom_bro_init
程序::打印=>kom_bro_打印
端型
接口运算符(+)
模块程序kom_bro_sab
端接口
接口kom_bro
模块程序kom_bro_init2
端接口
包含
函数kom_bro_init2(rea_部分,img_部分)结果(bro)
真实(rp)、意图(in):真实部分
真实(rp),意图(in)::img\U部分
类型(kom_bro)::bro
呼叫兄弟%init(真实部分、模拟部分)
端函数
子程序kom_bro_init(此,rea_部分,img_部分)
等级(kom_bro),意图(out)::此
真实(rp)、意图(in):真实部分
真实(rp),意图(in)::img\U部分
此%dio_rea=rea_零件
此%dio\u img=img\u零件
结束子程序
子程序kom_bro_print(本)
类(kom_bro),意图(in)::本
打印*,此%dio\u rea,此%dio\u img
结束子程序
函数kom_bro_sab(bro_a,bro_b)结果(bro_c)
类型(kom_bro),意图(in)::bro_a
类型(kom_bro),意图(in)::bro_b
类型(kom_bro)::bro_c
兄弟c%dio\U rea=兄弟a%dio\U rea+兄弟b%dio\U rea
兄弟c%dio\U img=兄弟a%dio\U img+兄弟b%dio\U img
端函数
端模块
程序(文件名
a.f90

程序kompleksni_broj
使用mod_kompleks
使用,内在::iso_c_绑定,仅:rp=>c_-double
隐式无
整数::i
类型(kom_bro):broj_01(3)、broj_02(3)、broj_03(3)
i=1,3吗
呼叫broj_01(i)%init(i+2.2\u rp,i+3.3\u rp)!通过类型绑定例程初始化
broj_02(i)=kom_bro(i+4.4_rp,i+5.5_rp)!通过接口kom_bro(又名“类型构造函数”)初始化
broj_03(i)=broj_01(i)+broj_02(i)
致电broj_03(i)%print()
结束
结束程序
输出

$gfortran-g3-Wall-fcheck=所有b.f90 a.f90&./a.out
3.2000000000000002        5.4000000000000004        8.6000000000000014     
4.2000000000000002        6.4000000000000004        10.600000000000001     
5.2000000000000002        7.4000000000000004        12.600000000000001

这是我写的代码,有点乱,但它显示了我认为您所追求的

ian@eris:~/work/stack$ gfortran --version
GNU Fortran (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ian@eris:~/work/stack$ cat poly.f90
module mod_kompleks

  use, intrinsic :: iso_c_binding, only : rp => c_double

  implicit none

  type, public :: kom_bro

    private

    real(rp) :: dio_rea
    real(rp) :: dio_img

    contains

      Procedure, private :: kom_bro_sab    ! 16 line
      Procedure, Public  :: print => kom_bro_print
      Procedure, Public  :: set   => kom_bro_set

      generic, public :: operator(+) => kom_bro_sab  ! 18 line

  end type kom_bro

!!$  interface kom_bro
!!$
!!$    module procedure :: kom_bro_set
!!$
!!$  end interface kom_bro

  Private

contains

  ! procedure - kom_bro_set

!!$    type(kom_bro) function kom_bro_set(rea_part, img_part) result(bro_c)
    Subroutine kom_bro_set( bro_c, rea_part, img_part)

      Class( kom_bro ), Intent( InOut ) :: bro_c

      real, intent(in) :: rea_part, img_part

      bro_c%dio_rea = rea_part
      bro_c%dio_img = img_part

!!$    end function kom_bro_set
    end Subroutine kom_bro_set

  ! procedure - kom_bro_sab

    function kom_bro_sab(bro_a, bro_b) result(bro_c)

      Class(kom_bro), intent(in) :: bro_a
      Class(kom_bro), intent(in) :: bro_b
      Class(kom_bro), Allocatable :: bro_c

      ! Allocate the return value to the same type as
      ! one of the provided arguments - may have to modify this depending
      ! on requirements
      Allocate( bro_c, Mold = bro_a )
      
      bro_c%dio_rea = bro_a%dio_rea + bro_b%dio_rea
      bro_c%dio_img = bro_a%dio_img + bro_b%dio_img

    end function kom_bro_sab

    Subroutine kom_bro_print( bro_a )

      Class( kom_bro ), Intent( In ) :: bro_a

      Write( *, * ) 'Real: ', bro_a%dio_rea, ' Imag: ', bro_a%dio_img
      
    End Subroutine kom_bro_print

end module mod_kompleks

program kompleksni_broj

  use, non_intrinsic :: mod_kompleks

  implicit none

  integer :: i

  type(kom_bro) :: broj_01(5)
  type(kom_bro) :: broj_02(5)
  type(kom_bro) :: broj_03(5)

  do i = 1, 5

!!$    broj_01(i) = kom_bro(i + 2.2,i + 3.3)
!!$    broj_02(i) = kom_bro(i + 4.4,i + 5.5)
     Call broj_01(i)%set(i + 2.2,i + 3.3)
     Call broj_02(i)%set(i + 4.4,i + 5.5)
     
    broj_03(i) = broj_01(i) + broj_02(i)

    Write( *, * ) i
    Call broj_01(i)%print
    Write( *, * ) i
    Call broj_02(i)%print
    Write( *, * ) i
    Call broj_03(i)%print

    Write( *, * )
    
  end do

end program kompleksni_broj
ian@eris:~/work/stack$ gfortran -std=f2008 -Wall -Wextra -fcheck=all poly.f90 
ian@eris:~/work/stack$ ./a.out
           1
 Real:    3.2000000476837158       Imag:    4.3000001907348633     
           1
 Real:    5.4000000953674316       Imag:    6.5000000000000000     
           1
 Real:    8.6000001430511475       Imag:    10.800000190734863     

           2
 Real:    4.1999998092651367       Imag:    5.3000001907348633     
           2
 Real:    6.4000000953674316       Imag:    7.5000000000000000     
           2
 Real:    10.599999904632568       Imag:    12.800000190734863     

           3
 Real:    5.1999998092651367       Imag:    6.3000001907348633     
           3
 Real:    7.4000000953674316       Imag:    8.5000000000000000     
           3
 Real:    12.599999904632568       Imag:    14.800000190734863     

           4
 Real:    6.1999998092651367       Imag:    7.3000001907348633     
           4
 Real:    8.3999996185302734       Imag:    9.5000000000000000     
           4
 Real:    14.599999427795410       Imag:    16.800000190734863     

           5
 Real:    7.1999998092651367       Imag:    8.3000001907348633     
           5
 Real:    9.3999996185302734       Imag:    10.500000000000000     
           5
 Real:    16.599999427795410       Imag:    18.800000190734863     

ian@eris:~/work/stack$ 

这是我写的代码有点乱,