[時間割:C言語]『はじめてのC言語完全入門』その13
2009/01/06 22:56 posted by kunkichi
火曜日は「C言語」。前回、ファイルからの入出をやったので、今度はファイルへの出力です。
塚越 一雄
技術評論社
売り上げランキング: 420963
- 書き込み時は、オープンモードを”w”にする。
FILE *ofp;
ofp = fopen("output.txt","w")
- ファイルへの出力にはfputcを使う。
fput(c, ofp);
- 書き込みの場合はエラー処理が重要。fputcは、EOFに達した場合も書き込みエラーの場合も両方-1を返すので、終了とエラーの区別ができない。よって、エラーが発生していたら真を返すferror関数を使って、「書き込みエラー」を取得する。
fputc(c,ofp);
if(ferror(ofp)){
printf("書き込みに失敗しました。¥n");
fclose(ofp);
return XXX;
}エラーが発生した場合に処理を終了する場合は、ファイルのクローズを忘れないように。
- 前回のサンプルスクリプトに出力処理を追加。sample.txtを読み込んで、その内容をそのままresult.txtに出力する、いわばcpコマンドのような感じで。
#include <stdio.h>
#define INFILE "./sample.txt"
#define OUTFILE "./result.txt"
int main()
{
FILE *ifp;
FILE *ofp;
if( !(ifp = fopen( INFILE, "r" )) ){
printf("cannot open input file.\n");
return 255;
}
if( !(ofp = fopen( OUTFILE, "w" )) ){
printf("cannot open output file.\n");
return 255;
}
int c;
while( (c = fgetc(ifp)) != EOF ){
fputc(c,ofp);
}
if(ferror(ofp)){
printf("書き込みに失敗しました。\n");
fclose(ofp);
fclose(ifp);
remove(OUTFILE);
return 1;
}
if( fclose(ofp) ){
printf("cannot close output file.\n");
return 255;
}
if( fclose(ifp) ){
printf("cannot close input file.\n");
return 255;
}
return 0;
}
- getcharを使うと、標準入力から1文字読み込むことができる。fgetcと同じように返り値はintで受ける。引数はなし。
- ferrorってイメージとしてはエラーフラグが立つという感じかな。whileのループの中でなく、ループが終了した後にチェックしているのはそういう意味かと。
- 上記はferrorで書き込みエラーを拾ったら、出力ファイルポインタをクローズすると共にファイルを削除している。削除にはremove(ファイル名)を使用する。Perlのunlinkみたいなもんかな。
- fputcは1文字単位なので、ちょっと使いにくい。だけど、fprintfを使えば、printfのように、文字列を特定の書式に当てはめる形で出力することができる。
fprintf(ofp,"今日は%d月%d日です。¥n", month, day);引数にファイルポインタを追加する以外はprintfと全く同じ使い方。
- fprintfを使ったファイル出力のサンプル
$ cat fprintf.c
#include <stdio.h>
#define OUTFILE "result.txt"
int main()
{
FILE *ofp;
if(!(ofp = fopen(OUTFILE,"w"))){
printf("cannot open outfile.\n");
return 255;
}
int num=0;
printf("数字を入力してください。 ");
scanf("%d",&num);
fprintf(ofp,"入力された数字は、%d です。\n",num);
fclose(ofp);
return 0;
}
ビルドして実行してみる。$ ./fprintf
数字を入力してください。 356
$ cat result.txt
入力された数字は、356 です。
- 標準出力、標準エラー出力にも出力できる。それぞれ組み込みのファイルポインタである、stdout、stderr を fprintfの引数にすれば良い。エラーメッセージ等はstderrに出すと良いね。
ということでファイルの出力もできるようになりました。
次は文字列とポインタです。
Category: C, Programming | コメント&トラックバック(0)
[時間割:C言語]『はじめてのC言語完全入門』その12
2009/01/03 04:22 posted by kunkichi
前回からずいぶん時間が経ってしまっているなぁ、、でも新年の誓いも経てたことだし、心機一転がんばります!
金曜日は「C言語」。ファイル入出力の章からです。
塚越 一雄
技術評論社
売り上げランキング: 420963
ここまでの内容をサンプルで書くとこんな感じに成りました。単にファイルを開いて出力するだけです。
#include <stdio.h>
#define FILENAME "./sample.txt"
int main()
{
FILE *fp;
if( !(fp = fopen( FILENAME, "r" )) ){
printf("cannot open input file.\n");
return 255;
}
int c;
while( (c = fgetc(fp)) != EOF ){
printf("%c",c);
}
if( fclose(fp) ){
printf("cannot close input file.\n");
return 255;
}
return 0;
}
出力時はprintfを使っているけど、putcharとか、他にもあるようです。
とりあえず今日はファイルからの入力まで。次はファイルへの出力をやります。
Category: C, Programming | コメント&トラックバック(0)
[時間割:C言語]『はじめてのC言語完全入門』その11
2008/11/21 22:59 posted by kunkichi
いかんいかん、XBOX360の「FIFA09」が出たせいでサボりまくり、、、
気分を取り直してがんばります。金曜日は「C言語」。今日は文字列です。
塚越 一雄
技術評論社
売り上げランキング: 420963
- Cには文字列型は存在しない。文字列は文字型の配列を使う。なぜなら可変長だから。
- 文字列の初期化は以下の数パターン。
- 文字単位で初期化。
#include <stdio.h>
int main()
{
char s[5];
s[0] = 'a';
s[1] = 'b';
s[2] = 'c';
s[3] = '\0';
printf("%s\n", s);
return 0;
}ポイントをいくつか。
- 宣言するときにサイズもあわせて宣言する。サイズは代入したい文字数に1を足しておく。
- 1を足したのは最後に文字列の終わりを示すEOS(End Of String)の分。EOSにはNULL文字を使う。もじれるの場合は\0。
- printfで出力する場合は%sで配列名を指定する。
- {}をつかったやり方
#include <stdio.h>
int main()
{
char s[] = {'a', 'b', 'c'};;
printf("%s\n", s);
return 0;
}この場合はサイズの宣言は不要。よしなにやってくれる。
- 文字列リテラルで。
#include <stdio.h>
int main()
{
char s[] = "abc";
printf("%s\n", s);
return 0;
}一番普通。
- {}を使った場合や文字列リテラルで初期化した場合でもサイズの指定は可能。ただし、EOSの分を足すことを忘れないこと。
- 同じ文字だけの文字列で初期化する場合は、string.hのmemset関数を使う。
#include <stdio.h>
#include <string.h>
int main()
{
char s[4];
memset(s,'a',3); /* 1: 代入する配列、2:文字、3:文字数 */
s[3] = '\0'; /* 最後にEOSを代入。面倒、、、 */
printf("%s\n", s);
return 0;
}
- 文字列宣言後に文字列リテラルで代入することはできない。その場合はベタに文字配列で要素ごとに代入するか、strcpyを使う(これはまだ先)。文字配列の場合はEOSを最後に代入することを忘れないこと。
- サイズを超えた場合でも、サイズに見たない場合でも、コンパイラはエラー等を返さないので注意。特に超えた場合は、、、
うーん、やっぱり文字列の扱いは面倒だなぁ、特にサイズを意識しないといけないってのは厳しい。十分に気をつけるようにして次へ進みましょう。次回は「ファイル入出力」。やっと実際のプログラミングらしくなってきました。
Category: C, Programming | コメント&トラックバック(0)
[時間割:C言語]『はじめてのC言語完全入門』その10
2008/11/09 00:27 posted by kunkichi
ここ2、3日格闘していた、ポインタですが、なーんとなく少し壁は超えれたような気がするので、わかってるところだけでもちょっとまとめてみます。あくまでも、なーんとなくのレベル。
塚越 一雄
技術評論社
売り上げランキング: 420963
ポインタ
- 変数は値を記憶する。ポインタ変数はアドレスを記憶する。
- 宣言する場合は、変数名の前に*をつける。あと、ポインタにも型は必要。
int *pval;
- ポインタで指定されるアドレスは先頭アドレス。そこから何バイトのデータなのかを判断するために、「型」が必要。(型がわかればバイト数がわかる。sizeof(int)とか)。つまりポインタは型情報を持つということ。
- ポインタへの代入は当たり前だけどアドレスを代入する。通常はアドレス演算子&を使う。変数に&をつけると、その変数の値ではなく、アドレスを参照する。
int *pval;
int val;
pval = &val;
- ポインタがさしている別の変数のアドレスから、値を参照する場合は、*を使って逆参照する。
int val = 10;
int *pval;
pval=&val;
printf("%d¥n",*pval);
結果は”10″が出力される。
- Cの関数では、実引数の値は仮引数にコピーされるため、関数内でどうこうしたとしても実引数には影響しない。つまり、スコープの話。
- 関数内で実引数を直接変更したい場合はポインタ引数を使う。
関数の宣言:void pointer_func( int *x, int *y )関数の呼び出し:pointer_func( &a, &b )関数内で値を参照:int val = *a;
- アドレスを返すような関数でエラーを返す場合はNULLポインタを使う。
配列とポインタ
- 配列の名前は、配列の先頭アドレスを意味するので、ポインタに代入できる。
int ary[] = { 1, 2, 3 };
int *pval;
pval = ary;
- 配列の先頭アドレスは、配列の最初の要素の先頭アドレスでもある。つまり、ポインタに代入した後、逆参照すれば、最初の要素の値を取得できる。
※上の続き
printf("%d¥n", *pval);結果は1となり、ary[0]の値となる。
- ポインタで演算をすると、そのポインタの型が使用するメモリサイズ分だけ加算される。
#include <stdio.h>
int main()
{
int *p;
printf("%p\n", p );
p += 1;
printf("%p\n", p );
return 0;
}結果は0x1000
0×1004となる。
- 上記を配列で使うと、2番目以降の要素の参照ができる。
#include <stdio.h>
int main()
{
int ary[] = {
1,
5,
8
};
int *p;
p = ary;
printf("%p:%d\n", p, *p );
printf("%p:%d\n", p+1, *(p+1) );
printf("%p:%d\n", p+2, *(p+2) );
return 0;
}結果:0xbffff9f0:1
0xbffff9f4:5
0xbffff9f8:8アドレスは4バイトずつ(僕の環境では)増えて、配列の要素を順に参照している。
- 上の例では参照するポインタを直接指定していたけど、ループを使ってポインタの値をインクリメントしながら参照してみる。
#include <stdio.h>
int main()
{
int ary[] = {
1,
5,
8
};
int *p;
p = ary;
int i;
for( i=0; i<(sizeof ary / sizeof ary[0]); i++ )
printf( "%d:%p:%d\n", i, p, *p++ );
return 0;
}結果は同じ0:0xbffff9f0:1
1:0xbffff9f4:5
2:0xbffff9f8:8
- ポインタを配列のように使う。上の例のforループの部分を以下のように書き換えてみる。
for( i=0; i<(sizeof ary / sizeof ary[0]); i++ )
printf( "%d:%p:%d\n", i, &p[i], p[i]);結果はこれまた同じ。0:0xbffff9ec:1
1:0xbffff9f0:5
2:0xbffff9f4:8つまり、配列のようにインデックスで指定して、元の配列要素の値を取得できる。
- 今度は逆に配列をポインタのように使う。
include <stdio.h>
int main()
{
int ary[] = {
1,
5,
8
};
int i;
for( i=0; i<(sizeof ary / sizeof ary[0]); i++ )
printf( "%d:%d\n", i, *(ary+i) );
return 0;
}結果はこうなる。0:1
1:5
2:8配列の各要素に、ポインタで使った逆参照演算子*を使って値を参照することができる。
- 配列とポインタの違いは、
- ポインタは変数であり、メモリ上にアドレスを記録するための領域が確保される。従って値を変更することができる。
- 配列名は、コンパイラがコンパイル中に使用する「定数」なので、メモリ上に配列名を記憶するための領域は確保されない(ただし配列の各要素を記録するための領域は確保される)。従って、値を変更することができない。
- 関数の引数に配列を渡す場合は配列名だけを渡す。
int ary[];
sample func(ary)
- 関数側の受け取り方は以下の2パターン。配列の要素から最大値を求めるmaxという関数をそれぞれのパターンで書いてみる。
- 配列で受け取る。例:
int sample_function(int a[]){
・・・
}サンプルコード:#include <stdio.h>
int max(int a[], int size);
int main()
{
int ary[] = {
1,
5,
8
};
int val;
val = max( ary, sizeof ary / sizeof ary[0]);
printf("%d\n",val);
return 0;
}
int max(int a[], int size)
{
int max = a[0];
int i;
for(i = 1;i<size;i++)
if(max < a[i])
max = a[i];
return max;
}
- ポインタで受け取る。
例:int sample_function(int *a){
・・・
}サンプルコード:#include <stdio.h>
int max(int *a, int size);
int main()
{
int ary[] = {
1,
5,
8
};
int val;
val = max( ary, sizeof ary / sizeof ary[0]);
printf("%d\n",val);
return 0;
}
int max(int *a, int size)
{
int max = a[0];
int i;
for(i = 1;i<size;i++)
if(max < a[i])
max = a[i];
return max;
}
- 配列を関数に渡す場合、渡されるのは配列の先頭アドレスだけなので、配列の要素数については別に渡してあげる必要があるので注意。上記の例で、関数の引数に配列だけじゃなくて、配列も渡しているのはそのため。試しに配列の要素数を返す関数を作って試してみる。
#include <stdio.h>
int arynum(int a[]);
int main()
{
int ary[] = {
1,
5,
8
};
int val;
val = arynum( ary );
printf("%d\n",val);
printf("%d\n",sizeof ary / sizeof ary[0]);
return 0;
}
int arynum(int a[])
{
int num;
num = sizeof a / sizeof a[0];
return num;
}結果は以下。1
3
ふぅー、途中ちょっと別の本も読んでみたりしつつでしたが、何度か繰り返し読んで、サンプルコードを自分で書いてみて、そんなこんなしてるうちに何となくわかってきました。やっぱり「何度も読む」ことで見えてこなかったものが少しずつ見えてくるんだよね。とりあえず最大の難関を終えてホッとしました。
次回は「文字列と文字配列」です。
Category: C, Programming, Book | コメント&トラックバック(0)
[時間割:C言語]『はじめてのC言語完全入門』その9
2008/11/04 00:34 posted by kunkichi
ここ2、3日の間、ポインタと格闘していました。ポインタ単体の意味は理解できるのだけど、配列とごっちゃになった瞬間もうわかりません、、、他の言語と比べると、C言語ではどうも配列とポインタの区別が曖昧な印象があるんだよね。
これはちょっとまずいってんで、その部分だけもう少ししっかり勉強しようと言うことで、教科書増やしました。
谷尻 かおり 谷尻 豊寿
技術評論社
売り上げランキング: 209427
前橋 和弥
技術評論社
売り上げランキング: 9027
両方ともヤフオクでゲットしたので比較的懐を痛めずに済みました(笑)
ここまでの印象では他言語と特に大きく変わるところもなかったし、特につまずいたところもなかったのですが、ここはC言語の一番の山場っぽいので苦戦しそうです。もう少し格闘してみたいと思います。
Category: C, Programming | コメント&トラックバック(0)
[時間割:C言語]『はじめてのC言語完全入門』その8
2008/10/25 22:49 posted by kunkichi
今週の頭は少しサボっちゃいましたが、気を取り直して。サボりの元凶となったのは Touch Diamond を買ったから(笑)ですが、遊びのために買ったんじゃない、ということを証明するために早速、金曜日の会社帰りに外で勉強しました。やっぱり外ははかどるな〜、3章一気に進んじゃったし。
ということで、木・金のアップです。まずは『C言語』の方から。
塚越 一雄
技術評論社
売り上げランキング: 420963
関数
スコープ
- 関数内の変数は関数内にのみ限定される(ローカル変数)。
- 実際には「ブロック」内、つまり{}で囲まれた範囲内に限定されているのがローカル変数。
- 関数の外側の変数は、関数から見た場合にはグローバル変数となり、参照可能。
- 変数名もブロック内に限定されるので、他の関数内で同じ変数名が使用されていても衝突しない。
- ただし、グローバルな変数名と同じ名前にした場合、関数内ではローカル変数が優先される。
- グローバル変数はファイルスコープ。
配列
- 配列にも型の概念がある。すなわち、同じ型のデータしか入れれない。異なる型のデータを入れるのは構造体。
- 配列は、基本の型とは異なるユーザ定義型の一つ。
- 配列を宣言するには、型・配列名・サイズ(要素数)をあらかじめ定義する。
int ary[10]
- 初期値を与えることもできる。
int ary[] = { 1, 2, 3 };この場合はサイズの指定は不要(自動的に初期値の個数がサイズとなる)
- 配列の要素へのアクセスは、インデックスを使う。
x = ary[0];
- 配列全体のメモリ量を求めるには 配列に対して sizeof を使う。
sum = sizeof ary;
- 配列要素の単体メモリ量を求めるには 配列のインデックス0 に対して sizeof を使う。
each = sizeof ary[0]
- つまり、全体メモリ量を単体メモリで割ると、配列の要素数を求めることができる。
num = sizeof ary / sizeof ary[0];forループの上限値等に設定する場合はこれをつかうとよろし。
- forループの脱出にもbreakが使える。
- ループの脱出にはbreakを使う。
- 配列はあらかじめサイズを指定しておかないといけないため、途中でサイズが大きくなった場合に対応できない。こういう場合は動的メモリが必要となる。
ふぅ、たくさん進んだ分、アウトプットも多くなってしまいましたが、これで教科書の残り3分の1まで来ました。やっと終わりが見えてきたのでがんばります。次はいよいよ「ポインタ」です!
Category: C, Programming, Book | コメント&トラックバック(0)
[時間割:C言語]『はじめてのC言語完全入門』その7
2008/10/15 00:36 posted by kunkichi
連休明けですががんばります。ということで先週〜連休中にかけての分はそのうちアップします。今日は『C言語』。
塚越 一雄
技術評論社
売り上げランキング: 420963
高度な選択文
- else if、switch、ifのネスト、三項演算子、この辺はほぼ他言語と同じ。
- 論理演算子のTIPS(というかひねりが効いたやり方)
#include <stdio.h>
int main()
{
int num1, num2;
num1=0;
num2=0;
printf("整数? ");
scanf("%d",&num1);
if( num1 && (num2=100) )
printf("num1=%d, num2=%d \n",num1,num2);
else
printf("num1=%d, num2=%d \n",num1,num2);
return 0;
}./sample
整数? 0
num1=0, num2=0
$ ./sample
整数? 1
num1=1, num2=100すなわち、&&を使った論理演算子の場合、最初の評価が偽だった場合は二つ目の評価は行わない。これを利用して、最初の評価が真だった場合のみ、代入を行う。
- ||の場合は逆になり、最初が真だった場合は二つ目の評価を行わずに、最初が偽だった場合のみ、二つ目の評価で代入を行う。
#include <stdio.h>
int main()
{
int num1, num2;
num1=0;
num2=0;
printf("整数? ");
scanf("%d",&num1);
if( num1 || (num2=100) )
printf("num1=%d, num2=%d \n",num1,num2);
else
printf("num1=%d, num2=%d \n",num1,num2);
return 0;
}$ ./sample
整数? 0
num1=0, num2=100
$ ./sample
整数? 1
num1=1, num2=0
反復文
- 代入演算子、インクリメント、デクリメントは全く同じ。
- while、do〜while、も同じ。do〜whileってあんまり使ったことないのだけど、入力検査に使うのは納得。
- forも同じやけど、Cの場合、ループ変数の宣言は別途せなあかんと、、、
この辺、目新しいところは特になかったな。まあ初歩レベルってことで。
Category: C, Programming, Book | コメント&トラックバック(0)
[時間割:C言語]『はじめてのC言語完全入門』その6
2008/10/07 20:54 posted by kunkichi
火曜日は『C言語』です。ちょいご無沙汰でした(^^; がんばります。
入力プログラムの応用
- 定数はdefineを使う。
#define TEISU 400
- 行の最後までが有効になる。
- スペースを含んでもOK。
- 行をまたぐ場合は最後に¥を使う。
- サンプル:
#include <stdio.h>
#define STR "word and space"
#define PARAGRAPH "This is test for paragraph.\
new line"
int main()
{
printf("%s\n" , STR);
printf("%s\n" , PARAGRAPH);
return 0;
}実行結果:$ ./en
word and space
This is test for paragraph. new line
- 定数を置き換えるのはプリプロセッサの地点。gcc -E でプリプロセスだけ行うとよくわかる。
$ gcc -E sample.c
・・・
int main()
{
printf("%s\n" , "word and space");
printf("%s\n" , "This is test for paragraph. new line");
return 0;
}
ifを使った選択文
- 他言語とほとんど一緒。
- 代入「式」を条件に使う
if( a = 4 )はa=4;
if(a)と同じ。
やっと本の半分弱まで来ました。日々の努力が大事です。
Category: C, Programming, Book | コメント&トラックバック(0)
[時間割:C言語]『はじめてのC言語完全入門』その5
2008/09/17 23:01 posted by kunkichi
火曜日の『C言語』を忘れてたので今日はがんばります!
12章「書式付き入力(その1)」から。
塚越 一雄
技術評論社
売り上げランキング: 420963
- scanfで定型フォーマットのデータを標準入力
scanf("変換仕様",&変数名)
- 複数のデータの場合は以下のような感じで空白で区切るとわかりやすい。
scanf("%c %d %f",&変数名1,&変数名2,&変数名3)とりあえず、区切りの空白は無視されるものとする。
- 標準入力に含まれる空白の扱いに注意
- 空白をフィールドの区切りとする
- 先頭部分の空白は削除される
- ただし、文字の場合のみ空白も改行も含まれる形で入力をとる。
- 変換仕様中の空白は無視されるとしたけど、実際は空白を含めると、入力データの空白を除去したのと同じになる。よって
- 空白を入力したい場合は文字書式(%c)等の前に空白を入れない。
- 空白を除去したい場合は文字書式(%c)等の前に空白を入れる。
- scanfは決まったフォーマットでデータを受けとる前提になっているので、入力エラーに対応できない。ではどうするか?
- scanfはintを返す。返す値は入力に成功したフィールドの数。これを使えば、エラーチェックができる。
int ret;
ret = scanf( "%d", &arg1 );retが1ならOK。0ならNG。でも数値は文字列ともとれるから、単に数値かどうかのチェックしかできない気がする。やっぱり正規表現がいいなぁ、それはまたあとで出てくるのかな?
- ただし複数フィールドの場合に最初のフィールドでエラーになったらscanfはそこで終わってしまうので、その場合はscanfを複数に分ける。
scanf("%d",&argv1);
scanf("%c",&argv2);1行目でエラーになっても2行目のscanfは実行される。
- EOF(キーボードならCtrl+D)の場合はscanfは-1を返す。
- 入力フィールドをスキップするには、変換仕様のフォーマットに*を含める。
scanf("%d %*d %d", &arg1, &arg3 )この例だと元データの2番目のフィールドはスキップされる。
- EOF(キーボードならCtrl+D)の場合はscanfは-1を返す。
- scanfの書式文字列に、変換仕様や空白以外を含めると、その文字列を含めた一連のフォーマット文字列の入力とすることができる。日付とかで便利かも。
scanf("%s/%s/%s", &y, &m, &d);
- scanfの書式文字列に”¥n”を含めると入力が終わらなくなるので注意!
ふぅ〜、とりあえずこれで入出力を両方できるようになりました。でもこれじゃちょっと入力チェックが弱すぎだな〜。もう少し進めば正規表現とかも出てくるのかな?がんばります。
『サーバ』は引き続き↓読んでます。アウトプットがなかなか難しいですが、そのうち。
デイビッド・A. パターソン ジョン・L. ヘネシー
日経BP社
売り上げランキング: 37621
Category: C, Programming, Book | コメント&トラックバック(0)
[時間割:C言語]『はじめてのC言語完全入門』その4
2008/09/10 01:30 posted by kunkichi
火曜日は『C言語』です。張り切っていってみよう!
今日は11章「変数と定数」から。
塚越 一雄
技術評論社
売り上げランキング: 420963
- Cでは変数の宣言が必要。
ex) int a とか int a = 1。後者は初期化も一括。
- sizeof で変数やデータ型のメモリ上のサイズを調べることができる。
- 定数の場合はconstで宣言する。ちなみに定数は大文字で定義することが一般的
ex) const int A = 1
- 列挙型。複数の定数をまとめて宣言。これちょっと今までなかったタイプの型だな。
enum { a, b, c }
- 列挙された定数=列挙定数は自動的に0,1,2…と値が割り当てられる
- 値を指定することもできる。
ex) enum { a, b=4, c }
この場合、a、b、cはそれぞれ0、4、5となる。つまり、指定した場合でもその次の値は+1。
- 列挙に名前を付けることができる。ex) enum DAY { MONDAY, TUESDAY, WEDNESDAY, … }
これをさらに変数宣言で使用できる。
ex) enum DAY w;
でこれに列挙された定数を代入できる。
ex) w = MONDAY; ・・・上の例だと結局のところ0になる。
- タグの指定と変数宣言は一括で書ける
ex) enum DAY { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY } var;
- 型自体を作る感じと言った方がわかりやすいかも。
列挙型ってちょっと使いどころがピンとこなかったのだけど、いろいろ調べてみたところ、以下のサイトでなんとなく雰囲気はつかめた感じ。
ポイントをまとめると、
- enum を用いると、 複数の数字に一意な「名前」を 付ける事が出来る。つまり、「名前」で判断すればよいということ。
- フラグをたてるような場合に、フラグ名と値の関連を考えずにフラグ名だけで考えれるので便利。defineとかだとそれを意識しないといけない
- switch文とか特に便利。
- 配列とそろえると連想配列的な使い方も可能。
- 値は整数のみ
- 基本的な手順は以下。
- 列挙型の定義・・・タグを使ってenum型を定義する
- 変数宣言・・・定義された列挙タグを使って変数として定義
- 変数を使う・・・変数に列挙定数を代入したり。
簡単なスクリプトを試しに作ってみた。
#include <stdio.h>
enum weekday { MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY } w;
main()
{
w = WEDNESDAY;
switch(w){
case MONDAY:
printf("月曜日です。\n");
break;
case TUESDAY:
printf("火曜日です。\n");
break;
case WEDNESDAY:
printf("水曜日です。\n");
break;
case THURSDAY:
printf("木曜日です。\n");
break;
case FRIDAY:
printf("金曜日です。\n");
break;
case SATURDAY:
printf("土曜日です。\n");
break;
case SUNDAY:
printf("日曜日です。\n");
break;
}
return 0;
}
内部的には整数だけど確かにこれだと値は意識しなくていいね。
Category: C, Programming, Book | コメント&トラックバック(0)
2009/01/05/ 22:51
2008/11/06/ 07:02
2008/10/09/ 07:30
2008/09/16/ 12:08
2008/08/31/ 12:22