C 言語の文法(1)

C 言語の文法(1) 今回は、C 言語の文法について学びます。 堅苦しく「文法」と考えずに、コンパイラが正しく理解してくれるようにプロ
グラムを書くには、必要最小限どんなルールに従ったら良いか?という程度に
考えて下さい。それが文法です。 意味が通じないことをつぶやいても、仕方がないから、相手に意味が
通じるように話す、という感じの話題です。 言葉なんて、通じればそれでいいんです。ですが、通じなければ全く
意味がありません。仲間同士で「どうよ」
「プンプン丸(¬¬_¬¬) 」
「ゲロ
Σ(`□´ ;)」「徹夜だね・・・」 これで、会話になっているなら、何の文句もありませんが、プログラ
ムは、他の人も読みますから、文法に従ってきちんと書かないと、他
のプログラマも読めませんし、何よりもコンピュータが理解してくれ
るように書かないと、全く意味がありません。 この機会に、今後の授業や、レベルアップした際に説明のために使われる「文
法上の用語」を導入しますので、覚えていって下さい。 ただ、文法については必要最小限にとどめたいと思います。慣れて、真似して
いるうちに、ひとりでに身に付くとも思います。
「言葉は、真似が大事」 C 言語の文法を学ぶと同時に、変数と出力を学びます。
プログラミングでは、白紙のキャンバスに絵を描いて、他の人に何かを伝える、
ということをやる訳ですが、実を言えば Visual Studio が「下絵」を書いてくれ
ています。
その「下絵」がどんな絵になっているの
かを、まず見てみましょう。
次に、軽く文法の基礎を扱います。
今日のキーワードは、
「変数」、
「出力」で
す。
1
白紙のキャンバスに、何を書くの。 ほとんどが自動合成されていますね。その構造を眺めてみましょう。授業では、
この説明を後回しして「課題」の方に先に行くかも知れません。
何もない、真っ白な画面には、主に 4 つの要素が来ます。
(1) コメント (2) プリプロセッサ用の記述 (3) 変数や関数の型定義 (4) 関数 こういう感じの「吹き出
し」がコメントです。
(1) コメント まず、先頭部分に「コメント」があります。
コメントとは、「注釈」とも言います。
何についてのプログラムなのか、必要な内容を、他のプログ
ラマが読んだとき(あるいは、将来の自分が見た時に)わか
るように、記しておくのがコメントです。
あるいは、プログラムのあちこちに「付箋」をつけておくよ
うな感じで、「この部分のプログラムは、こんなことをさせ
ている」というのを、わかりやすい言葉で書いておきます。
私たちは、恐ろしい勢いで「考えたことを忘れて」いきます。ちょっと凝った
ことをやろうとすると、
「ああして、こうして」と手順を考えてプログラムを書
いたりしますが、数日経つとその「アイディアや手順」を思い出せなくなって
いたりします。他の人のため、ではなく、そのプログラムを使う「近未来の自
分のため」にコメントは大切です。 C++ではコメントには、二通りの書き方があります。
まず、/*(スラッシュ、アスタリスク)で始めて、 */(アスタリスク、スラッ
シュ)で終わる部分がコメントです。
プログラム中に、 /* */で書かれている領域がコメントです。
この部分は、コンパイラは一切処理しません。人間が見てわかりやすいように、
メモを書き込む時に使います。
C++言語では、この/*
*/に加えて、//(スラッシュ、スラッシュ)がコメント
2
として使えます。//から後は、その行の終わりまでがコメントです。
コメントが多いプログラムは、本人にとっても、他の人にとってもわかりやす
い良いプログラムです。 コメントは、人によって様々なスタイルがあって、
/* -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ * データを集計する -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐*/ のように、区切りの線を引いたりします。見やすく、わかりやすくします。
ですが、あまりコテコテに飾ると、読んでいて疲れるのでほどほどにしておき
ましょう。
(2) プリプロセッサ用の記述 次に、
「プリプロセッサ」
(Pre-Processor:前処理)が処理する記述があります。
「Pre」(プリ)は、「前に」「事前に」という意味の英語です。カタカナにする
ならば「プレ」とも発音します。
「プリペイド カード」は、”Pre-paid card”事
前に支払いを済ませたカードのこと。「プレハブ」は、”Pre-fabricated”,で、予
め部品を作っておいた家などのこと。他にも「プレ」や「プリ」がついた英単
語は多いので、探してみて下さい。
料理で言えば、予め野菜を洗っておいたり、包丁やまな板を用意したり、そう
しら「前準備」を、プログラムを書く人が細かく気にしなくて良いように、(最
近の「ミックスカット野菜」みたいなものですが、)この一行を書き込むのだと
考えて下さい。
「今日はこれを使う」という必要なものの名前を宣言します。 3
#で始まっている行が、このプリプロセッサ用の記述です。
#include “stdafx.h” は、前処理で「ヘッダファイル」というファイルを読み込ませています。
なお、プリプロセッサ用の記述は、部分的に C 言語の一部ではあるのですが、
「文の終わり」に;(セミコロン)をつけません。#で始まっている行は、
「特別扱い」だと覚えておいて下さい。
コンピュータの開発環境では、様々な「ライブラリ」
が使えます。「セット」とか「キット」とか、「パッ
ク」とか、そういった感じのものをイメージして下
さい。
例えば、裁縫セットを用意すると、中には針も糸、
はさみなどなど、必要なものが一式用意されていま
す。個別に準備するのは大変ですので、「一まとめ」
にしてあります。
パック旅行(ツアー)に申し込むと、航空券や宿泊、食事や、時にはお土産ま
で「セット価格」に含まれています。
「ライブラリ」もそんな感じで、関係する
ものが全部一まとめになっています。
C 言語では、stdio(標準入出力)というライブラリを使う場合が多くあります。
多くの C 言語の教科書(この授業では指定していません)の中では、
#include <stdio.h>
というのが先頭にあります。今回は Visual C++を使いますので、stdafx(標準
環境)を使います。
ライブラリを使う時には、コンパイラに「そのライブラリには何が用意されて
いるか」を伝える必要があります。そこで、そのライブラリで利用可能な関数
や変数、マクロなどの「プログラム部品」の一覧を、プログラムの先頭で指定
しておきます。それらは、ヘッダファイルに書かれています。ヘッダファイル
の拡張子は h です。(今日は、さらりと流して下さい。) (新しい言葉、
「変数」、
「関数」、「マクロ」が出ました。マクロは後回し
しますが、今日この「変数」、「関数」を説明します。) 4
先週の授業では、Sleep を使うために windows.h をインクルードしました。
stdio(標準入出力)ライブラリ用のヘッダファイルは、stdio.h です。
標準ライブラリのファイルは、特別なので、include する時に””(ダブルクオー
テーション)ではなく、< >(不等号)で囲んで表示します。この辺の違いは、
今はあまり気にせずに次にいきましょう。
(3) 関数や変数の型定義 その次に「関数、変数などの使用宣言」が来ます。
まず、変数からいきましょう。これらの「プログラム用語」の説明は、何度で
も繰り返しますので、今日一日で全部覚えようなどと思わないで下さい。何度
も繰り返す説明の中で、2 回目で覚えてもいいし、20 回目で覚えても構いませ
ん。
プログラムそのものの説明のためには「プログラム用語」を使います。説明す
るために使う言葉なので登場してきますが、大切なのは、こうした文法用語を
覚えることよりも、プログラムそのものの書き方を覚えることですから、説明
を聞いて理解するために、これらの言葉を使っているのだと考えて下さい。
変数は、「値」の入れ物です。
値の入れ物に、名前をつけておきます。これが変数名です。
名前の付け方にはルールがあります。
・ 必ず、英字(A-Za-z)か_(下線)で始まる。 ・ 英字、下線の他に数字も使える。 ・ 途中に+,-などの記号を含めることはできない。 ・ 大文字と小文字は区別する。 ・ C 言語で特別な意味のある言葉(予約語)は、使えない。 などです。Visual Studio では 2048 文字まで「識別」(区別)してくれますが、
通常は 32 文字以内程度を考えておくと良いでしょう。
一つの変数には、値を一つだけ入れることができます。
5
また、変数にはスコープ(scope)と言って、見ることのできる範囲が決まっ
ています。(これは、後から出てきます。)
さらに、C 言語では変数に「型」が決まっています。
(「変数」に「型」が決まっていない言語もあります。)
ルールとは別に、
「名前の付け方」には「掟」
(笑)がありまして、必ず中身
がよくわかるような名前をつけろ、ということです。あるいは、職場によ
っては「ネーミングルール」が決まっていて、これが守れないプログラマは、
村八分にされます。(笑)
中身に、何を入れたいかで、「型」を宣言していきます。型には
(1) int (整数) (2) float (浮動小数点の実数) (3) double (倍精度の浮動小数点の実数) (4) char (文字型) などがあります。
ごみの分別と同じです。型を意識して変数を使い
ましょう。
型を間違えると思い通りの結果が得られなかっ
たり、コンパイラに警告されたり、予想外の結果
になることがあります。
ロジック(論理)には間違いがないのに、どうして結果がおかしいのか、型を
意識していないと「コンパイルエラー」はないのに、正しい結果が出ない場合
があります。
(4)関数 最後に、関数(プログラムの本体)です。
関数の説明は、
「関数」の正しい定義は後回しにして、まず、今日プログラムす
る_tmain の部分は「関数」という文法上の構造だということを、頭の片隅に置
いておいて下さい。
6
プリプロセッサに処理させるマクロを使ってプログラムを書く場合もあります
が、ほとんどの場合は、関数にロジック(論理)を書いてプログラムし
ます。
関数とは、「ひとまとまりの処理を行うプログラムの単位」です。
できるだけ、
「一つの機能」を「一つのかたまり」としてプログラムしていきま
す。この「機能」
(=function)を、数学用語の「関数」と呼んでプログラム用
語になっていますが、意味的には「機能」と考えた方が良いかも知れません。
余談ですが、関数を中国語で読むと(ファンシュエ)です。このファンシュエと
いう音が英語の function になった、という語源説がありますが、私は確認してい
ません。(トリビアです。)
コンパイラは、まず main という名前の関数を探しにいきます。つまり、全ての
プログラムが必ず持っているのが main 関数です。
Visual C++の環境では、コンソールアプリケーションとして_tmain が main を
呼び出すように、内部的に作られています。
(この読み解き方は、中級以上の課
題です。
)この main 関数から他の関数を呼び出す、という構造でプログラムを
書いていきます。
しばらくは、
(3)関数や変数の定義は登場しませんが、
「白紙のキャンバス」に
何が書かれるか、駆け足で説明しました。
今日から、main の関数の中に
プログラムを書いていきます。
まず、この関数の中に、変数を
定義して、数値の入れ物を用意
していきます。
プログラムの実行順序 7
プログラムは、原則として上から下へと実行してきます。
当たり前のようですが、大切なことです。
人と会話をする時には、話をする順番がありますね。それと同じように、相手
が「何の話題か」知らない時は、まずその説明から話します。
代入と表示 教材に、代入という言葉が登場しました。これは、数学の代入とほとんど同じ
意味です。より具体的には、「a に 31 を代入する」という表現は、a という名
前の「変数」
(値の入れ物)に、31 という値を保持させる(値を入れておく)と
いう意味になります。
ここで、気をつけて欲しいことがあります。プログラムの式で、
a = 31; と書いたとき、この「文」には「a に 31 を代入する」という意味はありますが、
「a は 31 に等しい」という読み方をしない、ということです。a には 31 の値
を代入しますから、元々a という変数(数値の入れ物)に 15 が入っていたとし
ても、この式で 31 を代入しますから、元々は違っていたのに結果として a は
31 に等しくなります。ですが、
「代入」という命令の結果です。
代入がもっとはっきりする例は、
kotae = a + b; です。この文には、
「a と b を加算して、その結果を kotae という変数に代入す
る」という意味があります。ですが、「kotae の値は、a + b に等しい」という
意味は全くありません。
こうした文を代入文と呼びます。
注意して欲しいことは、
「代入文は、決して数式として読むな」ということで
す。数学の問題ではありません。見た目は数式のようですが、=の右辺の値を左
辺に代入しろ、という「命令」なのです。=(等号)のことは、等号とは言わず
に(文字の名前は等号ですが)、文法的には代入演算子と言います。
演算子は、プログラム用語です。英語では operator と言います。
8
Operate するもの、という意味ですが、operate の意味は「動かす」、
「働かせる」、
「機能させる」などです。英語の operation には「手術」
という意味もありますし、
「作戦」という意味もあります。普通の英単
語の operator は、
「(機械などを)操作する人」という意味もあります。
そうした役割をしているのが演算子だと思って下さい。
値を代入したら、次は表示です。
「変数 kotae の中身を表示する」という場合には、printf 関数を使います。
本日最初の例題 以下のプログラムを入力してみましょう。
前回と同様に、Win32 コンソールアプリケーションとして作ります。
プロジェクト名は、ここでは tasizan としてみましたが、各自管理しやすい名前
ならば何でも構いません。
9
ここにプログラムして行きます。以下のプログラムを書きます。
int a, b, kotae; a = 31; b = 7; kotae = a + b; printf( “%d”, kotae ); ここで、画面に行番号が出るようにしてみましょう。
デバッグメニューから、「オプションと設定」を選びます。
10
テキストエディタをクリックして開いてから、C/C++を選び、
行番号にチェックを入れると、行番号が表示されるようになります。
8 行目を理解しましょう。 ← ここが、今日学習する 1 番のポイント
printf (“%d¥n”, kotae);
printf 関数は、””(ダブル・クォーテーション)で囲まれた部分を画面に表示
します。前回の例では、「今何してる?・・・」でした。
printf (“今何してる?”);
printf 関数で「書式指定」を行う時は、「変数」の前に””(ダブル・クォーテ
ーション)で囲んだ「書式指定文字列」を書いて、変数の値をはめ込む場所を%
で指定し、その後に変数のリストを続けます。
11
十進整数で表示を行う時は、d(decimal; 十進数)を用いて、%d と記します。
行の最後の¥n には、「改行」の意味があります。
こうした¥で始まる文字を、「エスケープ文字」と言います。
「エスケープ」とは escape(逃げる)ですが、通常目に見ることができない「改
行」とか「タブ」とかを見えるようにし、
「制御文字」の世界から「逃がして」書
くことができる文字として扱うのだという感じで理解して下さい。
先週の授業では、エスケープ文字をきちんと取り上げませんでした。¥(円マー
ク)は、エスケープ文字を開始する文字として使われてしまっているため、円マ
ーク自身を表示する時には、¥¥と、二つ並べます。最初の¥は「エスケープ文
字だよ」ということを意味し、二つ目の¥で円マークを表示する、ということ
を意味します。
なお、先週説明せずに使ってしまった言葉がありました。それは「ソースコ
ード」と「プログラムコード」です。
・ 英語のコード(Code)には、
「規律」とか「(意味のある) 記号列」とい
う意味があります。プログラムの記述のことを、プログラムコードとか呼
ぶ場合があります。
・ 機械語プログラムのことは、マシンコードと呼ぶことがあります。
・ ソースコードは、コンパイルして機械語にする前の言語、つまり C 言語の
プログラム記述を意味します。
・ プログラムの記述のことをプログラムリストとよぶ場合があります。さら
に、ソースプログラムのことですからソースリストとよぶ場合もあります。
これらの名称は、私の授業ではどれも同じものを指していますので、リストを
添付して下さい、とか、ソースを添付してと言われたら、プログラムリストを
テキストで切り取って、文書に貼付けて下さい。
(細かく言うと、きちんと区別しなければならない場面もありますが・・・、
この授業では気にしないで下さい。)
12
本日の課題(1) 課題(1) 以下の 2 行を画面に表示するプログラムを作成し、プログラムコー
ドと画面コピーを報告して下さい。
・ He said, “Yes, we can!”
・ 牛丼(並)¥250 に値引き
ヒント:
“ダブルクォーテーションや、¥(円マーク)の表示方法が問題です。
なお、二重引用符号が使ってあれば、もっと面白い英文でも構いませんし、¥(円
マーク)が使ってあれば、牛丼以外の値引きでも構いません。
(ここまで出来ていれば、C 評価とします。)
本日の例題(2) このプログラムを走らせて、結果を報告して下さい。
printf の中での書式指定では、%で始まる書式指定子と一対一に対応をつけます。
13
書式指定子 基本的な書式の指定は以下のようになります。
書式 意味 指定子 %d %g %e %f %x %o %c %s %% 機能(表示方法) Decimal 十進数で整数表示する。通常は int(整数型)の
(10 進数) 表示に使う。 %e か%f の E(浮動小数点型)や F(固定小数点型)を「適切」に
どちらか 切り替えて、見やすい表示をしてくれる。 Exponent A × 10B の形で表現する。 (指数表記) -1.23 E-4 = -1.23×10-4 Fixed Point 全体の桁数と、小数点以下の桁数とを指定して表
(固定小数点) 示する。 heXadecimal 16 進数の符号無し文字列で表示する。 (16 進数) (例 10 進数 63 = 16 進数 3F など) Octal 符号無しの 8 進数形式で表現する。 (8 進数) (例 10 進数 63 = 8 進数 77 など) Character %c 一つが1文字に相当する。’’(シングルクォ
(文字) ーテーションで囲まれているのが文字) String “”(ダブルクォーテーション)で囲まれているの
(文字列) が「文字列」 % %一文字だと「書式指定」の意味になるので、 %という文字を出す時は%%と書く。 などと、たくさんあります(Wikipedia で printf を検索)が、まずは、%d と%f
を覚えましょう。これらは、数字の表示によく使います。
なお、意味のところに書いた読み方は、プログラムの説明などにもよく使いま
す。英語の意味がわかっていると、プログラムの表現が読みやすくなります。
%g は実数を「適切な形で表示する」とても便利な書式指定子です。桁数などが
よくわからなかったら%g を使う、というプログラムの書き方で構いません。
データを取ったり、デバッグしたりしながら、必要な桁数がはっきりしたら%f
を使うようにして、それまでは%g で良いでしょう。
14
書式指定子の修飾(本日のメインイベント!) (今日の課題を行う上で、最も重要なポイントです。)
数字や、符号を書き加えて書式をさらに細かく指定する場合があります。
今日の一番の課題は、この部分です。
書式指定 %8.3f 意味 全体8桁、小数点以下 3 桁で実数を表示する。 小数点を1桁と数え、整数部は 4 桁になる。 (小数点以下に 3 桁を割り当てて、整数部の桁数が 4 桁より多い
場合には、必要な桁数に増やされて表示される。) %80s 文字列を、全体 80 桁分の領域に右寄せして表示する。 %-80s 文字列を、全体 80 桁分の領域に左寄せして表示する。 %03d ゼロサプレスしないで3桁表示。 ゼロサプレスとは、先行する 0 を表示しないこと。 2 をゼロサプレスせずに3桁で表示すると 002 になり、 15 ならば 015 になる。通常はゼロサプレスされている。 %3d 整数を 3 桁で表示(右寄せ) 1桁の数字は左側に 2 桁分の空白が表示される。 (ゼロサプレスされる。) %-3d 整数を左寄せ 3 桁で表示する。 この場合には左寄せされてしまうので、3 桁という桁数を 指定しても意味がない。 %+3d 整数を全体 3 桁で表示し、マイナスの場合だけでなく常に符号を
表示する。(1 は、+1 と表示される。) 15
本日の課題(2) 例題(2) のプログラムを書き換えます。
11 行目:(修正前) double wa, sa, seki, sho; 11 行目:(修正後) int wa, sa, seki, sho; 21 行目:(修正前) printf(“%f %f %f %f¥n”, wa, sa, seki, sho); 21 行目:(修正後) printf(“%d %d %d %d¥n”, wa, sa, seki, sho);
この時、結果がどうなったか、実行結果の画面をまず報告して下さい。 次に、なぜその結果になったのか、理由を説明して下さい。 また、エラーメッセージなどもよく読んで、関係があるならばメッセージの意
味を説明しなさい。 16
本日の例題(3) 以下の例題を入力してみて下さい。
本日の課題(3) 例題(3)のプログラムを書き換えます。
29 行目:(修正前) printf(“a / b = %f¥n”, sho); この%f の部分を%13.7f, %8.5f などに書き換えて、表示した時に、そのような
表示になった理由を説明して下さい。
17
【今日の課題レポート】 まず、「本日の課題(1)」について、報告。(ここまでで、C 評価)
・実行画面のコピー(各自のデスクトップの一部を含めること)
・プログラムのソースコードのテキスト
本日以後のレポートで、ソースコードを Visual Studio の画面添付として報告す
る必要はありません。ソースコードのレポート添付は常にテキストで行って下
さい。
(第 2 回は、きちんと実行出来ているかの確認のため添付を指定しました。)
「本日の例題(2)」を実行させて、その実行画面を添付して下さい。例題(2)は、
ソースコードの添付は要りません。(B 評価)
「本日の課題(2)」を行い、実行画面のコピーと、ソースコードのテキストを添
付し、さらに「考察」を加えて下さい。(A〜S 評価)
「本日の課題(3)」を行い、こんな風に書式指定を変えたら、こうなった、とい
う説明を、画面コピーを貼付けながら説明して下さい。(S〜SS 評価)
発展課題
第 2 回の授業で行った Line もどきの画面で、より、対話っぽくなるように、片
方の「発言」を「コンソール画面右寄せ」で表示するように切り替えて下さい。
ヒントは、”%80s”の書式指定を「文字列」の前に入れる、という方法です。
(この課題にはこれ以上のヒントを出しません。)(SS〜SSS 評価)
途中の「課題」が抜けている場合には、それぞれ 1 ランクずつ下げますが、で
きると思うものだけをやって構いません。
なお、今日の分の得点割当も 10 点満点ですが、C=6.5 点、A=8.5 点、S=9.5 点、
SS=10.5 点、SSS=11.5 点で採点します。
さらに書式指定を色々と試して、
「こういう指定をしたらこうなった」というバ
リエーションを増やして報告した場合にはさらに加点します。でもなるべく、
今日の授業中にレポートまで作成しましょう。提出期限は来週の金曜日の授業
開始時刻です。
18