Another introduction to programming language C 0F: 数値を読み込んで総和と平均を表示するプログラム

ちょっとは実用的なプログラムを書いてみよう.

数値をだーっと読み込んで,総和と平均を出してみよう.やることは単純だが,ここを出発点にすれば,数値処理がある程度出来るようになるだろう.

まず実数の配列を読むことから始める.というか,いきなり山場である.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関数より前に置くこと.
Comments