Fortran Coder

查看: 23683|回复: 9
打印 上一主题 下一主题

[讨论] 关于Fortran的赋值

[复制链接]

69

帖子

7

主题

0

精华

专家

F 币
320 元
贡献
224 点
跳转到指定楼层
楼主
发表于 2014-2-25 10:30:41 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 jason388 于 2014-2-25 10:31 编辑

Fortran标准对赋值(variable=expr)运算定义了三步操作:
1. 计算表达式expr及variable中的所有表达式;
2. 如果expr运算结果的类型或类型参数与variable不同,则将其转化为与variable相同;
3. 按上面计算结果定义variable。
理解了上面的定义,下面的例子不言自明:

[Fortran] 纯文本查看 复制代码
program test_assignment
implicit none
integer :: a(10,10)=1,b(10,10)=2
integer :: v(10)=[2,1,4,6,2,10,7,9,8,1]
integer :: i,j,n=10
integer, allocatable :: c(:)
real(kind=8) :: x,y

x=3.141592653589793; y=3.141592653589793_8
print '(2(a,g0,x),/)',"x=",x,"y=",y

x=1/2+x/2; y=1.0_8/2+y/2;
print '(2(a,g0,x),/)',"x=",x,"y=",y

forall(i=2:n-1,j=2:n-1)
  a(i,j)=a(i,j-1)+a(i,j+1)+a(i-1,j)+a(i+1,j)
  b(i,j)=a(i,j)
end forall
print '(a/,10(i0,x))',"b=",(b(i,:),i=1,n)

forall(i=1:10)a(i,:)=i
print '(/a/,10(i0,x))',"a(:,1)=",a(:,1)

a(:, 1)=a(v(:),1)
print '(/a/,10(i0,x))',"a(:,1)=",a(:,1)

allocate(c(5))
c=3
c=v
print '(/a/,10(i0,x))',"c=",c
deallocate(c)
end program test_assignment


用gfortran编译,其计算结果为:
x=3.1415927410125732 y=3.1415926535897931

x=1.5707963705062866 y=2.0707963267948966

b=
2 2 2 2 2 2 2 2 2 2
2 4 4 4 4 4 4 4 4 2
2 4 4 4 4 4 4 4 4 2
2 4 4 4 4 4 4 4 4 2
2 4 4 4 4 4 4 4 4 2
2 4 4 4 4 4 4 4 4 2
2 4 4 4 4 4 4 4 4 2
2 4 4 4 4 4 4 4 4 2
2 4 4 4 4 4 4 4 4 2
2 2 2 2 2 2 2 2 2 2

a(:,1)=
1 2 3 4 5 6 7 8 9 10

a(:,1)=
2 1 4 6 2 10 7 9 8 1

c=
2 1 4 6 2 10 7 9 8 1


分享到:  微信微信
收藏收藏1 点赞点赞 点踩点踩

69

帖子

7

主题

0

精华

专家

F 币
320 元
贡献
224 点
沙发
 楼主| 发表于 2014-2-26 08:19:54 | 显示全部楼层
本帖最后由 jason388 于 2014-2-26 08:40 编辑
chuxf 发表于 2014-2-25 11:22
jason 的帖子非常好,不但说明了赋值中的类型精度问题,还说明了 forall 的一些用法。值得好好琢磨一下。

...

1. 对于有一定规模的程序确实不应用(kind=8)这种采用具体数字定义类型参数的形式,而应采用selected系列函数。
比如对于单精度和双精度的下列定义是不依赖于任何编译器和机器类型的:
[Fortran] 纯文本查看 复制代码
integer,parameter :: sgl=selected_real_kind(p=6)
integer,parameter :: dbl=selected_real_kind(p=13)
real(kind=sgl) :: pi1=3.14159_sgl
real(kind=dbl) :: pi2=3.14159265_dbl

2. forall和where结构本质上是赋值操作,这里以forall举例一是说明数组赋值的方法,二是强调forall的赋值性质。
3. 前两个例子是初学者非常容易忽略的地方,在较大规模程序中这样的问题一般还不容易发现,所以这里特别予以强调。
4. 严格说起来,字面常数(literal constant)最好都给出类型参数,避免因为编译器内部转换等原因而达不到本来的意图。

69

帖子

7

主题

0

精华

专家

F 币
320 元
贡献
224 点
板凳
 楼主| 发表于 2014-3-1 09:19:47 | 显示全部楼层
fcode 发表于 2014-2-26 09:58
感谢jason分享您的经验。

要让大伙养成这些好的习惯,恐怕还需要一个过程。 ...

Fortran90一直到2008标准新增的功能使Fortran真正进化为一种功能强大的Formula Translation语言,真正对Fortran感兴趣的人确实需要好好地学习一下这些新增的功能并在新的程序中实践之,个人觉得用新标准写的代码相对其他语言(包括f77)更加简洁、容易理解且充满美感。

但遗憾的是大部分同学估计都是为了应付学业才接触Fortran代码而非对其真正感兴趣的,这也就是到现在还在用那些老掉牙的编译器以及讨论f77代码不断的原因吧。

69

帖子

7

主题

0

精华

专家

F 币
320 元
贡献
224 点
地板
 楼主| 发表于 2014-3-1 09:53:14 | 显示全部楼层
fcode 发表于 2014-3-1 09:36
jason 说得没错,对此我也表示很遗憾。

建立这个网站和论坛,一方面是QQ群有归档常见问题和讨论的需求, ...

争取有时间时努力下。虽然用F95好多年了,但认真学习2003和2008标准也是最近才开始的。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-5-4 22:15

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表