Sun Studio 12:Fortran 库参考

第 1 章 Fortran 库例程

本章介绍 Fortran 库例程。

本章介绍的所有例程在手册库的第 3F 节中都有对应的手册页。例如,执行 man -s 3F access 将显示库例程 access 的手册页条目。

本章没有介绍 Fortran 95 标准内例程。有关内例程的信息,请参见有关的 Fortran 95 标准文档。

另请参见《数值计算指南》,了解有关 可从 Fortran 和 C 调用的其他数学例程,其中包括 libmlibsunmath 中的标准数学库例程(请参见 Intro(3M))、这些库的优化版本、SPARC 向量数学库、libmvec 以及其他库例程。

有关 f95 编译器实现的 Fortran 77 和 VMS 内函数的详细信息,请参见2.3.4.2 内存函数

1.1 数据类型注意事项

除非另有说明,否则此处列出的函数例程均不是内函数例程。这意味着函数返回的数据类型可能与函数名称的隐式类型处理相冲突,需要用户进行显式类型声明。例如,getpid() 返回的是 INTEGER*4,这就需要有 INTEGER*4 getpid 声明,以确保能够正确处理结果。(如果没有显式类型处理,缺省情况下,会假设为 REAL,这是因为函数名称以 g 开头。)请注意,显式类型语句位于这些例程的函数摘要中。

请注意,IMPLICIT 语句以及 -dbl-xtypemap 编译器选项也会更改参数的数据类型处理以及返回值的处理。如果调用这些库例程时,预期的数据类型与实际的数据类型不一致,可能会导致出现意外行为。选项 -xtypemap-dbl 可将 INTEGER 函数、REAL 函数和 DOUBLE 函数的数据类型分别提升为 INTEGER*8REAL*8REAL*16。为了防止出现这些问题,库调用中出现的函数名和变量必须按照其预期大小进行显式类型处理,如下所示:


        integer*4 seed, getuid
        real*4 ran
        ...
        seed = 70198
        val = getuid() + ran(seed)
        ...

本示例中,进行了显式类型处理,以防止使用编译器选项 -xtypemap-dbl 时,库调用中出现任何数据类型提升。如果没有进行显式类型处理,这些选项可能会导致出现意外结果。有关这些选项的详细信息,请参见《 Fortran 用户指南》和 f95(1) 手册页。

Fortran 95 编译器 f95 提供了一个 include 文件 system.inc该文件定义了用于大多数非内库例程的接口。将该文件包含进来是为了确保对调用的函数及其参数正确地进行类型处理,尤其是在使用 -xtypemap 更改缺省的数据类型时。


        include ’system.inc’
        integer(4) mypid
        mypid = getpid()
        print *, mypid

可以使用 Fortran 编译器的全局程序检查选项 -Xlist 获取许多与库调用中出现的类型不一致有关的问题。《Fortran 用户指南》、《Fortran 编程指南》和 f95(1) 手册页中介绍了 f95 编译器执行的全局程序检查信息。

1.2 64 位环境

对程序进行编译以在 64 位操作环境中运行(也就是说,使用 -m64 进行编译,并在支持 64 位的 SPARC 或 x86 平台上运行可执行文件)会更改某些函数的返回值。这些通常是与标准系统级例程交互的函数(如 malloc(3F))(请参见1.4.35 mallocmalloc64reallocfree:分配/重新分配/解除分配内存),这些函数可能会根据环境采用或返回 32 位值或 64 位值。为了能够在 32 位环境与 64 位环境之间移植代码,提供了这些例程的 64 位版本,它们始终采用和/或返回 64 位值。下表列出了适用于 64 位环境的库例程:

表 1–1 适用于 64 位环境的库例程

功能 

说明 

malloc64

分配内存并返回指针 

fseeko64

重新确定大文件的位置 

ftello64

确定大文件的位置 

stat64、fstat64、lstat64

确定文件的状态 

time64、ctime64、gmtime64、ltime64

分解系统时间,转换为字符 

qsort64

将数组元素排序 

1.3 Fortran 数学函数

下列函数和子例程属于 Fortran 数学库。它们适用于使用 f95 编译的所有程序。这些例程属于非内例程,它们的参数采用特定数据类型并且返回值也是相同的数据类型。要使用非内例程,必须在引用它们的例程中进行声明。

其中许多例程都是“包装器”,即 C 语言库中例程的 Fortran 接口,它们本身并不是 Fortran 标准例程,其中包括 IEEE 推荐的支持函数以及专用的随机数生成器。有关这些库的更多信息,请参见《数值计算指南》以及 libm_single(3F)、libm_double(3F) 和 libm_quadruple(3F) 手册页。

1.3.1 单精度函数

这些子程序是单精度数学函数和子例程。

通常,下文介绍的函数可以访问单精度数学函数,它们没有对应的 Fortran 标准通用内函数,其数据类型按常用数据类型处理规则确定。

不必使用 REAL 语句对这些函数进行显式类型处理,只要保留缺省的类型处理即可。(以 "r" 开头的名称表示 REAL,以 "i" 开头的名称表示 INTEGER。)

有关这些例程的详细信息,参见 C 数学库手册页 (3M)。例如,有关 r_acos(x) 的信息,请参见 acos(3M) 手册页。

表 1–2 单精度数学函数

函数名 

返回类型 

说明 

r_acos( x )

r_acosd( x )

r_acosh( x )

r_acosp( x )

r_acospi( x )

REAL

REAL

REAL

REAL

REAL

反余弦

--

反双曲余弦

--

--

r_atan( x )

r_atand( x )

r_atanh( x )

r_atanp( x )

r_atanpi( x )

REAL

REAL

REAL

REAL

REAL

反正切

--

反双曲正切

--

--

r_asin( x )

r_asind( x )

r_asinh( x )

r_asinp( x )

r_asinpi( x )

REAL

REAL

REAL

REAL

REAL

反正弦

--

反双曲正弦

--

--

