[表示 : 全て 最新50 1-99 101- 2chのread.cgiへ]
Update time : 09/20 04:45 / Filesize : 38 KB / Number-of Response : 101
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

くだすれFORTRAN(超初心者用)その4



1 名前:デフォルトの名無しさん [2009/01/24(土) 18:32:01 ]
このスレッドは、他のスレッドでは書き込めない超低レベル、
もしくは質問者自身何が何だか分からない質問を勇気を持って書き込むスレッドです。
FORTRAN使いが優しくコメントを返しますが、
お礼はFORTRANの布教と初心者の救済と次期Fortran2008規格でのCOMEFROM文採用をお願いします。

●注意事項
・質問する前にGoogle等の検索サイトで検索しましょう。
・回答者にわかりやすい様に、質問内容はできる限り詳しく書きましょう。
・エラーの場合は起きた状況、環境(OS・コンパイラ・バージョン)、エラーメッセージも詳しく書きましょう。


●前スレ
くだすれFORTRAN(超初心者用)その3
pc11.2ch.net/test/read.cgi/tech/1196384126/

くだすれFORTRAN(超初心者用)その2
pc11.2ch.net/test/read.cgi/tech/1164121236/

くだすれFORTRAN(超初心者用)
pc8.2ch.net/test/read.cgi/tech/1138063703/


●関連スレ
FORTRAN W
pc11.2ch.net/test/read.cgi/tech/1163319215/


76 名前:69 mailto:sage [2009/02/22(日) 20:12:35 ]
>>75
レスどうもです。
ズバリ75のコードなのですが、私のコンパイラ(Fortran PowerStation 4.0)ではエラーが出ます。
4行めがイカンと言っているようです。

