01: プログラミング言語とは何か 02: 0から99まで印字するプログラムの解説 03: Pythonで書くと... 04: 変数と関数 05: 条件分岐とループ 06: プリプロセス 07: ポインタと配列1 08: ポインタと配列2 09: ポインタと配列3 0A: 文字列 0B: 多次元配列 0C: ファイル入出力 0D: 構造体 0E: コマンドライン引数 0F: 数値を読み込んで総和と平均を表示するプログラム 10: 数値を読み込んで総和と平均を表示するPythonプログラム 11:【番外編】文章中の単語を出現頻度順に表示するプログラム 12:【番外編】コマンドライン引数を処理するイディオム 13:【番外編】C言語でクロージャを実装する
ちょっとは実用的なプログラムを書いてみよう.
数値をだーっと読み込んで,総和と平均を出してみよう.やることは単純だが,ここを出発点にすれば,数値処理がある程度出来るようになるだろう.
まず実数の配列を読むことから始める.というか,いきなり山場である.C言語には可変長の配列が無いため,長さの分からない配列を読むには一工夫がいる.
最大長を決め打ちしてメモリを確保し,ファイルが最大長を越えないことを祈る.
一度ファイルを先頭から読んでいって配列長を確定し,メモリをきっちり確保して,改めてファイルを先頭から読む.
まずはある程度のメモリを確保して置いて,ファイルを読みつつ,配列が足りなくなったらメモリを別途確保する.
後ろに行くほど難易度が高くなる.一番簡単な方法を採用し,祈ることにしよう.(最後の方法は標準C++ライブラリを使うといとも簡単に対応できる.標準C++ライブラリのvectorはいくらでも数値を入れることが出来る.メモリが足りなくなったら,自動的により大きなメモリを確保しなおす.)
#include <stdio.h>
#include <stdlib.h>
void read_from_stdin(int *n_values, double *array) {
*n_values = 0;
while (!feof(stdin)) {
char buff[1000];
double v;
fgets(buff, 1000, stdin);
sscanf(buff, "%lf", &v);
array[n_values] = v;
*n_values += 1;
}
}
この関数read_from_stdinは次のように呼んでやればいい.
int main(int argc, char *argv[]) {
double *a = calloc(10000, sizeof(double));
int n;
read_from_stdin(&n, a);
/* do something */
return 0;
}
計算は /*do something */ の部分でする.まずコードを埋め込まずに独立した関数にしよう.
int main(int argc, char *argv[]) {
double *a = calloc(10000, sizeof(double));
int n;
read_from_stdin(&n, a);
do_something(n, a);
return 0;
}
関数do_somethingは配列の大きさnと配列aを受け取る.総和と平均を求めて印刷すればよいから,次のようなコードになる.
void do_something(int n, const double *a) {
double sum = 0;
int i;
for (i = 0; i < n; i += 1) {
sum += a[i];
}
printf("sum = %f, average = %f\n", sum, sum / n);
}
この関数はmain関数より前に置くこと.