補助資料:C言語の要点のメモ
(21/Nov/2002 版)


この文書は、C言語を学習する人が最低これくらいはおさえて欲しい、とい うところをざっとまとめたものです。網羅的に書かれてはいませんので、詳 細については別途参考書などで補ってください。
推薦図書は以下のようなものです。 ちなみにこの文書は以下の本の流れにそって書かれています。

C言語ことはじめ

Cプログラム(の、単純なもの)は以下のようになります。

(インクルード文など) main() { 宣言文(の並び) 文(の並び) }

ここで、

☆非常に簡単な(代表的な?)プログラムの例としては以下のようなものがあげ られます。

/* 最初の最初のプログラム by まえだとしゆき */ #include <stdio.h> main() { printf("Hello,World\n"); }


データ型

☆例として、整数の変数 i および浮動小数点数の変数 f をまず用意して、 1000000000 および 1.2 でその変数を初期化して、それらを表示させるプログラ ムは以下のようになります。

/* 型について by まえだとしゆき */ #include <stdio.h> main() { int i; float f; i = 1000000000; f = 1.2; printf("i=%d,f=%f\n",i,f); }


演算子と式

☆例として、 プログラムは以下のようになります。ちなみに結果は「i=1,j=2,k=-1,l=2」です。
/* 演算子について by まえだとしゆき */ #include <stdio.h> main() { int i,j,k,l; i = j = k = 1; l = ++j; k -= l; printf("i=%d,j=%d,k=%d,l=%d\n",i,j,k,l); }


プログラミングの基本要素

プログラムとは、端的に言えば命令をある順序で並べたものですが、それを(一 般論として)強いて機能的に分解すると以下のようにまとめられるでしょう。
  1. 情報の入力…標準入力関数がうけもちます。

  2. 情報の表現…定数や変数の宣言、定義など。

  3. 情報の操作・演算… 演算子と式 に従って 組み立てていきます。

  4. 情報の出力…標準出力関数がうけもちます。

  5. 流れの制御…if, while など。

  6. 処理のブロック化…(ライブラリ)関数を利用。

    関数については詳細は後述しますが、ここでは;

    くらいのことを把握しておいてください。

プログラムのスタイル

プリプロセッサの話

☆例として、

プログラムは以下のようになります。ちなみに結果は「i=1」です。
/* define マクロの使い方 */ #include <stdio.h> #define NUMBER 1 main() { int i; i = NUMBER ; printf("i=%d\n",i); }
☆別の例として、 プログラムは以下のようになります。ちなみに結果は(2の平方なので)「i=4」 です。
/* define マクロの使い方(2) */ #include <stdio.h> #define SQUARE(x) (x)*(x) main() { int i; i = 3 ; i = SQUARE(i-1) ; printf("i=%d\n",i); }



標準入出力 (standard input/output)

標準出力 (standard output)

☆例として、

プログラムは(出力をすこし装飾してますが)以下のようになります。これ は10進数の97が何の 文字のコード になって るかを示しているプログラム、といえます。
/* 標準出力の例1 */ #include <stdio.h> main() { int i; i = 97; printf("%d(dec) is %x(hex), and '%c'(char).\n",i,i,i); }

☆別の例として、

プログラムは(出力を多少装飾してますが)以下のようになります。for 文は ここでは単に i の値を1ずつ増やして、i が58未満のの間、すなわち57まで くり返す、とだけ理解しておいてください。
ちなみに 10進数の 48 (16進数の 0x30) はASCII コードの '0' です。 ここの「i=48」のところは、「i='0'」 と書いても全く同じことです。 ASCII では48 から 57 まで(あくまでも文字としての)数字が順にならんでい ますので、それらを表示する、ということで結果(の主要部)は「0123456789」 となります。
/* 標準出力の例2 */ #include <stdio.h> main() { int i; printf("Charactors (48-57) are [ "); for (i = 48; i < 58 ; i++) putchar(i); puts(" ]."); }

標準入力 (standard input)

基本的に、出力に対応したものたちがあります。

☆例として、

プログラムは以下のようになります。
/* 標準入出力の例 */ #include <stdio.h> main() { int i; printf("input integer: "); scanf("%d",&i); printf("%d(decimal) is %o(octal), %x(hexadecimal).\n",i,i,i); }


プログラム内の制御構造

Pascal という言語はこの構造化プログラミングを強く意識して設計された 言語で、Cもその流れを組んでいます。それ以前の FORTRAN や COBOL など にはこのような考え方はなくで、(機械語レベルの jump に対応する) GOTO 文 をつかって制御の流れをかえていたのですが、こ れを多用すると全体の見通しが非常に悪くなり、バグの温床となることが指 摘されていました。

if 文

if と else について、

とパターン化されると思いますが、これについて少し考えてみます。

☆例として、

プログラムは以下のようになります。
/* if 文の例 */ #include <stdio.h> main() { int i; printf("Input your point: "); scanf("%d",&i); if (i < 60) printf("You fail..\n"); else printf("You pass!!\n"); }

