2001 年度「計算機基礎論3B」 2001-10-26

unix の決まりごと

演習(の一例)

ループ

  1. 下の loop.c は、 1 から 10000 までの整数を一行にひとつずつ出力するプログラムである。 これを利用して、プログラムの中止、一時停止、再開の練習をせよ。

文字入出力とリダイレクト・パイプ

  1. 教科書の、入力を出力に複写するプログラム (の一つをコンパイルしてできた実行ファイル)を a.out とするとき、単に「a.out」としてそれを動かしてみよ。 「入力の終わり」は上に述べた通り。
  2. a.out を上の通りとするとき、次を確かめよ。
    1. a.out < file」とするとファイルの内容を画面に出力する。
    2. a.out > file」 とするとキーボードからの入力を内容とするファイルを作成する。 (上書きに注意。)
    3. a.out >> file」 とするとキーボードからの入力をファイルに追加する。
    4. a.out < file1 > file2」とするとファイル file1file2 に複写する。 (上書きに注意。)
    5. a.out < file1 >> file2」とするとファイル file1file2 に追加する。
  3. 下の toupper.c は小文字を大文字に変換しつつ入力を出力に複写する。 これをコンパイルしてできた実行ファイルを toupper と改名せよ。 まずはリダイレクトせずに動かしてみよ。 次にリダイレクトしていろいろやってみよ。
  4. unix にたいていついている sort は、 入力した複数の行をアルファベット順に並べ直して出力するプログラムである。 まずはリダイレクトせずに動かしてみよ。 次にリダイレクトしていろいろやってみよ。
  5. file を実在するファイルとするとき、 「cat file | toupper | sort」は何を行なうか? cat file | sort | toupper」はどう違うか?
  6. 下の rev.c は各行内の文字を逆転しつつ入力を出力に複写する。 これをコンパイルしてできた実行ファイルを rev と改名せよ。 まずはリダイレクトせずに動かしてみよ。 次にリダイレクトしていろいろやってみよ。
  7. cat file | rev | sort | rev」は何を行なうか?

プログラミング

教科書の例を見ながら、より簡単なプログラムを書いてみよう。 以下はその一例である。

  1. 整数型変数 a, b, c を宣言し、 a に 1 を、b に 2 を代入する。 それから ab の和を c に代入する。 そしてその結果を「何々 たす 何々 は 何々 です」 のように出力するプログラムを書け。
  2. 上のプログラムで、「和」を「差」「積」「商」に変えてみよ。 除数が 0 のときは何が起こるか?
  3. 上のプログラムで、整数型変数を浮動小数点型変数に変えてみよ。 除数が 0 のときは何が起こるか?
  1. 1 から 40(ぐらい)までの整数とその二乗を並べて出力するプログラムを書け。 二乗は x * x のようにして計算せよ。 Cにはベキ乗の演算子はない。
  2. 0 から 1 まで、0.1 おきに、数とその二乗を並べて出力するプログラムを書け。 今までに学んだ知識どおりに書くと 1 の場合が計算・出力されないはずである。 工夫すれば 1 も出力できるようになるが、そこまでしなくてもよろしい。

== loop.c =====================================================================
#include <stdio.h>

main()
{
    int i;

    for (i = 1; i <= 10000; i++) {
        printf("%d\n", i);
    }
}
===============================================================================

== toupper.c ==================================================================
#include <stdio.h>
#include <ctype.h>  /* toupper() を使うため */

main()
{
    int c;

    while ((c = getchar()) != EOF) {
        putchar(toupper(c));
    }
}
===============================================================================

== rev.c ======================================================================
#include <stdio.h>

char* rev(char*);
char buf[4096+1];

int main()
{
  while (gets(buf) != NULL) {
    puts(rev(buf));
  }
  return 0;
}

/* 文字列を反転する。日本語 euc に対応 */
char* rev(char* buf)
{
  unsigned char *p, *q;
  unsigned char tmp;

    /* 文字列の終わりを探しつつ2バイト文字の1バイト目と2バイト目を入れかえる */
  for (q = (unsigned char *) buf; *q != '\0'; q++) {
    if (*q & 0x80) {
      tmp = *q, *q = *(q+1), q++, *q = tmp;
    }
  }
    /* よくあるやりかたで文字列全体を反転する */
  for (p = (unsigned char *) buf, q--; p < q; p++, --q) {
    tmp = *p, *p = *q, *q = tmp;
  }
  return buf;
}
===============================================================================

岩瀬順一