为什么在每个子例程调用中计数器变量意外增加? [英] Why is the counter variable unexpectedly increased in every subroutine call?

查看:69
本文介绍了为什么在每个子例程调用中计数器变量意外增加?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[社论:我已阅读此问题,但是(事后看来,最终的联系方式与每个问题都以同样的方式联系在一起-例如,计算机为什么会发生故障?),答案不是我的问题的答案。这个问题是在问为什么标准组织在语言中设计了特定功能。而且,答案不能回答我的问题,即我在调试此问题时错过了什么。]

问题:为什么输出从下面显示的此Fortran程序( ExhaustiveListing.f08 + unicodeSupport.f08 )中可以看出,Fortran的做的有重大错误吗?

QUESTION: Why does the output from this Fortran program (ExhaustiveListing.f08 + unicodeSupport.f08) shown below indicate that Fortran's DO WHILE has a major bug?

以下是输出,后面是环境描述,最后是两个相关文件的源代码:

Here's the output followed by environment description and, finally, the source code of the two files in question:


十六进制现在为: 2500H

2500─

2501━

2502│

2503┃

2504┄

2505┅

2506┆

2507┇< br>
2508┈

2509┉

250A┊

250B┋

250C┌

250D┍

250E┎

250F┏

十六进制为: 2510H

十六进制为现在: 2520H

十六进制现在是: 2530H

十六进制不是w: 2540H

十六进制现在是: 2550H

十六进制现在是: 2560H

十六进制现在为: 2570H



运行完成;退出值0;实时:530ms;用户:0ms;系统:0ms

Hex is now: 2500H.
2500─
2501━
2502│
2503┃
2504┄
2505┅
2506┆
2507┇
2508┈
2509┉
250A┊
250B┋
250C┌
250D┍
250E┎
250F┏
Hex is now: 2510H.
Hex is now: 2520H.
Hex is now: 2530H.
Hex is now: 2540H.
Hex is now: 2550H.
Hex is now: 2560H.
Hex is now: 2570H.

RUN FINISHED; exit value 0; real time: 530ms; user: 0ms; system: 0ms



期望的输出



我预计会有16行现在,每个 十六进制之间的详细信息为: xxxxH 行,例如在 2500H 2510H 行之间打印的行。

EXPECTED OUTPUT

I expected to have 16 lines of detail between each "Hex is now: xxxxH" line such as that printed between the 2500H and 2510H lines.

该程序是我尝试解决的一个较大项目中的问题。该项目遇到问题(其中一个问题涉及在Fortran中使用Unicode),我创建了这个项目来隔离Unicode问题。首先,我将琐碎的unicodeSupport模块与主程序合并在同一个文件中。我将其删除到自己的文件中。不,没关系,而且-不会影响结果。该程序是如此简单,我看不到任何可能做错的事情。因此,我来​​SO是希望新的眼睛发现我的失误。否则,是时候使用gFortran提交错误报告了。

This program is my attempt to resolve an issue in a much larger project. Having issues with that project (one such problem revolving around working with Unicode in Fortran), I created this project to isolate the Unicode issue. At first, I had the trivial unicodeSupport module combined in the same file as the main program. I removed it into its own file. No, it should not matter and -- it did not affect the outcome. This program is so plainly simple, I cannot see anything which I might be doing wrong. Hence, my coming to SO in hopes that new eyes discover my blunder. Else, it's time to file bug report with gFortran.

我正在使用的环境是:

操作系统 Ubuntu 17.10
IDE Netbeans 8.2
JDK Oracle(内部版本1.8.0_161-b12)
COMPILER gFortran 7.2.0
COMPLLER FLAGS -std = f2008ts -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans
theGeeko61 在BASIC,Pascal,FORTRAN,C,Prolog,C ++,Java和许多其他语言(根据我学习它们的时间顺序排列)中发展了四十年。

The environment that I'm working in is:
OS: Ubuntu 17.10 IDE: Netbeans 8.2 JDK: Oracle (build 1.8.0_161-b12) COMPILER: gFortran 7.2.0 COMPILER FLAGS: -std=f2008ts -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans theGeeko61: 4 decades developing in BASIC, Pascal, FORTRAN, C, Prolog, C++, Java, many others (sorted chronologically by the order in which I learned them)

! File:   ExhaustiveListing.f08
! Author: geeko
!
! Created on March 25, 2018, 7:05 PM
!
! ☐ U2610 ☑ U2611 ☒ U2612
! Use above symbols for indicating items to
! be tested (☐), and items which have either
! passed (☑) or failed (☒) testing.
!
SUBROUTINE displayLine(hex)
    USE unicodeSupport
    IMPLICIT NONE
    INTEGER :: hex, counter=0, point

    DO WHILE (counter < 16)
        point = hex+counter
        WRITE(*,'(Z4.4,A)') point, CHAR(INT(point), ucs4)
        counter = counter+1
    END DO
END SUBROUTINE

PROGRAM ExhaustiveListingOfUnicodeBoxDrawingChars ! ☒
    USE ISO_FORTRAN_ENV
    USE unicodeSupport
!!!!!USE testUnicodeSupport         ! ☑
    IMPLICIT NONE
    INTEGER  :: hex

    open(output_unit, encoding='UTF-8')

    hex = 9472
    DO WHILE(hex<9600)
        PRINT '(A,Z4.4,A)', "Hex is now: ", hex, "H."
        CALL displayLine(hex)   ! ☒
        hex = hex+16
    END DO

!!!!CALL performTest()              ! ☑
END PROGRAM ExhaustiveListingOfUnicodeBoxDrawingChars



unicodeSupport.f08



unicodeSupport.f08

! File:   unicodeSupport.f08
! Author: geeko
!
! Created on March 25, 2018, 10:09 PM
!

MODULE unicodeSupport
    INTEGER, PARAMETER  :: ASCII = SELECTED_CHAR_KIND('ASCII')
    INTEGER, PARAMETER  :: UCS4 = SELECTED_CHAR_KIND('ISO_10646')
END MODULE unicodeSupport


推荐答案

变量 counter 在这里声明

INTEGER :: hex, counter=0, point

由于在初始化行上定义了其值,因此具有 save 属性。

possesses the save attribute by virtue of having its value defined on the initialization line.

第二次输入子程序时,其值为16,因此不会出现循环。

The second time you enter the subroutine, its value will be 16 and hence there will be no loop.

从声明行中删除 = 0 并写

counter = 0

之后。

这篇关于为什么在每个子例程调用中计数器变量意外增加?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