以下のように二次元配列の場合でsubroutineを使うときに、主プログラムで2重Doループ(iとj)で繰り返しをしているのですが、すでにsubroutineでDoループ(i)を用いて計算しています。これではsubroutineの利点をうまく使えていないと思うのですが、subroutineを使って配列、Doループをきれいにする方法をどなたか教えていただけませんか。
実際は4重ループ、4次元配列なので、プログラムをわかりやすくするためにサブルーチンを使いたいと思っています。
--------------------------------------------------------------
program S
real,dimension(5,5) :: B
real,dimension(5) :: A
integer :: i,j
do j=1,5
CALL sub1(A)
do i=1,3
B(i,j)=A(i)*j
write(*,*) B(i,j)
end do
end do
end program S
subroutine sub1(A)
real,dimension(5) :: A
integer :: i
do i=1,3
A(i)=3.*i
end do
end subroutine sub1
No.4ベストアンサー
- 回答日時:
subrountine に限らないんだけど, 基本的に主プログラムと副プログラム (サブルーチンや関数) とは同じ名前であっても違う変数となります (contains で含まれている副プログラムはそれが含むプログラムの変数が使えます). だから, メインの I, F, L などは副プログラム中では全く使っていません.
... っと, 変数が自動生成されているのか. なるほど, サンクスです>#3.
とりあえず, 全てのプログラムで
implicit none
を付けることを強くお勧めします.
ご指摘ありがとうございます。
このプログラムではsubrotineは使わないほうがいい気がしてきました...もう一度subroutineについて勉強してみます。あと、implicit noneも付けてみます。
また、何かあれば質問させていただくと思いますのでその時はどうぞ宜しくお願い致します。
No.3
- 回答日時:
subroutineを使う場合には引数に注意しないと予想と全く結果が異なることになります。
フォートランの参考書はあれば、subroutineの引数についての部分を一度読まれるのがいいでしょう。call test(a1,a2,a3)
subroutine test(b1,b2,b3)
上の場合には
1、a1,a2,a3をsubroutine testに渡す
2、subroutineはb1=a1,b2=a2,b3=a3として計算
3、subrouine内で計算後のb1,b2,b3をa1,a2,a3として返す。
という流れにになります。注意してほしいのはa1,a2,a3以外の変数はsubrutine内で定義しないといけません(0またはとんでもない数字になります)。つまりsubroutineに渡した変数しかmainには返ってきません。なのでsubroutine内で使いたい変数はすべて渡さないとおかしな結果が返ってきます。結果がおかしい原因はここにあると思います。
これはアドバイスですが、sub1をmainや他のsubroutineで呼んでいますがこういうのは慣れてないときはあまりしないほうがいいように思います。処理のフローチャートが非常に複雑になるためです。
No.2
- 回答日時:
メインプログラムにおける 3重ループの意味が見えないんだけど.... write 以外はループの中にいる意味ないのでは?
あと, sub4 で使ってる DIS2 とか DEPTH とかってどこから出てきたんだろう.
そもそもメインから呼び出している sub1, sub4, sub5 などに対する引数が全部違ってるから, 「それぞれ別個に実行しているだけ」ですよね. 「あるsubroutineでDoループで計算したものを受け渡す」ということは全くしていないように見えます.
この回答への補足
おっしゃる通りです。まさに「それぞれ別個に実行しているだけ」になっています...
>メインプログラムにおける 3重ループの意味が見えないんだけど.... write 以外はループの中にいる意味ないのでは?
CALLするときは3重ループの中に書く、書かないで処理の速度は変わってくるのでしょうか。ループの中でCALLしないと変数の(I,F,L)が定まらないと思い、中に書いていました。
>sub4 で使ってる DIS2 とか DEPTH とかってどこから出てきたんだろう
sub4では DIS2、 DEPTHは使わないのですが、どうせほかのルーチンで使うからと思って、sub1に入れてしまいました。
私はsubroutineの使い方を完全に間違っているみたいですね...
「あるsubroutineでDoループで計算したものを受け渡す」ということをしたいのですが、どうしたらそうなるのでしょうか。お手数お掛けして申し訳ありませんが、指南のほどよろしくお願い致します。
No.1
- 回答日時:
あなたのいう「この例では使えていない subrountine の利点」とは何なのでしょうか?
この例だと「j が変わるごとにサブルーチンを呼び出す意味はない」し「サブルーチンの中で do を使う必然性はない」とも言えるので確かに「サブルーチンの利点を使えていない」とはいえそうですが....
この回答への補足
実際は以下のようなプログラムを書いています。
各subroutine内で3重ループ、2重ループを頻繁に用いているのですが、受け渡しがうまくいってないようで、実行しても結果がでるのに半日かかったりします。そして答えも変です。subroutineの利点はただプログラムを見やすくするためであって、あるsubroutineでDoループで計算したものを受け渡すときにはその受け渡されるsubroutineでもまたDoループで計算しなければいけないものなのでしょうか?
program sub_1030_2
real :: SL3=10.
integer :: YR=1
integer :: F,I
real :: L
real,dimension(100) :: DIS2,FE,DEPTH
real,dimension(5,100) :: MTD
real,dimension(10,5,100) :: DR
OPEN(11, FILE='C:\Users\\Documents\究\FORTRAN\fortranopenfile\fortranresult.txt')
do I=1,YR
do F=1,2
do L=1.,SL3
CALL sub1(KE,DIS2,FE,DEPTH)
CALL sub4(MTD)
CALL sub5(DR)
CALL sub11(topPD)
write(11,'(5F15.5)') DIS2(L),FE(L),DEPTH(L),MTD(F,L),DR(I,F,L)
end do
end do
end do
CLOSE(11)
end program sub_1030_2
!-----------------------------------------------------
subroutine sub1(KE,DIS2,FE,DEPTH)
real :: KE
real :: RAIN
real,dimension(100) :: DIS2
real :: L
real :: SL1=100.
real :: DIS1=6.
real,dimension(100) :: FE,DEPTH
RAIN=129.
KE=(12.+9.*LOG10(RAIN))*RAIN/3600.
do L=1.,SL1
DIS2(L)=DIS1*L
FE(L)=(((1./1000.)*10.*DIS2(L)*0.1)/1.)
DEPTH(L)=0.0001*DIS2(L)+0.3
end do
end subroutine sub1
!-----------------------------------------------------
SUBROUTINE sub4(MTD)
real,dimension(5,100) :: MTD
real,dimension(100) :: FE
real :: L
integer :: F
real :: SL1=100.
real,dimension(5) :: P
P(1)=1.
P(2)=2.
do F=1,2
do L=1.,SL1
call sub1(KE,DIS2,FE,DEPTH)
MTD(F,L)=16.*EXP(-0.8*P(F))*FE(L)
end do
end do
end SUBROUTINE sub4
!------------------------------------------------------------
SUBROUTINE sub7(PD) !0年めの粒度分布
real,dimension(10,5,100)::pLEFTw,PD
integer :: F,I
real :: L
real :: SL1=100.
! integer :: YR=1
do I=0,0 !I=0年(侵食される前の初期値)
do L=1.,SL1
do F=1,2
pLEFTw(0,1,L)=200.
pLEFTw(0,2,L)=200.
PD(0,F,L)=pLEFTw(0,F,L)/(pLEFTw(0,1,L)+pLEFTw(0,2,L))
end do
end do
end do
end subroutine sub7
!-------------------------------------------------------------
SUBROUTINE sub5(DR)
real,dimension(100) :: DEPTH
real,dimension(10,5,100) :: DR
integer :: F,I
real :: L,KE,DU
real :: SL1=100.
real,dimension(5) :: P
integer :: YR=1
real,dimension(10,5,100)::PD
P(1)=1.
P(2)=2.
DU=600.
do I=1,YR
do F=1,2
do L=1.,SL1
CALL sub1(KE,DIS2,FE,DEPTH)
CALL sub7(PD)
DR(I,F,L)=((((-1.*LOG(P(F))+2.)/1.6)*KE*DU*EXP(-2.*DEPTH(L)))*0.1)*1.6/1000.*PD(I-1,F,L)
end do
end do
end do
end subroutine sub5
!----------------------------------------------------------
以下省略
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) FORTRAN77の配列(除算) 2 2023/02/01 14:34
- Visual Basic(VBA) ExcelVBAでDo Until loopのネスト、IF文を使って一致する物と一致しない物としたい 11 2022/12/24 17:46
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
- Visual Basic(VBA) Vbaで数式をポーランド記法に変換するコードを作って実行しようとするとフリーズします。 1 2022/05/24 17:53
- Visual Basic(VBA) VBA横データを縦にしたいです 2 2023/08/08 19:38
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- Visual Basic(VBA) vba GetAsyncKeyState関数について 1 2023/08/24 12:08
- Visual Basic(VBA) 【VBA】印刷マクロのループ処理が反映されません 3 2022/08/09 02:15
- Visual Basic(VBA) Excelで下記のようにマクロを作ったところ、一回目は実行できたのですが、二回目以降「実行時エラー1 1 2022/03/25 08:08
- Java Java 南京錠 2 2023/02/04 11:46
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
フローチャートで 変数に代入す...
-
二分法(FORTRAN)
-
フローチャートの菱形が狭い。。。
-
65536は2の何乗なのでしょうか?
-
あるプログラムのコマンドライ...
-
0除算して、落ちるプログラムと...
-
Excelで4096点以上のFFTの方法
-
VBAにてメール作成した際、一部...
-
正しい五十音順について
-
パックマンプログラム
-
Excelに埋め込んだVBAのプログ...
-
Notepad++の関数リスト表示でC...
-
Dijkstraて
-
「Outlookが他のプログラムによ...
-
VBAの再計算が反映されない件に...
-
Visual C++でdebugとreleaseで...
-
変数の値が勝手に変化する原因
-
アルゴリズムとプロトコールの違い
-
main関数を先頭に置くデメリット
-
C言語でのaccess violationに...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
フローチャートの菱形が狭い。。。
-
フローチャートで 変数に代入す...
-
フローチャート以外の設計方法
-
フローチャートで。
-
サブルーチンのフローチャート...
-
Delphiで配列をファイルに出力...
-
フローチャート
-
フローチャートの解き方が分か...
-
C++で二次方程式のプログラム
-
初心者のフローチャート
-
Rの質問です。 x<-rnorm(n=100,...
-
fortran90/95における計算結果...
-
for文のフローチャート
-
FORTRAN★DO WHILE★の問題
-
フローチャート
-
学校でフローチャートって教わ...
-
FORTRAN subroutineと配列と繰...
-
【fortran】フーリエ級数について
-
C言語のプログラミングに関する...
-
正しい五十音順について
おすすめ情報