C言語入門

1
C言語入門
第11週
プログラミング言語Ⅰ(実習を含む。),
計算機言語Ⅰ・計算機言語演習Ⅰ,
情報処理言語Ⅰ(実習を含む。)
2
いろいろなプログラム
3
名前付きの定数
列挙子
4
定数の種類
• リテラル
• 数値リテラル
• 文字列リテラル
• 列挙定数
マジックナンバーになると分かり辛いので、
マクロか const 変数にして名前付の定数に
する。
自動的に名前付定数の数値を割り振ってく
れる
5
列挙(enumeration)
列挙子(enumerator)
• 書式:
• enum 列挙名 {列挙定数名 [= 定整数値], ...}
• 値を設定しないと
• 0から開始
• 前の値から+1ずつ増加
• #define の代わりに使える
6
列挙(enumeration)
列挙子(enumerator)
• 例:
enum boolean {NO, YES};
enum escape
BELL
BACKSPACE
TAB
NEWLINE
VTAB
RETURN
{
=
=
=
=
=
=
NO = 0
YES = 1
JAN
FEB
MAR
...
DEC
= 1
= 2
= 3
= 12
'\a',
'\b', enum month {
'\t',
JAN = 1, FEB, MAR,
'\n',
APR, MAY, JUN,
'\v',
JUL, AUG, SEP,
'\r'};
OCT, NOV, DEC};
7
列挙(enumeration)
列挙子(enumerator)
• #define で書き変えた場合の例:
#define NO 0
#define YES 1
#define
#define
#define
#define
#define
#define
BELL
BACKSPACE
TAB
NEWLINE
VTAB
RETURN
'\a'
'\b'
'\t'
'\n'
'\v'
'\r'
#define
#define
#define
// ...
#define
JAN
FEB
MAR
1
2
3
DEC 12
8
関数のようなマクロ
パラメータ付きのマクロ
9
パラメータ付きのマクロ
• #define で定義するマクロに ( ) を付けるとパ
ラメータを与えることが出来る。
macro_ex1.c
1
2
3
4
5
6
7
8
#include <stdio.h>
#define MIN(X,Y) (X<Y?X:Y)
コンパイル前
プリプロセッサにより
(1<2?1:2)で置換される
void main()
{
printf("min: %d\n", MIN(1,2));
}
10
パラメータ付きのマクロの注意点
• マクロは単純な置換なので置換結果がどうな
るか注意する必要がある。
macro_ex2_1.c
1
2
3
4
5
6
7
8
#include <stdio.h>
#define POW2(X) (X*X)
コンパイル前
プリプロセッサにより
(2*2)と置換される
void main()
{
printf("pow2: %d\n", POW2(2));
}
11
パラメータ付きのマクロの注意点
• マクロは単純な置換なので置換結果がどうな
るか注意する必要がある。
macro_ex2_1.c
1
2
3
4
5
6
7
8
#include <stdio.h>
(2+1)*(2+1)=9 ではなく
2+(1*2)+1=5 になってしまう
#define POW2(X) (X*X)
コンパイル前
プリプロセッサにより
(2+1*2+1)と置換される
void main()
{
printf("pow2: %d\n", POW2(2+1));
}
12
パラメータ付きのマクロの注意点
• マクロは単純な置換なので置換結果がどうな
るか注意する必要がある。
macro_ex2_2.c
1
2
3
4
5
6
7
8
パラメータはなるべく括弧で括る
#include <stdio.h>
#define POW2(X) ((X)*(X))
コンパイル前
プリプロセッサにより
((2+1)*(2+1))と置換される
void main()
{
printf("pow2: %d\n", POW2(2+1));
}
13
パラメータ付きのマクロの注意点
• マクロは単純な置換なので置換結果がどうな
るか注意する必要がある。
macro_ex2_3.c
1
2
3
4
5
6
7
8
9
#include <stdio.h>
マクロのパラメータに
副作用を伴う演算を用いては駄目
#define POW2(X) ((X)*(X))
コンパイル前
プリプロセッサにより
((++x)*(++x))と置換され
結果として 3*4 になってしまう
void main()
{
int x=2;
printf("pow2: %d\n", POW2(++x));
}
14
swap
値の交換
15
値の交換
• 以下のケースで x,y の値を交換するにはどう
したら良いか?
int x = 10;
int y = 20;
// 以下で x,y の値を入れ替えたい
x = y;
y = x;
こうするとxは既に
20で上書きされているので、
両方20になってしまう。
16
値の交換
• 中間変数を用いると良い
int x = 10;
int y = 20;
int tmp;
// 以下で x,y の値を入れ替えたい
tmp = x;
x = y;
y = tmp;
こうやると中間変数tmpに保存された
xの値10をyに入れることで
x,yの値を入れ替える事が出来る。
17
値の交換
• マクロにしてみる
macro_ex3.c
#define SWAP(TYPE,X,Y) {TYPE SWAP_tmp=X; X=Y; Y=SWAP_tmp;}
int x = 10;
int y = 20;
// 以下で x,y の値を入れ替えたい
SWAP(int, x, y);
ブロック内のローカル変数として
中間変数を作成
プリプロセッサにより
以下のように置換される
// 以下で x,y の値を入れ替えたい
{int SWAP_tmp=x; x=y; y=SWAP_tmp;};
18
参考文献
• [1] B.W.カーニハン/D.M.リッチー著 石田晴久
訳、プログラミング言語C 第2版 ANSI 規格準
拠、共立出版(1989)