malloc.f90(4):error FOR3435: symbol IMEM is a dummy argument
- cannot be ALLOCATABLE detected between IMEM and (

文法的には間違っていないと思うのですが・・・
別のコンパイラでも試してみようと思います。
コードの調整までして下さり、本当にありがとうございました。


77 名前:デフォルトの名無しさん mailto:sage [2009/02/22(日) 23:41:01 ]
>>76
俺のおぼろげな記憶では、ALLOCATABLE な配列をサブルーチン側で ALLOCATE して
返せるようになったのは Fortran95 以降だった気がする。

Fortran90ではPointerでやるんじゃなかったかな?

文法書で確かめてくれw ガセネタだったらすまんこ。




78 名前:69 mailto:sage [2009/02/23(月) 06:31:29 ]
>>77
統合環境のオンラインマニュアルを良く読むと、以下の記載がありました。
 >Remarks
 >You can only use the ALLOCATABLE attribute to declare an array
 > that is not a dummy argument or a function result.

不注意でしたorz
どうやら仰る通りのようです。ポインタを勉強したいと思います。

実は、先輩がメインフレームで使っていたコードを引き継いだのですが、昔風のメモリ管理を
していて、ブロック名を直接メモリ域に書き込んだりしていたので、PC上ではコンパイル
出来ずに困っていました。それで、Fortran90を使って書きなおそうと考えた次第です。

重ね々々ありがとうございました。


79 名前:デフォルトの名無しさん mailto:sage [2009/02/24(火) 00:15:50 ]
>>78
POINTERに直すだけなら簡単。
ただALLOCATABLEに比べて自由度が大きい分最適化やチェックに支障が出るらし。

MODULE m_test
CONTAINS
subroutine alloc4i(imem, msize)
integer, POINTER :: imem(:)
integer, INTENT(IN) :: msize
if ( .not. ASSOCIATED(imem) ) then
allocate( imem(msize), stat=ier )
if (ier .ne. 0) stop
else
stop
endif
return
end subroutine alloc4i
END MODULE m_test

program mtest
USE m_test
integer, POINTER :: imem1(:), imem2(:)
msize = 100*100 * 200
call alloc4i(imem1, msize)
call alloc4i(imem2, msize)
PRINT *, SIZE(imem1), SIZE(imem2)
stop
end

ASSOCIATED だけでいいのか今一自信なし。

80 名前:69 mailto:sage [2009/02/24(火) 07:04:42 ]
>>79
何から何まで申し訳ありません。
コードはコンパイル1発でOKでした。

allocate後は配列と同じように使えるみたいですし、cのポインタより保護されている感が
あっていいですね。危険性に関しては、昔のメモリマネジメントより随分安全と感じますが、
別ルーチンでしっかりチェックするつもりです。

ただ、f90は利用情報が少ないので、少しずつ勉強しながら使って行こうと思います
(周りに利用者がいない。f77かcかVB)。特にPCの処理系では、方言等ありそうですね。
規格にも目を通したいと思います。

色々とありがとうございました。


81 名前:デフォルトの名無しさん mailto:sage [2009/03/11(水) 02:17:57 ]
モジュールで宣言した変数って自動的にsaveになるんですか?

82 名前:81 mailto:sage [2009/03/12(木) 21:16:17 ]
すいません。>>81は勘違いでした。

もう一つお聞きしたいんですが、INTERFACEって使ってますか?
外部プログラムを書いてから、また同じようなのをイチイチ書くのは
面倒臭いし、モジュールで全部代用できる気がするんですが・・・。



83 名前:81 mailto:sage [2009/03/12(木) 21:27:41 ]
ちなみに何故>>81で勘違いしたかですが、下のようなテストをしたところ
sub2でもi=1だったので、変数iはsave属性なのかと思ったためでした。
同じモジュール中の変数をuseしたから同じもの(実体)を見てるだけで
あって、save属性が付いているわけではない、が正解でしょうか?

以下、ソース(行頭タブは全角スペースにしてます)
module module0
 implicit none
 integer::i
contains
 subroutine set(j)
  integer,intent(in)::j
  i=j
  end subroutine
end module

subroutine sub1
 use module0
 call set(1)
 print *, 'in sub1 : i=' , i
end subroutine

subroutine sub2
 use module0
 print *, 'in sub2 : i=' , i
end subroutine

program main
 call sub1
 call sub2
end program

84 名前:デフォルトの名無しさん mailto:sage [2009/03/13(金) 08:47:00 ]
>>83
変数のスコープや寿命について勉強してみてはどうかな?



85 名前:デフォルトの名無しさん mailto:sage [2009/03/13(金) 13:10:10 ]
>>82
interface は使わないで済む事が多いよね。
pure 属性つけたサブルーチン内で
pure 属性つけたサブルーチンを呼ぶ時には
interface で前もって教えておかないとintel fortran に怒られるようなので
使うけど。これも多分使わないですむやり方がありそうな気もする。
>>83
愛が・・・

86 名前:83 mailto:sage [2009/03/13(金) 14:02:12 ]
どうもmoduleのuseを、Cでいうクラスのインスタンス生成みたいに
考えてたのが混乱の原因だったようです。

で、結局>>83の理解は間違っていますか?
教科書にモジュール変数をグローバル変数とする場合はsaveを付けろと
あるんですが、実際>>83のmodule0のiにsaveを付けても付けなくても、
module0をuseしたプログラムでiの値を確認すると、値が保持されているようです。

87 名前:デフォルトの名無しさん mailto:sage [2009/03/13(金) 22:22:24 ]
>>86
教科書に書いてることは正しい。
Fortranの規格からすると、Module変数はSAVE属性は無い。
Fortran Handbook なんかにもわざわざ書いてある。

本来の規格の上では >>83 でiが消えてもいいように思う。
NAGあたりの規格への忠実さを目指したコンパイラで試してみればいいのではないかと思う。

>>82
INTERFACE は、ソースが無くてバイナリ-だけで配られているような、
ライブラリを呼ぶようなときに必要になるもんだと思う。
ソースが揃っているなら、Moduleにまとめておけばおk?



88 名前:85 [2009/03/14(土) 03:06:21 ]
>>87 の後半
正統なFortranではOKとおもう。が、
ソースが揃ってるか一つのファイルにまとまっているなら interface文は無くてもいい子・・・
と思ってたらifortは文句行ってきた・・。まあ害が無いなら、interface を呼ぶ側でぺたぺた
使ってもいいと思う。
呼ばれるサブルーチンの頭の部分を変更した時に、呼ぶ側全部でそれを意識していたかを確認できるし。
手間が増えるだけな気もするけど、勘違いやバグ防止の対価と思えば高くもない、かな。

89 名前:デフォルトの名無しさん mailto:sage [2009/03/15(日) 02:09:34 ]
>勘違いやバグ防止の対価と思えば高くもない
たしかにそうね
先人が書いた得体の知れないFORTRAN77な外部副プログラムを安全に呼ぶために使う、とか

つーかinterfaceって名前が、javaやc#と意味が全然違くて紛らわしいというか、いまいち気に入らんw

90 名前:83 mailto:sage [2009/03/15(日) 20:19:01 ]
>>87
>本来の規格の上では >>83 でiが消えてもいいように思う。
とすると、>>83は実際には規格外の動作ということですか?
コンパイラはIntel Fortran 10.1です。(確かにintelはけっこう拡張してるからなぁ・・・)

メンバ変数みたいな真似をmoduleでやらせようかと思ってたんですが、
この方法じゃ駄目ぽいですね。そういうオブジェクト指向的なことって
Fortran2003をちゃんと勉強すればできるのかしら・・・?

91 名前:デフォルトの名無しさん [2009/03/16(月) 22:18:43 ]
サブルーチンがたくさんあるプログラムを作る時はmoduleよりもinterfaceの方が良いですか?
module間で相互にmoduleを参照(use)するとエラーが出て、悲しい状態です。
誰か教えてください。
ちなみに、moduleについて詳しく書いてある本があればそれも教えてください。

92 名前:デフォルトの名無しさん mailto:sage [2009/03/17(火) 03:15:21 ]
そのエラーがどんなものか分からないことには何とも・・・

確かにmoduleはよく考えて使わないと面倒な目に合うな
個人的にはFortranやるなら、あんまり細かく部品化しすぎないほうがいいと思う

93 名前:デフォルトの名無しさん mailto:sage [2009/03/17(火) 06:23:06 ]
>>91
module の前方参照のみしか許していないコンパイラーが多いよね。
ソースの前方に書いたmodule だけをuse するようにしてごらん。

94 名前:デフォルトの名無しさん mailto:sage [2009/03/17(火) 14:24:33 ]
>>91
コンパイラは何?



95 名前:91 [2009/03/21(土) 12:36:18 ]
返事遅くなりました。すんません。
>92
サブルーチンは使いまくってます。
サブルーチンがないと不便です…。
>93
前方参照はmoduleをprogramより前に書けってことですよね?
moduleは別ファイルです。こんな感じになってます。
ファイルa.f90
module a
use b
contains
subroutine foo
...
end module a
ファイルb.f90
module b
use a
contains
subroutine bar
...
end module b
わかりにくい質問ですんませんでした。
>94
コンパイラはifort(ver.11)です。

inteface使えよって意見は出ないもんなんですね。
みなさんはサブルーチン使うとき、どうやってるでしょう?

96 名前:デフォルトの名無しさん mailto:sage [2009/03/21(土) 19:50:38 ]
>>91
>module間で相互にmoduleを参照(use)する
相互にuseするのって不可能じゃないの?
コンパイルするときにuseするモジュールの.modファイルが必要だし。
というか、fortranに限らず相互に呼び合うようなのは概念的に許されるのかな・・・?
もし許されるとしても、混乱の元だろうし非常にまずいような・・・・


>inteface使えよって意見は出ないもんなんですね。
>みなさんはサブルーチン使うとき、どうやってるでしょう?
interfaceの主な用途としては、fortran77で書いた外部サブルーチンを
そのままいじらずに、より安全に使いたいとき、などじゃないかな。
形状引継ぎ配列や割付け配列などの機能を使いたいときは、
いずれにしろそのサブルーチンの修正が必要になるので、そのときは大人しく
モジュールで囲ってモジュールサブルーチンに変更すべきかと思うが。

97 名前:91 [2009/03/22(日) 10:19:29 ]
>>96
ありがとうございます。
相互に呼び出さないようにするためにはツリー構造を考えないといけないですね。
ちょっと面倒くさい気がします。

98 名前:デフォルトの名無しさん mailto:sage [2009/03/23(月) 20:26:55 ]
結局>>91のエラーは解決したの?

99 名前:91 mailto:sage [2009/03/24(火) 08:27:42 ]
相互参照しないように書けば、エラーは消えます。
ただ、皆さんがどういう風に対応してるのか知りたかったのです。
お相手ありがとうございました。

100 名前:デフォルトの名無しさん mailto:sage [2009/03/25(水) 12:58:20 ]
>>99
オレ、一個の超特大module にしている。






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧](*・∀・)<38KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef