2012 年度「計算数学」 2012-10-12

§2.1 プログラムを書くとは

(2.1.1) プログラムを書くに当たっては, テキストエディタで「ソースファイル」を作成し, 「コンパイラ」でそれを「コンパイル」し,「実行ファイル」を作る (のが普通である)。

        +----------------+                                 +----------------+
        | ソースファイル |  ---------------------------->  |  実行ファイル  |
        +----------------+     コンパイラでコンパイル      +----------------+
    (テキストエディタで書く)                              (これを動かす)
         (読んでわかる)                               (機械にしかわからない)

(2.1.2) 「実行ファイル」はコンピュータが読んで実行するもので, 人間が読んでもまずわからない。 「ソースファイル」は文字だけが並んでいるテキストファイルで, 訓練をつめば読み書きできるようになる。 「コンパイル」はここでは「変換する」「翻訳する」ぐらいの意味。 ソースファイルを書く際に用いる言語はいろいろあるが, ここでは「C言語」(シーげんご)を用いる。 C言語で書かれたソースファイルを実行ファイルにコンパイルするコンパイラのことを 「Cコンパイラ」とも言う。 Cコンパイラの使い方は,この授業で扱う範囲では極めて簡単である。 よって, これから学ぶことの中心はC言語によるソースファイルの書き方である。 以下,「プログラミング」と言ったらそれを指す。

(2.1.3) 【注意】 コンピュータにおいて, バックスラッシュ「」と円マーク「」 は半角文字では同じものと思ってよい。 スラッシュ「」は別物である。向きが違う。混同するな。 右手で文字を書く人にとって書きやすいほうがスラッシュ, 逆向きがバックスラッシュと覚えるとよい。 (「全角文字」とはほぼ正方形をしている「あいうえおABC123」などの文字。 「半角文字」はそれを縦に半分に割った大きさの, 「ABC123」などの文字。 この節の「」「」「」 はいずれも全角文字である。)

§2.2 初めてのCプログラム

(2.2.1) 次の例は参考書としてあげておいたカーニハン/リッチー著・石田晴久訳 「プログラミング言語C第2版」(共立出版) (以下 K&R2 と略す)の §1.1 とほとんど同じである。 画面に「hello, world」と出力するだけのもの。

#include <stdio.h>

main() {
    printf("hello, world\n");
}

(2.2.2) このプログラムについては, 「(いわゆる)ホームページからコピー & ペースト(以下「コピペ」という。)」 「キーボードから自分で打ち込む」 の両方で試せ。解説と注意は,(2.2.4) 以下に書いてある。 まずはコピペ」で試すとよいだろう。

(2.2.3) これを作成し,コンパイルし,実行する際の手順は次の通り。

  1. ホームに hello.c という名前の空のファイルを作る。
  2. それをダブルクリックして gedit で開く。
  3. プログラムを,コピペするか,自分で打ち込む。 その内容は上のとおり。保存するのを忘れずに。 (gedit は終了しないほうが,修正する際に便利である。)
  4. 端末に「cc hello.c」と打ち込んでコンパイルする。 何も出力されずにプロンプトが出れば成功である。 そのときは実行ファイル a.out ができている。
  5. 端末に「./a.out」と打ち込んで,プログラムを実行する。

失敗したときは 3 に戻ってやり直し。

(2.2.4) 1 行目。 きょうのところはこれは「決まり文句」と考えよう。 「#」は Shift しながら 3 のキーを打つ。 この記号は楽譜の中で使ったときの名称から 「シャープ」と呼んでおくが,正式名称は別にあったと思う。 include は英単語そのままだ。 この次にスペースを入れているが,入れなくてもよい。 stdio.h を囲む 「< >」は不等号をカッコの代わりに使っているもの。 Shift しながらカンマとピリオドのキーを打つ。

(2.2.5) 2 行目は空行である。見やすくするためにおいたもの。意味はない。

