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 90-分段错误_Fortran_Fortran90 - Fatal编程技术网

Fortran 90-分段错误

Fortran 90-分段错误,fortran,fortran90,Fortran,Fortran90,我正在制作一个程序,将十进制整数转换为二进制表示形式。这是我的密码: program test implicit none integer, dimension(:), allocatable :: binary integer :: decimalnum, i, initvalue print*, "Enter decimal number to convert: " read*,initvalue decimalnum = initvalue i = 0 do while (decim

我正在制作一个程序,将十进制整数转换为二进制表示形式。这是我的密码:

program test
implicit none
integer, dimension(:), allocatable :: binary
integer :: decimalnum, i, initvalue

print*, "Enter decimal number to convert: "
read*,initvalue

decimalnum = initvalue
i = 0

do while (decimalnum > 0)
    if (MOD(decimalnum,2)==0) then
        binary(i) = 0                  ! this is as far as the program executes up to 
        decimalnum = decimalnum / 2
        i = i + 1
    else if (MOD(decimalnum,2)==1) then
        binary(i) = 1
        decimalnum = (decimalnum -1) / 2
        i = i + 1
    end if
end do
end program test
在标记点,它返回错误分段错误并以代码139退出

为什么会发生这种情况


提前感谢。

根据评论,在定义二进制数组之前,您需要先执行一个allocate语句或其他为您进行分配的语句。最简单的分配语句形式类似于ALLOCATEbinary10,它将给定二进制数组10个元素,使用默认值,可以使用allocate语句起始数组索引1更改该数组

如果在使用阵列之前不容易知道分配的大小,则有两种基本方法:

执行两次传递,第一次传递只计算需要多少个元素,然后分配数组,第二次传递实际分配给相关元素。 将阵列分配到初始大小(可能为零),然后根据需要逐渐增大阵列。 与使用方法相关的决策有一些权衡,比如分配和计数时对每个测试的评估


在Fortran 90中,至少要转到Fortran 95!,增加一个可分配数组有点复杂分配一个临时数组,将数据从原始数组复制到临时数组,取消分配原始数组,将原始数组分配到新大小数组,将数据从临时数组复制回调整大小的原始数组,取消分配临时数组。在Fortran 2003中,此操作变得很简单。

根据注释,在定义二进制数组之前,您需要先执行一条allocate语句或在后台为您执行分配的某些操作。最简单的分配语句形式类似于ALLOCATEbinary10,它将给定二进制数组10个元素,使用默认值,可以使用allocate语句起始数组索引1更改该数组

如果在使用阵列之前不容易知道分配的大小,则有两种基本方法:

执行两次传递,第一次传递只计算需要多少个元素,然后分配数组,第二次传递实际分配给相关元素。 将阵列分配到初始大小(可能为零),然后根据需要逐渐增大阵列。 与使用方法相关的决策有一些权衡,比如分配和计数时对每个测试的评估


在Fortran 90中,至少要转到Fortran 95!,增加一个可分配数组有点复杂分配一个临时数组,将数据从原始数组复制到临时数组,取消分配原始数组,将原始数组分配到新大小数组,将数据从临时数组复制回调整大小的原始数组,取消分配临时数组。在Fortran 2003中,这个操作变得很简单。

所以这可能是一种糟糕的形式,当然是糟糕的运行时,它会复制数组的每一个位,但下面是我想到的。它似乎起作用了

  program test
      implicit none
      integer, dimension(:), allocatable :: binary
      integer :: decimalnum, i, initvalue, curSize, curBit


      print*, "Enter decimal number to convert: "
      read*,initvalue

      decimalnum = initvalue
      i = 1
      ALLOCATE ( binary(1) )
      curSize = 1

      DO WHILE (decimalnum > 0)
        IF (i > curSize ) THEN
            curSize = curSize * 2
            CALL expandArray( curSize, i-1 )
        END IF

        IF (MOD(decimalnum,2)==0) then
            binary(i) = 0                  ! this is as far as the program executes up to 
            decimalnum = decimalnum / 2
            i = i + 1
        ELSE IF (MOD(decimalnum,2)==1) then
            binary(i) = 1
            decimalnum = (decimalnum -1) / 2
            i = i + 1
        END IF

      end do
      PRINT*, binary


  CONTAINS
      SUBROUTINE expandArray( newSize, oldSize )
          IMPLICIT NONE
          INTEGER, DIMENSION(:), ALLOCATABLE :: temp
          INTEGER :: j, newSize, oldSize
          ALLOCATE( temp(newSize) )
          DO j=1,oldSize
              temp(j) = binary(j)
          END DO
          DEALLOCATE (binary)
          ALLOCATE( binary(newSize) )
          DO j=1,oldSize
              binary(j) = temp(j)
          END DO
          DO j=oldSize+1,newSize
              binary(j) = 0
          END DO
          DEALLOCATE (temp)
      END SUBROUTINE

  END PROGRAM test

所以这可能是一种糟糕的形式,当然是糟糕的运行时,它会复制数组中的每一位,但下面是我想到的。它似乎起作用了

  program test
      implicit none
      integer, dimension(:), allocatable :: binary
      integer :: decimalnum, i, initvalue, curSize, curBit


      print*, "Enter decimal number to convert: "
      read*,initvalue

      decimalnum = initvalue
      i = 1
      ALLOCATE ( binary(1) )
      curSize = 1

      DO WHILE (decimalnum > 0)
        IF (i > curSize ) THEN
            curSize = curSize * 2
            CALL expandArray( curSize, i-1 )
        END IF

        IF (MOD(decimalnum,2)==0) then
            binary(i) = 0                  ! this is as far as the program executes up to 
            decimalnum = decimalnum / 2
            i = i + 1
        ELSE IF (MOD(decimalnum,2)==1) then
            binary(i) = 1
            decimalnum = (decimalnum -1) / 2
            i = i + 1
        END IF

      end do
      PRINT*, binary


  CONTAINS
      SUBROUTINE expandArray( newSize, oldSize )
          IMPLICIT NONE
          INTEGER, DIMENSION(:), ALLOCATABLE :: temp
          INTEGER :: j, newSize, oldSize
          ALLOCATE( temp(newSize) )
          DO j=1,oldSize
              temp(j) = binary(j)
          END DO
          DEALLOCATE (binary)
          ALLOCATE( binary(newSize) )
          DO j=1,oldSize
              binary(j) = temp(j)
          END DO
          DO j=oldSize+1,newSize
              binary(j) = 0
          END DO
          DEALLOCATE (temp)
      END SUBROUTINE

  END PROGRAM test

下面是一种将整数i转换为二进制表示形式的简单方法:

write(*,'(b16)') i
如前所述,这不会写入任何前导0。如果你想要领先的0,试试看

当然,前面的代码将二进制表示写入默认输出单元,但使用Fortran的内部写入功能,我可以同样轻松地将位写入字符变量。例如:

character(len=16) :: bits
...
write(bits,'(b16.16)') i
将i的二进制数字写入字符变量位

现在,如果您真正想要的是创建一个整数数组,每个整数代表二进制表示的一位,那么

integer, dimension(16) :: bitarray
...
bitarray = 0
...
do ix = 1,len(bits)
    if (bits(ix:ix)=='1') bitarray(ix) = 1
end do

可能会有用。

这里有一个简单的方法将整数i转换为二进制表示:

write(*,'(b16)') i
如前所述,这不会写入任何前导0。如果你想要领先的0,试试看

当然,前面的代码将二进制表示写入默认输出单元,但使用Fortran的内部写入功能,我可以同样轻松地将位写入字符变量。例如:

character(len=16) :: bits
...
write(bits,'(b16.16)') i
将i的二进制数字写入字符变量位

现在,如果您真正想要的是创建一个整数数组,每个整数代表二进制表示的一位,那么

integer, dimension(16) :: bitarray
...
bitarray = 0
...
do ix = 1,len(bits)
    if (bits(ix:ix)=='1') bitarray(ix) = 1
end do

可能会工作。

1发生崩溃是因为您只为数组二进制文件分配了1个元素:,而While循环可能已移动到i=2,此时数组的索引超出了崩溃范围

Fortran有许多直接处理位的内在函数。比如说,

Bit_Sizevar返回var中的位数,因此如果必须 如果是可分配的,现在您可以提前知道所需的数组大小

b BTestiVar,pos返回。为True。如果iVar中pos处的位为1

例如,使用上面的其他声明:

Integer     :: n

n = Bit_Size(decimalnum)    

If( Allocated(Binary) ) DeAllocate(Binary)          ! good practice
Allocate( Binary(1:n) )                             ! in general, should get IOStat, just in case

Binary(:) = 0

ForAll(i=1:n, Mask = BTest( decimalnum, i-1 ) ) ! remember, bit intrinsics index from 0
    Binary(i) = 1
End ForAll
。。。与Do和While相比,这有点效率,并且可能有助于smp。Where/EndWhere构造也可以使用,但我发现ForAll的效率更高一些

c IBitsvar,pos,len从var中提取位,从pos开始计算len位数,例如,如果您想创建一个显式二进制表示,这可能是一种方法

等等

3如果你的意思是将十进制数转换为二进制数,那么你还有很多额外的问题,如果十进制数还包括浮点十进制数,即实数,因为实数的位表示是以指数表示的。我将假设情况并非如此,因为代码/解释要复杂得多


最后,在Fortran中,NUM通常是有符号NUM,前导位用于确定+ve 0或-ve 1。因此,如果您使用的是另一个方向Bin2Dec,那么您更希望使用一个额外的arg(可能是可选的)来控制结果是有符号的还是无符号的。如果是无符号的,则输出变量需要比输入变量更大。例如,如果将无符号1字节整数转换为Fortran整数,则必须至少使用2字节整数,即输入整数1必须输出为整数2等。

1由于只为数组二进制分配了1个元素,因此会发生崩溃:,While循环可能已经转到i=2,此时数组的索引超出了范围

Fortran有许多直接处理位的内在函数。比如说,

Bit_Sizevar返回var中的位数,因此如果必须使用可分配的,现在您可以提前知道所需的数组大小

b BTestiVar,pos返回。为True。如果iVar中pos处的位为1

例如,使用上面的其他声明:

Integer     :: n

n = Bit_Size(decimalnum)    

If( Allocated(Binary) ) DeAllocate(Binary)          ! good practice
Allocate( Binary(1:n) )                             ! in general, should get IOStat, just in case

Binary(:) = 0

ForAll(i=1:n, Mask = BTest( decimalnum, i-1 ) ) ! remember, bit intrinsics index from 0
    Binary(i) = 1
End ForAll
。。。与Do和While相比,这有点效率,并且可能有助于smp。Where/EndWhere构造也可以使用,但我发现ForAll的效率更高一些

c IBitsvar,pos,len从var中提取位,从pos开始计算len位数,例如,如果您想创建一个显式二进制表示,这可能是一种方法

等等

3如果你的意思是将十进制数转换为二进制数,那么你还有很多额外的问题,如果十进制数还包括浮点十进制数,即实数,因为实数的位表示是以指数表示的。我将假设情况并非如此,因为代码/解释要复杂得多


最后,在Fortran中,NUM通常是有符号NUM,前导位用于确定+ve 0或-ve 1。因此,如果您使用的是另一个方向Bin2Dec,那么您更希望使用一个额外的arg(可能是可选的)来控制结果是有符号的还是无符号的。如果是无符号的,则输出变量需要比输入变量更大。例如,如果将无符号1字节整数转换为Fortran整数,则必须至少使用2字节整数,即输入整数1必须输出为整数2等。

您有权进行调试吗?这样的gdbNo,我不知道如何使用。我对Fortran不太了解,但我只是查找了“Allocateable”,看起来您仍然需要一个“allocate”语句来实际保留空间。我将该行更改为allocatebinaryi=0,但编译器在allocate语句中返回语法错误。另外:数组以索引1开头。您有权访问调试吗?这样的gdbNo,我不知道如何使用。我对Fortran不太了解,但我只是查找了“allocatable”,看起来您仍然需要一个“allocate”语句来实际保留空间。我将该行更改为allocatebinaryi=0,但编译器在allocate语句中返回语法错误。另外:数组以索引1开头。注意:刚刚编辑-我错误地将binary作为expandArray的参数,而不是全局变量。出于某种原因,它还是起作用了。在任何情况下,它现在是固定的。我同意作者的观点,这段代码可能很糟糕,它会复制数组的每一位。它特别使用了FORTRAN77的continue语句,这些语句已被更好的功能所取代。@HighPerformanceMark尝试将其修饰得更好一点阵列重新分配,摆脱了do/continue。很明显,我还不是Fortran程序员,所以我非常感谢专业人士的编辑/反馈。注意:刚刚编辑-我错误地将二进制作为expandArray的参数,而不是全局变量。出于某种原因,它还是起作用了。在任何情况下,它现在是固定的。我同意作者的观点,这段代码可能很糟糕,它会复制数组的每一位。它特别使用了FORTRAN77的continue语句的功能,这些语句已被更好的功能所取代。@HighPerformanceMark尝试将其修饰得更好一点阵列重新分配,摆脱了do/contin
ue。很明显,我还不是Fortran程序员,所以我非常感谢专业人士的编辑/反馈。@AussieGamer:您将很难找到一个编译器,它可以接受2008年修订版添加的大量语法;现在市面上的大多数编译器都实现了Fortran 2003的大部分功能。@AussieGamer:你很难找到一个编译器,它能接受2008年修订版所增加的大部分语法;现在市场上的大多数编译器都实现了Fortran 2003的大部分功能。