Objective-C Primer 番外編 徹底C復習 5.制御文その2

この制御文その2では switch 文と for 文の説明をしております。
最終更新日時05/12/00:50
サンプルコードのダウンロード。
最終更新日時05/11/23:20


switch 文
前回の「4.制御文その1」で紹介したwhile文の中にif文を記述するという手法はユーザーからの指示を待つアプリケーションでは良く用いられる方法です。しかし if文をずらずらと並べて行くコードは分かりにくいですよね。そこでこのようなアプリケーションの指示を待つループの中で良く使われるのが switch文です。

まずはコードを見てください。なおこの回のサンプルコードは control2.zip からダウンロードすることもできます。



switch.m
d0122908_16342988.gif

コード説明
1行目、printfとfgets関数のためのヘッダファイルを読み込んでいます
2行目、atoiとexit関数のためのヘッダファイルを読み込んでいます。
5行目、計算結果を入れるための整数型(int型)変数goukeiを宣言して0で初期化しています。前回のchar型の宣言とは違い、宣言だけで0で初期化されることはありません。確実に初期化しておきましょう。
6行目、文字型(chat型)が100個集まった変数、つまり文字列を宣言しています。このように同じデータ型が集まりそれぞれを数字による順番(インデックス)で区別できるものを配列と呼びます。
9行目、1という真を表す定数を条件式に書き込むことによって無限ループを開始しています。
13行目、fgets関数は第1引数(この例の場合はss)に、第2引数(この例の場合は100)の数を上限として、第3引数(この例の場合はstdinでキーボードからの入力を表しています)のファイルから文字列を読み込みます
15行目、switch文の始まりです。条件式( )の中に整数値を表す変数(定数ではなくて必ず変数)を入れて、その数値と同じ数値の case 句へ分岐します(とびます)
16行目、case句は「 case 整数値 : 」の形で記述します。最後がセミコロンではなくコロン「:」であることに注意してください。 'c' のように文字がシングルクォーテーションで囲まれている場合はその文字の文字コードすなわち整数値を表します
17行目、case句に続けてそのcaseで処理したいことを記述します
18行目、break;に出会うとそのswitch文はそこで処理を中断してそのままswitch文を終ります。もしbreak文を書かなければ分岐の始まりは該当するcase句からはじまりますが、次のcaseさらに次のcaseへとbreak文もしくはブロック文の終わりの } に出会うまで処理は続くことになっています。
 ※switch文の中で用いられる break文は、ループ文( while文など)で用いれる場合と少し意味合いが違うように感じるかもしれませんが、ともに[switch文あるいはループ文を中止してswitch文あるいはループ文自体をその時点で終らせてしまう]という意味で同じです。少し戸惑うのはループ文の中で用いられる continue文だと思いますが、continue文はその時点でループの処理を中止しますが、その後はループの始まりに戻り処理を再開します。ループ文自体を終らせることはしません。
21行目、exit関数はそのプログラムを終了させます。引数( )の中には終了する際の返り値を書きます。通常、正常終了の場合は0を返します。
22行目、default:句にはcase句で指定されなかったその他の整数値の場合の処理を書きます。このdefault:句は必要なければ省略できます。
23行目、+=複合代入演算子と呼びます。詳しくは viva Cocoa ホームページ→「Objective-C」→「第7回 ローカル変数」の「Column」(ページの最下段)をお読みください。atoi 関数は引数( )の中の文字列を整数に変換します。数字でない文字列は0に変換されます。
24行目、最後のcase句もしくはdefault句のbreak文は省略してもかまいません。


実行画面
d0122908_16223135.gif

このソースファイルの拡張子は「 .m 」ですが、内容はまったくのC言語のファイルです。したがってコンパイルする際に「 -framework Foundation 」というオプションは省略することができます。
 加算する場合には「 +数字 」もしくは「 数字 」だけを入力してエンターします。マイナスする場合は「 -数字 」と数字の前に半角のマイナスをつけます。合計をクリアしたい場合には「 c 」を、終了する場合には「 q 」をタイプしてエンターして下さい。数字・c・q 以外の文字が入力された場合は0という数値として扱われます。結果、合計に影響を及ぼすことはありません。



for 文
while文と同じくループを行う制御文です。while文が何回ループするのかは分からないが、ある条件が満たされている間ループ処理を行うのに対して、for文では「何回ループさせるのか」あるいは「どこからどこまでループさせるのか」がハッキリしている場合におもに用いられます。当然、記述の仕方によってどちらの制御文でも同じことを行うことはできます。

