2023 年度「数学特論」 2023-12-08

§1.1 はじめに

(1.1.1) 金沢大学理工学域数物科学類の 4 年生を主たる対象とする。 内容は、C 言語によるプログラミングのうち、 文字、文字列、ポインタなどに関する、少し進んだ部分である。 その前に、「計算数学a」で学んだ 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) この授業だけで使う、「履修者番号」を以下で定義する。 数物科学類 4 年生は、名列番号そのもの(3 ケタ)である。 それ以外の履修者は、別途指示する。(ここにメモしておこう。)

§1.3 パソコンの基本操作

OS は Windows を用いる。Linux については今回の最後に説明する。

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

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

(1.4.2) z ドライブが、諸君のファイルを置くところである。 ここに保存したファイルは、次にログインしたとき、そのまま残っている。 ここ以外に置いたファイルは、どうなるかわからない。

(1.4.3) Explorer の操作法をおさらいしたいものは、 211001.html の §1.4 を見よ。

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

§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 23tok」と命令せよ。 プロンプトが「Z:\23tok>」と変わったであろう。 以下、この状態で作業をおこなう。

(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 ファイルのアイコンをダブルクリックすれば起動する。

(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) 忘れている人は、 211001.html の §1.10 を見よ。

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

(1.11.1) 忘れている人は、 211001.html の §1.11 を見よ。

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

§1.12 四則演算

(1.12.1) 忘れている人は、 211001.html の §1.12 を見よ。

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

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

(1.13.1) 忘れている人は、 211001.html の §1.13 を見よ。

§2.1 for によるループ(くり返し)

(2.1.1) 忘れている人は、 211008.html の §2.1 を見よ。

§2.2 二重ループ

(2.2.1) 忘れている人は、 211008.html の §2.2 を見よ。

§2.3(欠)

§2.4 プログラムの止め方

(2.4.1) ループの回数が多いプログラムを実行し、 「これは時間がかかりすぎだ、失敗!」と思うときがあろう。 プログラムの実行を中止してプロンプトに戻りたいときは Ctrl+C (Ctrl キーを押しながら C)を押す。

§2.5 if ... else による分岐

(2.5.1) 忘れている人は、 211008.html の §2.5 を見よ。

(2.5.2) ここで、for と並んで、くり返しに用いられる、while を紹介する。

  while (条件) {
    ...
  }

  for (   ; 条件;   ) {
    ...
  }

と同じである。

(2.5.3) アラレ数とは、次の漸化式で決まる数列である。 「ある項が偶数のときは次の項はその 1/2, 奇数の時はその項の 3 倍 + 1」。 どんな自然数から始めても 4, 2, 1, 4, 2, 1 ... の無限ループにおちいると予想されている。 このプログラムは、1 になったらそこで終わる。

これは、 211008.html の §2.5 では for を用いて書いたが、 while のほうが適切な例であった。

/* アラレ数 */

#include <stdio.h>

int main() {
  int n;

  printf("自然数を入れてください.\n");
  scanf("%d", &n);

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

※ 初期値が正の数以外とみなされると無限ループにおちいる可能性がある。 そのときは Ctrl+C で止める。

(2.5.4) くり返しには、もう一つ、do-while があるが、ここではとりあげない。

§2.6 中カッコの入れ子

(2.6.1) 忘れている人は、 211008.html の §2.6 を見よ。

§3(欠)

§4 関数の自作(後述)

§5.1 配列

配列および #define について、忘れている人は、 211105.html の §5.1 を見よ。

§6.1 一文字ずつの入力

(6.1.1)

#include <stdio.h>

int main() {
  int c;

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

(6.1.2) getchar() は、キーボードから一文字を入力する関数である。 文字が入力されれば、それは数値として、のちに述べる char 型に収まるのだが、 入力の終わり (End Of File) のときだけは EOF(後述)が返り、 char 型に収まらないので、 int 型変数に入れるのが普通である。 上のプログラムでは c = getchar() として、 変数 c に代入している。

その c = getchar() を小かっこでくくって EOF と比較している。 すると、c に代入された値を EOF と比較することになる。 これは、C 言語のイディオムの一つである。

このプログラムはキーボードからの入力を受けつけるわけだが、 いつか入力は終わらなければならない。終わりをプログラムに伝えるには、 Windows では「行頭で Ctrl+Z」、Linux では「行頭で Ctrl+D」を押す。 (「行頭で」とは、何も入力しないところで、あるいは Enter を押した直後に、の意味である。)

すると、 EOFCtrl+Z あるいは Ctrl+D のことか、と思うかもしれないが、 そうではない。 これらのキーが押されると getchar() が返す特別な値であり、 通常は -1 らしいが、そうと決まっているわけではない。

ここまでをまとめると、 while の行は、 「キーボードからの入力を c に収め、それが入力の終わりでない限り」 という意味になる。

で、その間、何をするかというと、ループの本体には putchar(c) とある。 この関数は c を画面に出力する。

ということは、 このプログラムは、キーボードからの入力を画面に出力する、 というものである。

(6.1.3) すると、このプログラムを動かしてキーボードから「abc」と打ったとすると、 打った文字と、このプログラムが画面に書く文字とが交互に並び、 aabbcc のようになると思うかも知れないが、そうではない。 getchar() は、Enter が押されるまで待っていて、 Enter が押されて初めて、そのまでに入力された文字を処理することになっている。 で、実際の出力は次のようになる。

abc
abc
defg
defg

(6.1.4) Ctrl+C を押してもこのプログラムは終わるが、 それは途中で中断したことになる。

§6.2 文字とその数値

(6.2.1)

#include <stdio.h>

int main() {
  int c;

  while ((c = getchar()) != EOF) {
    if (c == '\n') {
      putchar(c);
    } else {
      printf(" %02x", c);
    }
  }
}

(6.2.2) コンピュータの中では、文字も数値として扱われる。 その値を見てみるプログラムである。

while の行は前と同じ。 ループ本体を見よう。 if (c == '\n') とあるのは、 c を、\n という文字、すなわち改行と同じかどうか調べている。 「\n という文字」は、\n を一重引用符でくくって表す。 文字列なら二重引用符、単一の文字なら一重引用符、という規則である。 一重引用符は Shift しながら 7 のキーを押して入力する。

c が改行だったらそのまま putchar() する、ということは改行するということ。 それ以外の文字のときは、printf() 文が実行される。 %02x は、いままでよく使ってきた %d に代わるもの。 最小でも二桁の幅で、十六進法による表示、しかも十から十五までは小文字の a から f で表示せよ、 との意味である。

(6.2.3) 数字、大文字小文字、記号などを入力してみよ。

(6.2.4) (いわゆる)日本語を入力してみよ。かなや漢字一文字でよい。 一文字に対し 2 バイト分の出力がある。 (「バイト」とは、十六進の 00 以上 ff 以下の数一つを指す。)

§6.3 (いわゆる)日本語

いままで、「(いわゆる)日本語」と書いてきた。その理由を説明する。 コンピュータ関連で「日本語」というとき、 それは言語としての日本語ではなく、 日本語を表記するときに最も広く使われている、漢字かな交じり文に使われる文字を意味することが多かった。 よって、それを「(いわゆる)日本語」と私は書いている。

(最近では自動翻訳や生成 AI の出現によって、 言語としての日本語を扱うことも増えてきたが。)

コンピュータは最初、英語圏でできた。 そのため、アルファベットや数字、それにいくつかの記号が使えるよう、 「ASCII コード」が設定された。 その文字一覧は、 jis.html の左半分にある。 十六進の 20 から 7e までであることに注意。

そこに(いわゆる)日本語をつけ加えるため、 「JIS コード」が考えられた。 これは 2 バイトで一文字を表すのだが、ASCII コードと重複する。 そのため、“ここからは(いわゆる)日本語です”という特別なバイト列と、 “ここで(いわゆる)日本語は終わりです”という特別なバイト列とで囲んで使うことになっていた。

それでは使いにくいことがわかってきて、ASCII コードとぶつからないように、 JIS コードの数値をずらして使うようにしたのが、Shift_JIS である。 ここの Windows のコマンドプロンプトで使っている(いわゆる)日本語コードは Shift_JIS である。 その 1 バイト目は ASCII とぶつからないが、2 バイト目はぶつかることがある。 たとえば、前の節のプログラムで「」のコードを数値で出力させると、95 5c とわかる。 この 5c\ のコードと同じである。これが、(1.11.2) で述べた現象の起こる理由である。 (printf()\ そのものを表示させるには \\ と書くことになっている。)

ほかに、JIS コードを ASCII と両立させたコードとして、EUC-JP がある。 これだと、上に述べた問題が発生しない。

最近は、JIS コードとはまったく異なる、「Unicode」が使われるようになってきた。 「UTF-8」はその一つである。 言語 Java では、文字コードは Unicode と決められている。

多くのプログラムは、入力される文字列が 1 バイトの文字だと思って書けば、 (いわゆる)日本語を入力しても正しく動く。 ただし例外もある。すぐ出てくる。

付:パス (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 ..」を実行する。

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

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

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

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

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

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

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

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

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

付:Linux の使い方

学術メディア創成センター演習室のパソコンでは、 Windows のほかに Linux も使える。 Linux は UNIX とほぼ同じように使える OS である。 Linux にはいろいろな種類があるようだが、 はいっているのはそのうちの Ubuntu である。

OS 選択画面で Linux を選ぶ。

ユーザー名は KAINS ID から @kains.net を取り除いたもの。 パスワードは Windows と同じ。

左端の一番上が「Firefox ウェブ・ブラウザ」。 アカンサスポータルにアクセスできることを確認した。

その二つ下に「ファイル」がある。 これが Windows の Explorer に相当する。

左端の一番下、正方形が 3 × 3 に並んでいるのが、 「アプリケーションを表示する」である。ゲームもいくつかはいっている。

「ファイル」の中の、何もないところを右クリックし 「端末で開く」とすると、「端末」と呼ばれる、 Windows のコマンド・プロンプトに相当するものが開く。 コンパイルは Windows と全く同じように、「gcc hello.c」とする。 実行ファイルを動かすのは「./a.out」である。 「ファイル」の中で新規ファイルを作る方法は見つけられなかった。 代わりに、端末の中で「touch 新規ファイル名」とせよ。

「ファイル」の中でいままで作った .c ファイルを開くと、 (いわゆる)日本語は普通に表示される。 しかし、Windows と Linux ではデフォルトの(いわゆる)日本語コードが異なるため、 そのままコンパイル・実行すると文字化けする。 新規ファイルに全文をコピーする必要がある。

この端末では、 画面制御エスケープシーケンス(後述)が有効である。

この端末の中で使えるコマンド cd, pwd, ls, cp, rm, mv などについては、 ネット検索して調べられたい。

Linux の終了は右上の「▼」である。


岩瀬順一