2023 年度「計算数学a」 2023-04-07

§1.1 はじめに

(1.1.1) 金沢大学理工学域数物科学類の 2 年生を主たる対象とする。 内容は、C 言語によるプログラミングの初歩とアルゴリズムの初歩である。

(1.1.2) この建物(金沢大学学術メディア創成センター)は禁煙・飲食禁止である。

(1.1.3) この授業では「説明」はおこなわない。 各自でプリントを読んで「実習」をおこなう。 諸君の間で自由に相談などをしてよい。歩き回ってもよい。 私は諸君の間を回って質問を受けるので、 通路は空けておくように。

(1.1.4) 単位の認定は、出席と課題の提出状況でおこなう。 学生証をタッチすることを忘れずに。 課題は、出しただけではだめで、「OK」と認められなければならない。 決してむずかしくはない。

(1.1.5) プリントと全く同じものが、WebClass に置いてある。 授業期間終了後はインターネットで公開する予定である。

(1.1.6) 担当教員の研究室は自然科学5号館(旧:理学部)数学管理棟 383 号室。 氏名の「瀬」の字は実は正字なので一番右は「頁」ではなく 「刀」の下に「貝」だが、この授業では「瀬」。

§1.2 アカウント・履修者番号について

(1.2.1) センターの「ネットワーク ID」は、少し前に「KAINS ID」という名前に変わった。 その ID で、演習室のパソコンにログインする。

(1.2.2) この授業だけで使う、「履修者番号」を以下で定義する。 数物科学類 2 年生は、名列番号そのもの(3 ケタ)である。 それ以外の履修者は、別途指示する。(ここにメモしておくとよかろう。)

§1.3 パソコンの基本操作

Windows を用いる。

電源の入れ方・切り方、ログイン・ログアウト、基本操作、 (いわゆる)日本語入力の On/Off, テキストの範囲指定と移動・コピーは、 諸君のパソコンと同様なので省略する。

§1.4 ファイル管理ソフト Explorer

(1.4.1) キーボード左下の Windows キー(四辺形が四つ書かれている) を打ち、続いて「z:」(ゼッドに続いてコロン)と打ち、 Enter キーを打つと、 ファイル管理ソフト Explorer で z ドライブを開いた画面になる。 (タスクバー上のアイコンからも行ける。)

(1.4.2) z ドライブが、諸君のファイルを置くところである。 ここに保存したファイルは、次にログインしたとき、そのまま残っている。 ここ以外(デスクトップなど)に置いたファイルは、ログアウトすると消える。

(1.4.3) Explorer の操作法をおさらいしておこう。

(1.4.4) 【重要】 この授業のファイルを置くフォルダーを作れ。 (いわゆる)日本語は含めず、アルファベットと数字がよい。 とくに好みがなければ、23cma がよかろう。 23 は 2023 年度を、 cma はこの科目のむかしの英語名 computational mathematics にちなむ。 以下の説明は、この名前をつけたものとしておこなう。 別の名前にした人は自分で読み替えること。 それから、そのフォルダーの中に、なんでもよいから、ファイルを作れ。

§1.5 ブラウザ

(1.5.1) (いわゆる)ホームページを見るためのブラウザは Edge である。 タスクバーの上にアイコンがあるのでそれをダブルクリック。

(1.5.2) ブックマークは次にログインしたときには消えているので、 意味がない。

§1.6 コマンドプロンプト

(1.6.1) Windows キーを打ち、続いて「cmd」と打ちかかると、途中で、 画面に「コマンド プロンプト」が検索結果として出てくる。 ここで Enter キーを打つと、それが起動する。

(1.6.2) それは黒い画面であり、中に「Z:\>」のような文字列が出ている。 それを「プロンプト」と呼ぶ。 プロンプトの出ているところでコンピューターへの命令を打ち込むと、 それが実行され、終わるとまたプロンプトが出て止まる。 これのくり返しで作業を進める。

(1.6.3) この授業での作業は、(1.4.4) で作ったフォルダーの中でおこなう。 そこへ「カレントディレクトリ」を移すため、 「cd 23cma」と命令せよ。 プロンプトが「Z:\23cma>」と変わったであろう。 以下、この状態で作業をおこなう。

(1.6.4) 【練習】 ファイル一覧を見るコマンド dir を試せ。 プロンプトが出ているところへこの文字列を打ち込み、最後に Enter キーを押す。 (1.4.4) で作ったファイルの名前などが出るはずである。 また、現在時刻を知るコマンド time も試せ。

