■C言語の特徴
まずプログラムは大別するとインタープリタとコンパイラに分かれます。
インタープリタの代表としてBASIC、コンパイラ型の言語の代表としてC言語があげられます。
世の中ではC言語が主流です。なぜC言語は普及しているのでしょう。
とりあえずBASICとC言語の違いについて述べておきます。
BASICは、ハッキリ言って単純です。なので、誰にでもかけます。
でも、そのうち限界を感じます。その理由の一つとして、
○遅い
ことがあげられます。それに比べC言語は速いです。なぜこのように違いが生じるのでしょう
?
そもそもプログラムがどう動くか考えてみます。
まず人間が書いたプログラムは機械(パソコン)には分かりません。
そこで、プログラムを機械が分かる言葉(以下、マシン語)に翻訳する必要があります。
このマシン語に翻訳する作業を、コンパイルと呼びます。
話を元に戻すと、インタープリタは、その場で実行できるかわりに、
実行時に翻訳しながら実行しています。対してコンパイラは、
実行前にコンパイルを終わらせてるので、あとはマシン語を実行するのみ!
と言うわけで、C言語はコンパイル分実行が速くできます。
C言語の利点は速いだけではありません。
BASICでは使えない関数や構造体等を使って、プログラムをきれいにまとめることが可能です。
そしてC言語は汎用性に優れています。あと基本的にBASICでできることはC言語でも出来ます。
■開発環境を手に入れよう
○Borland C .... Windowsで有名なコンパイラ。ただで入手可能。
○Visual C++ .... 市販のコンパイラ。Win対応。
○MPW .... フリーのMac対応コンパイラ。
Borland Cの場合、テキストエディタがないので、有名なものを紹介します。
○CPad .... コンパイラのパスを渡すとと自動でコンパイルしてくれる
○BCC developer .... 普通はこちらを使いましょう。多機能で便利。
○ボーランド帳 .... CRenさん作のエディタ。ホームページから入手可。(リンクページからどうぞ)
■世界に挨拶を!
<サンプルプログラム>
#include <stdio.h &rt;
void main(){
printf("Hello world");
}
|
では、ソースコードの解説。
1行目 #include <stdio.h&rt;
include・・・<>内にあるファイルを読み込む。
どう言う意味でしょう?
stdio.hには、普通の入出力の関数が書かれています。(関数についてはあとで話します)
このstdio.hというファイルが、全部このプログラムの一行目に読み込まれ、
三行目のprintfを使えるようになります。
ちなみに、拡張子(.h)がつくファイルは、ヘッダファイルと呼ばれ、
機能ごとにファイルに分割されています。
必要に応じてincludeして、その関数(命令)を使えるようにします。
また、#から始まる文は、プリプロセッサと呼ばれ、
コンパイル時に実行されます。
2行目 void main(){
まず、mainは、C言語の命令が始まった時、一番初めに呼ばれる関数です。
C言語は関数が次々に呼ばれて処理を実行するので、どこから始めるのか
コンピュータに教えなければいけないって訳です。
次にvoidって何? 何も値を返さないってことなんですが、
関数とは命令を実行させるだけでなく、その結果出た値を関数を呼び出した所に返すことができます。
このmainという関数は、何も値を返さないので、voidです。
関数の所でもう一度説明するので、今は分からなくていいですが。
次。()って何に使う?
関数は値を返すだけでなく、変数の値などをもらって、
それらをその関数の命令内で使うことができます。
()にはその渡す値(引き数といいます)を書くわけですが、
詳しいことはまたあとで。ここは()だから、なにも引き数がないと思ってください。
{は? 関数の始まりの印です。 反対に、}は関数の終わりの印です。
3行目。printf("Hello world");
このプログラムのメインです。Hello worldと画面に表示します。
printf("文字"); で画面に文字を出力できます。
;(セミコロン)は、文末の印。付け忘れないようにしてください。
よく見ると、この命令のあいだに、空白が入っていますが、なくてもいいんです。
ただ、空白が入っていると、「この関数の命令ですよ」というのが、
一目で分かります。
■今回のまとめ
|
○mainは、プログラムで一番始めに呼びだされる。 ○関数の始めと終わりは、{ }(中括弧)で区切る ○printf("文字"); で画面に文字を表示できる。 ○printfなどの命令の文末には「;」を忘れずつける。 |
■変数の宣言、代入、表示
今回は変数の使い方を説明したいと思います。
下のサンプルを見て下さい。
<サンプルプログラム>
#include <stdio.h&rt;
void main(){
int a;
a=3;
printf("a=%d",a);
}
|
では、ソースコードの解説へといきます。
1行目 #include <stdio.h&rt;
これは前回と一緒。分かりますね。
2行目 void main(){
これも同じ。C言語はmain関数から始まります。
3行目。int a;
これは何?>「これからaという変数を使いますよ」と宣言をしているのです。
intの後のaが変数名です。
じゃあ、intとは何ぞや?ってことですが、
C言語の変数には変数の種類によって使える数の範囲が違うのです。
このintを変数の「型」といいます。
変数を箱にたとえると、名前は箱の名前で、
型は箱の大きさ。
では、変数の型の種類をざっと紹介しましょう。
| 型名 | 使える範囲 | char | -128〜+127 | short | -32768〜+32767 | int | -2147483648〜+2147483647 | long | -2147483648〜+2147483647 |
|---|
4行目。a=3;
予想はつきますね。代入文です。
ここでは、変数aに3が代入されています。
セミコロンをつけるのを忘れないよう注意しましょう。
5行目。printf("a=%d",a);
aの値を画面に表示します。
%dって何?
""で囲まれた部分を文字列と言い、そのまま画面に表示させるのですが、
この%dは、画面にはあらわれず、
カンマの後の数字を%dに持ってこさせるようにしてます。
つまり、%dには,の後のaの値、つまり3が入ります。
二つの変数を表示させるには?
printf("a=%d b=%d",a,b);
一つ目の%dはaを、二つ目の%dはbを持ってこさせています。
頭に%がつく文字は、幾つか種類があります。
| 種類 | 効果 | 扱う変数の型 | %d | 数字を表示 | int,short,long,float,double | %i | 整数を表示 | int,short,long | %f | 小数を表示 | float,double | %c | 一文字を表示 | char | %s | 文字列を表示 | char(配列) | %% | %を表示 | -- |
|---|
■変数の演算
<サンプルプログラム2>
#include <stdio.h&rt;
void main(){
int a,b,c=7;
char d;
a=3;
b=12-a;
c++;
a*=2;
d = 'A'
printf("a=%d",a);
printf("b=%d",b);
printf("c=%d",c);
printf("d=%c",d);
}
|
実行結果は..?予想してみて下さい。(後で解答があります)
では、ソースコード2を解説します。
まず3行目のint a,b,c=7;ですが、
複数の変数を宣言したい時には、カンマで区切って下さい。
型が違う時は別にしなきゃ行けませんが。
c=7ですが、宣言といっしょに代入することも出来ます。
4行目。char d;
char型の変数dを宣言しています。
5行目のb=6+a;
予想はつくと思います。
4行目でaには3が代入されているので、
bには12-3で9が代入されます。
6行目。c++;
...? これはインクリメントといって、変数の値を+1します。
だから、cには8が入ります。また、++c;という書き方も出来て、これでもOKです。
ちなみに、逆にデクリメント(--)というのもあって、変数の値を-1します。
7行目。a*=2;
これも何か変。僕も始め見た時は訳が分かりませんでした。
*=は、特殊な代入演算子で、ここではaに2をかけたものをaに代入します。
つまり、a=a*2;と同じ意味です。ただ、aを2つ書かなくてよく、便利です。
他にも、+=,-=,/=,^=などがあります。
8行目。d = 'A'
'A'をchar型の変数に代入しています。
char型は整数だけだなく、一文字(1byte)も扱えます。
別に他の型でもいいのですが、無駄なメモリが割り当てられてしまいます。
あと注意したいことは、一文字を表す場合は「'」で囲むことです。
前に書きましたが、printfで出力するには%cを使います。
9〜12行目は出力をしているのですが!
予想した結果とは、違いますね。
一行に連なって出力されてしまいました。
これを解決するには、「改行」の意味を表す、\nを文字列の部分に入れます。
printf("a=%d",a);
printf("\nb=%d",b);
printf("\nc=%d",c);
printf("\nd=%c",d);
\nも%dなどと同じように、実行結果には\nなどと表示されたりはしません。
また、これにも幾つか種類があります。
| 種類 | 効果 | \n | 改行 | \t | タブ | \r | 同じ行の先頭に戻る | \\ | \を表示 |
|---|
■小数を使った変数
|
<サンプルプログラム3>
#include <stdio.h>
void main(){
float a=16,b=3;
int c;
float d;
c = a/b;
d = a/b;
printf("c=%d",c);
printf("\nd=%f",d);
}
|
では、ソースコード3を解説します。今回はやけに長いなぁ。
2、4行目に注目して下さい。float型って何でしょう?
いままでは整数しか扱ってこなかったけど、この型を使えば、
小数も扱うことが出来ます。
float型以外にも小数を扱える型があります。(下の表を見て下さい。)
さて実行結果は...
c=5、d=5.333333
cはint型なので、小数でも整数に直されます。
float型の変数を表示するには、%fを使います。
| 型名 | 使える範囲 | 桁数 | float | 3.40282*1038 〜 3.40282*1038 | 7桁 | double | 省略 | 14桁 |
|---|
■今回のまとめ
さて今回は、インクリメント、デクリメントの補足説明、
scanfなど、細かいことを書きます。
■前置演算、後置演算
|
//サンプルプログラム1
#include <stdio.h&rt;
int main(){
int a=1;
int b=2;
b = a++;
printf("a=%d",a);
printf("\nb=%d",b);
return 0;
}
//サンプルプログラム2
#include <stdio.h&rt;
int main(){
int a=1;
int b=2;
b = ++a;
printf("a=%d",a);
printf("\nb=%d",b);
return 0;
}
|
さて、メインはここからなんです。
先に実行結果を書いてみます。
サンプルプログラム1では、
a=2
b=1
でした。
でもサンプルプログラム2では、
a=2
b=2
でした。
実はサンプルプログラム1のb = a++のインクリメントの使い方、後置演算と呼んで、
先に代入をしてからインクリメントの処理をします。
つまり、先にbにaの値1が代入されてからaが1増えるのです。
これに対してサンプルプログラム2のb = ++aのインクリメントの使い方を前置演算と呼んで、
先にインクリメントの処理をしてから代入します。
先にaが1増えてからbに代入されるので、bがaの値と同じ2になります。
では次のステップに行きませう
■scanfで値を入力
<サンプルプログラム3>
#include <stdio.h&rt;
int main(){
int a;
printf("aの値を入力して下さい");
scanf("%d",&a);
printf("\na=%d",a);
return 0;
}
|
aの値を入力させ、表示させるプログラムです。
scanf("書式指定文字列",アドレス)
書式指定文字列とは、printfにでてきた、%cとか、%dとかいうやつです。
ここでもう一回かきます。
| 型指定文字 | 意味 | 使われるデータ型 |
|---|---|---|
| %c | 「1文字」として入力する | char型 |
| %d | 10進数で入力する | int型 |
| %x | 16進数で入力する | |
| %o | 8進数で入力する | |
| %ld | long型変数を 10進数で入力する | long型 |
| %f | float型変数に実数を入力する | float型 |
| %lf | double型変数に実数を入力する | double型 |
| %s | 文字列を入力する | char型配列 |
#include <stdio.h&rt;
int main(){
char a;
printf("aの値を入力して下さい");
scanf("%c",&a);
printf("\na=%c",a);
return 0;
}
|
■今回のまとめです。
|
○a=++bは、bの値を+1をしてからaに代入(前置演算) ○a=b++は、aにbの値を代入してからbの値を+1(後置演算) ○scanf("書式指定アドレス",&変数名) |
今回は予告通りfor文,while文とif文の解説です。
■for文でループ
<サンプルプログラム>
#include <stdio.h>
int main(){
int a;
for(a=1;a<=5;a++){
printf("\n%d",a);
}
return 0;
}
|
ソースコードの解説です。
4行目の for(a=1;a<=5;a++){ ですが、
書式はこうです。 for(最初の代入文;条件;実行文){
まず3行目で宣言した変数aに1が代入されます。
そして中かっこの中の文に移動し、aの値を表示させたあと、
さっきのfor文に戻ります。
for文の3番目の実行文でaの値を1プラスし、
そしてfor文の2番目の条件と比べます。
ここで、aは2なので、条件にあっています。
それなら printf("\n%d",a); をまた実行して
またのfor文に戻ります。
この繰り返し。
最後にfor文の2番目の条件にあっていなかったら、ループはそこで終了。
まとめると、
for(A;B;C){
D
}
また、for文の中のDが1行なら、
for(a=1;a<=5;a++) printf("\n%d",a);
for文の3つめの実行文、実は+1だけじゃなくてもいいです。
for(a=1;a<=5;a+=2) (a+=2 → a=a+2です。覚えてますか?)
こう書けば、奇数の数だけを表示できますし、
for(a=1;a<=16;a=*2) こう書けば、aが1,2,4,8,16と2倍2倍になっていきます。
まあこのようにfor文は汎用性が高いです。
■while文でループ
次にwhile文。
<サンプルプログラム2>
#include <stdio.h>
int main(){
int a;
while(a<=5){
printf("\n%d",a);
a++;
}
return 0;
}
|
while文は、for文の簡易版です。
()の中の条件式が正しければ、{}で囲まれた文を実行します。
要は、for文の3番目の実行文がループ内に入ったって感じ。
forよりも使いやすいので、個人的にはこちらがお勧めです。
また、こんなことも出来ます。
while(1){
printf("無限ループ\n");
}
whileの()内に1を入れると、それだけで無限ループします。
実は、C言語において、条件式が正しければ「1」、
違うなら「0」という意味になるんです。
(後のif文で詳しくやります)
ループ文の基本的な使い方は終わり。分かりました?
次はif文!あ〜急がし
■if文で条件判断
|
<サンプルプログラム3>
#include <stdio.h>
int main(){
int a,b;
for(a=1;a<=5;a++){
b=a*5
printf("\n%d",a);
if (a==3) {
printf("\n%d",b);
}
}
return 0;
}
|
この部分、重要です。
今回は変数が2つ出てきます。
ループ文の中で、b=a*5とあるので、
5,10,15...と増えているのでしょう。
ここからが本題。
if (条件式) {実行文}
もし条件式が1(つまり正しい)なら{}内の文を実行する。
つまりここではaが3なら、bの値を表示させています。
BASIC、HyperCardなどを使い慣れている人には、
「あれ、なんでイコールが2つなの?(==)」
って思うかも知れません。(僕もそうでした)
でも『=』だと、C言語では「代入」を表すわけです。
区別するために、イコールを2つつけています。
では、改めて条件式をまとめてみます。
| 条件式 | 意味 | 実例 | ←の意味 | == | 等しい | a==3 | aは3に等しい | <= | 〜以下 | a<=4 | aは4以下である | >= | 〜以上 | a>=17 | aは17以上である | <= | 〜より小さい | a<4 | aは4より小さい | >= | 〜より大きい | a>17 | aは17より大きい | != | 〜でない | a!=10 | aは10でない |
|---|
最後の「!=」がC言語独特です。
<サンプルプログラム3>
#include <stdio.h>
int main(){
int a,b,c=0;
for(a=1;a<=5;a++){
b=a*5
c++;
printf("\n%d",a);
printf("\n%d",b);
if (a!=3) {
c++;
}
}
printf("\n%d",c);
return 0;
}
|
forとifを使った応用編です。
Aは1,2,3,4,5 と増えるので、
Bは5倍して5,10,15,20,25 と増えていきます。
では、Cの値は?
『Aが3でない』時にCは2つ増えるので、
1,2,4,5でCは8。
Aが3の時はCは一つしか増えないのでCは9。
■練習問題1
@
@@@
@@@@@
・・・・・・・
■今回のまとめ
|
○for(最初の代入文;条件;実行文) 条件が正しい間ループ ○while(条件) 条件が正しい間ループ ○while(1) 無限ループ ○if(条件) 条件が正しければ、次の{}内の文を実行 ○} else 前のif文の条件が正しくなかった時、次の{}内の文を実行 |
■練習問題の答
___@ __@@@ _@@@@@
○空白の数 ・・・最大段数(ここでは10)−現在段数
○@の数 ・・・現在段数×2−1
for文を入れ子にして使って表示させます。
//変数宣言
int dan,blank,a
//第1ループ
for (dan=1;dan<=10;dan++){
//空白描画
for (blank=1;blank<=10-dan;blank++){
printf(" ");
}
//アットマーク描画
for (a=1;a<=2*dan-1;a++){
printf("@");
}
//改行
printf("\n");
}
|
blank<=10-dan や a<=2*dan-1 のところがミソです。
■配列
プログラミングで最も重要な要素の1つである『配列』について解説します。
配列って何かというと、変数の説明で箱を使ったけど、それが1列に並んだような感じです。
//配列変数宣言 int a[5]; |
上ので、『aという名前の配列を6つ用意せよ』、という意味。
//配列変数宣言
a[5]={1,3,-5,10,-4};
|
上ので、 a[0],a[1],a[2],a[3],a[4] に数を代入しています。
a[5]には代入されてません。むしろ、a[5]は配列の中で使いません。
配列を宣言した時に、a[5]にはすでに『終わり』を表す文字 『\0』(ヌル文字)がすでに入っています。
だから結局、配列を用意したい時は、a[n]に配列にデータを入れたい数分だけ、nの値をきめることになります。
また以上2つのは一行でまとめて出来ます。
//配列変数宣言
int a[]={1,3,-5,10,-4};
|
int a[] にはコンピューターが勝手に適当な数を代入してくれるので、楽です。
//配列変数宣言
int a[]={1,3,-5,10,-4};
int n,total;
for (n=0;n<=4;n++){
total+=a[n]
}
|
配列は普通の変数と同じように計算できます。
これは配列変数に入ってる数の合計を計算させるプログラムです。
これをa1,a2,a3,a4,a5..といちいち変数を5つ決めて、代入させて...とやってると日が暮れてしまいます。
■2次配列
配列は横だけでなく縦にも並べられます。
//配列変数宣言
a[3][5]={{1,3,-5,10,-4},
{2,0,-9,7,6},
{-5,8,4,9,1} };
|
まず一つ一つの{}内に今まで通りに宣言します。
そして一つの{}を一まとまりと考え、それを『,』で区切ります。
区切った幾つかのまとまりの{}をまた{}で入れ子にします。そしてセミコロン。
この時、下の図のように数が代入されています。
また、一次元配列では完全に[]の数字を省略できましたが、
2次元配列では2次元目(最初の[])だけ省略できることに気をつけて下さい。
a[2][2]=+a[1][3]
■文字列
配列を使えば文字列を扱えます。
//配列変数宣言
char a[]={"this is a pen."};
|
文字列はダブルクォーテーションでくくって下さい。
この時、配列の中身はこうなってます。
このうちの一文字、例えば『a』を表示するには、
printf("%c",a[8]);
|
とすればいいのはもう分かりますね。
この文字列全体を表示するには、文字列をもってこさせる『%s』を使います。
printf("%s",a);
|
■2次配列を使った文字列
//配列変数宣言
char a[][15]={{"this is a pen."},
{"c language"},
{"あいうえお"}};
|
//配列変数宣言
printf("%s",a[0])
|
//配列変数宣言
printf("%s",a[2])
|
■練習問題2
■練習問題3
■今回のまとめ。
|
○型名 変数名[] で配列の宣言。 ○int a[6]={5,3,1,-1,-3,-5};この時、a[0]=5のように 0から始まることに注意 ○int a[6]={5,3,1,-1,-3,-5};の時、配列の最後(a[6])は使えないことに注意 ○型名 変数名[][] で2次元配列。 ○int n[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}}; の時、 2次元目は省略できるが(○n[][4])、1次元目は省略出来ない(×n[3][]、n[][]) ○文字列を扱うにはchar型の配列を使う ○文字列を表示するには%sを使う ○文字列を参照..1次元配列の場合、a とそのまま。(printf("%s",a);) ○文字列を参照..2次元配列の場合、a[n] 何行目かを示す。(printf("%s",a[1]);→2行目) |
間違い等ありましたら御指摘をお願いします。