• 検索結果がありません。

条件文

ドキュメント内 note.dvi (ページ 93-96)

第 6 章 C 言語入門

6.9 いくつかのプログラム

6.10.8 条件文

条件文とは,条件によって実行を分岐させるための制御文である.

6.10.8.1 if文

最も簡単な条件文は if文である. if文は以下のような構文を持つ.

if (式) 文

ここで,式は省くことはできない. ここで,式は算術型もしくはポインタでなくてはならない.

このようなif文は,次のように制御される.

式が0でなければ,文が実行される.

Id: C4.tex,v 1.6 2001-03-15 20:35:03+09 naito Exp

6.10.8.2 if–else 文

if–else文は以下のような構文を持つ.

if (式) 文1 else

文2

ここで,式は省くことはできない. ここで,式は算術型もしくはポインタでなくてはならない.

このようなif–else 文は, 次のように制御される.

式が0でなければ,文1が実行される.

式が0であれば,文2が実行される.

if–elseは繰り返して使うことができ,次のような形になる.

if (式1) 文1

else if (式2) 文2

else if (式3) 文3

else 文4

この形では, 式1から順番に式が評価される. 式1が 0であれば,式2を評価するという順番で,条件式 が評価されていく.

Example 6.10.15 次の例はnが 0か正か負かを判定している.

int n;

if (n == 0)

printf("n is equal 0\n") ; else if (n < 0)

printf("n is negative\n") ; else

printf("n is positive\n") ;

Remark 6.10.5 上のExampleの最初のif (n == 0)はif (!n)と書くこともできるが,後のif--else との整合性を考えると,ここはn == 0と書いた方が良い.

C の標準関数の中で,int型の変数が 英小文字であるかどうかを判定するための関数として,islower 関数がある. cが英小文字であるときにはislower(c) は 1となり,そうでないときには0 となる. この ような関数を利用するときには,

if (islower(c))

と書けば(そのままこの文章を英語で読めば)非常にわかりやすい.

しかし, Cの標準関数の中で,2つの文字型の配列(文字列)が同一であるかどうかを判定する関数とし て,strcmpがある. char *s, *tに対して,strcmp(s,t)はその辞書式順序に従う差を与える. すなわち, s,tの指し示す文字列が同一内容であるときに0を返すため,

if (strcmp(s,t) == 0)

によって,s, tが等しいときの分岐を表すことになる.

条件式を簡潔に書くことは,プログラムを見易くするために重要なことであるが,条件式を余りに簡潔に しすぎると思わぬバグを産む可能性がある.

Id: C4.tex,v 1.6 2001-03-15 20:35:03+09 naito Exp

if–else文には曖昧な構文がある.

Example 6.10.16 次の例はelseがどちらのifに結び付いているかわかりにくくなった例である.

if (n > 0) if (a > b)

z = a ; else

z = b ;

ここで,文法的にはelse は2番めのifに結び付いている.

このような表現を避けるため,if–elseで制御される文は{}をつけて複文にすることが望ましい.

if (n > 0) {

if (a > b) z = a ; }

else z = b ;

if (n > 0) {

if (a > b) z = a ; else z = b ; }

6.10.8.3 switch文

switch文は以下のような構文を持つ.

switch (式) { case 定数式: 文 case 定数式: 文 default: 文 }

ここで, 式は省くことはできない. 式は整数型でなくてはならない. default はなくても良い. 一つ の switchに許される defaultは高々一つ. case の定数式で重複するものがあってはならない. 一つの switch文には少なくとも257個のcaseラベルを用いることが出来る. また,switchは入れ子にできる.

このようなswitch文は,次のように制御される.

式の結果に応じて,定数式で表されたどれかの式に制御が移る.

もし, defalutが存在し, 式の結果が定数式のどれとも一致しない時には,default が実行されるが, defaultが存在しない時には,どれも実行されない.

ここで,式は,副作用も含めて,全て最初に評価され, 整数への格上げを受けた定数式と比較される.

switchで重要なことは,次のことである.

マッチした定数式に対応する文が実行された後,制御は次のcaseラベルもしくはdefaultラベルを 持つ文に移され,無条件に実行される.

Example 6.10.17 この例では,nの値によって,結果を印字しようとしているが,期待通りには動かない.

int n ; switch (n) {

case 1: printf("n は 1 だよ\n") ; case 0: printf("n は 0 だよ\n") ; case -1: printf("n は -1 だよ\n") ;

default: printf("n は 1, 0, -1 のどれでもない\n") ; }

これは,n = 1の時,

Id: C4.tex,v 1.6 2001-03-15 20:35:03+09 naito Exp

n は 1 だよ n は 0 だよ n は -1 だよ

n は 1, 0, -1 のどれでもない という結果をうち出す.

このようにswitch文の中で,一つのcaseラベルを実行し,次のcaseラベルに制御が移ってしまうこと

を“Fall Throught” と呼ぶが, Fall Throughtを使う仕様はバグの原因となる.

このようなことを避けるためには,break 文を使う.

Example 6.10.18 上のExampleを改良した.

int n ; switch (n) {

default: printf("n は 1, 0, -1 のどれでもない\n") ; break ;

case 1: printf("n は 1 だよ\n") ; break ;

case 0: printf("n は 0 だよ\n") ; break ;

case -1: printf("n は -1 だよ\n") ; break ;

}

この改良により, この switch 文ではどれか一つのラベルに対する文しか実行しなくなる. 出来れば

defaultラベルを持つ文は一番最後につけよう. その方がわかりやすい.

ドキュメント内 note.dvi (ページ 93-96)