2. プログラムの作成と実行
まずは計算機が実行するプログラムの作成および実行する方法を学び,Fortranプログラムの基本的な構造について理解しよう.
参考
sample1.f90 : Hello, world
sample2.f90 : Fortranプログラムの基本構造
dot.Xmodmap : CapsLockと左Controlの交換
dot.emacs.el : emacsの設定
2.1. Hello, world !
プログラミング言語を学ぶ時には "Hello, world !" を表示するプログラムから始めるのが慣例になっている.以下に示したものがその最初のプログラムである.
1program sample
2 write(*, *) 'Hello, world !'
3 stop
4endprogram sample
これはソースコードと呼ばれ,人間が読める形式で記述されるテキストファイルである.拡張子はFortran 90/95の場合は .f90
とする [1].プログラムを実行するには,これをコンパイラと呼ばれるプログラムを用いて実行形式(計算機が読み込んで実行することができる形式)に変換してやる必要がある.これをコンパイルと言う.この演習ではgfortranというコンパイラを用いることにしよう.カレントディレクトリに sample1.f90
というファイルがあることを確認して,ターミナルで以下のコマンドを実行しよう.
1$ gfortran sample1.f90
2$ ./a.out
3Hello, world !
1行目でgfortranコマンドによってコンパイルを実行している.コンパイルが成功すると a.out
という名前の実行形式のファイルが作成される.2行目で作成された a.out
を実行し,結果が3行目に表示されている.このように"Hello, world !"が表示されれば成功である.
ちなみに
1$ gfortran sample1.f90 -o hello
のように -o
オプションを使って作成される実行形式のファイル名を指定することが出来る.上の場合は hello
というファイルが作成されるのでこれを実行すると先ほどと同じ結果が得られるはずである.なおコンパイラに渡すことの出来るオプションは他にも山ほど存在するので,興味がある人は
1$ man gfortran
で調べて欲しい.まあよく使うようなオプションはせいぜい数個程度であろう.このように,どんなプログラムであっても基本的にはemacsやvi等のエディタでソースコードを編集し,コンパイル,最後に実行という流れになる [2].
注釈
プログラミングを始めたばかりの時にはコンパイラの吐き出すエラーメッセージの意味が分からず困ってしまうことも多いだろう.そんなときには,まずは落ち着いて英語のメッセージを読んでみよう.何がどうおかしいのかが書いてあるハズである.
なお,コンパイラのエラーメッセージは長くなりがちだが,最初のエラーから解決していったほうがよいことが多い.なぜなら後のエラーは前のエラーに引きずられて発生したものであることが多く,その場合は前が解決されれば自動的に後も解決されるからである.
いずれにせよ,自分で解決できそうもない時には遠慮なく質問しよう.
2.2. ソースコードの基本
以下に示すサンプルを例にとってFortranのソースコードの基本的な構造を説明しよう.
1! これ以降は「コメント」として無視される.
2! ソースコードは人間が直感的に理解できないので, 適宜コメントを入れてプログラムの
3! 内容を理解しやすくすることを推奨.
4! 日本語も入力できるが, 環境によっては文字化けする可能性がある.
5
6program sample ! ここにコメントを書いても良い
7 ! 空行は無視される
8
9 ! 標準出力に文字列を表示(シングルクオートもしくはダブルクオートで囲む)
10 write(*, *) 'Hello, world 2 !'
11
12 ! 複数の文字列や変数をカンマで区切って並べてもよい
13 write(*, *) "This is ", "also ", "OK"
14
15 ! 1文が複数行に渡る場合には `&` を用いる.
16 write(*, *) &
17 & 'This is a continuation line'
18
19 print *, 'This is another way to print out'
20
21 ! プログラムを終了する. 多くの場合無くても構わないがあったほうが無難.
22 stop
23endprogram sample
2.2.1. 使用可能な文字
ソースコードの編集に用いることが出来るのは半角の英数字および下線(アンダースコア)といくつかの四則演算などに使う特殊文字である.(要するに日本語は使えないと思えば良い.) なおFortranは英字の大文字と小文字を区別しない( fortran
,Fortran
,FORTRAN
は全て同一と解釈される)という現代においては大変珍しい言語の一つである.これは歴史的な事情によるものである.古いFortran 77のソースコードには大文字だけで記述されているものも多く存在するが,単に読みにくくなるだけなのでそのような意味のないことはやめよう.
2.2.2. コメント
ソースコードには計算機に実行させる命令だけでなくコメント(注釈)を含めることができる.Fortranでは "!" から行末までがコメントとみなされる.コメントはプログラムの実行とは無関係であり,コンパイル時には単純に無視される.ソースコードはプログラミング言語固有のキーワードなどで記述されているため人間には理解しづらいのに対して,コメントには人間が理解できるように自由に説明を加えることができる.コメントはソースコードの可読性を良くするものなので積極的に活用すべきである [3].なおコメントには日本語を用いても問題ないが,それ以外の部分に日本語を使うとコンパイル時にエラーとなる.特に気づきにくいのがソースコード中に全角スペースが混じってしまってコンパイルが通らないという現象である.エディタにemacsを用いている場合は,後に見るように設定によってこの問題を回避出来る.
2.2.3. プログラムの構造
Fortranのソースコードは以下のように program
と end program
で囲まれる.以下のコードの program_name
は基本的に何でも良く,分り易い名前を付けるのがよい.ただしFortranの予約語( program
などのキーワード)は使えない.また後述の組込み関数と同じ名前にしてしまうとその組込み関数は使えなくなってしまうので注意して欲しい.stop
はプログラムを終了するという意味であり,end program
の直前では省略しても通常は問題無いのだが,入れておいた方がお行儀が良いのでそうしておこう.
1program program_name
2
3 ! ここに処理を記述する
4
5 stop
6end program program_name
また
1write(*,*) 'This will be printed out to the termnal.'
これは
1print *, 'This will be printed out to the termnal.'
と書くこともできる.動作はまったく同じであるので,どちらを用いてもよい.
とすると標準出力(ターミナル)に文字列を表示することができる.write(*,*)
はここではとりあえず文字列を出力するためのオマジナイと思っておいて欲しい.プログラミング言語を学ぶ時にはこの「オマジナイ」というやつが多く出てくるのだが,そのうち意味がわかるようになるので心配しなくて良い.なお read(*,*)
で標準入力(ターミナルからのキーボード入力)を読み込むことが出来るが,これについては変数を学んでから説明しよう.なお先ほどのサンプルの13行目の様に複数の文字列や後で説明する変数をカンマで区切って並べても良い.これを入出力リストと呼ぶ.
2.2.4. 継続行
Fortranでは1行が132文字以下でなければいけないという制限が課せられている.1行に収まらない長い文を記述するには行の最後に &
を記述することで,次の行へと継続することが出来る.実際には80文字とか100文字とか(要するにエディタの表示範囲で)改行する方がプログラムが読みやすくなる.サンプルの16-17行目のような形で記述すればよい.17行目の &
は必ずしも必要では無いが,あった方が読みやすいので入れておくことを推奨する.なおemacsでは改行したい位置で C-c RET
と打つと &
を自動で挿入して字下げまでしてくれる [4].
2.3. ソースコード編集にまつわるエトセトラ †
注釈
2024年現在では以下の内容はかなり古めかしい情報となってしまった.筆者は長年Emacsのヘビーユーザーであったが,現在はsshでログインしたリモートマシンのファイル編集もVS Codeで不自由なくできる時代となってしまたので,久しく emacs
コマンドの実行すらしていない.ただし,キーバインディングはEmacsで使用しているし,ちょっとしたファイル編集にviは頻繁に利用するので,知っておいた方がよいだろう.
ソースコードの編集に用いるソフトウェアはテキスト形式のファイルが編集できるものであればどんなものであっても構わない.しかし世の中には専用に開発された便利なものがあるので利用しない手は無い.この演習ではemacsの使用を推奨することにするが,当然他のエディタを使っても全く問題はない.最近人気のVisual Studio CodeやAtomなどのフリーでクロスプラットホームな高機能エディタを使ってみるのもよいだろう.また,Eclipse等に代表される統合開発環境が好みの人もいるかもしれない.ただし,何を使うにしても大事なのはその機能を使いこなすことが出来るか(使いこなせないのであれば何を使っても同じ)である.
ひとつだけコメントしておくと,将来シミュレーションを生業にしたい人はemacsやviなどのエディタにある程度は慣れておいた方が良いかもしれない.というのは,sshログインしたリモートマシンでソースコードの編集をする機会が多くなると予想されるためである.viはもちろん,emacsでも emacs -nw
でターミナル上でソースコードの編集が可能である.両者とも使いこなすのは難しいが,その機能は折り紙つきなので,興味のある人は自分でどんどん調べてカスタマイズしていくと良い.
以下ではemacsで(Fortranに限らず)ソースコードを編集する際に知っておいた方が良いことや,便利な設定などをほんの一部だけ紹介する.知らなくても効率が悪くなるだけで何かが出来なくなるわけではないので興味のない人は無視してもらって構わない.
2.3.1. Control
と CapsLock
の交換 (setxkbmap)
まずemacsでは Control
をかなり多様するので A
のキーの左の CapsLock
を Control
と交換して使用する人がほとんどである(多分).最近のLinux系のOS環境では CapsLock
と Control
を交換するには
1$ setxkbmap -option ctrl:swapcaps
とするのが手っ取り早い.
このコマンドをログイン時に自動で実行して欲しいわけだが,これには ~/.xsession
や ~/.xinitrc
などのファイルに上記のコマンドを書き込むことで実現出来ることが多い.ただし自動実行の設定は環境依存の話であるので自分の環境に合わせて適宜やり方を調べて欲しい.またこのようなキーボードのカスタマイズの仕方は他にも複数の方法があるので必要な人は自分で調べてみよう.
なお,同様にviユーザーは Escape
を多用するのでスペースキーの左もしくは右のキー(普通の日本語キーボードでは「無変換」とか「変換」)を Escape
として使う人が多いようである.
2.3.2. Control
と CapsLock
の交換 (古い方法)
以下の方法は古典的な方法で,最近の環境では必要ない(というか紛らわしい)情報かもしれないが,念のため残しておく.
Linux系の環境では xmodmap
というコマンドでキーボードのカスタマイズが出来る.ホームディレクトリに .Xmodmap
というファイルを作り,以下の様な内容で保存する.
1remove Lock = Caps_Lock
2remove Control = Control_L
3keycode 37 = Caps_Lock
4keycode 66 = Control_L
5add Lock = Caps_Lock
6add Control = Control_L
そして
1$ xmodmap ~/.Xmodmap
というコマンドを実行すると CapsLock
と 左の Control
キーが交換されたハズだ.ログイン時に自動でこのコマンドを実行するように設定しておけば便利である.
2.3.3. 基本的な編集作業
まずマウスを使わずに作業できるようになることを目標にしよう.なぜなら将来リモートマシンにログインして作業する際にはマウスを使うことは出来ないからだ [5].
既にこれまでの演習で学んだことだとは思うがemacsでは( Control
キーと CapsLock
を交換しておけば)キーボードのホームポジションから手を動かさずに全ての作業が出来るようになっている.これにはカーソルキーに対応する C-n
(↓ next-line
),C-p
(↑ previous-line
),C-f
(→ forward-char
),C-b
(← backward-char
),と Delete
キーに対応する C-h
は必須である.また C-a
(行頭へ移動),C-e
(行末へ移動) や,C-k
(カーソルから行末までを削除) もよく使うので覚えておこう.ちなみにemacsとは関係無いが,多くの環境で Alt-Tabによってウィンドウの切り替えが出来る.またターミナルでのコマンドライン編集時にもemacsと同じキーバインドが使える場合が多いので,これらを覚えておくだけでマウスの使用頻度が激減すること請け合いである.
viユーザーの名誉のために述べておくと,当然のようにviでも( Escape
の場所を適切にしておけば)ホームポジションから一切手を動かす必要が無い.更に言うとviでは片手でコーヒーを飲みながらカーソル移動が出来るので,少なくともこの点ではviの方が優れている(なので余裕があればviも勉強しよう).
2.3.4. Tabの利用
ソースコードは適切に字下げされていると格段に見やすくなるし,明らかな文法間違いに気づくきっかけにもなるので字下げの徹底を強く推奨する.emacsでは Tabキーを押すと自動でカーソルのある行の字下げをしてくれる.複数行を一気に字下げしたい場合には字下げしたい領域を選択して M-x indent-region
もしくは M-C-\
で選択された領域の字下げが出来る.ファイル全体を字下げしたい時には C-x h M-C-\
とすれば良い.
またFortranは program
に限らず,実行ブロックが end ???
で終わるようになっている.emacsでは end
まで入力した状態でTabキーを押すと自動で end
の後に適切なキーワードを挿入してくれる.(例えば program sample
の場合はTabキーによって end
の後に program sample
が挿入される.) これは非常に便利なので是非利用して欲しい.
2.3.5. コメントアウト
ソースコードを編集していると(特にデバッグ中は)複数行をまとめてコメントアウトしたいことが多々ある.そんな時に各行の先頭にいちいち"!"を挿入するのはバカバカしい.emacsでは領域を選択して M-x comment-region
とするとまとめてコメントアウトしてくれるようになっている.ちなみにコメントアウトした領域を元に戻す時は M-x uncomment-region
とすれば良い.なお多くのemacsのデフォルト環境で .f90
のファイルを開いた場合には(自動でf90-modeというモードになり) C-;
が M-x comment-region
に設定されている.同様に C-u C-;
が M-x uncomment-region
である.
2.3.6. 全角スペースの表示
前述の通りソースコードに全角スペースが含まれているとコンパイルが出来ない(しかもエラーメッセージからはそれが分からない)という厄介な問題が存在する.これは初心者ほど陥りやすい罠であるが,emacsの設定でこの問題を回避することが出来る.例えば以下の様な設定を .emacs
などの設定ファイルに書いておくと全角スペースが "□" と表示されるので一目瞭然である.
1(require 'whitespace)
2(setq whitespace-style '(face trailing spaces tabs space-mark tab-mark))
3(setq whitespace-space-regexp "\\(\x3000+\\)")
4(setq whitespace-display-mappings
5 '((space-mark ?\x3000 [?\□])
6 (tab-mark ?\t [?\xBB ?\t])
7 ))
8(setq fgcolor "RosyBrown1")
9(setq bgcolor "blue3")
10(set-face-attribute 'whitespace-trailing nil
11 :foreground fgcolor
12 :background bgcolor
13 :underline t)
14(set-face-attribute 'whitespace-empty nil
15 :background bgcolor)
16(global-whitespace-mode t)
なお上の設定では行末のスペースやタブなども表示するように設定されているが,このあたりは完全に好みである.以下はemacsでソースコードを編集中のスクリーンショットである.
2.3.7. 複数ファイルの編集
真のemacs使いはいちいちemacsを立ち上げたり終了したりはしない.常にemacsを立ち上げておき,複数のファイル(emacsではバッファと呼ぶ)を縦横無尽に切り替えながら編集するのである [6].C-x f
で新しいファイルを開くことは当然出来るとして,過去に編集していたバッファに切り替える方法を覚えておこう.C-x b
でミニバッファに既に開いているバッファ名(ファイル名)を入力するとそのバッファに移ることが出来る.またTabによる補完も使うことが出来る.C-x C-b
では現在開いているバッファの一覧が表示され,選択することでそのバッファに移ることが出来る.
なお最近ではemacsにもタブ(タブブラウザのあれである)を導入することが出来るらしい.興味のある人は tabbar.el
で調べてみよう.
2.3.8. まとめ
細かいことはどうでもいいという実践派の人は以下の表を頭に入れておけばよい.正確には体が勝手に覚えるものなのだが.
キーバインド |
説明 |
---|---|
|
上へ移動 |
|
下へ移動 |
|
右へ移動 |
|
左へ移動 |
|
行頭へ移動 |
|
行末へ移動 |
|
|
|
カーソル位置から行末までを削除 |
|
領域選択を開始 |
|
選択範囲を切り取り |
|
選択範囲をコピー |
|
コピーした内容を貼り付け |
|
選択領域をコメントアウト |
|
選択されたコメントアウトされている領域のコメントを外す |
|
継続行の挿入 |
|
選択された領域の字下げ |
|
ファイルの全てを選択して字下げ |
|
ファイルを開く |
|
バッファの切替え |
|
バッファ一覧の表示 |
|
前方検索 |
|
後方検索 |
|
置換(置換前にその都度確認をする) |
2.4. 第2章 演習課題
参考
2.4.1. 課題1
サンプルプログラムをコンパイル・実行して動作を確認せよ.
2.4.2. 課題2
サンプルプログラムをエディタで修正,コンパイルし、実行して結果を確認せよ.例えば sample1.f90 の出力を Hello, Fortran !
に変更して出力を確認せよ.
2.4.3. 課題3 †
本演習では扱わないが,C言語やPythonの場合についてもプログラムの実行の方法も知っておこう.
C言語はFortranと同じようにコンパイル言語なので,ソースをコンパイルして実行する.C言語のコンパイラとしては gcc
を用いることが出来る.ここでは hello.c をコンパイル,実行してみよう.
1$ gcc hello.c
2$ ./a.out
3Hello, world !
このように,コンパイラのコマンドとして gcc
を使うこと以外は基本的に同じである.
Pythonはスクリプト言語と呼ばれ,コンパイルが必要なく,直接ソースから実行することが出来る.ここでは hello.py を実行してみよう.
1$ python hello.py
2Hello, world !
また,hello.pyに実行権限があれば直接実行することもできる.実行権限を付与するには
1$ chmod 755 hello.py
などとすればよい.このときは
1$ ./hello.py
2Hello, world !
のように実行することができるだろう.
プログラムの規模が大きくなってくると,次第にコンパイルにも時間がかかるようになってくるが,Pythonのような言語ではコンパイルの必要がないことが大きな利点となる.一方で実行速度は(書き方に大きく依存するものの)C言語やFortranの方が一般には高速である.