レポート課題の雛形

No.3

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/*	
  ここに関数のプロトタイプ宣言を書く
  関数の定義部分をよく見よう
*/

// グローバル変数の宣言
int score[10][6];
double average[6], stdev[6];
char person_name[10][20], subject_name[5][20];
int num_person; // 学生数
int num_subjects; // 科目数

int main() {
  input(); // ファイルから科目数や得点を読み込み学生数を数える関数
  total(); // 各学生の総得点を計算する関数
  calc_statistics(); // 各科目ごとの平均点と標準偏差を計算する関数
  print();           // 結果を印刷する関数
}

/*==================================================================*/
void input(void) {
  int i, j;
  FILE *fp;

  if ((fp = fopen("report3.dat", "r")) == NULL) {
    /* エラー処理を書く */
  }
  fscanf(fp, "%d", &num_subjects); // 科目数の読み込み
  printf("Number of subjects = %d\n", num_subjects);

  for (i = 0; i < num_subjects; i++) { // 科目名の読み込み
    fscanf(fp, "%s", subject_name[i]);
  }

  num_person = 0;
  while (fscanf(fp, /* ヒント参照 */) != EOF) { // 名前の読込み
    for (i = 0; i < num_subjects; i++) {
      fscanf(fp, /* */); // 整数型の数値として点数を読み込む
    }
    ++num_person; // 学生数をインクリメント
  }
  fclose(fp);
  printf("Number of students = %d\n", num_person);
}

/*==============================================================*/
void total(void) {
  int i, j;
  for (i = 0; i < num_person; i++) {   // 学生ごとのループ(行)
    /* 自分で考える */ = 0;              // 学生ごとに総得点をゼロ初期化
    for (j = 0; j < num_subjects; j++) { // 科目ごとループ(列)
      /* 自分で考える*/ += score[i][j];
    }
  }
}

/*==============================================================*/
void calc_statistics(void) {
  double sum, sqsum, t;
  int i, j;

  for (j = 0; j <= num_subjects; j++) { // 平均点の計算
    /*
			自分で考える
		*/
    average[j] = sum / num_person;
  }
  for (j = 0; j <= num_subjects; j++) { // 標準偏差の計算
    sqsum = 0.0;
    for (i = 0; i < num_person; i++) {
      t = score[i][j] - average[j];
      sqsum += t * t;
    }
    stdev[j] = sqrt(sqsum / num_person);
  }
}

/*==============================================================*/
void print(void) {
  // 結果の印刷
  // 参考:printf関数の書式例
  // 文字列の左づめ書式 "%-10s", 数値の3桁表示書式 "%3d"
}

No.4

#include <stdio.h>

int menu(void); // メニュー関数のプロトタイプ宣言
void kuku10(void); // 10進数の九九表を表示する関数のプロトタイプ宣言
void kuku(int); // 10進数以外の九九表表示の関数のプロトタイプ宣言

int main() {
  int num;

  do {
    num = menu();
    if (num == 0) {
      printf("終了します\n");
    } else if (num == 10) {
      kuku10();
    } else if (3 <= num && num <= 16) {
      kuku(num);
    } else {
      printf("表示できるのは3進数から16進数までです.\n");
    }
  } while (num != 0);
}

// メニュー関数
int menu(void) {
  int n;
  printf("何進数の掛け算表を出力しますか? (0で終了): ");
  scanf("%d", &n);
  return n;
}

// 10進数の九九表を表示するユーザ関数
void kuku10(void) { /* 自分で考える */
}

// num進数(10進数以外)の九九表を表示するユーザ関数
void kuku(int num) {
  // ヒント1: num進数一桁同士の掛け算は高々num進数2桁で収まる.
  // ヒント2: 上位の桁は割り算の商,下位の桁は余りで求められる
  // ヒント3: 16進数の表示には文字列を使うのが便利
  //          char c[] = "0123456789ABCDEF";
  //   要素数を省略すると自動的に適切なサイズの配列が確保される
  /* 後は自分で考える */
}

No.5

#include <stdio.h>

#include "pgm.h"  // PGM画像の読み書きに必要.Blackboardからダウンロードしておく.

// プロトタイプ宣言
void subsampling(int, int, unsigned char *, unsigned char *);

int main() {
  int width0, height0, maxval;    // 処理前の画像の幅,高さ,ピクセルの最大値
  int width1, height1;            // 処理後の画像の幅,高さ
  unsigned char *input, *output;  // 処理前および処理後の画像のピクセルデータへのポインタ

  // PGM画像の読み込み: 読み込まれたピクセルデータはinputによってアクセス可能になる
  input = read_pgm("./barbara.pgm", &width0, &height0, &maxval);
  // 幅 x 高さ, 最大値の表示 (確認用)
  printf("%d x %d, %d\n", width0, height0, maxval);

  width1 = width0 / 2;
  height1 = height0 / 2;
  // 処理後の画像データのためのメモリを確保
  output = (unsigned char *)malloc(width1 * height1);

  subsampling(width1, height1, input, output);
  // PGM画像の書き込み:
  write_pgm(width1, height1, maxval, "output.pgm", output);

  free(input);   // メモリの解放
  free(output);  // メモリの解放
}

// 関数の定義
void subsampling(int width, int height, unsigned char *input, unsigned char *output) {
  for (int i = 0; i < height; ++i) {
    int pos_in = (i * 2) * width * 2;
    int pos_out = i * width;
    for (int j = 0; j < width; ++j) {
      unsigned char *val = input + pos_in;
      unsigned char *op = output + pos_out;
      *op = *val;
      pos_in += 2;
      pos_out++;
    }
  }
}

No.6

#include <stdio.h>
#include <stdlib.h>

#include "pgm.h"

void upsampling(int width, int height, unsigned char *input, unsigned char *output);
int interpolation(int width, int height, unsigned char *data, int algorithm);

int main() {
  int width0, height0, maxval;
  int width1, height1;
  unsigned char *input, *output;

  input = read_pgm("./barbara.pgm", &width0, &height0, &maxval);
  printf("%d x %d, %d\n", width0, height0, maxval);

  width1 = width0 * 2;
  height1 = height0 * 2;
  output = (unsigned char *)malloc(width1 * height1);

  // アップサンプリング
  upsampling(width0, height0, input, output);

  // 補間
  int algorithm = 0;  // 0: ニアレストネイバー法,1: Bilinear法
  if (interpolation(width1, height1, output, algorithm)) {
    return EXIT_FAILURE;
  };
  write_pgm(width1, height1, maxval, "output.pgm", output);
}

void upsampling(int width, int height, unsigned char *input, unsigned char *output) {
  int o_stride = width * 2;
  for (int i = 0; i < height; ++i) {
    for (int j = 0; j < width; ++j) {
      output[(2 * i) * o_stride + 2 * j] = input[i * width + j];
    }
  }
}

int interpolation(int width, int height, unsigned char *data, int algorithm) {
  int ret = EXIT_SUCCESS;
  switch (algorithm) {
    case 0:  // ニアレストネイバー法による補間
      // 水平方向
      for (int i = 0; i < height; i += 2) {
        for (int j = 0; j < width; j += 2) {
          data[i * width + j + 1] = data[i * width + j];
        }
      }
      // 垂直方向
      /* 自分で考える部分*/
      break;
    case 1:  // バイリニア法による補間
      /* 自分で考える部分*/
      break;

    default:
      printf("ERROR: Unkown algorithm\n");
      ret = EXIT_FAILURE;
      break;
  }
  return ret;
}