for.m
d0122908_2245140.gif

コード説明
4行目、for文の中で使う変数 i をmain関数の先頭で宣言しています。for文の中で用いられる変数にはこのように「 i 」と名付ける習慣があります。もちろん自由な名前をつけることはできます。
6行目、for文はこのように3つの引数をとります。今までの引数と違い、引数の区切りをセミコロン「 ; 」で行っていることに注意してください。第1引数で最初の数字を指定しています。第2引数で最後の数字を指定しています。この例では i が1から10までの間ループすることを指定しています。第3引数では1回ループが終る毎に i がどのように変化するのか指定します。この「 i++ 」の ++インクリメント と呼ばれ、i をひとつ増やすことを意味しています。つまり1回ループするたびに i は1つずつ増えることになります。逆に1つずつ減らす場合は「 i-- 」と記述します。--デクリメント と呼ばれます。

実行画面

d0122908_0162125.gif

コンパイルの際に -o オプションで実行ファイルの名前を for にするように指定しています。このオプションを打ち込まなければ実行ファイル名は今まで通り a.out という名前になります。また今回は -framework オプションは打ち込みませんでした。
 実行結果とコードとの関係はおよそ理解できると思います


最後に、プログラミング入門書によくある「西暦何年がうるう年になるのか」をfor文を使って算出するプログラムのサンプルコードを示して、この制御文の説明を終わりにしたいと思います。


うるう年


1.うるう年とは4で割り切れる年で
2.しかも100で割り切れる年ではありません。
3.しかし400で割り切れる年はうるう年になるそうです

まずはサンプルコードをみてみましょう
if、while、do-while、continue、break、for と switch文以外のすべての制御文が出てきます。

uruu.m
d0122908_13444728.gif

コード説明

コード数が多いのは、ほとんどユーザーとのやりとり(インターフェース)部分です。後でじっくり見て下さい。はじめて登場する関数は23行目と29行目の abs関数です。この関数は引数の中の整数を絶対値(つまりプラス・マイナスという符号のない値)に変換します。
 さて肝心なのは36行目から42行目の for 文と、その中の37行目から41行目の if 文です。

37行目の if 文の条件式の中では
1.その年(start)を4で割った場合の余りを % 演算子で求めています。余りが 0 なら 4 で割り切れることになり、条件1は該当していることになります。
2.次に && 演算子で 1番目の条件と2番目の条件を繋いで両方の条件に該当しないと 真 にならないことにしています。&& は AND演算子と呼ばれまています。
3.次の条件とは「100で割り切れないか」 || (あるいは) 「400で割り切れる」という条件になっています。 || は OR演算子と呼ばれ、この演算子の左辺と右辺のどちらかが該当すれば 真 を返します。この2番目の条件をまとめるために ( ) を使っていることに注意してください。この if 文の中の条件式を言葉にすると
「条件1が真で、かつ 条件2もしくは条件3のどらかが真なら」となります。
ブロック文 { } の中で count を1加算しているのは、うるう年が存在したかどうかをのちほど判定するのに使うためです。

次に36行目の for 文では
1. startの整数値から
2. endの整数値まで
3. ブロック文 { } の中の処理をすすめて、strtの値を1加算する
という繰り返しなっています。ユーザーから受け取った開始西暦年を入れた start 変数と終了西暦年を入れた end 変数をそのまま使っていることに注意してください。

44行目から49行目 5/13/14:00修正
修正前は変数 count が 0 ならうるう年は「ありませんでした。」という表示をするのみでしたが、変数 count が 1 以上の場合に次のループにそなえて 0 で初期化するのを忘れていたました。またうるう年が存在していた場合には年代を表示したあとに「です。」という言葉を追加するようにいたしました。


d0122908_23213528.gif

実行画面

今回は「 -o 」オプションで実行ファイルを「 uruu 」という名前でコンパイルしています。
「 -framework 」オプションは、このコードの内容がまったくのC言語のままなので使っていません。(使っても問題はおきません)
実行するときは「 ./uruu 」とします。
色々な入力を試してみてください。それなりに色々なケースに対応できていると思います。
[PR]
by vivacocoa | 2007-05-02 16:42


<< Objective-C Pri... Objective-C Pri... >>