表示してみよう

せっかくプログラムを書いても結果が見られなければ寂しい。たぶん実行画面さえ跡形も無く消えてしまうでしょう。消えない方にはちょっと無駄な所があるけど・・・さぁ、書き直してみよう。

#include <stdio.h>
//Lesson2例題
/*まずは実行して
結果を見よう*/

int main(void){
  int a,b,c,d,e,f,g,h;
  a = 7;
  b = 3;
  c = a + b;
  d = a - b;
  e = a * b;
  f = a / b;
  g = a % b;

  printf("a = %d,b = %d\n",a,b);
  printf("a + b = %d\n",c);
  printf("a - b = %d\n",d);
  printf("a * b = %d\n",e);
  printf("a / b = %d\n",f);
  printf("a %% b = %d\n",g);

  printf("エンターで終わります。\n");
  scanf("%c",&h);

  return (0);
}

今度は結果が見られたかな?下記のような画面が表示されているはず。

a = 7,b = 3
a + b = 10
a - b = 4
a * b = 21
a / b = 2
a % b = 1
エンターで終わります。
_

足し算や掛け算をするだけですごくめんどくさいんだ・・・。でも簡単な事をさせるからそう思うんだよ。

そのありがたみは後々にわかるとして解説だ。その前にmain()やprintf()やscanf()は関数といって、a,b,c,d,e,f,g,hは変数ということをまず覚えておいてね。

 

#include <stdio.h>?

Lesson1ではなかったね。これはstdio.hをincludeして下さいとコンパイラにお願いしている。丁寧にお願いすれば快く引き受けてくれると思う。

includeとはプリプロセッサ命令の一つでファイルをインクルードする(読み込ます)時に使う言葉だ。一般的に<>は元々用意されているファイル、""は自作ファイルに使うと誰かが決めた。たとえば「<stdio.h>」の代わりに「"kimi.h"」と書いてあれば、そのプログラムには「kimi.h」が付属しているはず。なければどうしようもない。

stdio.hはヘッダファイルと言って、関数の仕様が記されている重要なファイルだ。特にC言語に元々用意されているヘッダファイルを標準ヘッダファイルと言って、その中に記された関数を標準関数という。このヘッダファイルはprintf関数とscanf関数を使うためにインクルードした。他にも標準ヘッダファイルはたくさん用意されているし、ヘッダファイルを自分で作る事だってできる。

//、/*・・・*/?

//はコメントの始まりを表す。同じ行のココから先はプログラムとしては無視される。

で、複数行に跨るときは/*をコメントスタート、*/をコメント終わりとしてこの間はプログラムとしては無視される。

int main(void){}?

C言語は全てはmain関数から始まる。プログラミングとはmain関数を作ることと言っても良いと思う。名前がmainってだけで他の関数となんらかわらない。違うのはプロトタイプ宣言をしなくて良いだけ。だってmainから始めるって決まってるからわざわざ使うって宣言はいらないさ。あっ、プロトタイプ宣言(詳しくは後のレッスンで)とは「こんな関数を使いますっ!」ってコンパイラに覚えてもらうことね。

intは変数の型。ん、変数の型?関数じゃないのか??と疑問を持ったあなたはすごい。実は根本的に関数には型もヘッタクリも無い。関数の前に付く型は、その関数の呼び出し元に戻る値の型を指しているんだ。だからこのmain関数からはint型の値が返りますってことをコンパイラに宣言したんだ。ちなみに「宣言」とは、難しく考えずに「記す」とか「教える」ってニュアンスで覚えてもらって結構だと思う。

voidも変数の型。でもこいつはちょっと異端児で横着い。「こいつに型は無いっ」っていう型宣言で、何にでも変身するんだ。便利だけれどそれなりに使うのが難しい。まだそんなに深く知らなくても気にしないでおこう。で、関数の隣の()の中は、渡された引数(関数が受けとる値)に対応する変数を宣言する場所なんだ。そこがvoidだけになっているからmainへは何にも渡されないと思って良い。・・・voidの横に宣言される変数が無い?そう、単品で使える不思議な型なんだ。「だったら()内は空でいいじゃないか!」と思う人、kimiもそう思うけれどこらえてね。