r_atan2(( y, x )

r_atan2d( y, x )

r_atan2pi( y, x )

REAL

REAL

REAL

反正切

--

--

r_cbrt( x )

r_ceil( x )

r_copysign( x, y )

REAL

REAL

REAL

立方根

计算大于或等于 x 的最小整数

--

r_cos( x )

r_cosd( x )

r_cosh( x )

r_cosp( x )

r_cospi( x )

REAL

REAL

REAL

REAL

REAL

余弦

--

双曲余弦

--

--

r_erf( x )

r_erfc( x )

REAL

REAL

误差函数

--

r_expm1( x )

r_floor( x )

r_hypot( x, y )

r_infinity( )

REAL

REAL

REAL

REAL

(e**x)-1

计算不大于 x 的下一个整数

计算直角三角形的斜边长度

--

r_j0( x )

r_j1( x )

r_jn(n, x )

REAL

REAL

REAL

贝塞尔--

--

ir_finite( x )

ir_fp_class( x )

ir_ilogb( x )

ir_irint( x )

ir_isinf( x )

ir_isnan( x )

ir_isnormal( x )

ir_issubnormal( x )

ir_iszero( x )

ir_signbit( x )

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

--

--

--

--

--

--

--

--

--

--

r_addran()

r_addrans( x, p, l, u )

r_lcran()

r_lcrans( x, p, l, u )

r_shufrans(x, p, l, u)

REAL

子例程 REAL

子例程

子例程

随机数生成器

r_lgamma( x )

r_logb( x )

r_log1p( x )

r_log2( x )

REAL

REAL

REAL

REAL

gamma(x) 的对数

--

--

--

r_max_normal()

r_max_subnormal()

r_min_normal()

r_min_subnormal()

r_nextafter( x, y )

r_quiet_nan( n )

r_remainder( x, y )

r_rint( x )

r_scalb( x, y )

r_scalbn( x, n )

r_signaling_nan( n )

r_significand( x )

REAL

REAL

REAL

REAL

REAL

REAL

REAL

REAL

REAL

REAL

REAL

REAL

 

r_sin( x )

r_sind( x )

r_sinh( x )

r_sinp( x )

r_sinpi( x )

REAL

REAL

REAL

REAL

REAL

正弦

--

双曲正弦

--

--

r_sincos( x, s, c )

r_sincosd( x, s, c )

r_sincosp( x, s, c )

r_sincospi( x, s, c )

子例程

子例程

子例程

子例程

正弦和余弦

--

--

--

r_tan( x )

r_tand( x )

r_tanh( x )

r_tanp( x )

r_tanpi( x )

REAL

REAL

REAL

REAL

REAL

正切

--

双曲正切

--

--

r_y0( x )

r_y1( x )

r_yn( n, x )

REAL

REAL

REAL

贝塞尔

--

--

另请参见:intro(3M) 和《数值计算指南》。

1.3.2 双精度函数

以下子程序为双精度数学函数和子例程。

通常,这些函数没有对应的 Fortran 标准通用内函数,其数据类型按常用数据类型处理规则确定。

这些 DOUBLE PRECISION 函数应该用于 DOUBLE PRECISION 语句中。

有关详细信息,请参阅 C 库手册页: acos(3M) 手册页中介绍了 d_acos(x)

表 1–3 双精度数学函数

函数名 

返回类型 

说明 

d_acos( x )

d_acosd( x )

d_acosh( x )

d_acosp( x )

d_acospi( x )

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

反余弦

--

反双曲余弦

--

--

d_atan( x )

d_atand( x )

d_atanh( x )

d_atanp( x )

d_atanpi( x )

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

反正切

--

反双曲正切

--

--

d_asin( x )

d_asind( x )

d_asinh( x )

d_asinp( x )

d_asinpi( x )

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

反正弦

--

反双曲正弦

--

--

d_atan2(( y, x )

d_atan2d( y, x )

d_atan2pi( y, x )

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

反正切

--

--

d_cbrt( x )

d_ceil( x )

d_copysign( x, x )

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

立方根

计算大于或等于 x 的最小整数

--

d_cos( x )

d_cosd( x )

d_cosh( x )

d_cosp( x )

d_cospi( x )

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

余弦

--

双曲余弦

--

--

d_erf( x )

d_erfc( x )

DOUBLE PRECISION

DOUBLE PRECISION

误差函数

--

d_expm1( x )

d_floor( x )

d_hypot( x, y )

d_infinity( )

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

(e**x)-1

计算不大于 x 的下一个整数

计算直角三角形的斜边长度

--

d_j0( x )

d_j1( x )

d_jn(n, x )

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

贝塞尔

--

--

id_finite( x )

id_fp_class( x )

id_ilogb( x )

id_irint( x )

id_isinf( x )

id_isnan( x )

id_isnormal( x )

id_issubnormal( x )

id_iszero( x )

id_signbit( x )

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

 

d_addran()

d_addrans(x, p, l, u)

d_lcran()

d_lcrans(x, p, l, u )

d_shufrans(x, p, l,u)

DOUBLE PRECISION

子例程

DOUBLE PRECISION

子例程

子例程

随机数生成器

d_lgamma( x )

d_logb( x )

d_log1p( x )

d_log2( x )

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

gamma(x) 的对数

--

--

--

d_max_normal()

d_max_subnormal()

d_min_normal()

d_min_subnormal()

d_nextafter( x, y )

d_quiet_nan( n )

d_remainder( x, y )

d_rint( x )

d_scalb( x, y )

d_scalbn( x, n )

d_signaling_nan( n )

d_significand( x )

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

 

d_sin( x )

d_sind( x )

d_sinh( x )

d_sinp( x )

d_sinpi( x )

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

正弦

--

双曲正弦

--

--

d_sincos( x, s, c )

d_sincosd( x, s, c )

d_sincosp( x, s, c )

d_sincospi( x, s, c )

子例程

子例程

子例程

子例程

正弦和余弦

--

--

d_tan( x )

d_tand( x )

d_tanh( x )

d_tanp( x )

d_tanpi( x )

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

正切

--

双曲正切

--

--

d_y0( x )

d_y1( x )

d_yn( n, x )

DOUBLE PRECISION

DOUBLE PRECISION

DOUBLE PRECISION

贝塞尔

--

--

另请参见:intro(3M) 和《数值计算指南》。

1.3.3 四倍精度函数

以下子程序为四倍精度 (REAL*16) 数学函数和子例程。

通常,这些函数没有对应的标准通用内函数,其数据类型按常用数据类型处理规则确定。

四倍精度函数必须用于 REAL*16 语句中。

表 1–4 四倍精度 libm 函数

函数名 

返回类型 

q_copysign( x, y )

q_fabs( x )

q_fmod( x )

q_infinity( )

REAL*16

REAL*16

REAL*16

REAL*16

iq_finite( x )

iq_fp_class( x )

iq_ilogb( x )

iq_isinf( x )

iq_isnan( x )

iq_isnormal( x )

iq_issubnormal( x )

iq_iszero( x )

iq_signbit( x )

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

INTEGER

q_max_normal()

q_max_subnormal()

q_min_normal()

q_min_subnormal()

q_nextafter( x, y )

q_quiet_nan( n )

q_remainder( x, y )

q_scalbn( x, n )

q_signaling_nan( n )

REAL*16

REAL*16

REAL*16

REAL*16

REAL*16

REAL*16

REAL*16

REAL*16

REAL*16

如果需要使用其他任何四倍精度 libm 函数,可以在调用前使用 $PRAGMA C(fcn) 来进行调用。有关详细信息,请参见《Fortran 编程指南》中介绍 C–Fortran 接口的章节。

1.4 Fortran 库例程参考

本节详细介绍了 Fortran 库中属于 Sun Studio Fortran 95 软件但不是 Fortran 95 标准内例程和函数的子例程和函数。

下面以表的形式概要说明调用接口

数据声明

带参数的调用原型概要说明

参数 1 名称

数据类型

输入/输出

说明

参数 2 名称

数据类型

输入/输出

说明

返回值

数据类型

输出 

说明

可以在 Sun Studio 手册页的第 3f 节中找到其他手册页。例如,执行 man -s 3f 命令将显示 access() 函数的手册页。在本手册中,手册页参考均表示为 manpagename(section)。例如,有关 access() 函数的手册页参考表示为 access(3f),有关 Fortran 95 编译器的手册页参考表示为 f95(1)。

1.4.1 abort:终止并写入核心转储文件

该子例程的调用方式如下所示:


call abort

abort 刷新 I/O 缓冲区,然后中止进程,可能会在当前目录中生成核心转储文件内存转储。有关限制或抑制核心转储的信息,请参见 limit(1)。

1.4.2 access:检查文件权限或文件是否存在

该函数的调用方式如下所示:

INTEGER*4 access

status = access ( name, mode )

name

字符

输入 

文件名 

mode

字符

输入 

权限 

返回值 

INTEGER*4

输出 

status=0:OK;status>0:错误代码

access 确定是否可以使用 mode 指定的权限访问文件 name。如果可以使用 mode 指定的权限成功访问文件,access 将返回零。另请参见 gerror(3F),了解有关错误代码的信息。

可以将 mode 设置为 rwx 中的一个或多个(以任何顺序或任意组合),也可以为空白,其中 rwx 的含义如下:

’r’

测试是否有读取权限 

’w’

测试是否有写入权限 

’x’

测试是否有执行权限 

’ ’

测试文件是否存在 

示例 1:测试是否有读/写权限:


      INTEGER*4  access, status
      status = access ( ’taccess.data’, ’rw’ )
      if ( status .eq. 0 ) write(*,*) "ok"
      if ( status .ne. 0 ) write(*,*) ’cannot read/write’, status

示例 2:测试文件是否存在:


      INTEGER*4  access, status
      status = access ( ’taccess.data’, ’ ’ )    ! blank mode
      if ( status .eq. 0 ) write(*,*) "file exists"
      if ( status .ne. 0 ) write(*,*) ’no such file’, status

1.4.3 alarm:在指定的时间后调用子例程

该函数的调用方式如下所示:

INTEGER*4 alarm

n = alarm ( time, sbrtn )

time

INTEGER*4

输入 

等待的秒数(0=不调用) 

sbrtn

例程名称 

输入 

要执行的子程序必须列在外部语句中 

返回值 

INTEGER*4

输出 

最后一次报警的剩余时间 

示例:alarm-等待 9 秒后调用 sbrtn


       integer*4 alarm, time / 1 /
       common / alarmcom / i
       external sbrtn
       i = 9
       write(*,*) i
       nseconds =  alarm ( time, sbrtn )
       do n = 1,100000         ! Wait until alarm activates sbrtn.
        r = n              ! (any calculations that take enough time)
        x=sqrt(r)
       end do
       write(*,*) i
       end
       subroutine sbrtn
       common / alarmcom / i
       i = 3                     ! Do no I/O in this routine.
       return
       end

另请参见:alarm(3C)、sleep(3F) 和 signal(3F)。注意以下限制条件:

1.4.4 bit:位函数 andor、…、bitsetbit、…

定义如下:

and( word1, word2 )

对其参数进行按位运算。

or( word1, word2 )

对其参数进行按位运算。

xor( word1, word2 )

对其参数进行按位异或运算。

not( word )

返回其参数的按位结果。

lshift( word, nbits )

结果不循环进位的逻辑左移。

rshift( word, nbits )

带符号扩展的算术右移。

call bis( bitnum, word )

word 中的 bitnum 位设置为 1。

call bic( bitnum, word )

word 中的 bitnum 位清除为 0。

bit( bitnum, word )

测试 word 中的bitnum 位,如果该位是 1,则返回 LOGICAL .true.,如果该位是 0,则返回 .false.

call setbit(bitnum,word,state)

如果 state 是非零值,则将 word 中的 bitnum 位设置为 1,否则将其清除。

MIL-STD-1753 的另一可换用外部版本为:

iand( m, n )

对其参数进行按位运算。

ior( m, n )

对其参数进行按位运算。

ieor( m, n )

对其参数进行按位运算。

ishft( m, k )

结尾不循环进位的逻辑移位(如果 k>0 则为左移,如果 k<0 则为右移)。

ishftc( m, k, ic )

循环移位:m 最右边的 ic 位循环左移 k 个位置。

ibits( m, i, len )

提取位:从 m 中的 i 位开始提取 len 个位。

ibset( m, i )

设置位:返回值等于字 m,且位数 i 设置为 1。

ibclr( m, i )

清除位:返回值等于字 m,且位数 i 设置为 0。

btest( m, i )

测试 m 中的 i 位;如果该位是 1,则返回 LOGICAL .true.,如果该位是 0,则返回 .false.

有关对位字段进行操作的其他函数,另请参见1.4.36 mvbits:移动位字段以及第 2 章和第 3 章。

1.4.4.1 用法:andorxornotrshiftlshift

对于内函数:

x = and( word1, word2 )

x = or( word1, word2 )

x = xor( word1, word2 )

x = not( word )

x = rshift( word, nbits )

x = lshift( word, nbits )

wordword1word2nbits 都是整型输入参数。这些函数是编译器内联扩展的内函数。返回值的数据类型是第一个参数的数据类型。

不测试 nbits 的值是否合理。

示例:andorxornot


demo% cat tandornot.f
        print 1, and(7,4), or(7,4), xor(7,4), not(4)
 1      format(4x ’and(7,4)’, 5x ’or(7,4)’, 4x ’xor(7,4)’,
     1         6x ’not(4)’/4o12.11)
        end
demo% f95 tandornot.f
demo% a.out
    and(7,4)     or(7,4)    xor(7,4)      not(4)
 00000000004 00000000007 00000000003 37777777773
demo%

示例:lshiftrshift


demo% cat tlrshift.f
       integer*4 lshift, rshift
       print 1, lshift(7,1), rshift(4,1)
 1     format(1x ’lshift(7,1)’, 1x ’rshift(4,1)’/2o12.11)
       end
demo% f95 tlrshift.f
demo% a.out
 lshift(7,1) rshift(4,1)
 00000000016 00000000002
demo%

1.4.4.2 用法:bicbisbitsetbit

对于子例程和函数

call bic( bitnum, word )

call bis( bitnum, word )

call setbit( bitnum, word, state )

LOGICAL bit

x = bit( bitnum, word )

bitnumstateword 都是 INTEGER*4 输入参数。函数 bit() 的返回值是逻辑值。

各个位都进行编号,0 位表示最低有效位,31 位表示最高有效位。

bicbissetbit 是外部子例程,bit 是外部函数。

示例 3:bicbissetbitbit


        integer*4 bitnum/2/, state/0/, word/7/
        logical bit
        print 1, word
 1      format(13x ’word’, o12.11)
        call bic( bitnum, word )
        print 2, word
 2      format(’after bic(2,word)’, o12.11)
        call bis( bitnum, word )
        print 3, word
 3      format(’after bis(2,word)’, o12.11)
        call setbit( bitnum, word, state )
        print 4, word
 4      format(’after setbit(2,word,0)’, o12.11)
        print 5, bit(bitnum, word)
 5      format(’bit(2,word)’, L )
        end
<output>
             word 00000000007
after bic(2,word) 00000000003
after bis(2,word) 00000000007
after setbit(2,word,0) 00000000003
bit(2,word) F

1.4.5 chdir:更改缺省目录

该函数的调用方式如下所示:

INTEGER*4 chdir

n = chdir( dirname )

dirname

字符

输入 

目录名称 

返回值 

INTEGER*4

输出 

n=0:OK;n>0:错误代码

示例:chdir-将cwd 更改为 MyDir


       INTEGER*4  chdir, n
       n =  chdir ( ’MyDir’ )
       if ( n .ne. 0 ) stop ’chdir: error’
       end

另请参见:chdir(2)、cd(1) 和 gerror(3F),了解有关错误代码的信息。

路径名长度不能超过 <sys/param.h> 中定义的 MAXPATHLEN 值。路径可以是相对路径,也可以是绝对路径。

使用该函数可能会导致按单元查询失败。

某些 Fortran 文件操作会按文件名重新打开文件。执行 I/O 操作时使用 chdir 可能会导致运行时系统不能跟踪使用相对路径名创建的文件。(包括使用打开语句创建但没有文件名的文件)。

1.4.6 chmod:更改文件的模式

该函数的调用方式如下所示:

INTEGER*4 chmod

n = chmod( name, mode )

name

字符

输入 

路径名 

mode

字符

输入 

chmod(1) 可以识别的任意字符,

例如 o-w444 等。

返回值 

INTEGER*4

输出 

n = 0:OK;n>0:系统错误编号

示例:chmod-添加对 MyFile 的写入权限:


        character*18 name, mode
        INTEGER*4 chmod, n
        name = ’MyFile’
        mode = ’+w’
        n =  chmod( name, mode )
        if ( n .ne. 0 ) stop ’chmod: error’
        end

另请参见:chmod(1) 和 gerror(3F),了解有关错误代码的信息。

路径名长度不能超过 <sys/param.h> 中定义的 MAXPATHLEN 值。路径可以是相对路径,也可以是绝对路径。

1.4.7 date:获取以字符串表示的当前日期


注 –

由于该例程只返回两位数值的年份,因此它存在“2000 年安全”问题。在 1999 年 12 月 31 日之后,使用该例程输出计算日期差异的程序可能无法正常工作。如果执行使用此 date() 例程的程序,第一次调用该例程时会显示运行时警告消息,向用户发出报警。请参见另一个可换用的例程 date_and_time()


该子例程的调用方式如下所示:

call date( c )

c

CHARACTER*9

输出 

变量、数组、数组元素或字符子串 

返回的字符串 c 的格式为 dd-mmm-yy,其中 dd 表示两位数的当月日期,mmm 表示三个字母的月份缩写,yy 表示两位数的年份(因此存在 2000 年安全问题!)。

示例:date


demo% cat dat1.f
* dat1.f -- Get the date as a character string.
        character c*9
        call date ( c )
        write(*,"(’ The date today is: ’, A9 )" ) c
        end
demo% f95 dat1.f
demo% a.out
Computing time differences using the 2 digit year from subroutine
        date is not safe after year 2000.
 The date today is: 9-Jan-02
demo%

另请参见 idate()date_and_time()

1.4.7.1 date_and_time:获取日期和时间

这是一个 2000 年安全的 Fortran 95 内例程。

子例程 date_and_time 返回实时时钟和日期的相关数据。返回数据包括本地时间以及本地时间与通用协调时间 (Universal Coordinated Time, UTC) 之间的时差,通用协调时间也称为格林威治标准时间 (Greenwich Mean Time, GMT)。

子例程 date_and_time() 的调用方式如下:

call date_and_time( date , time, zone, values )

date

CHARACTER*8

输出 

以 CCYYMMDD 格式表示的日期,其中 CCYY 表示四位数的年份,MM 表示两位数的月份,DD 表示两位数的当月日期。例如:19980709 

time

CHARACTER*10

输出 

以 hhmmss.sss 格式表示的当前时间, 其中 hh 表示小时,mm 表示分钟,ss.sss 表示秒和毫秒。 

zone

CHARACTER*5

输出 

与 UTC 的时差,以小时数和分钟数表示,采用 hhmm 格式。 

values

INTEGER*4 VALUES(8)

输出 

下面介绍的 8 个元素组成的整数数组。 

INTEGER*4 values 数组中返回的 8 个值为

VALUES(1)

以 4 位整数表示的年份。例如:1998。 

VALUES(2)

以从 1 到 12 的整数表示的月份。 

VALUES(3)

以从 1 到 31 的整数表示的当月日期。 

VALUES(4)

以分钟数表示的与 UTC 的时差。 

VALUES(5)

以从 1 到 23 的整数表示的当天小时时间。 

VALUES(6)

以从 1 到 59 的整数表示的一个小时中的分钟时间。 

VALUES(7)

以从 0 到 60 的整数表示的一分钟中的秒数。 

VALUES(8)

位于范围 0 至 999 中的毫秒数。 

date_and_time 使用示例:


demo% cat dtm.f
       integer date_time(8)
       character*10 b(3)
       call date_and_time(b(1), b(2), b(3), date_time)
       print *,’date_time    array values:’
       print *,’year=’,date_time(1)
       print *,’month_of_year=’,date_time(2)
       print *,’day_of_month=’,date_time(3)
       print *,’time difference in minutes=’,date_time(4)
       print *,’hour of day=’,date_time(5)
       print *,’minutes of hour=’,date_time(6)
       print *,’seconds of minute=’,date_time(7)
       print *,’milliseconds of second=’,date_time(8)
       print *, ’DATE=’,b(1)
       print *, ’TIME=’,b(2)
       print *, ’ZONE=’,b(3)
       end

2000 年 2 月 16 日在美国加利福尼亚的一台计算机上运行该例程时,输出结果如下所示:


 date_time    array values:
 year= 2000
 month_of_year= 2
 day_of_month= 16
 time difference in minutes= -420
 hour of day= 11
 minutes of hour= 49
 seconds of minute= 29
 milliseconds of second= 236
 DATE=20000216
 TIME=114929.236
 ZONE=-0700

1.4.8 dtimeetime:已用的执行时间

这两个函数的返回值都是已用时间(如果为 -1.0,表示出现错误)。返回的时间以秒数表示。

缺省情况下,Fortran 95 使用的 dtimeetime 版本使用系统的低精度时钟。该精度是百分之一秒。但是,如果在 Sun OSTM 操作系统实用程序 ptime(1) (/usr/proc/bin/ptime) 下运行程序,则使用高精度时钟。

1.4.8.1 dtime:自上次调用 dtime 后已用时间

对于 dtime,已用时间为:

该函数的调用方式如下所示:

e = dtime( tarray )

tarray

real(2)

输出 

e= -1.0:错误:tarray 值未定义

e≠ -1.0:没有错误,tarray(1) 中存储的是用户时间,tarray(2) 中存储的是系统时间

返回值 

real

输出 

e= -1.0:错误

e≠ -1.0:tarray(1)tarray(2) 之和

示例:dtime(),单处理器:


demo% cat tdtime.f
       real e, dtime, t(2)
       print *, ’elapsed:’, e, ’, user:’, t(1), ’, sys:’, t(2)
       do i = 1, 10000
        k=k+1
       end do
       e = dtime( t )
       print *, ’elapsed:’, e, ’, user:’, t(1), ’, sys:’, t(2)
       end
demo% f95 tdtime.f
demo% a.out
elapsed: 0.0E+0 , user: 0.0E+0 , sys: 0.0E+0
 elapsed: 0.03 , user: 0.01 , sys: 0.02
demo%

1.4.8.2 etime:自开始执行后已用时间

对于 etime,已用时间为:

如果环境变量 PARALLELOMP_NUM_THREADS 定义为大于 1 的某个整数值,运行时库就确定程序是在多处理器模式下执行。

该函数的调用方式如下所示:

e = etime( tarray )

tarray

real(2)

输出 

e= -1.0:错误:tarray 值未定义

e≠ -1.0:单处理器:tarray(1) 中存储的是用户时间,tarray(2) 中存储的是系统时间

多处理器:tarray(1) 中存储的是挂钟时间,tarray(2) 中存储的是 0.0

返回值 

real

输出 

e= -1.0:错误

e≠ -1.0:tarray(1)tarray(2) 之和

请注意,初次调用 etime 时所得结果不准确。它只是使系统时钟开始运转。请勿使用初次调用 etime 返回的值。

示例:etime(),单处理器:


demo% cat tetime.f
       real e, etime, t(2)
       e = etime(t)         !  Startup etime - do not use result
       do i = 1, 10000
        k=k+1
       end do
       e = etime( t )
       print *, ’elapsed:’, e, ’, user:’, t(1), ’, sys:’, t(2)
       end
demo% f95 tetime.f
demo% a.out
elapsed: 0.02 , user: 0.01 , sys: 0.01
demo%

另请参见 times(2) 和《Fortran 编程指南》。

1.4.9 exit:终止进程并设置状态

该子例程的调用方式如下所示:

call exit( status )

status

INTEGER*4

输入 

示例:exit()


     ...
       if(dx .lt. 0.) call exit( 0 )
    ...
       end

exit 刷新并关闭进程中的所有文件,然后通知父进程(如果它在执行 wait)。

status 的低 8 位可用于父进程。此时,这 8 位左移 8 位,其他所有位均为零。(因此,status 应介于 256 到 65280 之间。)该调用从不返回任何值。

执行 C 函数 exit 时,可能会在系统最终 'exit' 之前执行清除操作。

调用 exit 时不使用参数会导致出现编译时警告消息,并自动将零作为参数。另请参见:exit(2)、fork(2)、fork(3F)、wait(2) 和 wait(3F)。

1.4.10 fdate:返回以 ASCII 字符串表示的日期和时间

该子例程或函数的调用方式如下所示:

call fdate( string )

string

character*24

输出 

或者:

CHARACTER fdate*24

string = fdate()

如果用作函数,调用例程必须定义 fdate 的类型和大小。

返回值 

character*24

输出 

示例 1:fdate 用作子例程:


       character*24 string
       call fdate( string )
       write(*,*) string
       end

输出:


 Wed Aug  3 15:30:23 1994

示例 2:fdate 用作函数,输出相同:


       character*24 fdate
       write(*,*)  fdate()
       end

另请参见:ctime(3)、time(3F) 和 idate(3F)。

1.4.11 flush:刷新逻辑单元的输出

该函数的调用方式如下所示:

INTEGER*4 flush

n = flush( lunit )

lunit

INTEGER*4

输入 

逻辑单元 

返回值 

INTEGER*4

输出 

n = 0 表示没有错误,n > 0 表示错误编号

flush 函数将逻辑单元 lunit 的缓冲区的内容刷新到关联文件中。逻辑单元 0 和逻辑单元 6 都与控制台终端关联时,该函数对它们特别有用。如果出现错误,该函数返回正的错误编号,否则返回零。

另请参见 fclose(3S)。

1.4.12 fork:创建当前进程的副本

该函数的调用方式如下所示:

INTEGER*4 fork

n = fork()

返回值 

INTEGER*4

输出 

n>0:n 为副本的进程 ID

n<0, n 为系统错误代码

fork 函数创建调用进程的副本。两个进程之间的唯一区别在于返回给其中一个进程(称为进程)的值是副本的进程 ID。副本通常称为进程。返回给子进程的值将为零。

为了避免外部文件中的 I/O 缓冲区内容重复,在执行 fork 操作之前,会刷新所有已开放供写入的逻辑单元。

示例:fork()


       INTEGER*4 fork, pid
       pid = fork()
       if(pid.lt.0) stop ’fork error’
       if(pid.gt.0) then
              print *, ’I am the parent’
       else
              print *, ’I am the child’
       endif

目前尚未提供对应的 exec 例程,这是因为没有一种令人满意的方法能够在整个 exec 例程中保持开放的逻辑单元。但是,可以使用 system(3F) 执行 fork/exec 的常用函数。另请参见:fork(2)、wait(3F)、kill(3F)、system(3F) 和 perror(3F)。

1.4.13 fseekftell:确定文件的位置和复位文件

fseekftell 是用于实现文件复位的例程。ftell 返回文件的当前位置,以距文件开头的字节偏移量表示。在程序中后面某处,fseek 可以使用此保存的偏移值,将文件复位到原来位置以便读取。

1.4.13.1 fseek:将文件复位到逻辑单元中

该函数的调用方式如下所示:

INTEGER*4 fseek

n = fseek( lunit, offset, from )

lunit

INTEGER*4

输入 

开放的逻辑单元 

offset

INTEGER*4

INTEGER*8

输入 

相对于 from 指定位置的字节偏移量

 

如果针对 64 位环境进行了编译,需要 INTEGER*8 偏移值。如果提供了文字常量,它必须是 64 位常量,例如:100_8

from

INTEGER*4

输入 

0=文件开头 

1=当前位置 

2=文件结尾 

返回值 

INTEGER*4

输出 

n=0:OK;n>0:系统错误代码


注 –

对于后续文件,在调用 fseek 后面执行输出操作(例如 WRITE)会导致 fseek 位置后面的所有数据记录被删除,并替换为新的数据记录(以及文件结束标记)。只有在使用直接访问文件时,才能将记录重新写入到位。


示例:fseek()-将 MyFile 复位到距开头两个字节处


        INTEGER*4 fseek, lunit/1/, offset/2/, from/0/, n
        open( UNIT=lunit, FILE=’MyFile’ )
        n = fseek( lunit, offset, from )
        if ( n .gt. 0 ) stop ’fseek error’
        end

示例:同上,但在 64 位环境中,使用 -m64 编译:


        INTEGER*4 fseek, lunit/1/,  from/0/, n
        INTEGER*8 offset/2/
        open( UNIT=lunit, FILE=’MyFile’ )
        n = fseek( lunit, offset, from )
        if ( n .gt. 0 ) stop ’fseek error’
        end

1.4.13.2 ftell:返回文件的当前位置

该函数的调用方式如下所示:

INTEGER*4 ftell

n = ftell( lunit )

lunit

INTEGER*4

输入 

开放的逻辑单元 

返回值 

INTEGER*4

输出 

n>=0:n 为距文件开头的字节偏移量

n<0:n 为系统错误代码

示例:ftell()


       INTEGER*4 ftell, lunit/1/, n
       open( UNIT=lunit, FILE=’MyFile’ )
       ...
       n = ftell( lunit )
       if ( n .lt. 0 ) stop ’ftell error’
       ...

示例:同上,但在 64 位环境中,使用 -m64 编译:


       INTEGER*4 lunit/1/
       INTEGER*8 ftell, n
       open( UNIT=lunit, FILE=’MyFile’ )
       ...
       n = ftell( lunit )
       if ( n .lt. 0 ) stop ’ftell error’
       ...

另请参见 fseek(3S) 和 perror(3F) 以及 fseeko64(3F) 和 ftello64(3F)。

1.4.14 fseeko64ftello64:确定大型文件的位置和复位大型文件

fseeko64ftello64fseekftell 的“大型文件”版本。它们采用并返回 INTEGER*8 的文件位置偏移值。(“大型文件”是指大于 2 GB 的文件,因此字节位置必须以 64 位整型值表示。)可使用这些函数确定大型文件的位置和/或复位大型文件。

1.4.14.1 fseeko64:将文件复位到逻辑单元中

该函数的调用方式如下所示:

INTEGER fseeko64

n = fseeko64( lunit, offset64, from )

lunit

INTEGER*4

输入 

开放的逻辑单元 

offset64

INTEGER*8

输入 

相对于 from 指定位置的 64 位字节偏移量

from

INTEGER*4

输入 

0=文件开头 

1=当前位置 

2=文件结尾 

返回值 

INTEGER*4

输出 

n=0:OK;n>0:系统错误代码


注 –

对于后续文件,在调用 fseeko64 后执行输出操作(例如 WRITE)会导致 fseeko64 位置后面的所有数据记录被删除,并替换为新的数据记录(以及文件结束标记)。只有在使用直接访问文件时,才能将记录重新写入到位。


示例:fseeko64()-将 MyFile 复位到距开头两个字节处:


       INTEGER fseeko64, lunit/1/, from/0/, n
       INTEGER*8 offset/200/
       open( UNIT=lunit, FILE=’MyFile’ )
       n = fseeko64( lunit, offset, from )
       if ( n .gt. 0 ) stop ’fseek error’
       end

1.4.14.2 ftello64:返回文件的当前位置

该函数的调用方式如下所示:

INTEGER*8 ftello64

n = ftello64( lunit )

lunit

INTEGER*4

输入 

开放的逻辑单元 

返回值 

INTEGER*8

输出 

n≥0:n 为距文件开头的字节偏移量

n<0:n 为系统错误代码

示例:ftello64()


       INTEGER*8 ftello64, lunit/1/, n
       open( UNIT=lunit, FILE=’MyFile’ )
       ...
       n = ftello64( lunit )
       if ( n .lt. 0 ) stop ’ftell error’
       ...

1.4.15 getargiargc:获取命令行参数

getargiargc 访问命令行上的参数(在命令行预处理程序扩展后)。

1.4.15.1 getarg:获取命令行参数

该子例程的调用方式如下所示:

call getarg( k, arg )

k

INTEGER*4

输入 

参数索引(0=第一个=命令名称) 

arg

character*n

输出 

k 个参数

n

INTEGER*4

arg 的大小

大得足以容纳最长的参数 

1.4.15.2 iargc:获取命令行参数的数量

该函数的调用方式如下所示:

m = iargc()

返回值 

INTEGER*4

输出 

命令行中参数的数量 

示例:使用 iargcgetarg 获取参数的数量和每个参数:


demo% cat yarg.f
       character argv*10
       INTEGER*4 i, iargc, n
       n = iargc()
       do 1 i = 1, n
         call getarg( i, argv )
 1       write( *, ’( i2, 1x, a )’ ) i, argv
       end
demo% f95 yarg.f
demo% a.out *.f
1 first.f
2 yarg.f

另请参见 execve(2) 和 getenv(3F)。

1.4.16 getcfgetc:获取下一个字符

getcfgetc 从输入流中获取下一个字符。请勿将这些例程的调用与相同逻辑单元中进行的正常 Fortran I/O 混在一起。

1.4.16.1 getc:从 stdin 中获取下一个字符

该函数的调用方式如下所示:

INTEGER*4 getc

status = getc( char )

char

字符

输出 

下一个字符 

返回值 

INTEGER*4

输出 

status=0:OK

status=-1:文件结束

status>0:系统错误代码或 f95 I/O 错误代码

示例:使用 getc 获取从键盘输入的每个字符;请注意 Ctrl-D (^D):


       character char
       INTEGER*4 getc, status
       status = 0
       do while ( status .eq. 0 )
         status = getc( char )
         write(*, ’(i3, o4.3)’) status, char
       end do
       end

编译之后,运行以上源代码的样例如下:


demo% a.out
ab            Program reads letters typed in
0 141         Program outputs status and octal value of the characters entered
0 142            141 represents ’a’, 142 is ’b’
0 012            012 represents the RETURN key
^D               terminated by a CONTROL-D.
-1 377        Next attempt to read returns CONTROL-D
demo%

对于逻辑单元,请勿将正常的 Fortran 输入与 getc() 混在一起。

1.4.16.2 fgetc:从指定逻辑单元中获取下一个字符

该函数的调用方式如下所示:

INTEGER*4 fgetc

status = fgetc( lunit, char )

lunit

INTEGER*4

输入 

逻辑单元 

char

字符

输出 

下一个字符 

返回值 

INTEGER*4

输出 

status=-1:文件结束

status>0:系统错误代码或 f95 I/O 错误代码

示例:使用 fgetctfgetc.data 中获取每个字符;请注意换行 (Octal 012):


       character char
       INTEGER*4 fgetc, status
       open( unit=1, file=’tfgetc.data’ )
       status = 0
       do while ( status .eq. 0 )
          status = fgetc( 1, char )
          write(*, ’(i3, o4.3)’) status, char
       end do
       end

编译之后,运行以上源代码的样例如下:


demo% cat tfgetc.data
ab
yz
demo% a.out
0 141       ”a’ read
0 142       ”b’ read
0 012       linefeed read
0 171       ”y’ read
0 172       ”z’ read
0 012       linefeed read
-1 012      CONTROL-D read
demo%

对于逻辑单元,请勿将正常的 Fortran 输入与 fgetc() 混在一起。

另请参见:getc(3S)、intro(2) 和 perror(3F)。

1.4.17 getcwd:获取当前工作目录的路径

该函数的调用方式如下所示:

INTEGER*4 getcwd

status = getcwd( dirname )

dirname

character*n

输出 

返回当前目录的路径 

当前工作目录的路径名称。n 必须足够大,以便能容纳最长的路径名称

返回值 

INTEGER*4

输出 

status=0:OK

status>0:错误代码

示例:getcwd


       INTEGER*4 getcwd, status
       character*64 dirname
       status = getcwd( dirname )
       if ( status .ne. 0 ) stop ’getcwd: error’
       write(*,*) dirname
       end

另请参见:chdir(3F)、perror(3F) 和 getwd(3)。

注意:路径名长度不能超过 <sys/param.h> 中定义的 MAXPATHLEN 值。

1.4.18 getenv:获取环境变量值

该子例程的调用方式如下所示:

call getenv( ename, evalue )

ename

character*n

输入 

寻找的环境变量名称 

evalue

character*n

输出 

找到的环境变量值,如果不成功,则为空白。 

enameevalue 的大小必须足够大,以便能容纳相应的字符串。

如果 evalue 太短而不能容纳整个字符串值,则字符串将被截断以符合 evalue

子例程 getenv 在环境列表中搜索格式为 ename=evalue 的字符串,如果找到,则通过 evalue 返回值;否则在 evalue 中填入空白。

示例:使用 getenv() 打印 $SHELL 值:


       character*18  evalue
       call getenv( ’SHELL’, evalue )
       write(*,*) "’", evalue, "’"
       end

另请参见:execve(2) 和 environ(5)。

1.4.19 getfd:获取外部单元编号的文件描述符

该函数的调用方式如下所示:

INTEGER*4 getfd

fildes = getfd( unitn )

unitn

INTEGER*4

输入 

外部单元编号 

返回值 

INTEGER*4 INTEGER*8

输出 

如果已连接文件,则返回文件描述符;如果未连接文件,则返回 -1。如果针对 64 位环境进行了编译,返回 INTEGER*8

示例:getfd()


       INTEGER*4 fildes, getfd, unitn/1/
       open( unitn, file=’tgetfd.data’ )
       fildes = getfd( unitn )
       if ( fildes .eq. -1 ) stop ’getfd: file not connected’
       write(*,*) ’file descriptor = ’, fildes
       end

另请参见 open(2)

1.4.20 getfilep:获取外部单元编号的文件指针

该函数为:

irtn = c_read( getfilep( unitn ), inbyte, 1 )

c_read

C 函数 

输入 

用户自己的 C 函数。请参见示例。 

unitn

INTEGER*4

输入 

外部单元编号。 

getfilep

INTEGER*4INTEGER*8

返回值 

如果已连接文件,则返回文件指针;如果未连接文件,则返回 -1。如果针对 64 位环境进行了编译,则返回 INTEGER*8

该函数用于将标准的 Fortran I/O 与 C I/O 混在一起。此类混合不可移植,也不保证在使用后续发行版本的操作系统或 Fortran 时可以进行此操作。建议不要使用该函数,并且没有提供直接的接口。必须创建自己的 C 例程,才能使用 getfilep 返回的值。下面所示是一个 C 例程样例。

示例:Fortran 通过将 getfilep 传递给 C 函数来使用 getfile:


demo% cat tgetfilepF.f

        character*1  inbyte
        integer*4    c_read,  getfilep, unitn / 5 /
        external     getfilep
        write(*,’(a,$)’) ’What is the digit? ’

        irtn = c_read( getfilep( unitn ), inbyte, 1 )

        write(*,9)  inbyte
   9    format(’The digit read by C is ’, a )
        end

实际使用 getfilep 的 C 函数样例:


demo% cat tgetfilepC.c

#include <stdio.h>
int c_read_ ( fd, buf, nbytes, buf_len )
FILE **fd ;
char *buf ;
int *nbytes, buf_len ;
{
         return fread( buf, 1, *nbytes, *fd ) ;
}

下面是编译-生成-运行该函数的样例:


demo% cc -c tgetfilepC.c
demo% f95 tgetfilepC.o tgetfilepF.f
demo% a.out
What is the digit? 3
The digit read by C is 3
demo%

有关更多信息,请参见《Fortran 编程指南》中介绍 C-Fortran 接口的章节。另请参见 open(2)。

1.4.21 getlog:获取用户的登录名

该子例程的调用方式如下所示:

call getlog( name )

name

character*n

输出 

用户的登录名,如果运行的进程已与终端分离,则全为空白。n 应足够大,以便能容纳最长的名称。

示例:getlog


       character*18 name
       call getlog( name )
       write(*,*) "’", name, "’"
       end

另请参见 getlogin(3)。

1.4.22 getpid:获取进程 ID

该函数的调用方式如下所示:

INTEGER*4 getpid

pid = getpid()

返回值 

INTEGER*4

输出 

当前进程的进程 ID。

示例:getpid


       INTEGER*4 getpid, pid
       pid = getpid()
       write(*,*) ’process id = ’, pid
       end

另请参见 getpid(2)。

1.4.23 getuidgetgid:分别获取进程的用户 ID 和组 ID

getuidgetgid 分别获取进程的用户 ID 和组 ID。

1.4.23.1 getuid:获取进程的用户 ID。

该函数的调用方式如下所示:

INTEGER*4 getuid

uid = getuid()

返回值 

INTEGER*4

输出 

进程的用户 ID 

1.4.23.2 getgid:获取进程的组 ID

该函数的调用方式如下所示:

INTEGER*4 getgid

gid = getgid()

返回值 

INTEGER*4

输出 

进程的组 ID 

示例:getuid()getpid()


       INTEGER*4 getuid, getgid, gid, uid
       uid = getuid()
       gid = getgid()
       write(*,*) uid, gid
       end

另请参见:getuid(2)。

1.4.24 hostnm:获取当前主机的名称

该函数的调用方式如下所示:

INTEGER*4 hostnm

status = hostnm( name )

name

character*n

输出 

当前主机系统的名称。n 必须足够大,以便能容纳主机名。

返回值 

INTEGER*4

输出 

status=0:OK

status>0:错误

示例:hostnm()


      INTEGER*4 hostnm, status
      character*8 name
      status = hostnm( name )
      write(*,*) ’host name = "’, name, ’"’
      end

另请参见 gethostname(2)。

1.4.25 idate:返回当前日期

idate 将当前系统日期放入一个整型数组中:日期、月份和年份

该子例程的调用方式如下所示:

call idate( iarray ) 标准版本

iarray

INTEGER*4

输出 

三元素数组:日期、月份和年份 

示例:idate(标准版本):


demo% cat tidate.f
       INTEGER*4 iarray(3)
       call idate( iarray )
       write(*, "(’ The date is: ’,3i5)" )  iarray
       end
demo% f95 tidate.f
demo% a.out
 The date is: 10 8 1998
demo%

1.4.26 ieee_flags、ieee_handler 和 sigfpe:IEEE 算术

这些子程序提供了在 Fortran 程序中充分利用 ANSI/IEEE 标准 754-1985 算术所需的模式和状态。它们与函数 ieee_flags(3M)、ieee_handler(3M) 和 sigfpe(3) 一一对应。

概括介绍如下:

表 1–5 IEEE 算术支持例程

ieeer = ieee_flags( action,mode,in,out )

ieeer = ieee_handler(action,exception,hdl )

ieeer = sigfpe( code, hdl )

action

字符

输入 

code

sigfpe_code_type

输入 

mode

字符

输入 

in

字符

输入 

exception

字符

输入 

hdl

sigfpe_handler_type

输入 

out

字符

输出 

返回值 

INTEGER*4

输出 

有关如何有策略地使用这些函数的详细信息,请参见 Sun 的《数值计算指南》。

如果使用 sigfpe,必须在浮点状态寄存器中设置对应的陷阱-启用-掩码位。SPARC 体系结构手册中介绍了详细信息。libm 函数 ieee_handler 可为您设置这些陷阱-启用-掩码位。

modeexception 接受的字符关键字取决于 action 值。

表 1–6 ieee_flags( action , mode , in , out) 参数和操作

action = 'clearall'

modeinout 未使用;返回 0

action = 'clear'

清除 modein

out 未使用;返回 0

mode = 'direction'

 

mode = 'exception'

in = 'inexact'

'division'

'underflow'

'overflow'

'invalid'

'all'

'common'

action = 'set'

设置浮点 modein

out 未使用;返回 0

mode = 'direction'

in = 'nearest'

'tozero'

'positive'

'negative'

mode = 'exception'

in = 'inexact'

'division'

'underflow'

'overflow'

'invalid'

'all'

'common'

action = 'get'

测试 mode 设置

in 和 out 可为空白或要测试的其中一个设置,返回的当前设置取决于 mode,也可为 'not available'。如果 mode = 'exception',该函数返回 0 或当前异常标志。

mode ='direction'

out = 'nearest'

'tozero'

'positive'

'negative'

mode ='exception'

out = 'inexact'

'division'

'underflow'

'overflow'

'invalid'

'all'

'common'

表 1–7 ieee_handler( action , in , out) 参数

action = 'clear'

清除 in 的用户异常处理;out 未使用

in = 'inexact'

'division'

'underflow'

'overflow'

'invalid'

'all'

'common'

action = 'set'

设置 in 的用户处理异常;out 是处理程序例程的地址,或者是 floating point.h 中定义的 SIGFPE_DEFAULTSIGFPE_ABORT

SIGFPE_IGNORE

in = 'inexact'

'division'

'underflow'

'overflow'

'invalid'

'all'

'common'

示例 1:将舍入方向设置为向零舍入,除非硬件不支持要求的舍入模式:


    INTEGER*4 ieeer
    character*1 mode, out, in
    ieeer = ieee_flags( ’set’, ’direction’, ’tozero’, out )

示例 2:将舍入方向清理为缺省方向(向最近的值舍入):


    character*1 out, in
    ieeer = ieee_flags(’clear’,’direction’, in, out )

示例 3:清除所有由于产生异常而出现的位:


    character*18 out
    ieeer = ieee_flags( ’clear’, ’exception’, ’all’, out )

示例 4:按如下所示检测溢出异常:


    character*18 out
    ieeer = ieee_flags( ’get’, ’exception’, ’overflow’, out )
    if (out .eq. ’overflow’ ) stop ’overflow’

上述代码将 out 设置为 overflow 并将 ieeer 设置为 25(该值视平台而定)。类似的编码可检测异常,例如 invalidinexact

示例 5:hand1.f,编写并使用信号处理程序:


       external hand
       real r / 14.2 /,  s / 0.0 /
       i = ieee_handler( ’set’, ’division’, hand )
       t = r/s
       end

       INTEGER*4 function hand ( sig, sip, uap )
       INTEGER*4 sig, address
       structure /fault/
           INTEGER*4 address
       end structure
       structure /siginfo/
           INTEGER*4 si_signo
           INTEGER*4 si_code
           INTEGER*4 si_errno
           record /fault/ fault
       end structure
       record /siginfo/ sip
       address = sip.fault.address
       write (*,10) address
 10    format(’Exception at hex address ’, z8 )
       end

addressfunction hand 的声明更改为 INTEGER*8,以便示例 5 可以在 64 位 SPARC 环境中使用 (-m64)。

请参见《数值计算指南》。另请参见:floatingpoint(3)、signal(3)、sigfpe(3)、floatingpoint(3F)、ieee_flags(3M) 和 ieee_handler(3M)。

1.4.26.1 floatingpoint.h:Fortran IEEE 定义

头文件 floatingpoint.h 定义了根据 ANSI/IEEE 标准 754-1985 实现标准浮点所使用的常量和类型。

在 Fortran 95 源程序中包含该文件的方式如下所示:


#include "floatingpoint.h"

如果要使用该 include 文件,需在进行 Fortran 编译之前进行预处理。如果引用该 include 文件的源文件的扩展名为 .F.F90.F95,则会自动预处理该文件。

IEEE 舍入模式:

fp_direction_type

IEEE 舍入方向模式的类型。枚举顺序随硬件的不同而异。 

SIGFPE 处理:

sigfpe_code_type

SIGFPE 代码的类型。

sigfpe_handler_type

处理特定的 SIGFPE 代码时调用的用户自定义 SIGFPE 异常处理程序的类型。

SIGFPE_DEFAULT

表示缺省 SIGFPE 异常处理的宏:得到缺省结果时,IEEE 异常继续出现;如果是其他 SIGFPE 代码,IEEE 异常将中止。

SIGFPE_IGNORE

表示另外一种可用的 SIGFPE 异常处理的宏,即忽略异常并继续执行。

SIGFPE_ABORT

表示另外一种可用的 SIGFPE 异常处理的宏,即中止核心转储。

IEEE 异常处理:

N_IEEE_EXCEPTION

不相同的 IEEE 浮点异常数。 

fp_exception_type

N_IEEE_EXCEPTION 异常的类型。每个异常都指定有一个位编号。

fp_exception_field_type

专门用于至少容纳与按 fp_exception_type 列入的 IEEE 异常对应的 N_IEEE_EXCEPTION 位的类型。因此,fp_inexact 对应于最低有效位,fp_invalid 对应于第五个最低有效位。有些操作可以设置多个异常。

IEEE 分类:

fp_class_type

IEEE 浮点值和符号分类的列表。 

请参见《数值计算指南》。另请参见 ieee_environment(3F)。

1.4.27 index、rindex 和 lnblnk:子串的索引或长度

这些函数通过字符串搜索:

index(a1,a2)

字符串 a1 中第一次出现的字符串 a2 的索引

rindex(a1,a2)

字符串 a1 中最后一次出现的字符串 a2 的索引

lnblnk(a1)

字符串 a1 中最后一个非空白字符串的索引

index 有以下几种形式:

1.4.27.1 index:字符串中第一次出现某子串

索引是通过以下方式调用的内函数:

n = index( a1, a2 )

a1

字符

输入 

主字符串 

a2

字符

输入 

子串

返回值 

INTEGER

输出 

n>0:a1 中第一次出现的 a2 的索引

n=0:a2 不在 a1

如果声明了 INTEGER*8,在针对 64 位环境进行了编译且字符变量 a1 是非常大的字符串(大于 2 GB)时,index() 将返回 INTEGER*8 值。

1.4.27.2 rindex:字符串中最后一次出现某子串

该函数的调用方式如下所示:

INTEGER*4 rindex

n = rindex( a1, a2 )

a1

字符

输入 

主字符串 

a2

字符

输入 

子串 

返回值 

INTEGER*4 INTEGER*8

输出 

n>0:a1 中最后一次出现的 a2 的索引

n=0:a2 不在 a1 中,在 64 位环境中返回 INTEGER*8

1.4.27.3 lnblnk:字符串中最后一个非空白字符串

该函数的调用方式如下所示:

n = lnblnk( a1 )

a1

字符

输入 

字符串 

返回值 

INTEGER*4INTEGER*8

输出 

n>0:a1 中最后一个非空白字符串的索引

n=0:a1 全部不为空白,在 64 位环境中返回 INTEGER*8

示例:index()rindex()lnblnk()


demo% cat tindex.f
*                        123456789012345678901
       character s*24 / ’abcPDQxyz...abcPDQxyz’ /
       INTEGER*4 declen, index, first, last, len, lnblnk, rindex
       declen = len( s )
       first = index( s, ’abc’ )
       last = rindex( s, ’abc’ )
       lastnb = lnblnk( s )
       write(*,*) declen, lastnb
       write(*,*) first, last
       end
demo% f95 tindex.f
demo% a.out
24 21     <- declen is 24  because intrinsic len() returns the declared length of  s
1 13

注 –

对于编译为要在 64 位环境中运行的程序,必须将 indexrindexlnblnk(以及它们的接收变量)声明为 INTEGER*8,以便处理非常大的字符串。


1.4.28 inmax:返回最大正整数

该函数的调用方式如下所示:

m = inmax()

返回值 

INTEGER*4

输出 

最大正整数 

示例:inmax


demo% cat tinmax.f
       INTEGER*4 inmax, m
       m = inmax()
       write(*,*) m
       end
demo% f95 tinmax.f
demo% a.out
   2147483647
demo%

另请参见 libm_single(3F) 和 libm_double(3F)。另请参见第 3 章中介绍的 FORTRAN 77 非标准内函数 ephuge()

1.4.29 itime:当前时间

itime 将当前系统时间放入整型数组中:小时、分钟和秒。该子例程的调用方式如下所示:

call itime( iarray )

iarray

INTEGER*4

输出 

三元素数组: 

iarray(1) = 小时

iarray(2) = 分钟

iarray(3) = 秒

示例:itime


demo% cat titime.f
       INTEGER*4 iarray(3)
       call itime( iarray )
       write (*, "(’ The time is: ’,3i5)" )  iarray
       end
demo% f95 titime.f
demo% a.out
 The time is: 15 42 35

另请参见 time(3F)、ctime(3F) 和 fdate(3F)。

1.4.30 kill:向进程发送信号

该函数的调用方式如下所示:

status = kill( pid, signum )

pid

INTEGER*4

输入 

其中一个用户进程的进程 ID。 

signum

INTEGER*4

输入 

有效的信号编号。请参见 signal(3)。

返回值 

INTEGER*4

输出 

status=0:OK

status>0:错误代码

示例(片段):使用 kill() 发送消息:


       INTEGER*4 kill, pid, signum
*    …
       status = kill( pid, signum )
       if ( status .ne. 0 ) stop ’kill: error’
       write(*,*) ’Sent signal ’, signum, ’ to process ’, pid
       end

该函数将信号 signum 和整型信号编号发送到进程 pid。有效的信号编号列在 C include 文件 /usr/include/sys/signal.h 中。

另请参见:kill(2)、signal(3)、signal(3F)、fork(3F) 和 perror(3F)。

1.4.31 linksymlnk:创建指向现有文件的链接

link 创建指向现有文件的链接。symlink 创建指向现有文件的符号链接。

该函数的调用方式如下所示:

status = link( name1, name2 )

INTEGER*4 symlnk

status = symlnk( name1, name2 )

name1

character*n

输入 

现有文件的路径名 

name2

character*n

输入 

要链接到文件 name1 的路径名

name2 不得已存在。

返回值 

INTEGER*4

输出 

status=0:OK

status>0:系统错误代码

1.4.31.1 link:创建指向现有文件的链接

示例 1:link:创建一个指向文件 tlink.db.data.1 的链接 data1


demo% cat tlink.f
        character*34 name1/’tlink.db.data.1’/, name2/’data1’/
        integer*4 link, status
        status = link( name1, name2 )
        if ( status .ne. 0 ) stop ’link: error’
        end
demo% f95 tlink.f
demo% ls -l data1
data1 not found
demo% a.out
demo% ls -l data1
-rw-rw-r-- 2 generic 2 Aug 11 08:50 data1
demo%

1.4.31.2 symlnk::创建指向现有文件的符号链接

示例 2:symlnk:创建一个指向文件 tlink.db.data.1 的符号链接 data1


demo% cat tsymlnk.f
       character*34 name1/’tlink.db.data.1’/, name2/’data1’/
       INTEGER*4 status, symlnk
       status = symlnk( name1, name2 )
       if ( status .ne. 0 ) stop ’symlnk: error’
       end
demo% f95 tsymlnk.f
demo% ls -l data1
data1 not found
demo% a.out
demo% ls -l data1
lrwxrwxrwx 1 generic 15 Aug 11 11:09 data1 -> tlink.db.data.1
demo%

另请参见:link(2)、symlink(2)、perror(3F) 和 unlink(3F)。

注意:路径名长度不能超过 <sys/param.h> 中定义的 MAXPATHLEN 值。

1.4.32 loc:返回对象的地址

该内函数的调用方式如下所示:

k = loc( arg )

arg

任意类型 

输入 

变量或数组 

返回值 

INTEGER*4

INTEGER*8

输出 

arg 的地址

 

如果使用 -m64 进行编译以在 64 位环境中运行,则返回 INTEGER*8 指针。参见下面的说明。

示例:loc


       INTEGER*4 k, loc
       real arg / 9.0 /
       k = loc( arg )
       write(*,*) k
       end

注 –

对于编译为要在 64 位环境中运行的程序,应将接收 loc() 函数输出的变量声明为 INTEGER*8


1.4.33 longshort:整型对象转换

longshort 处理 INTEGER*4INTEGER*2 之间的整型对象转换,在子程序调用列表中特别有用。

1.4.33.1 long:将短整型转换为长整型

该函数的调用方式如下所示:

call ExpecLong( long(int2) )

int2

INTEGER*2

输入 

返回值 

INTEGER*4

输出 

1.4.33.2 short:将长整型转换为短整型

该函数为:

INTEGER*2 short

call ExpecShort( short(int4) )

int4

INTEGER*4

输入 

返回值 

INTEGER*2

输出 

示例(片段):long()short()


       integer*4 int4/8/, long
       integer*2 int2/8/, short
       call ExpecLong( long(int2) )
       call ExpecShort( short(int4) )
       …
       end

ExpecLong 是用户程序调用的某子例程,要使用 long (INTEGER*4) 整型参数。而类似的子例程 ExpecShort 要使用 short (INTEGER*2) 整型参数。

如果在库例程调用中使用了常量且编译代码时使用了 -i2 选项,long 很有用。

在长型对象必须作为短整型传递的这类上下文环境中,short 很有用。将整数传递给幅度太大的短整型虽然不会导致出现错误,但会导致出现未预料的行为。

1.4.34 longjmpisetjmp:返回到由 isetjmp 设置的位置

isetjmplongjmp 设置位置;而 longjmp 返回到该位置。

1.4.34.1 isetjmp:为 longjmp 设置位置

该内函数的调用方式如下所示:

ival = isetjmp( env )

env

INTEGER*4

输出 

env 是由 12 个元素组成的整数数组。在 64 位环境中,它必须声明为 INTEGER*8

返回值 

INTEGER*4

输出 

如果显式调用 isetjmpival = 0

如果通过 longjmp 调用 isetjmpival ≠ 0

1.4.34.2 longjmp:返回到由 isetjmp 设置的位置

该子例程的调用方式如下所示:

call longjmp( env, ival )

env

INTEGER*4

输入 

env 是由 isetjmp 初始化并由 12 个元素组成的整型数组。在 64 位环境中,它必须声明为 INTEGER*8

ival

INTEGER*4

输出 

如果显式调用 isetjmpival = 0

如果通过 longjmp 调用 isetjmpival ≠ 0

说明

isetjmplongjmp 例程用于处理在程序的低级例程中遇到的错误和中断。它们属于 f95 内函数。

如非必要,不应使用这些例程。它们受规范约束,且不可移植。有关错误和其他详细信息,请参见 setjmp(3V) 手册页。

isetjmpenv 中保存堆栈环境。它还会保存寄存器环境。

longjmp 会恢复上次调用 isetjmp 时保存的环境,并以继续执行这种方式返回值,就好像刚执行 isetjmp 调用返回 ival 值一样。

如果未调用 longjmp,从 isetjmp 返回的整型表达式 ival 为零,如果调用了 longjmp,则返回的 ival 不为零。

示例:使用 isetjmplongjmp 的代码片断:


       INTEGER*4  env(12)
       common /jmpblk/ env
       j = isetjmp( env )
       if ( j .eq. 0 ) then
               call  sbrtnA
           else
          call error_processor
       end if
       end
       subroutine sbrtnA
       INTEGER*4  env(12)
       common /jmpblk/ env
       call longjmp( env, ival )
       return
       end

限制

请参见 setjmp(3V)。

1.4.35 mallocmalloc64reallocfree:分配/重新分配/解除分配内存

函数 malloc()malloc64()realloc() 分配内存块并返回块的起始地址。返回值可以用于设置 INTEGER 或 Cray 样式的 POINTER 变量。realloc() 根据新的大小重新分配现有内存块。free() 解除分配由 malloc()malloc64()realloc() 分配的内存块。


注 –

这些例程在 f95 中以内函数实现,而在 f77 中是外部函数。它们不应该出现在 Fortran 95 程序的类型声明和 EXTERNAL 语句中,除非您要使用自己的版本。只有 f95 中实现 realloc() 例程。


符合标准的 Fortran 95 程序应该将 ALLOCATEDEALLOCATE 语句用于 ALLOCATABLE 数组,以便执行动态内存管理,且不能直接调用 malloc/realloc/free

传统的 Fortran 77 程序可以使用 malloc()/malloc64() 为 Cray 样式的 POINTER 变量赋值,这些变量的数据表示形式与 INTEGER 变量的数据表示形式相同。在 f95 中实现了 Cray 样式的 POINTER 变量,以便能够从 Fortran 77 进行移植。

1.4.35.1 malloc malloc64:分配内存

malloc() 函数的调用方式如下所示:

k = malloc( n )

n

INTEGER

输入 

内存的字节数 

返回值 

INTEGER(Cray POINTER)

输出 

k>0:k 为分配的内存块起始位置的地址

k=0:错误

 

如果使用 -m64 针对 64 位环境进行了编译,则返回 INTEGER*8 指针值。参见下面的说明。


注 –

该函数在 Fortran 95 中属于内函数,而在 Fortran 77 中属于外部函数。对于编译为要在 64 位环境中运行的 Fortran 77 程序,应将 malloc() 函数和接收其输出的变量声明为 INTEGER*8。有一个函数 malloc64(3F),它用于实现在 32 位环境与 64 位环境之间移植程序。

k = malloc64( n )

n

INTEGER*8

输入 

内存的字节数 

返回值 

INTEGER*8

(Cray POINTER)

输出 

k>0:k 是分配的内存块起始位置的地址

k=0:错误


这些函数会分配一片内存区域,并返回该区域起始位置的地址。(在 64 位环境中,返回的字节地址可能超出 INTEGER*4 数值范围-必须将接收变量声明为 INTEGER*8 以免内存地址被截断。)内存区域并未以任何方式初始化,因此,不应假设它已预设为什么内容,尤其是零!

示例:使用 malloc() 的代码片段:


       parameter (NX=1000)
       integer ( p2X, X )
       real*4 X(1)
       …
       p2X = malloc( NX*4 )
       if ( p2X .eq. 0 ) stop ’malloc: cannot allocate’
       do 11 i=1,NX
 11         X(i) = 0.
       …
       end

在上面的示例中,获取了 4,000 字节的内存(p2X 指向该内存),并将其初始化为零。

1.4.35.2 realloc:重新分配内存

f95 内函数 realloc() 的调用方式如下所示:

k = realloc(ptr, n )

ptr

INTEGER

输入 

现有内存块的指针。(上次调用 malloc()realloc() 时返回的值)。

n

INTEGER

输入 

请求的新内存块大小(以字节数表示)。 

返回值 

INTEGER

(Cray POINTER)

输出 

k>0:k 是分配的新内存块起始位置的地址

k=0:错误

 

如果使用 -m64 针对 64 位环境进行了编译,则返回 INTEGER*8 指针值。参见下面的说明。

realloc() 函数将 ptr 指向的内存块的大小更改为 n 字节,并返回指向(可能已移动的)新内存块的指针。内存块的内容保存不变,其大小为新内存块大小和旧内存块大小中较小者。

如果 ptr 为零,则 realloc() 的行为与 malloc() 的行为相同,其分配大小为 n 字节的新内存块。

如果 n 为零而 ptr 不为零,则指向的内存块可以进一步进行分配,且仅在终止应用程序后才返回给系统。

示例:使用 malloc()realloc() 以及 Cray 样式的 POINTER 变量:


       PARAMETER (nsize=100001)
       POINTER (p2space,space)
       REAL*4 space(1)

       p2space = malloc(4*nsize)
       if(p2space .eq. 0) STOP ’malloc: cannot allocate space’
       ...
       p2space = realloc(p2space, 9*4*nsize)
       if(p2space .eq. 0) STOP ’realloc: cannot reallocate space’
       ...
       CALL free(p2space)
       ...

请注意,只有 f95 中实现 realloc() 例程。

1.4.35.3 free:解除分配由 Malloc 分配的内存

该子例程的调用方式如下所示:

call free ( ptr )

ptr

Cray POINTER

输入 

free 解除分配先前由 mallocrealloc() 分配的内存区域。此时,该内存区域返回给内存管理器,用户程序不能再使用它。

示例:free()


       real x
       pointer ( ptr, x )
       ptr = malloc ( 10000 )
       call free ( ptr )
       end
 

1.4.36 mvbits:移动位字段

该子例程的调用方式如下所示:

call mvbits( src, ini1, nbits, des, ini2 )

src

INTEGER*4

输入 

来源 

ini1

INTEGER*4

输入 

来源中初始位的位置 

nbits

INTEGER*4

输入 

要移动的位数

des

INTEGER*4

输出 

目标 

ini2

INTEGER*4

输入 

目标中初始位的位置 

示例:mvbits


demo% cat mvb1.f
* mvb1.f -- From src, initial bit 0, move 3 bits to des, initial *           bit 3.
*    src    des
* 543210 543210 <- Bit numbers
* 000111 000001 <- Values before move
* 000111 111001 <- Values after move
       INTEGER*4 src, ini1, nbits, des, ini2
       data src, ini1, nbits, des, ini2
     1    / 7,    0,     3,   1,    3 /
       call mvbits ( src, ini1, nbits, des, ini2 )
       write (*,"(5o3)") src, ini1, nbits, des, ini2
       end
demo% f95 mvb1.f
demo% a.out
  7  0  3 71  3
demo%

请注意以下事项:

1.4.37 perrorgerrorierrno:获取系统错误消息

这些例程执行下列函数:

perror

将消息打印到 Fortran 逻辑单元 0 stderr

gerror

获取(上一次检测到的系统错误的)系统错误消息。 

ierrno

获取上一次检测到的系统错误的错误编号。 

1.4.37.1 perror:将消息打印到逻辑单元 0 stderr

该子例程的调用方式如下所示:

call perror( string )

string

character*n

输入 

消息。它写在上一次检测到的系统错误的标准错误消息前面。 

示例 1:


    call perror( "file is for formatted I/O" )

1.4.37.2 gerror:获取上一次检测到的系统错误的消息

该子例程或函数的调用方式如下所示:

call gerror( string )

string

character*n

输出 

上一次检测到的系统错误的消息 

示例 2:gerror() 用作子例程:


       character string*30
       …
       call gerror ( string )
       write(*,*) string

示例 3:gerror() 用作函数;未使用 string


       character gerror*30, z*30
       …
       z = gerror( )
       write(*,*) z

1.4.37.3 ierrno:获取上一次检测到的系统错误的编号

该函数的调用方式如下所示:

n = ierrno()

返回值 

INTEGER*4

输出 

上一次检测到的系统错误的编号 

该数值只有在真正出现错误时才更新。可能会生成此类错误的大多数例程和 I/O 语句在调用之后会返回错误代码;该值能够比较可靠地反映导致出现错误状况的原因。

示例 4:ierrno()


       INTEGER*4 ierrno, n
       …
       n = ierrno()
       write(*,*) n

另请参见 intro(2) 和 perror(3)。

注意:

1.4.38 putcfputc:向逻辑单元写入字符

putc 向逻辑单元 6 写入(通常是控制终端输出)。

fputc 向逻辑单元写入。

这些函数绕过正常的 Fortran I/O,将字符写入与 Fortran 逻辑单元关联的文件中。

请勿将正常的 Fortran 输出与相同单元中这些函数的输出混在一起。

请注意,要写入任何特殊的 \ 转义符(如换行符 '\n'),需要在编译时使用 FORTRAN 77 兼容选项 -f77=backslash

1.4.38.1 putc:向逻辑单元 6 写入

该函数的调用方式如下所示:

INTEGER*4 putc

status = putc( char )

char

字符

输入 

要写入单元的字符 

返回值 

INTEGER*4

输出 

status=0:OK

status>0:系统错误代码

示例:putc()


demo% cat tputc.f
       character char, s*10 / ’OK by putc’ /
       INTEGER*4 putc, status
       do i = 1, 10
        char = s(i:i)
        status = putc( char )
       end do
       status = putc( ’\n’ )
       end
demo% f95 -f77=backslash tputc.f
demo% a.out
OK by putc
demo%

1.4.38.2 fputc:向指定的逻辑单元写入

该函数的调用方式如下所示:

INTEGER*4 fputc

status = fputc( lunit,char )

lunit

INTEGER*4

输入 

要写入的单元 

char

字符

输入 

要写入单元的字符 

返回值 

INTEGER*4

输出 

status=0:OK

status>0:系统错误代码

示例:fputc()


demo% cat tfputc.f
       character char, s*11 / ’OK by fputc’ /
       INTEGER*4 fputc, status
       open( 1, file=’tfputc.data’)
       do i = 1, 11
        char = s(i:i)
        status = fputc( 1, char )
       end do
       status = fputc( 1, ’\n’ )
       end
demo% f95 -f77=backslash tfputc.f
demo% a.out
demo% cat tfputc.data
OK by fputc
demo%

另请参见 putc(3S)、intro(2) 和 perror(3F)。

1.4.39 qsort 和 qsort64:对一维数组的元素排序

该子例程的调用方式如下所示:

call qsort( array, len, isize, compar )

call qsort64( array, len8, isize8, compar )

array

array

输入 

包含要排序的元素。 

len

INTEGER*4

输入 

数组中的元素数量。 

len8

INTEGER*8

输入 

数组中的元素数量。 

isize

INTEGER*4

输入 

元素的大小,通常: 

4 代表整数或实数 

8 代表双精度或复数 

16 代表双复数 

字符数组的字符对象长度 

isize8

INTEGER*8

输入 

元素的大小,通常: 

4_8 代表整数或实数 

8_8 代表双精度或复数 

16_8 代表双复数 

字符数组的字符对象长度 

compar

函数名 

输入 

用户提供的 INTEGER*2 函数的名称。

确定排序的顺序。compar(arg1,arg2)

可在 64 位环境中将 qsort64 用于大于 2 GB 的数组。请确保将数组长度 len8 和元素大小 isize8 指定为 INTEGER*8 数据。可使用 Fortran 95 样式的常量显式指定 INTEGER*8 常量。

compar(arg1, arg2) 参数是 array 的元素,它返回以下值:

负数 

如果认为 arg1 排在 arg2 前面

零 

如果 arg1arg2 的位置相同

正数 

如果认为 arg1 排在 arg2 后面

例如:


demo% cat tqsort.f
       external compar
       integer*2 compar
       INTEGER*4 array(10)/5,1,9,0,8,7,3,4,6,2/,len/10/,
     1           isize/4/
       call qsort( array, len, isize, compar )
       write(*,’(10i3)’) array
       end
       integer*2 function compar( a, b )
       INTEGER*4 a, b
       if ( a .lt. b ) compar = -1
       if ( a .eq. b ) compar = 0
       if ( a .gt. b ) compar = 1
       return
       end
demo% f95 tqsort.f
demo% a.out
  0 1 2 3 4 5 6 7 8 9

1.4.40 ran:生成介于 0 和 1 之间的随机数

反复调用 ran 可生成一个分布均匀的随机数序列。请参见 lcrans(3m)。

r = ran( i )

i

INTEGER*4

输入 

变量或数组元素 

r

REAL

输出 

变量或数组元素 

示例:ran


demo% cat ran1.f
* ran1.f -- Generate random numbers.
       INTEGER*4 i, n
       real r(10)
       i = 760013
       do n = 1, 10
        r(n) = ran ( i )
       end do
       write ( *, "( 5 f11.6 )" ) r
       end
demo% f95 ran1.f
demo% a.out
   0.222058 0.299851 0.390777 0.607055 0.653188
   0.060174 0.149466 0.444353 0.002982 0.976519
demo%
 

请注意以下事项:


    SEED = 6909 * SEED + 1 (MOD 2**32)

1.4.41 randdrandirand:返回随机值

rand 返回介于 0.0 到 1.0 之间的实数值。

drand 返回介于 0.0 到 1.0 之间的双精度值。

irand 返回介于 0 到 2147483647 之间的正整数。

这些函数使用 random(3) 生成随机数序列。这三个函数共用同一个 256 字节的状态数组。这些函数的唯一优点是它们可以广泛用于 UNIX 系统上。要获得更好的随机数生成器,请比较 lcransaddransshufrans。另请参见 random(3) 和《数值计算指南》。

i = irand( k )

r = rand( k )

d = drand( k )

k

INTEGER*4

输入 

k=0:获取同一序列的下一个随机数

k=1:重新开始序列,返回第一个数

k>0:用作新序列的种子,返回第一个

数 

rand

REAL*4

输出 

 

drand

REAL*8

输出 

 

irand

INTEGER*4

输出 

 

示例:irand()


demo% cat trand.f
       integer*4 v(5), iflag/0/
       do i = 1, 5
        v(i) = irand( iflag )
       end do
       write(*,*) v
       end
demo% f95 trand.f
demo% a.out
   2078917053 143302914 1027100827 1953210302 755253631
demo%
 

1.4.42 rename:重命名文件

该函数的调用方式如下所示:

INTEGER*4 rename

status = rename( from, to )

from

character*n

输入 

现有文件的路径名 

to

character*n

输入 

文件的新路径名称 

返回值 

INTEGER*4

输出 

status=0:OK

status>0:系统错误代码

如果 to 指定的文件已存在,则 fromto 必须属于相同的文件类型,并且必须位于相同的文件系统中。如果 to 已存在,应先将其删除。

示例:rename()-将文件 trename.old 重命名为 trename.new


demo% cat trename.f
       INTEGER*4 rename, status
       character*18 from/’trename.old’/, to/’trename.new’/
       status = rename( from, to )
       if ( status .ne. 0 ) stop ’rename: error’
       end
demo% f95 trename.f
demo% ls trename*
trename.f trename.old
demo% a.out
demo% ls trename*
trename.f trename.new
demo%

另请参见 rename(2) 和 perror(3F)。

注意:路径名长度不能超过 <sys/param.h> 中定义的 MAXPATHLEN 值。

1.4.43 secnds:获取系统时间(秒)减去参数值后所得值

t = secnds( t0 )

t0

REAL

输入 

常量、变量或数组元素 

返回值 

REAL

输出 

自午夜起的秒数减去 t0 所得值

示例:secnds


demo% cat sec1.f
       real elapsed, t0, t1, x, y
       t0 = 0.0
       t1 = secnds( t0 )
       y = 0.1
       do i = 1, 10000
        x = asin( y )
       end do
       elapsed = secnds( t1 )
       write ( *, 1 ) elapsed
  1    format ( ’ 10000 arcsines: ’, f12.6, ’ sec’ )
       end
demo% f95 sec1.f
demo% a.out
 10000 arcsines:     0.009064 sec
demo%

请注意:

1.4.44 set_io_err_handlerget_io_err_handler:设置和获取 I/O 错误处理程序

set_io_err_handler() 声明每当在指定的输入逻辑单元中检测到错误时要调用的用户自定义例程。

get_io_err_handler() 返回当前声明的错误处理例程的地址。

这些例程为模块子例程,只有当调用例程中有 USE SUN_IO_HANDLERS 时,才能访问这些例程。

USE SUN_IO_HANDLERS

call set_io_err_handler(iu, subr_name, istat)

iu

INTEGER*8

输入 

逻辑单元编号 

subr_name

EXTERNAL

输入 

用户提供的错误处理程序子例程的名称。 

istat

INTEGER*4

输出 

返回状态。 

USE SUN_IO_HANDLERS

call get_io_err_handler(iu, subr_pointer, istat)

iu

INTEGER*8

输入 

逻辑单元编号 

subr_pointer

POINTER

输出 

当前声明的处理程序例程的地址。 

istat

INTEGER*4

输出 

返回状态。 

SET_IO_ERR_HANDLER 设置用户提供的子例程 subr_name,它在出现输入错误时用作逻辑单元 iu 的 I/O 错误处理程序。对于格式化的文件,iu 必须是连接的 Fortran 逻辑单元。如果有错误,istat 将设置为非零值,否则设置为零。

例如,如果在打开逻辑单元 iu 之前调用 SET_IO_ERR_HANDLERistat 将设置为 1001(“非法单元”)。如果 subr_name 为 NULL,用户错误处理将关闭,且程序恢复到缺省的 Fortran 错误处理。

可使用 GET_IO_ERR_HANDLER 获取当前用作相应逻辑单元的错误处理程序的函数的地址。例如,先调用 GET_IO_ERR_HANDLER 保存当前 I/O,然后再切换到另一个处理程序例程。以后可以通过保存的值恢复错误处理程序。

subr_name 是用户提供的例程的名称,用于处理逻辑单元 iu 上的 I/O 错误。运行时 I/O 库将所有相关信息传递给 subr_name,以使该例程可以诊断问题并在可能的情况下修复错误,然后继续运行。

用户提供的错误处理程序例程的接口如下所示:

SUBROUTINE SUB_NAME(UNIT, SRC_FILE, SRC_LINE, DATA_FILE, FILE_POS,

CURR_BUFF, CURR_ITEM, CORR_CHAR, CORR_ACTION )

INTENT (IN) UNIT, SRC_FILE, SRC_LINE, DATA_FILE

INTENT (IN) FILE_POS, CURR_BUFF, CURR_ITEM

INTENT (OUT) CORR_CHAR, CORR_ACTION

UNIT

INTEGER*8

输入 

报告错误的输入文件的逻辑单元编号 

SRC_FILE

CHARACTER*(*)

输入 

引起输入操作的 Fortran 源文件名称。 

SRC_LINE

INTEGER*8

输入 

输入操作的 SRC_FILE 中有错误的行号。

DATA_FILE

CHARACTER*(*)

输入 

正在读取的数据文件名称。仅适用于已打开的外部文件。如果名称不可用(例如,逻辑单元 5),DATA_FILE 将设置为长度为零的字符数据项。

FILE_POS

INTEGER*8

输入 

在输入文件中的当前位置(以字节数表示)。只有当 DATA_FILE 的名称已知时,才能定义该项。

CURR_BUFF

CHARACTER*(*)

输入 

包含输入记录中剩余数据的字符串。错误的输入字符是字符串中的第一个字符。 

CURR_ITEM

INTEGER*8

输入 

检测到错误时,记录中已读取的输入项数(包括当前输入项)。例如:READ(12,10)L,(ARR(I),I=1,L)

在此示例中,如果 CURR_ITEM 的值为 15,表示在读取 ARR 的第 14 个元素时出现错误,L 是第一项,ARR(1) 是第二项,依此类推。

CORR_CHAR

CHARACTER

输出 

由处理程序返回的用户所提供的更正字符。只有当 CORR_ACTION 不为零时,才使用该值。如果 CORR_CHAR 是无效字符,将会再次调用处理程序,直到返回有效字符。这可能会导致出现无限循环,用户要防止出现这种情形。

CORR_ACTION

INTEGER

输出 

指定 I/O 库要采取的更正措施。如果值为零,则不采取特殊措施,库将恢复到其缺省的错误处理。如果值为 1CORR_CHAR 将返回到 I/O 错误处理例程。

1.4.44.1 局限性

I/O 处理程序只能用另一个字符替换一次。它不能用多个字符替换一个字符。

错误恢复算法只能修复当前读取的错误字符,而不能修复在其他上下文环境中已经解释为有效字符的错误字符。例如,在进行列表控制的读取时,如果输入是 "1.234509.8765",而正确的输入应该是 "1.2345 9.8765",I/O 库将在第二个阶段遇到错误,因为它不是有效的数字。但此时不能回去将 '0' 更改为空白。

当前,这种错误处理功能不适用于名称列表控制的输入。在进行名称列表控制的输入时,如果出现错误,不会调用指定的 I/O 错误处理程序。

只能为外部文件而不能为内部文件设置 I/O 错误处理程序,这是因为没有与内部文件关联的逻辑单元。

只能针对语法错误而不能针对系统错误或语义错误(例如溢出的输入值)调用 I/O 错误处理程序。

如果用户提供的 I/O 错误处理程序不断向 I/O 库提供错误的字符,从而导致反复调用用户提供的 I/O 错误处理程序,则可能出现无限循环。如果在同一个文件位置反复出现错误,错误处理程序应该自行终止运行。一种解决方法就是通过将 CORR_ACTION 设置为 0 来采用缺省的错误路径。这样,I/O 库将继续运行并进行正常的错误处理。

1.4.45 sh:快速执行 sh 命令

该函数的调用方式如下所示:

INTEGER*4 sh

status = sh( string )

string

character*n

输入 

包含执行命令的字符串 

返回值 

INTEGER*4

输出 

执行的 shell 的退出状态。有关该值的说明,请参见 wait(2)。

示例:sh()


       character*18 string / ’ls > MyOwnFile.names’ /
       INTEGER*4 status, sh
       status = sh( string )
       if ( status .ne. 0 ) stop ’sh: error’
       ...
       end

函数 shstring 作为输入传递给 sh shell,就好像以命令方式键入该字符串。

当前进程将等到命令终止。

函数 sh(3f) 和 system(3f) 将参数字符串传递给 shell 用于执行。它们将参数字符串从 Fortran 字符值转换为 C 字符串值,并将其传递给 C 例程 system(3c)。例程 sh(3f) 和 system(3f) 的不同之处在于,system 在调用 C 例程系统前将刷新 Fortran I/O 缓冲区,而 sh 则不会刷新缓冲区。由于刷新缓冲区需要很长时间,因此,如果 Fortran 输出与调用结果无关,那么优先使用例程 system,而非例程 sh

sh() 函数不能安全地用于多线程程序。请勿从多线程或并行程序中调用该函数。

另请参见:execve(2)、wait(2) 和 system(3c)。

注意:string 不能超过 1,024 个字符。

1.4.46 signal:按信号更改操作

该函数的调用方式如下所示:

INTEGER*4 signal INTEGER*8 signal

n = signal( signum, proc, flag )

signum

INTEGER*4

输入 

信号编号,请参见 signal(3)

proc

例程名称 

输入 

处理例程的用户信号名称;必须在外部语句中。 

flag

INTEGER*4

输入 

flag < 0:将 proc 用作信号处理程序

flag ≥ 0:忽略 proc;传递 flag 来指定操作:

flag = 0:使用缺省操作

flag = 1:忽略该信号

返回值 

INTEGER*4

输出 

n=-1:系统错误

n>0:上一个操作的定义

n>1:n 是本应调用的例程的地址

n<-1:如果 signum 是有效的信号编号:n 是本应调用的例程的地址。如果 signum 不是有效的信号编号:n 是错误编号。

 

INTEGER*8

 

在 64 位环境中,必须将 signal 和接收其输出的变量声明为 INTEGER*8

如果调用 proc,则将信号编号作为整数参数传递给它。

如果进程引发信号,缺省的操作通常是清理并中止。信号处理例程提供了捕捉特定异常或中断以便进行特殊处理的功能。

返回值可以用于后续 signal 调用中,以便恢复以前的操作定义。

即使没有错误,您也有可能会获得负返回值。事实上,如果将有效的信号编号传递给 signal(),获得的返回值小于 -1,这是正常的。

floatingpoint.h 定义 procSIGFPE_DEFAULTSIGFPE_IGNORESIGFPE_ABORT。请参见1.4.26.1 floatingpoint.h:Fortran IEEE 定义

在 64 位环境中,必须将 signal 和接收其输出的变量声明为 INTEGER*8,以免可能返回的地址被截断。

另请参见 kill(1)、signal(3) 和 kill(3F) 以及《数值计算指南》。

1.4.47 sleep:暂停执行一段时间

该子例程的调用方式如下所示:

call sleep( itime )

itime

INTEGER*4

输入 

要休止的秒数 

由于系统守时粒度的影响,实际时间最多可能会比 itime 少 1 秒钟。

示例:sleep()


       INTEGER*4 time / 5 /
       write(*,*) ’Start’
       call sleep( time )
       write(*,*) ’End’
       end

另请参见 sleep(3)。

1.4.48 statlstatfstat:获取文件状态

这些函数返回以下信息:

statlstat 都是按文件名查询。fstat 是按逻辑单元查询。

1.4.48.1 stat:按文件名获取文件状态

该函数的调用方式如下所示:

INTEGER*4 stat

ierr = stat ( name, statb )

name

character*n

输入 

文件的名称 

statb

INTEGER*4

输出 

文件的状态结构,由 13 个元素组成的数组 

返回值 

INTEGER*4

输出 

ierr=0:OK

ierr>0:错误代码

示例 1:stat()


       character name*18 /’MyFile’/
       INTEGER*4 ierr, stat, lunit/1/, statb(13)
       open( unit=lunit, file=name )
       ierr = stat ( name, statb )
       if ( ierr .ne. 0 ) stop ’stat: error’
       write(*,*)’UID of owner = ’,statb(5),’,
     1   blocks = ’,statb(13)
       end

1.4.48.2 fstat:按逻辑单元获取文件状态

该函数的调用方式如下所示:

INTEGER*4 fstat

ierr = fstat ( lunit, statb )

lunit

INTEGER*4

输入 

逻辑单元编号 

statb

INTEGER*4

输出 

文件的状态:由 13 个元素组成的数组 

返回值 

INTEGER*4

输出 

ierr=0:OK

ierr>0:错误代码

示例 2:fstat()


       character name*18 /’MyFile’/
       INTEGER*4 fstat, lunit/1/, statb(13)
       open( unit=lunit, file=name )
       ierr = fstat ( lunit, statb )
       if ( ierr .ne. 0 ) stop ’fstat: error’
       write(*,*)’UID of owner = ’,statb(5),’,
     1      blocks = ’,statb(13)
       end

1.4.48.3 lstat:按文件名获取文件状态

该函数的调用方式如下所示:

ierr = lstat ( name, statb )

name

character*n

输入 

文件名 

statb

INTEGER*4

输出 

文件夹的状态数组,共 13 个元素 

返回值 

INTEGER*4

输出 

ierr=0:OK

ierr>0:错误代码

示例 3:lstat()


       character name*18 /’MyFile’/
       INTEGER*4 lstat, lunit/1/, statb(13)
       open( unit=lunit, file=name )
       ierr = lstat ( name, statb )
       if ( ierr .ne. 0 ) stop ’lstat: error’
       write(*,*)’UID of owner = ’,statb(5),’,
     1   blocks = ’,statb(13)
       end

1.4.48.4 文件状态数组的详细信息

INTEGER*4 数组 statb 中返回的信息的含义在 stat(2) 的 stat 结构中进行了介绍。

备用值不包括在内。顺序如下表所示:

statb(1)

statb(2)

statb(3)

statb(4)

statb(5)

statb(6)

statb(7)

statb(8)

statb(9)

statb(10)

statb(11)

statb(12)

statb(13)

索引节点所在的设备 

相应索引节点的编号 

保护 

文件的硬链接数 

属主的用户 ID 

属主的组 ID 

属于设备的索引节点的设备类型 

文件的总大小 

上次访问文件的时间 

上次修改文件的时间 

上次更改文件状态的时间 

文件系统 I/O 操作的最佳块大小 

分配的实际块数 

另请参见 stat(2)、access(3F)、perror(3F) 和 time(3F)。

注意:路径名长度不能超过 <sys/param.h> 中定义的 MAXPATHLEN 值。

1.4.49 stat64lstat64fstat64:获取文件状态

它们是 statlstatfstat 的 64 位“长文件”版本。除了由 13 个元素组成的数组 statb 必须声明为 INTEGER*8 之外,这些例程与非 64 位例程相同。

1.4.50 system:执行系统命令

该函数的调用方式如下所示:

INTEGER*4 system

status = system( string )

string

character*n

输入 

包含执行命令的字符串 

返回值 

INTEGER*4

输出 

执行的 shell 的退出状态。有关该值的说明,请参见 wait(2)。

示例:system()


       character*8 string / ’ls s*’ /
       INTEGER*4 status, system
       status = system( string )
       if ( status .ne. 0 ) stop ’system: error’
       end

函数 systemstring 作为输入传递给 shell,就好像以命令方式键入该字符串。注意:string 不能超过 1,024 个字符。

如果 system 可以找到环境变量 SHELL,则 system 会将 SHELL 值用作命令解释程序 (shell);否则使用 sh(1)。

当前进程将等到命令终止。

一直以来,对 cc 开发时进行了不同的假设:

system 函数会刷新打开的所有文件:

函数 sh(3f) 和 system(3f) 将参数字符串传递给 shell 用于执行。它们将参数字符串从 Fortran 字符值转换为 C 字符串值,并将其传递给 C 例程 system(3c)。例程 sh(3f) 和 system(3f) 的不同之处在于,system 在调用 C 例程 system 前将刷新 Fortran I/O 缓冲区,而 sh 则不会刷新缓冲区。由于刷新缓冲区需要很长时间,因此,如果 Fortran 输出与调用结果无关,那么优先使用例程 system,而非例程 sh

另请参见:execve(2)、wait(2) 和 system(3)。

system() 函数不能安全地用于多线程程序。请勿从多线程或并行程序中调用该函数。

1.4.51 timectimeltimegmtime:获取系统时间

这些例程具有以下函数:

time

标准版本:获取以整数表示的系统时间(自 GMT 1970 年 1 月 1 日 0 时起至今的秒数)

VMS 版本:获取以字符表示的系统时间 (hh:mm:ss) 

ctime

将系统时间转换为 ASCII 字符串。 

ltime

将系统时间分解成当地时间的月份、日期等等。 

gmtime

将系统时间分解成 GMT 时间的月份、日期等等。 

1.4.51.1 time:获取系统时间

time() 函数的调用方式如下所示:

INTEGER*4 time INTEGER*8

n = time() 标准版本

返回值 

INTEGER*4

输出 

自 GMT 1970 年 1 月 1 日 0:0:0 时起至今的时间(秒) 

 

INTEGER*8

输出 

在 64 位环境中,time 返回 INTEGER*8 值

函数 time() 返回自 GMT 1970 年 1 月 1 日 00:00:00 起至今的时间(秒)整数。这是操作系统时钟值。

示例:在操作系统中使用的 time() 标准版本:


demo% cat ttime.f
        INTEGER*4  n, time
        n = time()
        write(*,*) ’Seconds since 0 1/1/70 GMT = ’, n
        end
demo% f95 ttime.f
demo% a.out
 Seconds since 0 1/1/70 GMT =   913240205
demo%

1.4.51.2 ctime:将系统时间转换为字符

函数 ctime 转换系统时间 stime,并以由 24 个字符组成的 ASCII 字符串返回该值。

该函数的调用方式如下所示:

CHARACTER ctime*24

string = ctime( stime )

stime

INTEGER*4

输入 

通过 time()(标准版本)获得的系统时间

返回值 

character*24

输出 

以字符串表示的系统时间。ctimestring 声明为 character*24

下面的示例中显示了 ctime 返回值的格式。ctime(3C) 手册页中对此进行了介绍。

示例:ctime()


demo% cat tctime.f
        character*24 ctime, string
        INTEGER*4  n, time
        n = time()
        string = ctime( n )
        write(*,*) ’ctime: ’, string
        end
demo% f95 tctime.f
demo% a.out
 ctime: Wed Dec  9 13:50:05 1998
demo%

1.4.51.3 ltime:将系统时间分解成月份、日期等(当地时间)

该例程将系统时间分解成当地时区的月份、日期等。

该子例程的调用方式如下所示:

call ltime( stime, tarray )

stime

INTEGER*4

输入 

通过 time()(标准版本)获得的系统时间

tarray

INTEGER*4(9)

输出 

当地系统时间,包括年份、月份、日期等 

有关 tarray 中各元素的含义,请参见下一节。

示例:ltime()


demo% cat tltime.f
        integer*4  stime, tarray(9), time
        stime = time()
        call ltime( stime, tarray )
        write(*,*) ’ltime: ’, tarray
        end
demo% f95 tltime.f
demo% a.out
 ltime: 25 49 10 12 7 91 1 223 1
demo%

1.4.51.4 gmtime:将系统时间分解成月份、日期等 (GMT)

该例程将系统时间分解成 GMT 时间的月份、日期等。

此子例程的调用方式如下所示:

call gmtime( stime, tarray )

stime

INTEGER*4

输入 

通过 time()(标准版本)获得的系统时间

tarray

INTEGER*4(9)

输出 

GMT 系统时间,包括年份、月份、日期等 

示例:gmtime


demo% cat tgmtime.f
        integer*4  stime, tarray(9), time
        stime = time()
        call gmtime( stime, tarray )
        write(*,*) ’gmtime: ’, tarray
        end
demo% f95t tgmtime.f
demo% a.out
 gmtime:   12  44  19  18  5  94  6  168  0
demo%

下面是 ltimegmtimetarray() 值:索引、单位和范围:

秒 (0 - 61) 

分钟 (0 - 59) 

小时 (0 - 23) 

一个月中的天数 (1 - 31) 

自一月起的月份 (0 - 11) 

年份-1900 

星期几(星期日= 0) 

一年中的天数 (0 - 365) 

夏令时,如果实行夏令时,则为 1。 

C 库例程 ctime(3C) 对这些值进行了定义,它解释了系统可能会返回值大于 59 的秒数的原因。另请参见:idate(3F) 和 fdate(3F)。

1.4.51.5 ctime64gmtime64ltime64:64 位环境的系统时间例程

这些是例程 ctimegmtimeltime 的对应版本,用于在 64 位环境中进行移植。除了输入变量 stime 必须是 INTEGER*8 之外,它们与这些例程相同。

在 32 位环境中使用且 stimeINTEGER*8 时,如果 stime 值超出 INTEGER*4 范围,ctime64 的返回值全是星号,而 gmtimeltime 在 tarray 数组中填入 -1。

1.4.52 ttynamisatty:获取终端端口的名称

ttynamisatty 处理终端端口的名称。

1.4.52.1 ttynam:获取终端端口的名称

函数 ttynam 返回与逻辑单元 lunit 关联的终端设备的空白填充路径名。

该函数的调用方式如下所示:

CHARACTER ttynam*24

name = ttynam( lunit )

lunit

INTEGER*4

输入 

逻辑单元 

返回值 

character*n

输出 

如果返回非空白字符串:namelunit 中设备的路径名。大小 n 必须足够大,以便能容纳最长的路径名。

如果返回空白字符串(全部为空白):lunit 与目录 /dev 中的终端设备没有关联。

1.4.52.2 isatty:确定单元是否为终端

函数 isatty 根据逻辑单元 lunit 是否为终端设备返回 true 或 false。

该函数的调用方式如下所示:

terminal = isatty( lunit )

lunit

INTEGER*4

输入 

逻辑单元 

返回值 

LOGICAL*4

输出 

terminal=true:是终端设备

terminal=false:不是终端设备

示例:确定 lunit 是否为 tty


       character*12 name, ttynam
       INTEGER*4 lunit /5/
       logical*4 isatty, terminal
       terminal = isatty( lunit )
       name = ttynam( lunit )
       write(*,*) ’terminal = ’, terminal, ’, name = "’, name, ’"’
       end

输出为:


 terminal = T, name = "/dev/ttyp1  "

1.4.53 unlink:删除文件

该函数的调用方式如下所示:

INTEGER*4 unlink

n = unlink ( patnam )

patnam

character*n

输入 

文件名 

返回值 

INTEGER*4

输出 

n=0:OK

n>0:错误

函数 unlink 删除由路径名 patnam 指定的文件。如果这是指向该文件的最后一个链接,则该文件的内容将会丢失。

示例:unlink()-删除文件 tunlink.data


demo% cat tunlink.f
       call unlink( ’tunlink.data’ )
       end
demo% f95 tunlink.f
demo% ls tunl*
tunlink.f tunlink.data
demo% a.out
demo% ls tunl*
tunlink.f

另请参见:unlink(2)、link(3F) 和 perror(3F)。注意:路径名长度不能超过 <sys/param.h> 中定义的 MAXPATHLEN 值。

1.4.54 wait:等待进程终止

该函数的调用方式如下:

INTEGER*4 wait

n = wait( status )

status

INTEGER*4

输出 

子进程的终止状态 

返回值 

INTEGER*4

输出 

n>0:子进程的进程 ID。

n<0:n 为系统错误代码;请参见 wait(2)。

wait 暂停调用程序,直到收到信号或其中一个子进程终止。如果自上一次执行 wait 后所有子进程都已终止,则立即返回子进程 ID。如果没有子进程,则立即返回错误代码。

示例:使用 wait() 的代码片段:


       INTEGER*4 n, status, wait
       …
       n = wait( status )
       if ( n .lt. 0 ) stop ’wait: error’
       …
       end

另请参见:wait(2)、signal(3F)、kill(3F) 和 perror(3F)。