2006 年度「計算機基礎論3B」 2006-11-10

§20 ここまでの知識で書けるいくつかのプログラム

(20.1) アラレ(霰)数とは、

という漸化式で定義される数列である。 この数列は、初項がいかなる自然数であってもそのうち 1, 4, 2, 1, 4, 2, ... というループに落ち着くであろうと予想されているそうだ。 (「霰」とは、空から降るあの「あられ」である。)

(20.2) 次のプログラムは、ユーザが入力した数から始めて 1 になるまで、 この数列を出力する。 for の小カッコの中は二つのセミコロンで三つに区切られるが、 何もない部分は空白にしておくことができる。 下の例では継続条件しかない。 (こういった場合、while を使うほうがはるかに自然である。)

#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");
}

(20.3) この例では中カッコが入れ子になっている。 その場合のインデントの(一つの)やり方は以下の通りである。 上のプログラムで確かめよ。

  1. {」を打ったらその直後で改行し、 次の行はその行の(空白以外の)頭よりもタブ一つ分(ここでは空白四文字分) 下げて始める。 (ただし、コメントは「{」の右に書いても構わない。)
  2. }」を打つときは、 それに対応する「{」を含む行の(空白以外の)頭の文字とそろえる。
  3. その他の行の頭は前の行とそろえる。
これらの規則はすぐに慣れることができるし、 これらを守ってさえいれば、「ある中カッコとペアになる中カッコをさがす」 ことや「ある文を囲む最小の中カッコをさがす」ことはきわめて容易である。 前にも言ったが、 自分流のインデントをすでに編み出している人はそれで構わない。 そうでない人はまずはこれを覚えよ。 また、プログラムを書き上げてから最後にインデントを整えるのではなく、 きちんとインデントしながら書く習慣をつけるとよい。 そのほうが、いままで書いた部分をよりよく理解できるので、 より整理された頭でプログラムを書くことができる。

(20.4) 自然対数の底 e を e = 1/0! + 1/1! + 1/2! + 1/3! + ... として計算するプログラムである。 階乗は、C言語には用意されていないので、自力で計算しなければならない。



#include <stdio.h>  /* 自然対数の底 e の計算 */

main() {
    int n;
    double sum, factorial;

    sum = 1;
    factorial = 1;

    for (n = 1; n < 23; n++) {
        factorial = factorial * n;
        sum = sum + 1 / factorial;
        printf("第 %2d 項までの和は %.53f です.\n", n, sum);
    }
}

(20.5) int 型と double 型をいっしょに使うときはこのように宣言する。 順序は逆でも構わない。 %2d は「二ケタの幅で表示せよ」の意味、 %.53f は「小数点以下 53 ケタで表示せよ」の意味である。 「factorial = factorial * n」では double 型と int 型とを掛けている。 この場合、結果は double 型になる。 C言語はこのあたりの約束ごとがやや煩雑である。 K&R2 §2.7, A6 に出ているが、 とりあえずは intdouble しか使わないので 「intdouble との演算結果は double になる」 とだけ覚えておけばよい。

(20.6) ※ センターの linux 上のCコンパイラでは、 第 3 項までの和 1+1+1/2+1/6 = 2+2/3 の小数点以下十数ケタ目ですでに違っている。 よって、 上のプログラムの計算結果は小数点以下十数ケタ目あたりまでしか信頼できない。 コンピュータの計算は近似計算なので、 むやみに桁数を多く表示させても意味がないときがある。 53 ケタ目まで表示させたのはそのことを知ってもらうためにすぎない。 (岩波「数学辞典第3版」1434 ページによれば e = 2.7182818284590452353... だそうである。)

(20.7) ※ 計算は第 22 項までで打ち切っているが、これは試行錯誤をくり返しながら決めたもの。 「収束したら打ち切る」とすることもできなくはないが。

(20.8) 「かつ」や「または」は次のように書く。 これらは for の継続条件にも使える。 K&R2 では §2.6 を見よ。

    if ((x > 0) && (x < 8)) {       /* 「かつ」 */
        ........
    }

    if ((x < 0) || (x > 2)) {       /* 「または」 */
        ........
    }
x > 0 などを囲んでいる小カッコは実は不要である。 これについての詳細は K&R2 §2.12 を参照。 「0 < x < 8」はC言語でも意味のある式だが、 数学とは意味が異なるので上の意味では使えない。

(20.9) 「かつ」も「または」も同じ文字を二つ打つことに注意。 まちがって「&」「|」をひとつだけ書いた場合、 それらにも意味があるのでコンパイラはエラーメッセージを出さない (かもしれない)。



§21 二重ループ

(21.1) 次のプログラムは九九の表を出力する。 for を二重に使っていること以外は、 いままでに習ったことでわかると思う。

#include <stdio.h>

main() {
    int i, j;

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

(21.2) 二重ループについて説明する。 まず外側のループから始まる。 最初は i が 1 で、 外側のループの中カッコにはいる。 するとそこに内側のループがあり、 j が 1 から 9 までこの内側のループを回る。 それが済んで改行を出力すると外側のループの中カッコの中がおわる。 そこで外側のループの再初期化にゆき、 i が 1 だけ増えて 2 になる。 これを i が 9 になるまでくり返す。

(21.3) 次は、素因数分解のプログラム。 三重ループになっている。 素因数が見つかるまで 2, 3, 4, ... と順に割ってみる素朴なやり方なので、 素因数分解される数が一億ぐらいになるとちょっと時間がかかる場合がある。

#include <stdio.h>

#define FROM    1   /* この数から */
#define TO    100   /* この数まで */

main() {
    int n, m, p, i;

    for (n = FROM; n <= TO; n++) {      /* n を素因数分解する */
        printf("%d =", n);
        for (m = n; m != 1; m = m/p) {  /* m を割る最小の素数を p に入れる */
            p = 0;                      /* 0 は「まだはいっていない」の印 */
            for (i = 2; p == 0; i++) {  /* 2, 3, 4, ... と順に割ってゆく */
                if (m % i == 0) {       /* 割り切れたら */
                    p = i;              /* p に格納 */
                }
            }
            printf(" %d", p);
        }
        printf("\n");
    }
}

§22 練習問題

全部やらなくても構いません。 むずかしさはまちまちです。

  1. (18.2) のプログラムを改変し、 「いくつまで足しますか?」に 10 を入力すると
    1 から 1 まで足すと 1 です.
    1 から 2 まで足すと 3 です.
        ....
    1 から 10 まで足すと 55 です.
    
    と出力されるようにせよ。
  2. (19.2) のプログラムを改変し、 1 から始めて 1, 2, 4, 8, 16, ... と順に倍になってゆく数列を表示するプログラムを書け。 2 の何乗で答えがおかしくなるだろうか?
  3. (21.1) の九九のプログラムを、桁をそろえてきれいに表示するように改良せよ。次に、
       |  1  2  ...  9
    ---+--------...----
     1 |
     2 |
     : :
     9 |
    
    のように被乗数・乗数を左と上に出力するようにしてみよ。
  4. 鶴亀算は知らないものとし、 全ての可能性を調べることで答えを見つけるプログラムを書け。 次が出力例。ただし「5」と「16」はユーザが入力したものである。
    ツルとカメを合わせて何匹いますか?
    5
    足は何本ですか?
    16
    ツル 0 匹、カメ 5 匹のとき足は 20 本で、これは答えではありません。
    ツル 1 匹、カメ 4 匹のとき足は 18 本で、これは答えではありません。
    ツル 2 匹、カメ 3 匹のとき足は 16 本で、これが答えです。
    ツル 3 匹、カメ 2 匹のとき足は 14 本で、これは答えではありません。
    ツル 4 匹、カメ 1 匹のとき足は 12 本で、これは答えではありません。
    ツル 5 匹、カメ 0 匹のとき足は 10 本で、これは答えではありません。
    
  5. 2 以上の自然数 n を一つ固定する。 “数”としては 0, 1, 2, ..., n-1 だけを考え、 足し算、掛け算は結果が n 以上になったら n で割った余りをもって答えとする。 この掛け算の表を出力するプログラムを書け。 n はプログラム中では「#define N 12」のようにし、 容易に変更できるようにせよ。 そして、いろいろな n に対しての出力結果を見ながら、 「一番上の行・一番左の列を除く各行・各列に 0, 1, 2, ..., n-1 がすべて現れるのは n がどのような数の場合か?」という数学の問題を考えてみよ。 この“数”を数学では Z/nZ, Z/n, Zn などと書き表す。
  6. 0 は偶数です.
    1 が奇数です.
    2 は偶数です.
      ...
    9 は奇数です.
    10 は偶数です.
    
    のように出力されるプログラムを書け。
  7. ユーザが入力した数から始めて、 次々と平方根を計算して出力するプログラムを書け。
  8. ユーザが入力した数の約数を全て出力するプログラムを書け。
  9. ユーザが入力した二つの自然数の最大公約数を出力するプログラムを書け。
  10. ユーザが入力した二つの自然数の最小公倍数を出力するプログラムを書け。
  11. プログラムの実行にかかった時間を調べるには 「date; ./a.out; date」 として開始前後の時刻を出力させるのが最も簡単であろう。 一億回まわるループ
        for (i = 0; i < 10000; i++) {
            for (j = 0; j < 10000; j++) {
                sum = sum + (i + j);    /* 意味のない適当な計算 */
            }
        }
    
    はどのくらい時間がかかるか? 回数を変えていろいろ調べてみよ。
  12. (20.4) のような、無限級数の和(の近似値)を求めるプログラムを書け。 等比級数でもよい。

§23 Active! mail で電子メール

(23.1) Active! mail はブラウザの中でメール送受信を行なうので、 linux でも Windows でも使えて便利である。 Windows から使う場合はこのページの最後の注意を読むこと。 また、 よく理屈を理解している人を除いては、 一つのアカウント宛てのメールの読み書きは一つのメールソフトで行なうように。 そうでないと、いろいろなところに受信メールが分散してしまう。 なお、諸君のメールアドレスは eb18b??@mailedu1.ipc.kanazawa-u.ac.jp である。 (mailedu1 の最後の文字は数字の一。)

(23.2) Netscape が起動している状態でもう一つ Netscape の画面を出したいときは Netscape のメニューから「ファイル」「新規作成」「Navigator ウィンドウ」 (または「Navigator タブ」)とクリックする。 こうすれば、ホームページでこの説明を読みながら Active! mail を使うことができる。

(23.3) https://email.kanazawa-u.ac.jp/ がセンターの Active! mail のページである。 このページにもブックマークを付けるとよいだろう。

(23.4) 「セキュリティの警告」が出るかもしれないが、 これは「このあとの画面ではパスワードなどを打っても大丈夫だ」 と言っているのであるから、ざっと読んでから OK を押せばよい。

(23.5) 「ユーザ ID」「パスワード」はログイン時のものを打ち込む。 「サーバ」のうちの mailedu1.ipc の前の白丸をクリックしてそこに黒い点を入れる。 もし間違えたら正しくクリックしなおせば OK だ。 「言語選択」は日本語のままがよいだろう。 それからその下の「ログイン」をクリック。

(23.6) 上部に「メールホーム」「メール受信」「メール作成」 「スケジューラ」「オプション」と出ている画面になったはずだ。 この画面が、このソフトの最初のページ、「メールホーム」である。

(23.7) 【最初に一度だけ行なう設定】 ページの上のほうに並んでいる「オプション」をクリック。 「プロフィール」をクリック。 「名前」には自分の氏名(として大学に届けてあるもの) を大学に届けてあるとおりの文字で打ち込む。 ここでの日本語入力のやり方は §9.1 を参照。 氏と名の間は「空けない」「半角スペース一つだけ空ける」 「全角スペース(=Shift+Z に続いてスペースバー) 一つだけ空ける」のどれでもよい。 「返信アドレス」「所属」「署名」は空白のままにする。 記入が終わったら「OK」を押すが、 このボタンは押しても引っ込まない(=引っ込んだように見えない)ので注意。 これで、「標準プロフィール」というのが表にはいったであろう。 もしもあとで修正が必要になったら、 「オプション」「プロフィール」と進んでこの画面に至り、 「内容修正」の下の鉛筆マークをクリックすればよい。

(23.8) 「オプション」「表示と編集」をクリック。 「ウインドウ」内の「カラー」は好きなのを選べ。 「メール受信」内の「添付モード」の二つはチェックをつける (=行頭の白い四角をクリックし、中に「レ」印を入れる)。 それから一番下の「OK」をクリック。

(23.9) 「オプション」「住所録」をクリック。 ここで、自分と担当教員を登録しよう。 「住所録作成」をクリック。 「名前」に氏名、「eMAIL」にメールアドレスを記入。 「ふりがな」も記入。 それから「OK」をクリック。 これで一つのアドレスが登録できた。 さらに登録するには、 「住所録作成」をクリックする。 担当教員のプロフィールは 「いわせじゅんいち」 「岩瀬順一」 「cf2956@mailedu1.ipc.kanazawa-u.ac.jp」 である。「様」や「先生」はつけないこと。

(23.10) 【メールの受信】 「メール受信」をクリックする。 「件名」の部分がリンクになっているのでクリックすればメールが読める。 (件名が全角スペースだけからなる場合はクリックできないが、 そのときはその左の「△」をクリックすると別にウィンドウが開く。)

(23.11) 【メールに関連する用語】

(23.12) 【メール作成】 「メール作成」をクリックすると別ウィンドウが開く。 「宛先」「Cc」(および「Bcc」)にはそれぞれアドレスを書くのだが、 住所録に登録してあるアドレスはそれを利用するとよい。 簡単だし、 アドレスだけでなく名前もはいるのでわかりやすいからだ。 それには、そのうえの「住所録」をクリックし、 虫眼鏡のアイコンをクリックすると一覧が出るので 「宛先」「Cc」などの四角に適宜チェックを入れればよい。 「件名」にはメールの内容を簡潔に表現する文字列を書く。 「土曜日の件」「Summer Concert」など。 「本文」に本文を書く。 一行の長さは半角文字で数えて 60 文字ぐらいになるよう、 Enter キーを押して改行すること。 本文の書き方については、次のサンプルを参照。

○○先生、

先生の授業で習ったとおり、なんたらかんたら。ああたらこうたら
したらああでこうで。

どこかおかしくしてしまったのでしょうか? 教えてください。

-- 
金沢大学理学部数学科2年
△△△△

(23.13) メール作成の際の(いわゆる)日本語入力は linux のそれなのであまり使いやすくない。 emacs のほうがいいと思う人は、emacs で書いてそこからコピーすればよい。

(23.14) 「署名」「添付ファイル」「重要度」はそのままでよい。 書き終えたら「送信」を押す。 (「取消」は廃棄する場合、 「下書き保存」はいまは送らず保存しておきたいとき。 後者については §23.19 を見よ。)

(23.15) 押しても送信ボタンは引っ込まず、何も起こらないが、 少し待つと作成ウィンドウが消えるので送られたことがわかる。

(23.16) 自分に Cc を送ってあるなら、少し経ってから 「メール受信」をクリックすればそれがきているはずだ。

(23.17) 【メール受信】 受信したメールに返信するには、 そのメールを画面に出しておいて返信のアイコン (件名などのすぐ上、左から三番目。 マウスカーソルを乗せて少し待つと字が出てくる) をクリックする。 「宛先」には元のメールの送信者がはいっているから、そのままでよい。 元のメールの本文が行頭に「>」をつけてすでに本文内におかれているから、 必要ならそれを利用して返事を書く。

金沢大学理学部数学科2年
△△△△君、

>先生の授業で習ったとおり、なんたらかんたら。ああたらこうたら
>したらああでこうで。

どこそこをこれこれしていませんか? とりあえずそこを確かめて
みてください。

-- 
○○○○

(23.18) 【「受信箱」「送信箱」「ごみ箱」「下書き保存」】 「メール受信」の画面では、 左上に「受信箱」と書いてあるであろう。 これは、いまは受信箱の中のメールを見ているんだよ、という意味である。 そのあたりをクリックして 「送信箱」「ごみ箱」「下書き保存」を選ぶとそれぞれの中が表示される。

これらの間でメールを移動するには、 移動させたいメール(複数も可)の件名の左の四角にチェックをつけ、 「移動先」を選んでからそのすぐ右の封筒のアイコンを押す。 (アイコンの上にマウスカーソルを乗せてしばらく待つと 「移動」の文字が出てくるはずである。)

(23.19) 「下書き保存」したメールの続きを書きたいなら、 “便せんの上に鉛筆”といった感じのアイコン (マウスカーソルを乗せて待つと「再編集」の文字が現れる) をクリックすると作成画面になる。

(23.20) ホームに .forward, .mailboxlist, Sent, Trash, Drafts, JunkMail などの名前のファイルができるかもしれないが、 これは Active! mail が作ったファイルなので、 変更したり削除したりしないこと。

(23.21) 【終わり方】 右上の「ログアウト」をクリックする。

(23.22) 【注意】 ブラウザの「戻る」や「再読み込み」は、 Active! mail の使用中は押さないこと。

(23.23) アカウントを複数持っている場合、 ログインしたユーザ名と、 Active! mail の画面に打ち込んだユーザ名とが異なっていても構わない。 読み書きできるメールは後者のものである。 例えば、 ほかの授業の自習で別のアカウントでログインしているときにこの授業のアカウントあてのメールをチェックしたいと思ったら、 わざわざログインしなおさなくてもいいわけだ。

(23.24) ほかの先生から「氏名はローマ字で書くように」と言われたら、 次のようにして「プロフィール」を追加すればよい。 「オプション」「プロフィール」の順にクリック。 ここでいう「プロフィール」とは 「送ったメールに自分の名前がどう書かれるか」だけだと理解せよ。 「標準プロフィール」は、すでに登録され、表示されているはずだ。 その二つ下の「名前」に、ローマ字などで自分の名前を記入する。 その上の「プロフィール名」には、自分の覚えとなるような文字列を記入する。 「名前がローマ字」のようなメモでもよいし、 「名前」に記入したものと同一の文字列でも構わない。 氏名をローマ字で書くよう指示された先生の名前でもよいだろう。 それから「OK」をクリックし、「戻る」。 メール作成ウィンドウで、 「住所録」の右に表示されている「標準プロフィール」 のすぐ右の「▼」をクリックすると、 登録してあるプロフィールから好きなものが選べる。 試しに自分にメールを送って確認してみよ。

(23.25) 【MS-Windows から使う場合の注意】 実習室の Windows では、 Explorer を起動して最初に表示されるページに 「Active! Mail」というリンクがある。

(23.26) 自宅のパソコンをインターネットに接続していれば、 自宅からも使える。

(23.27) Active! mail のいくつかの機能は、 センターの判断で使えないようにしてあるようである。 「メール転送」も使えないようで、 Active! mail の中からではなく直接操作しなければならない。 .forward という名前のファイルをホームに作り、 一行目には自分のユーザ id の前に「\」をつけたものを書く。 二行目以降には、メールを転送したい先を書く。

\eb18b??
......@....ne.jp
こうしておくと、 いままでどおり自分のアカウントにもメールがくるし、 ほかのアドレスにも転送される。 自分の携帯電話のアドレスにも転送されるよう設定しておくと、 教員からレポートの返事がきたときなどにすぐわかって便利である。 なお、必ずテストメールを送って正しく設定されたことを確認せよ。


岩瀬順一