mainの前をvoidってしているプログラムがたまにあるけど、それは良くないからkimiを信じてくれるなら真似しないように。int main(void)ってのはC言語の決まりで、こうなるしか方法がないんだ。そう、mainはintを返せって決まり事があるわけ。もう一種類あるけどもっと胡散臭いからこちらで覚えよう。ヒントは「char」。気になるあなたは調べてみてね。kimiの講座では出てこないから。。。

それで最後は{}で締める。main関数の中身はこの中だ!ま、威張らなくてもパッと見わかると思う。

int a,b,c,d,e,f,g,h;?

intは型の種類ってことはさっきわかって頂けたと思う。ちなみに,(コンマ)で区切れはいくつでも宣言できる。で、どんな型かといえば整数の型。-123や123などの小数点が付いてないもの。大きさにも制限があるんだ。でも大きさは環境によって違うから困る。ただ、コンパイルした時に大きさが決定されるので、実行環境で変わることは無いから自分の環境での大きさがわかればよい。ついでなので型種類と各参考サイズを多々紹介しておこう。

 

・char
1バイト文字を一文字
・short (int)
2バイトの整数(-32,768~32,767)
・int
4バイトの整数(-2,147,483,648~2,147,483,647)
・long (int)
4バイトの整数(-2,147,483,648~2,147,483,647)
・signed char
1バイトの整数(-128~127)
・unsigned char
1バイトの整数(0~255)
・unsigned short (int)
2バイトの整数(0~65,535)
・unsigned int
4バイトの整数(0~4,294,967,295)
・unsigned long (int)
4バイトの整数(0~4,294,967,295)
・float
4バイトの浮動小数点
・double
8バイトの浮動小数点

 

とは言え64bitのパソコンが増えてきた今、サイズがどうなっていくのか不明。どうして最初にちゃんと決めておかなかったって?急にパソコンが発達するもんだから決める暇が無かったんだ。参考に、kimiは普段から文字にchar、数字に(unsigned)intか(unsigned)longかdoubleしか使わないよ。え、intもlongも一緒だって?感覚的に短いか長いかわかるから使い分けてるだけだよ。

ココまで来れば勘のいいあなたは気付いたと思うけれど、a,b,c,d,e,f,g,hはint型だって宣言したんだ。これでint型8個分のスペースがメモリ上に確保されて、aからhの名前がそれぞれに付けられた。でもそのスペースに何が入っているかは誰も知らないんだ。そう、プログラム自体も知らない。使って初めて中身を知るんだけれど、変なもの(まさに変数)が入っているかもしれないから使わずそっとしておこう。そっと覗く方法もあるけどまだ秘密。

最後の;は何って?これは「プログラムにとっての一行」の終わりをあらわすんだ。こいつが居ないと長い長い一行になってしまう。決まってコンパイルエラーが出ると思う。kimiは未だにこいつを忘れるよ。ちなみに#で始まるプリプロセッサ命令の行には要らないよ。

=,+,-,*,/はまだしも%って何さ?

算数でならった普通の意味と少し違うところがあるから慣れてね。

算数で=は右辺と左辺が一緒って意味だけれど、C言語では右辺を左辺に代入するって意味なんだ。宣言したままの変数(中身は不明)を使うとエラーやバグの原因になるから使う前に必ず何かを代入してあげてね。

 

a = 7;
変数aに7を代入。aは7という数字を指す変数になった。
b = 3;
変数bに3を代入。bは3という数字を指す変数になった。
c = a + b;
cにaとbを足したものを代入。今は10。
d = a - b;
dにaからbを引いたものを代入。今は4。
e = a * b;
eにaとbをかけたものを代入。今は21。
f = a / b;
fにaをbで割ったものを代入。あまりは無視。今は2。
g = a % b;
gにaをbで割った余りを代入。今は1。

 