くり返し(ループ)

while 文

for 文

☆例として、

プログラムは以下のようになります。
/* ループの例 */ #include <stdio.h> main() { int i,j,k; printf("Input: "); scanf("%d",&j); for (i=1,k=0;i<=j;i++) k += i; printf("Summation=%d .\n",k); }

その他の制御構造

switch 文

goto 文とラベル

☆例として、

プログラムは以下のようになります。
/* switch の例 */ #include <stdio.h> main() { int i; printf("数字を入力してください: "); scanf("%d",&i); switch (i) { case 1 : printf("1つですね\n"); break; case 2 : printf("2つですね\n"); break; default: printf("たくさんですね\n"); break; } }


配列 (array)

☆例として、

プログラム(の1例)は以下のようになります。実はバブルソートというよ く知られた列び替えのアルゴリズムの実現例です。
/* bubble sort */ #include <stdio.h> main() { int i,j,temp,a[10]; for (i=0;i<10;i++) { printf("data %d : ",i); scanf("%d",&a[i]); } for (i=0;i<10;i++) { for (j=i+1;j<10;j++) { if (a[i]>a[j]) { temp=a[i]; /* You cannot exchange data directly! */ a[i]=a[j]; a[j]=temp; } } } printf("Outputs="); for (i=0;i<10;i++) { printf("%d ",a[i]); } printf("\n"); }

ポインタと配列

ここがC言語をマスターできるかどうかの分かれ目ですので、 こころして(!?)学習してください。

☆例として、

プログラムは以下のようになります。まったく同じp (の中味のポインタ) を扱っていても、その指し示す先の値を変更することで出力が異なることを 確認してください。
#include <stdio.h> main() { int a,*p; p = &a ; a = 1; printf("%d\n",*p); a = 2; printf("%d\n",*p); }

文字列のポインタ操作

☆例として、

プログラムは以下のようになります。for 文の終了条件、すなわち'\0' (ヌル文字)は数値として0なので、論理として偽であることに注意してく ださい。もちろん、*cp != '\0' とかいても問題はないです(丁寧、だけど 冗長と言えます)。
このような簡潔な書き方は実際のプログラムでは非常に多いので、 見馴れておくとよいでしょう。
#include <stdio.h> main() { char str[8], *cp; int i; cp = "APROG" ; for(i=0;*cp;cp++,i++) /* before end-of-string */ str[i]=*cp; /* copy each character */ str[i]='\0'; /* treat end-of-string */ printf("%s\n",str); }

さらに string について(補助資料)

素朴な気持ちとして
char a[4] = "abc" ;
chat b[4];
の場合、
b = a;
で文字列変数 b に "abc" という文字列が入って欲しい、というのは理解はでき ます。し、実際 perl など他のプログラム言語では可能です。

しかし、C ではあくまでも「文字列」は実現としては文字の配列で、その取り扱 いについては文字配列の先頭アドレス(ポインタ)をもって行う、という決まり になってます。だから、前の例ではアドレス同士の演算なので、実際の文字列操 作にはなってないわけです。

ちなみにC++ や Java では、String クラスという文字列用のクラスを準備して、 さらに "=" (代入演算子)を overload (上書き?)することで、
String a = "abc";
String b;
b = a;
のような記述は可能となっています(詳細は略します)。

そこで、strcpy などのような標準関数が用意されるわけです。この場合は stdio.h だけではなく string.h というヘッダもインクルードする必要があるこ とにも注意しておいてください。

文字列操作関数としては、以下のようなものがあります。


ポインタの配列

☆例として、

プログラムは以下のようになります。
#include <stdio.h> main() { char *strs[2]; int i; strs[0] = "hannan-u"; strs[1] = ".ac.jp"; for (i=0;i<2;i++) printf("%s",strs[i]); printf("\n"); }

記憶クラス

関数

☆例として、 プログラムは以下のようになります。ここでは巾乗、すなわちi の j 乗と は、i を j 回掛けたもの(jが0の場合は i の値にかかわらず1)であるこ とをC言語で既述しています。
#include <stdio.h> int beki(int i, int j); main() { int i = 2, j = 3; printf("%d\n",beki(i,j)); } int beki(int i, int j){ int ii, ret = 1; for (ii=0;ii<j;ii++) ret *= i; return ret; }


再帰関数について


構造体について

☆例として、 プログラムは以下のようになります。
#include <stdio.h> main() { struct kumi { int bangou; char sensei[10]; }; static struct kumi classes[3]={ 1, "yamada", 2, "sato", 3, "suzuki", }; int i; for (i=0;i<3;i++){ printf("Class no.%d: %s-sensei\n", classes[i].bangou, classes[i].sensei); } }

構造体とポインタ


型についてのあれこれ

いままで曖昧なままにしていた「型」の扱いについてすこし解説を加えておきます。

複雑なデータ構造(中級以上向き)


目次へ戻る
前田としゆき / maechan@hannan-u.ac.jp