【问题标题】:I have problem translating C code in fortran我在用 fortran 翻译 C 代码时遇到问题
【发布时间】:2020-10-02 02:44:17
【问题描述】:
for(i=1;i<=ntype;i++)
        for(cnt=0,j=1;j<=nbeta[i];j++) {
        cnt++;
        pos[i][cnt]=j;
        if (lll[i][j]==0)  {
         for(kk=1;kk<=kkbeta[i];kk++)
                bfunc[i][cnt][kk]=bfunctmp[i][j][kk];
                llltmp[i][cnt]=lll[i][j];
        } // if
        if (lll[i][j]>0)  {
         for(kk=1;kk<=kkbeta[i];kk++)
                bfunc[i][cnt][kk]=0.5*(bfunctmp[i][j  ][kk]+
                                       bfunctmp[i][j+1][kk]);
                llltmp[i][cnt]=lll[i][j];
         j++;
        } // if
        } // j,i

!我翻译的fortran代码是

     do i =1,ntype
         cnt =0
         do j =1,nbeta(i)
             cnt = cnt+1
             pos(i,cnt) =j
             
             if(lll(i,j) ==0) then
                 do kk =1, kkbeta(i)
                     bfunc(i,cnt,kk)= bfunctmp(i,j,kk)
                 end do !end kk
                 llltmp(i,cnt) =lll(i,j)
!                 write(*,*)i,j,lll(i,j)
!                 write(*,*)i,cnt,llltmp(i,cnt)  ! '(5x,3I5)'
             end if

    !         cnt1 =j 
             if(lll(i,j) > 0) then 
                 do kk =1, kkbeta(i)
                     bfunc(i,cnt,kk)= 0.5 *(bfunctmp(i,j,kk) + bfunctmp(i,j+1,kk))
                 end do !end kk
                 llltmp(i,cnt) =lll(i,j)
               j =j+1
             end if
             
         end do !end j
     end do !end i

! DO 主体内的 do 变量不应出现在变量定义上下文中。 [j]
我期待尽快解决这个问题。谢谢!

【问题讨论】:

  • 它不喜欢分配j 的事实,因为它用于包含DO 循环。您需要为它保留一个单独的计数器,它不会在 DO 循环中使用。
  • @TomKarzes 我尝试更改不同名称的计数器,但没有提供相同的结果。但是这里 j 连接到 pos[i][cnt]=j;

标签: c fortran


【解决方案1】:

正如@TomKarzes 在 cmets 中所说,您不能在该循环的主体内分配给DO 循环的控制变量。有时您可以通过使用不同的变量来解决此类问题。但是,在您的代码中,j=j+1 的目标似乎是跳过循环迭代,而您根本无法在 DO 循环中执行此操作。

但是,您可以将 DO 循环替换为 DO WHILE 循环:

      j = 1
      do while (j <= nbeta(i))
!       ...

        if (lll(i,j) > 0) then
!           ...
            j = j + 1
        end if

        j = j + 1
      end do

这应该适用于您的特定代码,但在进行此类转换时必须非常小心。至少必须考虑以下因素:

  • 在迭代的DO 循环中,循环变量在每次执行循环体后自动递增,即使循环体的执行因执行CYCLE 语句而提前终止。然而,在DO WHILE 循环中,变量仅由执行的语句修改,因此CYCLE 本身不会导致任何变量被更新。

  • 迭代DO 循环要执行的迭代次数是在执行第一次迭代之前计算的,基于在执行到达DO 语句时收集的数据(例如nbeta(i) 的值)。只有通过EXITRETURNGOTOSTOP 语句提前终止循环,或执行导致程序终止的过程,才能更改该迭代次数。另一方面,DO WHILE 的条件会在每次迭代之前进行评估。

【讨论】:

  • 谢谢约翰。它为我节省了更多时间。
猜你喜欢
  • 1970-01-01
  • 2018-09-23
  • 2020-08-17
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2015-02-15
  • 2020-07-28
相关资源
最近更新 更多