(2.2.6) 3 行目と 5 行目もCプログラムに必ずおくもの。 「main」の次にあるのは小カッコの開きと閉じ。 Shift しながら 8 と 9 のキーを打つ。 この次にスペースを入れているが,入れなくてもよい。 その次にあるのは中カッコの開き。 5 行目にあるのが中カッコの閉じ。 中カッコは,Shift しながら大カッコのキー(Enter のすぐ左にある)を打つ。 これらの中カッコは 4 行目を囲んでいる。つまり, 「main() { ... }」のことである。 こう書かずに上のようにする理由はそのうちわかってくる。 また,この中カッコの書き方は K&R2 とやや異なる。 この授業では一貫して私の書き方で教えるので, すでに自分流のつけ方を編み出している人以外はとりあえずそれにならえ。

(2.2.7) よって,4 行目がこのプログラムのうちで最も意味のある部分ということになる。 この行は頭に空白がある。 この空白は Tab(タブ)キーを一度押すことでとる。 空白を置く理由はそのうちわかってくる。 このように行頭に空白を置くことを「字下げ」「インデント」という。 また,そこには tab という見えない文字があると考える。 (プログラムを(いわゆる)ホームページからコピペした場合には, インデントの空白は tab ではなくスペース四つになるが, コンパイル結果には影響しないので気にするな。)

(2.2.8) printf() は元々用意されている「関数」である。 「プリントエフ」と読むことが多いかと思う。 関数の原語は function で,ここでは本来の意味である「機能」に近い。 この関数の機能は後ろの小カッコの中の文字列を印字する(=画面に書く) ことである。 文字列は二重引用符「" "」 (Shift しながら 2 のキーを打つ)で囲む。 ここでは印字される文字列に「\n」が含まれている。 「\n」はこの二文字で「改行」を意味する。 すなわち,これを画面に書くとそこで改行する。 よって,「hello, world\n」を画面に書くということは, 「hello, world」を画面に書いて最後に改行する, ということになる。

(2.2.9) 4 行目の最後にはセミコロン「;」がついている。 C言語では文はセミコロンで終わることになっているので,忘れるな。 また,この「セミコロン」などの名称もこの機会にきちんと覚えよ。

(2.2.10) 練習: 出力される文字列を別のものに変えて, コンパイル,実行してみよ。

§2.3 ごく簡単な計算

(2.3.1) 以下では,ファイル名は適当に決めよ。 C言語のソースファイルは「.c」で終わる名前でなければならない。

(2.3.2) 次のプログラムは,まずはコピペして実行してみよ。 「2 たす 3 は 5 です.」と画面に書くだけのプログラムである。

(2.3.3) 細かい説明は (2.3.4) 以下に書いたが,1行目の 「/*」と「*/」とで囲まれた部分だけ先に説明する。 これはコメントである。 何を書いてもコンパイルしてできる実行ファイルには関係ないので, 自由にメモを書くことができる。 ここでは,何をするプログラムか,いつ誰が作ったかを書いている。 その下のコメントは以下で説明する際の便宜のためにつけたものである。 これらは諸君は打ち込まなくてよい。

    /* たし算  1990-04-28, written by Iwase */

#include <stdio.h>

main() {
    int a, b, s;                /* 変数の宣言 */

    a = 2;                      /* 代入 */
    b = 3;
    s = a + b;

    printf("%d たす %d は %d です.\n", a, b, s);
}

(2.3.4) 「変数の宣言」の行。 変数を使う場合,前もって「宣言」しておく必要がある。 ここでは「変数 a, b, sint 型」と宣言している。 変数名には小文字を使うのが普通である。 「int 型」は整数のみを格納できる「整数型」の一つで, この名前は整数 integer に由来している。 私は「イントがた」と読んでいる。 変数の宣言はこの位置(i.e. main() が始まってすぐのところ) で行なわなければならない。 その次には空行をおくと見やすくなる。 なお,中カッコの中の行は(空行以外)すべて字下げする。