(1.6.5) プロンプトの出ているところで「↑」「↓」キーを押すと、 前に打ったものが出てくる。それを修正して実行することもできる。

(1.6.6) コマンドプロンプトを終了する際には、 プロンプトが出て止まっている状態であることが望ましい。

§1.7 テキストエディタ「メモ帳」

(1.7.1) 「テキストファイル」とは、 (いわゆる)全角文字と(いわゆる)半角文字だけを扱い、 文字の大きさなどは変えられないものをいう。

(1.7.2) テキストファイルを編集するためのプログラムが「テキストエディタ」である。

(1.7.3) 「メモ帳」は Windows 付属のテキストエディタであり、 機能は限られているが、十分に使えるものである。 .txt ファイルのアイコンをダブルクリックすれば起動する (がこの授業では .txt ファイルは扱わない)。

(1.7.4) この授業では、hello.c のような名前の、 .c ファイルを使う。これもテキストファイルである。 .txt ファイルとして Explorer(§1.4 参照)の中に新規作成し、 拡張子 .txt も込めて名前を変更する。 その際、警告が出るが、「はい」を押す。 .c ファイルを「メモ帳」で編集するには、 アイコンをダブルクリックするのではなく、 右クリックして「プログラムから開く」「メモ帳」とする。

(1.7.5) 【練習】 Explorer, メモ帳 の練習をせよ。 具体的には、(1.4.4) で作ったフォルダーの中に、 適当な名前のテキストファイルを作り、 適当な文字列を打ち込んで保存してみよ。

(1.7.6) 【重要な注意】 (いわゆる)日本語を含むファイルをメモ帳で作る場合、めんどうだが、次の操作をして、 メモ帳の画面右下の「UTF-8」を「ANSI」に変えないと、コマンドプロンプトとの相性が悪い。

この操作は、ファイルに(いわゆる)日本語が含まれている状態で、 一つのファイルにつき一度だけおこなえよい。 また、ANSI のファイルをコピーしたものはまた ANSI となる。

(1.7.7) よって、次のようにすると便利かもしれない。 (いわゆる)日本語を含むファイルを一つ作って UTF-8 から ANSI に変え、 それを !.c という名前で保存しておく。 ソースファイルを新規作成するときは、代わりに !.c をコピーして使う。 そうすれば、この操作をファイルごとにしなくて済む。(ソースファイルについては後述。)

§1.8 電子メール

電子メールは、@stu.kanazawa-u.ac.jp のアドレスを用いよ。

§1.9 課題0

(1.9.1) 担当教員にメールを送れ。 メールアドレスは iwase@staff.kanazawa-u.ac.jp である。

(1.9.2) 【大切な注意】 件名は指定されたとおり、正しくつけること。 送り先のアドレスにはこの授業以外にも多くのメールがくる。 それらのメールに紛れないためである。

(1.9.3) メールが正しく送れるかどうかの確認であるから、点数にはならない。 一週間以内に、受け取ったメールには返信を送る予定である。 間違っているとの返信を受け取った場合には、送りなおせばよい。

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

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

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

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

(1.10.3) 【注意】 コンピュータにおいて、 バックスラッシュ「」と円マーク「」 は半角文字では同じものと思ってよい。 スラッシュ「」は別物である。向きが違う。混同するな。 右手で文字を書く人にとって書きやすいほうがスラッシュ、 逆向きがバックスラッシュと覚えるとよい。

§1.11 printf() による画面出力

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

#include <stdio.h>

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

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

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

  1. z ドライブ(§1.4 参照)のフォルダー 23cma の中に新規テキストファイルを作り、 hello.c に名前を変更する。
  2. hello.c をメモ帳で開く。(§1.7 参照)
  3. メモ帳の中に、プログラムを、コピペするか、自分で打ち込む。 その内容は上のとおり。保存するのを忘れずに。 (メモ帳は終了しないほうが、修正する際に便利である。)
  4. コマンドプロンプト(§1.6 参照) ――プロンプト「Z:\23cma>」が出ていることを確かめよ―― に「gcc hello.c」と打ち込んでコンパイルする。 何も出力されずにプロンプトが出れば成功である。 そのときは実行ファイル a.exe ができている。
  5. コマンドプロンプトに「a」と打ち込めば、 実行ファイル a.exe が実行される。

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

(gcc は、GNU Project の一環として、無償で配布されている C コンパイラである。感謝しよう。)

