Fortran でも C/C++ でも、数値計算をする上で基本になるデータ構造は多く の場合に配列である。
// calculate_sum #include <iostream> using namespace std; int main() { int n ; int data[100]; int i,sum; cout << "How many numbers you want to input?"; cin >> n; for (i=0;i<n;i++) cin >>data[i]; sum = 0; for (i=0;i<n;i++){ sum += data[i]; cout << "data[" << i <<"]=" << data[i] << " sum=" << sum << endl; } }
これは配列を使う簡単な例である。
int data[100] ;と変数宣言で書くと、100個の整数型変数ができ、それぞれが data[0] から data[99] までといった風に、番号で指定して操作 できる。
これはもちろん Fortran で
integer data(100)と書くのとほとんど変わらないが、どうでもいいような違いがいくつかある。
integer data(0:100)といった具合に「最初と最後」を指定できるので、実は 1 から始めないとい けないというわけではない。しかし、 C/C++ の場合には必ず 0 から始まり、 それを変更する方法はない。
宣言はFortran では
integer data(100,100)とか書いたが、C/C++ では
int data[100][100];と書く。使い方も同様に Fortran では data(i,j) のところを data[i][j] と書く。次元が増えても同様である。 Fortran では配列の次元 は 7 次元までとかいう制限があるが、 C/C++ では特に制限はない。
なお、他にも細かく違うところはある。実用上で大事なのは、メモリ上にデー タがしまわれる順番である。 1 次元配列ではもちろん配列要素が順にメモリ 上におかれるが、2次元配列では 2 つの可能性がある。つまり、最初の要素 data(1,1) あるいは data[0][0] の次に来るのがなにか?であ る。 Fortran では data(2,1) が来るが、C/C++ではdata[0][1] が来る。この違いは、いろいろな場面で意識する必要がある。
なお、このC の言語仕様で定義された普通の配列に関する限り、 C/C++ の多 次元配列には Fortran のそれに比べた大きな欠点がある。 それは、関数の引数として配列を渡す時に、大きさを変数として渡すことがで きないということである。つまり、 Fortran では
subroutine sub1(a, n, nn) integer n, nn real*8 a(nn,nn) .....といった形で、次元ごとの大きさを引数として渡すことができる。このために、 汎用の行列計算や連立一次方程式の解法などのサブルーチンを準備するのが容 易である。ところが、 C/C++ では引数としては渡せないので話が面倒になる。 もっとも、Cの最新の言語仕様ではこれが可能になっているが、現在のところ存在 するほとんどのプログラムはこの機能を使わないで書かれている。
もっとも、これはあくまでも汎用のライブラリを準備し、しかもそれをソース プログラムとしてではなくあらかじめコンパイルしたいわゆるバイナリライブ ラリとして準備する時にだけ問題になることではある。従って、自分でプログ ラムを書く場合にはあまり問題にはならない。
コンパイルしたライブラリを作るにはいろいろな方法がある。 C++ では、ユー ザーが新しいデータ型を定義することができるので、自分で定義してしまえば Fortran の配列よりももっと便利に使えるものができる。また、既に人が作っ た便利なものがいろいろあるので、高度なことをするにはそういったものの利 用を考えるベきである。
配列を使う例だが、 計算天文学とはいえ、数値計算ばかりでも芸がないので、ここではちょっと違 うこともやってみよう。
// sort.C #include <iostream> using namespace std; double data[100]; int main() { int n; int i,j; cin >> n; for (i=0;i<n;i++)cin >> data[i]; cout << "Input data\n"; for (i=0;i<n;i++) cout << data[i]<<endl; for (i=0;i<n-1;i++){ for (j=i+1;j<n;j++){ if (data[i] > data[j]){ double work; work = data[i]; data[i] = data[j]; data[j]= work; } } } cout << "Sorted data\n"; for (i=0;i<n;i++) cout << data[i] << endl; return 0; }
このプログラムは、入力した数を小さい順に並べ変えて出力する。並べ変える 原理は、以下のようなものである。
このプログラムを実行するには、まずデータファイルを別にエディタで作って おく。これは先頭にデータ数を書き、後は一行に一つ数字を書いておけばいい。このデータファイルの名前 を sample.dat、コンパイルしてできた実行ファイルの名前を simple_sort とすれば、
simple_sort < sample.datとシェルウインドウで入力すれば結果が得られるはずである。
なお、あるプログラムの実行時間を計るには time コマンドが使える。
time simple_sort < sample.dat という風に入力すると、実行結果のあとにもう一行 0.040u 0.080s 0:00.56 21.4% 0+135k 2+0io 21pf+0w
というような出力が出てくる。この最初の数字が秒単位の実行時間である。な お、実際にかかった時間はもっと長いことがあり得る。これは、ファイルの読 み書きの時間は正確には入らないこと、また何人かで1台の計算機を使ってい るとその分余計に時間がかかることによる。