(2.3.5) 「代入」の行。 「a = 2」は,「a は 2 に等しい」という平叙文ではなく, 「a に 2 を代入せよ」という命令文である。 その下の二行も同様。 プログラムは特に指定しなければ上から下へと実行されるので, s = a + b; を実行したあとの s の値は 5 になる。 なお, 「=」は Shift しながら「-」のキー, 「+」は Shift しながらセミコロンのキーを打つ。 「a = 2;」の 「a」「=」「2」の間にはスペースを置いても置かなくてもよい。

(2.3.6) printf 文の行。 記号「%d」は,順に後ろの変数の値に置き換わって画面に出力される。 ここでは, 一つめの %da の値で, 二つめの %db の値で, 三つめの %ds の値で置き換わる。

    printf("%d たす %d は %d です.\n", a, b, s);
            --      --    --           -  -  -
            |       |     |            |  |  |
            +-------|-----|------------+  |  |
                    +-----|---------------+  |
                          +------------------+

よって,出力は「2 たす 3 は 5 です.」のあと改行,となる。 「%」は Shift しながら 5 のキーを打つ。 (句点「」の代わりに半角のピリオドを使っているのは単に趣味の問題である。)

(2.3.7)

(2.3.8) 練習: 出力の文の二重引用符の間の文字列からスペースを除去し, 「printf("%dたす%dは%dです.\n", a, b, s);」 としたら出力はどう変わるか。 「printf("%d%d%d\n", a, b, s);」としたらどうなるか。

§2.4 少しは意味のあるプログラム

(2.4.1) 以下は,少しは意味のあるプログラムである。 細かい点は次回に説明する。 コピペして動かしてみよ。 定数の値を変えて試してみよ。

(2.4.2)

/* 0 から 99 までの整数の二乗を計算して出力 */

#include <stdio.h>
 
main() {
    int n;
 
    for (n = 0; n < 100; n++) {
        printf("%d の二乗は %d です.\n", n, n*n);
    }
}

(2.4.3)

/* 0 から 99 までの整数の足し算 */

#include <stdio.h>
 
main () {
    int n, sum;
 
    sum = 0;
    for (n = 0; n < 100; n++) {
        sum = sum + n;
        printf("0 から %d まで足すと %d です.\n", n, sum);
    }
}

(2.4.4)

/* かけ算九九の表を出力。戦前(?)バージョン */

#include <stdio.h>
 
main() {
    int i, j;
 
    for (i = 1; i < 10; i++) {
        for (j = 1; j < i; j++) {
            printf("             ");
        }
        for (     ; j < 10; j++) {
            printf("%d * %d = %2d   ", i, j, i*j);
        }
        printf("\n");
    }
}

(2.4.5)

/* 2 から n-1 までの整数の最小の素因数を出力 */

#include <stdio.h>
 
main() {
    int n, p;
 
    for (n = 2; n < 100; n++) {
        for (p = 2; n % p != 0; p++) {
            ;
        }
        if (n == p) {
            printf("%d は素数です.\n", n);
        } else {
            printf("%d の最小の素因数は %d です.\n", n, p);
        }
    }
}

(2.4.6) アラレ数とは,次の漸化式で決まる数列である。 「ある項が偶数のときは次の項はその 1/2, 奇数の時はその項の 3 倍 + 1」。 どんな数から始めても 4, 2, 1, 4, 2, 1 ... の無限ループに陥ると予想されている。 このプログラムは,1 になったらそこで終わる。 また,キーボードからの数の入力があるが,これは今後この授業では使わない。

/* アラレ数 */

#include <stdio.h>

main() {
    int n;

    printf("自然数を入れてください.\n");
    scanf("%d", &n);            /* キーボードから数を入力 */

    for (     ; n != 1;      ) {
        if (n % 2 == 0) {       /* n が偶数のとき */
            n = n / 2;
        } else {                /* n が奇数のとき */
            n = 3 * n + 1;
        }
        printf("%d ", n);
    }
    printf("\n");
}

付:emacs を使いたい人へ

emacs -nw hello.c」と, 「-nw」をつけて起動してください。 端末の中で emacs が使えます。 つけないと,字が小さくて見にくいです。


岩瀬順一