(1.11.4) 1 行目。 きょうのところはこれは「決まり文句」と考えよう。 「#」は Shift しながら 3 のキーを打つ。 この記号は「シャープ」と呼ばれることが多いが、正式には「番号記号」という。 include は英単語そのままだ。 この次にスペースを入れているが、入れなくてもよい。 stdio.h を囲む 「<」、「>」は不等号をカッコの代わりに使っているもの。 Shift しながら、それぞれ、カンマ、ピリオドのキーを打つ。 stdio は英単語ではないので、つづり字に注意しよう。

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

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

(1.11.7) よって、4 行目がこのプログラムのうちで最も意味のある部分ということになる。

(1.11.8) 4 行目の冒頭には空白(半角スペース)を 2 文字、置く。 それから printf... を打ち込む。 空白を置く理由はそのうちわかってくる。 このように行頭に空白を置くことを「字下げ」「インデント」という。

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

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

(1.11.11) 練習: 出力される文字列を別のものに変えて、コンパイル、実行してみよ。 たとえば「"hello, world\n\nhello, world\n"」 とするとどうなる? (いわゆる)日本語を含めると、どうなるか?  (もしもめちゃめちゃな文字列が出力された場合、(1.7.6) を忘れている可能性が高い。)

(1.11.12) 練習: 自分の氏名を出力するプログラムを書いてみよ。 その際、 「ソ 噂 浬 欺 圭 構 蚕 十 申 曾 箪 貼 能 表 暴 予 禄 兔 喀 媾 彌 拿 杤 歃 濬 畚 秉 綵 臀 藹 觸 軆」 を含む名前の人は要注意。 これらの文字のあとに \ を置かねばならないのが、 ここの gcc での約束である。 たとえば「十郎」と出力させたければ printf("十\郎"); としなければならない。 これは、gcc が十分に(いわゆる)日本語に対応していないことが原因である。

§1.12 四則演算

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

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

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

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

#include <stdio.h>

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

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

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

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

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

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

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

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

(1.12.7)

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

§1.13 scanf() によるキーボードからの入力

(1.13.1)

#include <stdio.h>

int main() {
  int a, b;

  printf("数を入れてください.\n");
  scanf("%d", &a);                        /* 数の入力 */
  printf("もう一つ数を入れてください.\n");
  scanf("%d", &b);
  printf("%d たす %d は %d です.\n", a, b, a + b);
}

(1.13.2) 「数の入力」の行。 ここでプログラムは止まってキーボードからの入力を待ち、 入力された値を変数 a に格納する。 関数 scanf() はそのための関数である。 私は「スキャンエフ」と読んでいる。 変数名 a の前に & がついて &a となっていることに注意。 なぜ & が必要かは、いまは説明しない。 & は Shift しながら 6 のキーを打つ。

(1.13.3) 練習:(1.12.7) で説明した、 割り算をする演算子「/」を試すプログラムを書き、 余りは切り捨てられることを確認せよ。 また、 余りを求める演算子「%」を試すプログラムを書け。 商と余りの両方を出力させるのもよい。 そのプログラムに負の数を入力するとどうなるか?  割る数・割られる数の両方で試してみよ。

(1.13.4) 練習:(1.12.7) で説明した、 演算子の優先順位を確認するプログラムを書け。 たとえば、a + b * c では乗法が先に計算されることを確かめる、など。

(1.13.5) 練習: 0 で割ったら何が起こるか確かめよ。 (答え:ここのシステムでは、しばらく止まるだけ。)

付:コマンドライン引数の使い方

ここまでで、「整数に解をもつ、整数係数の一次方程式」 を解くプログラムが書ける。 (電卓で済むのでほとんど意味はないが。)

方法 1. プログラム内に係数や定数項の値を書き込んでしまうもの。 出力は次のようになろう。

2 x + 6 = 8 を解きます.
x = 1 です.

方法 2. プログラムが動きだしてから、係数や定数項の値を打ち込ませるもの。 実行例は次のようになろう。

ax + b = c を解きます.
a の値を入力してください.
2
b の値を入力してください.
6
c の値を入力してください.
8
2 x + 6 = 8 の解は x = 1 です.

方法 3. 実行時に、プロンプトの出ているところに 「a 2 6 8」のように a, b, c の値を打ち込んで動かし、 プログラムの側でそれらの値を利用する方法。 興味のある者は、以下の例で学べ。 この「2 6 8」をコマンドライン引数と呼ぶ。

#include <stdio.h>
#include <stdlib.h> /* atoi() を使うのに必要 */