簡単でしょ?算数が出来れば当たり前だね。これらの記号は演算子っていって他にもたくさんあるんだ。ころあいをみて紹介していくね。

printf("a = %d,b = %d¥n",a,b);?

これは難しい!printfおよびfprintfでわかっていただけるかな?

無理だね。これを理解できるようになるのはもっと先だ・・・と言うことで簡単に簡潔にいこう!

printfが関数で("a = %d,b = %d¥n",a,b)が関数に渡される引数部分。基本は最後のprintfにあるように"***"だけで、***を表示してねって命令。¥n(後ほど詳しく)は改行文字で名の通り改行を表す。

問題は%やら""からはみ出た部分だ。%は引数を表示するって意味で、その次に形式を示す文字が1文字以上続く。ここでのdは対応する引数を十進数で表示してねってこと。その他は上記リンクfprintfの変換形式を見ていろいろ試してみるとわかりやすいかな。また、対応する引数とは""からはみ出た部分に順に対応していく。

「じゃぁ、%はどうやって表示するんだっ!」って?6個目のprintfを見ていただきたい。答えは簡単で、%%とすれば良い。

printfの説明を終わってもいいかな?後は必要な時に少しずつ覚えていってね。

scanf("%c",&h);?

printfがわかったなら要領はほとんど一緒だ。scanfおよびfscanfを参考にして欲しい。

printfが出力ならscanfは入力だ。こいつは入力されたものを%cでhに代入してよって意味。%dが十進数だったのと同じように%cは文字だ。

「ねぇ、ちょっとっ!&って何?私は見過ごさないしだまされないわっ」って貴女、kimiにとっては残念な文句だ。流してくれればよかったのに・・・

&hはhのアドレスを意味していてポインタ(後のLesson参照)という難解な構文を理解し無ければいけない。ただし、printfとscanfで片方変数、片方ポインタという謎は解決できない。なんか、ポインタの説明を使ってあたかもそれらしく初心者を納得させるような説明を見たことあるが、これは根本的にポインタとは別問題だ。

printfとscanfは別の関数だ。違っても普通、同じである必要は無い。同じような関数なので同じにした方が良かったのにとkimiも思うけれど、違うんだから仕方ない。残された道は一つ、おとなしくscanfはアドレス指定だと覚えるだけだ。

「いやぁ・・・ってかなんでこんなところにscanfが必要なんだい?」とおもった貴方、するどいっ。

なんでも良かったんだ・・・プログラムを邪魔できれば。宣言からhを消して、scanfの行を削除してコンパイルしなおして実行してみてください。結果がちゃんと読めたかな?

えぇ、読めた?そりゃすごい!!

「あのぉ・・・intに文字入れていいの?」と言うあなた!すごすぎる、そこまで気付くとは・・・kimiはお手上げ。

と言っちゃぁおしまいだ。もちろんcharとしてhを宣言しても結果は同じなんだ。出来ないと思い込むと矛盾がこの先出てくるから例を出しておいた。でも普段はちゃんと使いたい型で宣言してね。intが似ているからたまたまできるけどこれは悪い例・・・わざとやらないと説明で問題提起しにくいじゃない?

return (0);?

ついにLesson2もreturnの説明で終わりだ。疲れちゃったかたな・・・でもkimiも疲れてるんだよ。なかなか難しいね、説明って。

本題にいこう。こいつは呼び出し元に()内を返せって事。returnはかなり強い権力を持っていて、どこからでもさっと脱出する。returnが実行されると、同じ関数内でこの下に書かれた行は完璧に無視されてしまうんだ。

実はね、returnはえらっそうにしているけれど、たいしたこと出来ないんだ。一つの変数(値)しか返すことできないんだよ。嫌な上司みたいだね。でも大丈夫、たくさんの値を一つのように見せかけてだます方法があるからそのうち紹介するね。

 

これでLesson2を終わるけれど大丈夫だったかな?懲りずにLesson3も読破してみたいというあなたは長い付き合いになりそうだね。よろしくっ!とりあえずコーヒー飲んでくるよ。