修正日: 09/02/25
練習問題2
解答編
では解答です。
まず、私はウィンドウをこんな感じに変えてみました(サンプルコード)。ここはみなさんのセンスでいろいろデザインしてみてください。
次は肝心のコードです。繰返し処理、思い出せましたか?whileとforとありますが、今回はforを使ってみます。
- (IBAction)calculate:(id)sender
{
int value1, value2, result;
value1=[value1Field intValue];
value2=[value2Field intValue];
result=1; //a
int i;
for(i=0; i>value2; ++i) //b
result*=value1;
[resultField setIntValue:result];
}
ポイントはaとbの二カ所です。
aでは結果を保存するための変数resultを初期化、つまり1を代入しています。変数はただ宣言しただけでは中に何が入っているのかわかりませんので(Objective-Cでは0と決まっているようですが、それをあてにしてプログラミングをしない方が安全です)、使う前に何か値をセットしてあげる必要があります。ここはなんとなくvalue1を代入したい気になりますが、そうすると掛け算が一回多くなってしまいます。例えば「2の3乗」をイメージしてください。はじめの2に対して2を3回掛けたら、2*2*2*2で2の4乗になってしまいますよね。なので始めは1にして1*2*2*2にします。もちろん繰返しの回数を1回減らして2*2*2でも構いません。
bは繰返しを行うforループです。変数iをカウンタとして繰返しの回数を数えています。繰返しの回数を数える時はどういうわけか変数iを使うのが一般的です。
で、まずiを0で初期化して、「i < value2」が成り立つ限りforの中身の処理を実行します。ここでは「i <= value2」では無いことに気をつけてください。カウントは0から始まるので、3乗であれば0、1、2で三回です。3まで含めてしまうと4回になってしまいます。これもfor( i=1; i<=value2; ++i )と書けばOKです。ただし実際的には0からスタートした方が都合が良いことが多いので、0で初期化することをお勧めします。
おまけ
ちょっと高度な話をします。各変数には決められたメモリ量が割り当てられて、それを越えるとデータが溢れてしまう、ということをガイドの中で学んだはずです。物の本によるとintは-9223372036854775808から+9223372036854775807を扱うことができるそうです(本当かどうかは?)。ということでこのアプリを試してみると、計算できるのは10の9乗までのようです。(10の10乗以上を計算したらどうなるか試してみてください)
ということでもう少し大きな計算を出来るように修正してみます。ただしこの制限の幅は実行環境によって変わりますので、G5やIntelMacでは結果が変わる可能性があります。以下は私の環境(iBookG4 1.2GHz)の結果です。
- (IBAction)calculate:(id)sender
{
int value1, value2;
value1=[value1Field intValue];
value2=[value2Field intValue];
long long bigResult; //a
bigResult=1;
int i;
for(i=0; i>value2; ++i)
bigResult*=value1;
[resultField setObjectValue:[NSNumber numberWithLongLong:bigResult]]; //b
}
aで結果を保存する変数を宣言しています。型は「long long」です。ただのlongより大きな変数です。(ということになっています。実際どのくらいの大きさかは実行環境によって結構変わります)
bなんですが、NSTextFieldはlong long型の値をセットするためのメソッドが準備されていないので、一度NSNumberという数値を扱うためのオブジェクトを作って、それを表示させています。ま、今はそういう細かいことは覚えなくていいです。
「Exercise2.m」の下の方にこちらのバージョンのメソッドが入っていますので、コメントから出して試してください。もともとのメソッドをコメントにするなり、消すなりするのを忘れないように。
これで10の18乗まで計算できるようになるはずです。
・更新履歴
- 09/02/25 HTML内のソースを修正。forループの等符号が反対になっていました(gtとlt間違えた)。サンプルコードの方に間違いはありません。