int main(int argc, char *argv[ ]) {     /* 小かっこの中は、常にこう書く。きょうは説明しない */
  int a, b, c, x;

  a = atoi(argv[1]);    /* これで第一引数が a にはいる */
  b = atoi(argv[2]);    /* これで第二引数が b にはいる */
  c = atoi(argv[3]);    /* これで第三引数が c にはいる */

  /* ここで解を x に代入する。各自考えよ。*/

  printf("%d x + %d = %d の解は ", a, b, c);
  printf("x = %d です.\n", x);
}

このプログラムを「a」とだけ打ち込んで動かすと、 何も出ずに終わってしまう。 これをどう改良するかは、次回以降に学ぼう。

付:自分のパソコンで gcc を動かすには

Windows の場合。ファイルのコピーは担当教員にまかされたい。

その後、 コマンドプロンプトの起動は演習室と同じ。 プロンプトは「C:\Users\田中美佐子>」のようになっていると思う。 コマンド「cd documents」で、パソコンの中の「ドキュメント」に行く。 そこに、(たとえば)23cma という名前のフォルダーを作る。 さらに、「cd 23cma」でそこにはいる。 プロンプトは「C:\Users\田中美佐子\Documents\23cma>」となったであろう。

ここで、コマンド「path c:\mingw64\bin;%path%」を実行する。 これで初めて、gcc が使える。

(上の段落のコマンド「path c:\mingw64\bin;%path%」は、 コマンドプロンプトを開くたびにおこなわなければならない。 それがめんどうな場合、c:\mingw64\bin に「パスを通す」 操作をすれば、その必要はなくなる。)

Mac の場合は、担当教員に尋ねよ。

付:作ったプログラムを持ち帰りたい場合

ソースファイルを、メールを利用して持ち帰ればよい。

実行ファイルをメールに添付しようとすると拒否されることがある。 実行ファイルは、 ソースファイルを移動した先のコンピュータの C コンパイラで作る。

付:パス (path) について

まずは Windows について。

諸君はすでに、Explorer を利用して、 いろいろなフォルダーの中を移動できるであろう。

ここで、コマンドプロンプトでそれをおこなう方法を説明しよう。

プロンプトが「C:\Users\田中美佐子>」となっている場合。 最初の「C:」は、「カレントドライブ」が C ドライブであることを意味している。 これを変えるには、たとえばコマンド「d:」を実行する。 すると D ドライブがカレントドライブになる。 (いまどんなドライブが実在しているかは、Explorer でわかる。)

C ドライブについて説明する。 「C:\」というディレクトリが存在する。これを「ルートディレクトリ」と呼ぶ。 Explorer でそこにゆくなら、「ローカル ディスク(C)」をダブルクリックすればよい。 コマンドプロンプトでそこへカレントディレクトリを写すには、 コマンド「cd \」を実行する。 プロンプトが「C:\>」に変わったであろう。

そこでコマンド「dir」を実行してみて、 Explorer で見えるフォルダーと比べてみよ。 (Usersユーザー に変わるなど、いくつかの違いはある。)

以下は、架空の例で説明する。 Explorer で見て、C:\ にフォルダー ab とがあるとし、 フォルダー a の中にはフォルダー ccdd とがあるとする。 次のような図式で考えるとよい。

\ ---+--- a ---+--- cc
     |         |
     |         +--- dd
     |
     +--- b

上の a\a と呼ぶ。 cc\a\cc と呼ぶ。 このように \ から始まるのを「絶対パス指定」という。

C ドライブのどこがカレントディレクトリであっても、 「cd \a」で上の a にカレントディレクトリを移せる。 「cd \a\cc」で上の cc にカレントディレクトリを移せる。

\ がカレントディレクトリのとき、 「cd a」で上の a にカレントディレクトリを移せる。 \a がカレントディレクトリのとき、 「cd cc」で上の cc にカレントディレクトリを移せる。 \ がカレントディレクトリのとき、 「cd a\cc」で上の cc にカレントディレクトリを移せる。 \ がカレントディレクトリのとき、 「cd cc」を実行しても何も起こらない。 このように \ から始まらないのを「相対パス指定」という。 上の ccdd から見て a を「親ディレクトリ」と呼ぶ。 カレントディレクトリを親ディレクトリに移すには「cd ..」を実行する。

Mac では、\ の代わりに / を用いる。

cmd」を実行すると、 Windows ではカレントドライブとカレントディレクトリを表示するのに対し、 Mac ではホームディレクトリにカレントディレクトリが移る。 Mac でカレントディレクトリを表示させるコマンドは「pwd」である。


岩瀬順一