roy > naoya > 基礎プログラミングI·情報検索 > (3)演算子・制御構造[1]
(3) 04/27の授業内容:演算子・制御構造[1]
[1] 演算子・条件判断への導入
前回getsメソッドやprintメソッド、printfメソッドを組み合わせたプログラムを作成した。これらを組み合わせるだけでも、ユーザからの入力に応じて計算を行い結果を表示するプログラムを作成することができたが、これだけでは表現しきれないことがいくつかあった。今回は、以下の2つの問題に焦点を絞って話を進める。
- 演算子:÷や×はどう書けばよいか。その他にも特殊な演算子があるのか(例:時給と労働時間からアルバイト代を計算する場合、アルバイト代=時給×時間、となるが×がキーボードにない。)。
- 制御構造(条件判断):条件に応じてメッセージを変更することはできないか(例:卒業までに必要な残り単位数が100単位以上ある場合、50単位以下の場合、それ以外の場合、でそれぞれ異なるメッセージを表示させたい。)。
[2] Rubyにおける演算子の記法
+や−、×、÷などの記号を演算子とよぶ。いくつかの演算子はキーボードに存在しないため、日常的に使用する演算子とは異なる演算子を使用する。
- 乗算(掛け算)は×ではなく*を使用する(例:2×5→2*5)。
- 除算(割り算)は÷ではなく/を使用する(例:20÷4→20/4)。
- べき乗はabではなく**を使用する(例:25→2**5)。
- 剰余(割り算の余り)は%で表現できる(例:10を3で割った余り→10%3)。
- {中括弧}や[大括弧]は使用せず全て(小括弧)で記述する(例:{4*(8+1)}→(4*(8+1)))。
- 分数では分母と分子を上下に記述するのではなく1行で記述する。
これらを組み合わせた例を見てみよう。
- 6×4÷2 → 6*4/2
- {5÷(4+1)2}2 → (5/(4+1)**2)**2
- 5 → 5/2
2
演算子の記法のまとめ
- ×は*、÷は/と書く(例:2*3、6/7)
- べき乗は**で表現する(例:2**10)
- 割り算の余り(剰余)は%と書く(例:10%3)
- 括弧({[は全て(で書く
[3] 出席課題
以下の式をRubyの記法にしたがって記述しよう。
- a × b - c ÷ d
- 7を3で割った余り+1
- {1-(i-0.1)2}2
制限時間は10分。できる範囲で実施し、制限時間内にメールで解答を送信すること。出席点は2点。
提出要領
- 提出先:課題提出用メールアドレス
- メールのSubject:ruby03
- 本文の構成:1行目で学籍番号、氏名を記載する。2行目以降に解答を書く。
[4] 制御構造とは何か
プログラムは上から順番に実行される。通常はこれで問題ないが、場合によっては困ることもある。いくつか例をあげてみよう。
- 計算問題を出す。正解していれば「正解です!」と表示し、間違っていれば「不正解です!」と表示する。
- 5問クイズを出す。4問以上正解で「ワンダフル!」、それ以外は「まあまあ」と表示する。
これらの例を図式的に(フローチャートで)表現すると以下のようになる。◇の箇所で条件を満たしているかどうか判定が行われ、満たしている場合と満たしていない場合では異なる動作を行っている。
プログラムでこれを表現する場合、左右に分けて書くことができないので、上下に分割して書く。
正解している場合 正解です!と表示 そうでない場合 不正解です!と表示
プログラムは上から進んでくるが、この部分では条件に応じて「正解です!」が表示されたり「不正解です!」が表示されたりする。順番に1行ずつ実行されて両方のメッセージが表示されることはない。
通常は上から順に実行するプログラムの処理の流れを変更する構造を制御構造という。制御構造には条件判断と繰り返しがある。今回は条件判断を取り上げ、次回繰り返しを行う。
制御構造のまとめ
- 上から順に実行するプログラムの流れを変えるものを制御構造という。
- 制御構造には条件判断と繰り返しがある。
- 条件に応じて異なる処理をさせることを条件判断という。
[5] 条件判断(1):if-end
条件判断の代表格となるのがif-endである。if文と呼ぶこともあるが同じものである。
条件が1つの場合
if文の基本構造を先ほどの日本語で書いた条件分岐の例と対比させながら確認してみよう
正解している場合 正解です!と表示 そうでない場合 不正解です!と表示
if 条件A #=>条件Aを満たせば 処理A #=>処理Aを実施する else #=>条件Aを満たさない場合は 処理B #=>処理Bを実施する end
「正解している場合」に対応するのが「if 条件A」となる。ifの横に具体的に条件を書く。「そうでない場合」は「else」と表現する。最後にはendがついている。endをつけ忘れるとプログラムが動かない。この構造を把握するために、以下のプログラムをif.rbという名称で保存し、実行してみよう。
#!/usr/koeki/bin/ruby
print"問題です。\n"
print"28の約数の和は28になる。\n"
print"Yesの場合は1を、Noの場合は2を入力\n"
answer = gets.chomp!.to_i
if answer == 1
print"正解です!\n"
else
print"不正解です!\n"
end
ifの横には「answer == 1」という条件が書かれている。==は右辺と左辺が等しいという意味である。つまり条件は「answer(に代入されている値)が1である」ということになる。このプログラムの実行結果を以下に示す。正解した場合と不正解の場合いずれも示すので、各自で実行した際に同じ結果となるか確認してみよう。
pan{c10xxxx}% ruby if.rb[Return] 問題です。 28の約数の和は28になる。 Yesの場合は1を、Noの場合は2を入力 1[Return] 正解です!
pan{c10xxxx}% ruby if.rb[Return] 問題です。 28の約数の和は28になる。 Yesの場合は1を、Noの場合は2を入力 2[Return] 不正解です!
条件が2つ以上の場合
次はもう少し複雑なケースを考えてみよう。以下は80点以上ならA、60点以上ならB、60点未満ならCと表示するという状況をフローチャートで表現したものである。1つ目の◇で80点以上という条件を満たしているか判定が行われ、満たさない場合は2回目の◇で60点以上という条件を満たしているかどうか調べている。
このように2つの条件がある場合、if文ではどのように書くのだろうか。このフローチャートをプログラムで表現したものが以下(hantei.rb)である。
#!/usr/koeki/bin/ruby
print"得点を入力してください\n"
score = gets.chomp!.to_i
if score >= 80 #=>1つ目の条件を記載
print"A評価です\n" #=>1つ目の条件を満たす場合に実施
elsif score >= 60 #=>1つ目の条件を満たさない場合2つ目の条件を満たすか判定
print"B評価です\n" #=>2つ目の条件を満たす場合に実施
else #=>いずれも満たさない場合は
print"C評価です\n" #=>これを実施する
end
2つ目の条件を記載するためにelsifが登場している。ifの横に記載された1つ目の条件を満たすか否かがまず判定され、満たした場合にはその下に書かれた処理が実行される。満たさない場合にはelsifの行で2つ目の条件を満たすかどうか判定が行われ、満たす場合はその下の処理、満たさない場合はelse以下の処理が行われる。最後には必ずendがつく。
なお、ifの行やelsifの行で登場している「>=」は≧と同じ意味である。キーボードには≧のキーはないので、≧のかわりに「>=」としている。
条件が3つ以上になった場合はelsifを何度も使用して記述する。これについて詳細は[6]if-endの応用[補足]を参照のこと。
if文のまとめ
- 次の基本構造を持つ。
if 条件A 処理A elsif 条件B 処理B else 処理C end
- 最後にはendを必ずつける。
- 条件が3つ以上の場合はelsifを繰り返し使用する。
[6] 条件判断(1'):if-endの応用[補足]
[7] 条件判断(2):その他の条件判断[補足]
[8] 演算子の種類
+や×などの計算に用いる記号を演算子と呼ぶことは説明したが、演算子は用途に応じて3つの区分がある。すなわち算術演算子、代入演算子、論理演算子である。
- 算術演算子:数値計算を行う際に利用する演算子(+, -, *, /, **, %)
- 代入演算子:変数への代入を行う際に利用する演算子(=, +=, -=, *=, /=, **=, %=)
- 論理演算子:制御構造の条件を記載するときに利用する演算子(==, <, <=, >, >=, &&, ||, !, not)
[9] 算術演算子
加算 (+)・減算 (−)・乗算 (×)・除算 (÷) 等を指す。前述の通り、数学で用いる記号とは異なる場合がある。
算術演算子 | 意味 | 例 |
---|---|---|
+ | 加算 | 2+5(2に5を加える) |
- | 減算 | 6-3(6から3を減じる) |
* | 乗算 | 9*2(9に2をかける) |
/ | 除算 | 12/4(12を4で割る) |
% | 剰余 | 9%2(9を2で割った余り) |
** | べき乗 | 2**8(2を8乗する) |
算数・数学と同様、演算子には優先順位がある。
- 高:**
- 中:* / %
- 低:+ -
したがって、1+2*3は2*3が先に行われ7に、3*2**3は2**3が先に行われ24になる。ただし(括弧)があれば、先に括弧内が計算される。(1+2)*3は9に(3*2)**3は216となる。
算術演算子のまとめ
- 数値計算を行う際に用いる演算子を算術演算子という。
- +, -, *, /, **, %がある(働きは上の表参照)
- 演算子には優先順位がある。
- ()をつけた場合は()内の計算が優先される。
[10] 代入演算子
Rubyでは=は右辺と左辺が等しいという意味ではなく、左辺に右辺を代入するという意味になる。変数に値を代入する際に利用するのが代入演算子である。算術演算子と=を組み合わせることで様々な働きを持たせることができる。例えば+=は左辺に右辺を加算するという意味になる。
data = 10 というように初期値10が与えられていた場合、data += 5とすると、10に5が加算され15となる。
代入演算子 | 意味 | 例 |
---|---|---|
= | 通常代入 | z=10(zに10を代入する) |
+= | 加算代入 | z+=10(zの現在の値に10を加算する) |
-= | 減算代入 | z-=10(zの現在の値から10を引く) |
*= | 乗算代入 | z*=5(zの現在の値を5倍する) |
/= | 除算代入 | z/=10(zの現在の値を1/10にする) |
%= | 剰余代入 | z%=5(zの現在の値を5で割った余りを新しいzとする) |
**= | べき乗代入 | z**=5(zの現在の値を5乗した値を新しいzとする) |
以下のプログラムは変数xに初期値として0を与え、その後代入演算子を用いて様々な値を代入していきながらprintfでx内の値がどのように変化していくかを確認するものである(assign.rb)。
#!/usr/koeki/bin/ruby
x = 0
printf("xの値は%dです\n",x)
x = 10
printf("xの値は%dです\n",x)
x += 5
printf("xの値は%dです\n",x)
x *= 2
printf("xの値は%dです\n",x)
x %= 4
printf("xの値は%dです\n",x)
このプログラムを実行すると以下の結果が得られる。
pan{c10xxxx}% ruby assign.rb[Return] xの値は0です xの値は10です xの値は15です xの値は30です xの値は2です
代入演算子のまとめ
- 変数への代入を行う際に用いる演算子を代入演算子という。
- =は左辺に右辺を代入するという意味を持つ
- その他に+=, -=, *=, /=, **=, %=がある(働きは上の表参照)
[11] 論理演算子
if文において条件を記述する際に==や>=が登場したが、これらは右辺と左辺を比較するために利用していた。このように条件を記載するときに用いるのが論理演算子である。「以上」「以下」といった表現に加え、複数の条件を指定する際の「かつ」(論理積)や「または」(論理和)などもある。
論理演算子 | 意味 |
---|---|
== | 左辺と右辺が等しい |
< | 左辺が右辺よりも小さい |
<= | 左辺が右辺以下 |
> | 左辺が右辺よりも大きい |
>= | 左辺が右辺以上 |
&& | かつ(論理積) |
|| | または(論理和) |
! | 否定 |
not | 否定 |
「以上」や「以下」では不等号と等号を組み合わせるが、不等号の後に等号を書くのが正しい順番である。すなわち>=や<=が正しく=>や=<は間違いである。以下には、論理演算子を用いた条件記述例を示す。
if x >= 1 #->xが1以上であれば
x -= 1 #->xから1を引く
end
if x >= 1 && x <= 10 #->xが1以上かつ10以下であれば
x += 1 #->xに1を加える
end
if x > 1 || x < 10 #->xが1より大きい、またはxが10未満であれば
x *= 2 #->xを2倍する
end
if !(x <= 1 && x >= 10) #->1以下または10以上でなければ
x -= 4 #->xから4を引く
end
論理演算子のまとめ
- 制御構造の条件を記載するときに利用する演算子を論理演算子という。
- ==は右辺と左辺が等しいという意味を持つ。
- その他に<, <=, >, >=, &&, ||, !, notがある(働きは上の表参照)
[12] コメントをつける
コメントとは、プログラム中に記述する注釈であり、作者名を残したり、説明を行うために使用する。プログラム中に書かれていてもプログラムとして認識されることはないので、実行する上では特に問題は無い。他人の書いたプログラムはわかりづらいと言われることが多いが、わかりやすさの向上を目指すためにコメントを利用することが望ましい。
コメントをあらわす記号は「#」である。プログラム中に「#」があると、その行の「#」以降の記述はコメントとして扱われる(代入演算や論理演算の項で示したサンプルのプログラムを参照のこと)。行の先頭に「#」があれば、1行全てがコメントになる。
[13] レポート課題
前回の授業で自分で作成したプログラムは、キーボードからの入力を受け取り、何らかの計算をした結果を出力するものであったが、今度はさらに条件判断を追加してみよう(report1.rb)(8点満点)。
つまり、キーボードからの入力を受け取り、(何らかの計算を行い、)その結果の値に応じて異なるメッセージを表示できるようにする。
例えば、
- 英語と国語と数学の得点を入力してもらい合計が100点以上なら合格、80点以上なら補欠合格、それ以下なら不合格と表示する。
- 誕生日を入力すると星座を教えてくれるプログラム。
- 宝くじ。
などが考えられる。他の人とテーマが重複しないように面白いテーマを考えてプログラムを作成してみよう。キーボードから2つ以上の数字を入力させる、数多くの演算子を使用する、条件判断における条件数を複数にするなどの工夫が行われているプログラムは得点が高くなる。作成したプログラム、実行結果、プログラムの説明をメールに記載して送信する。
提出要領
- 提出先:課題提出用メールアドレス
- 提出期限:5/10(日)23:00
- メールのSubject:report01
- 本文の構成:1行目で学籍番号、氏名を記載する。2行目以降は以下の構成とする
- 作成したプログラム
- プログラムの実行結果
- プログラムの説明
- 感想
採点要領
- 採点基準:期限内提出点(2点)、メールの体裁(1点)、プログラムの間違い(2点)、プログラムの説明(2点)、プログラムの複雑さ(1点)
- 今回は初めての課題提出であり、長いプログラムではないため、1行ずつどのような処理をしているのかをメソッドの働きや制御構造の働きについて触れながら説明する。
- わかりにくい説明や、Webページを単にコピー&ペーストしただけの説明は減点することがある。一度読み直してから提出すること。
- 驚異的に良くできているレポートについては満点の8点を超える得点をつけることがある。
- よくできていたレポートは、他の人の参考になるよう、本人が特定できないような形で掲載する。掲載してほしくない場合はメールでの課題提出時にその旨記載すること。