情報科学概論
2003.5.27

Back to index page



  1. 本日の作業内容

  2. 変数と代入(2)

    先週は代入について学習しました.代入とは名前のついた器に「値」を納めるこ とでした.図1に改めてイメージを示しますので,この概念をよく理解しておい て下さい.

    図1 変数を箱に例えた代入の説明

    図1のように,代入とは数値や文字列を箱に入れるようなものと考えて下さい. 値を呼び出すときには,箱の名前,すなわち変数名を指定すると値が「返され」 ます.別の値を再び代入する,と言う操作は,以前の内容を破棄して新しく入れ られた値のみを保持します.

    • 多重代入

      変数をいくつかまとめて初期化するとき,ひとつひとつ式を立てて代入しなくても, 一度に代入することが可能です.このような代入を「多重代入」と言います.方 法は,言語に依存する部分もありますが,Rubyでは以下のようにすると,一度に 複数の代入が実行できます.

      a, b, c, d = 1, 2, 3, 4
      

      値は並びの順番に代入されます.値を表示する行を追加して,自分で確認して みましょう.

      変数の個数と代入すべき値の個数が異なる場合には注意が必要です.次の例をそ れぞれ試してみて下さい.

      e, f, g = 1, 2, 3, 4
      

      h, i, j, k = 1, 2, 3
      

      変数の個数の方が多い場合には,値の入っていない (初期化されていない) 変数 が存在するため,その値を表示しようとすると,エラーになります.一方,変数 の個数の方が少ない場合には,余分な動作は破棄されています.

      多重代入の特殊な例として,先週行った変数の値の入れ換えというのも可能です. 次の例で確認して下さい.

      a, b, c, d = 1, 2, 3, 4
      a, b = b, a
      c, d = d, c
      

      入れ換えは単純な代入の応用例なので,3個以上の変数に対しても可能です.次 の例はどのような結果になるでしょうか.

      a, b, c, d = 1, 2, 3, 4
      a, b, c = b, c, a
      

      多重代入は便利ですが,使い過ぎると見通しの悪いスクリプトになる可能性もあ るので,利用には注意しましょう.また,今後,「配列」を学習するときには,威力を 発揮することになるでしょう.

    • 自己代入

      次週以降,「制御構造」という処理の流れを制御するスクリプトを扱いますが, その中のくり返し操作などで重要になるのがこの「自己代入」です.非常に 便利な機能ですので,どの言語を学習する際にも必ず使用されます.これが分か らないと,今後の作業は難しくなりますので注意して下さい.

      自己代入の考え方は,自分自身の値を一度読み出してそれに何かの演算を行った 後,再び自分に代入することです.次の例を見てみましょう.

      a = 1
      a = a + 1
      

      2行目は,数学的に考えると間違っていますが,先週と同様この処理は代入なの で問題無く実行されます.最初,a には1が代入されているので,1と いう値を持っています.2行目は,1という値を持つ a に1を加えたも の,すなわち,2を a に代入する操作ですので,この式が実行された 段階で a の値は2に変わっています.他の四則演算の例でもためして みましょう.

      sum = 1
      diff = 10
      pro = 5
      div = 6
      sum = sum + 2
      diff = diff - 1
      pro = pro * 3
      div = div / 3
      

      四則演算以外にも自己代入は可能ですが,それは今後制御構造を学習した後に必 要に応じて,紹介することにします.また,自己代入は頻繁に登場するので,簡 単に記述する方法が各言語で用意されています.Rubyでは上の処理は次のように 書くことが可能です.

      sum += 2
      diff -= 1
      pro *= 3
      div /= 3
      

      先週行った連続する整数の和などの逐次計算においても,自己代入は効果的です. 繰り返し処理をまだ行っていないので,現時点ではまだ簡単には記述できませんが,次のような 処理が考えられます.

      sum = 0
      sum += 1
      sum += 2
      sum += 3
      sum += 4
      sum += 5
      sum += 6
      sum += 7
      sum += 8
      sum += 9
      sum += 10
      

      この処理は,電卓で「メモリ機能」を使ったことがあるなら分かるのではないでしょ うか.数字を入力しては電卓の M+ のキーを押していくと,数値がメ モリに加算されて行くので,最後に MR のキーを押すとそれまでの合 計が表示されるのが電卓のメモリ機能です.これと同じようなものだと思って下 さい.

      文字列には和の演算が可能でした.自己代入も同様になるのでしょうか.試して みましょう.

      str = "abc"
      str += "def"
      

      結果はどうなったでしょうか.また,文字列は,実はさらに定数倍の操作が可能です.すなわち,

      str = "abc"
      str *= 5
      

      のような操作も可能です.これは,文字列に整数の5をかけることは,文字列を5 回加えることになる,と言う意味です.注意するのは,順番が逆だとエラーにな ることです.すなわち,str * 3 の表現は動作しますが,3 * str はダメだと言うことです.

    • 特殊な定数

      これまで文字や数値をスクリプト上に記述して作業を行ってきました.この場合, ちょっと変数の値を変えようとしても,エディタ上でスクリプトを修正して保存 し直す必要がありました.そこで,「コマンドライン引数」として数値を与え る場合について考えてみます.このような引数を格納する特殊な定数が実は用 意されています.ただし,定数と言っても,定数を扱う「配列」となっています ので,扱いには注意が必要です.今日のところは,深く考えずに,そのまま作業 してみましょう.例えば,二つの数の2乗の和を計算するスクリプトを次のよう に作成します.

      #square.rb
      
      a = ARGV[0].to_i
      b = ARGV[1].to_i
      square = a * a + b * b
      printf "The answer of %d^2 + %d^2 = %d\n", a, b, square
      

      これを square.rb と言う名前で保存したとすると,ターミナルで

      $ ruby square.rb

      としてみると,次のような結果になります.

      The answer of 0^2 + 0^2 = 0
      

      さて,3行目と4行目に見慣れない文字があります.これが,コマンドライン引数を表す 定数 ARGV です.英語で引数を argument と言いますので,値,value を保持する定数としてこのような名前で用意されています.

      その次に問題なのが,[0] のような括弧つきの数字です.これは,配列を表すときの特徴で,配列と言う,値 を格納する列車の貨車のような入れ物の番号を指し示しています.そして,序数 は計算機言語では0 (ゼロ) から始まることが多いのですが,「0」というのは最初の 要素の番号です.4行目はそれが「1」になっていますので,その次,2番目の要素となりま す.最後にある to_i と言うのは,値を整数 (integer) に変換する操 作で,Rubyでは目的物に対して処理をドットで繋げることにより処理が可能です ので,このような記述になっています.もう一度繰り返すと,3行目は

      コマンドから与えた1番目の引数の値を整数として扱い,a に代入する

      と言うことです.しかし,先ほどの実行例はコマンドから引数として何も与え ていません.次のようにやり直してみましょう.

      $ ruby square.rb 2 3

      結果は見るとすぐに分かることと思います.ターミナルでコマンドにより与えた 2と3の数値を利用してそれぞれを2乗して和を求めています.今のコマンド作業 は,次の図2のように分解できます.

      図2 コマンドライン引数の考え方

      スクリプトが読み込む引数としては1番目が2,2番目が3になりますので, ARGV[0] に2が代入され,ARGV[1] には3が代入され ることになり,計算結果のようになります.この ARGV とい う定数をうまく利用すると,スクリプトの動作をいろいろ試すときに, 修正が簡単になります.いくつか,試してみて下さい.

      a = ARGV[0]
      b = ARGV[1]
      str = a + b
      

      a = ARGV[0].to_f
      b = ARGV[1].to_f
      div = a * a / b * b
      

      コマンドライン引数として与えた値はたとえ数字であっても最初は文字列として 扱われます.また,先ほど整数に直す to_i を紹介しましたが,同じ ような動作するもので浮動小数に直すのは to_f になります.

    • 数学関数

      数値に関することを扱い始めると,数学で使ってきた関数を使いたくなります. 基本的な関数はRubyにも用意されていますが,使うためには準備が必要です.ス クリプトの最初に必ず数学用のモジュールを呼び出すことをしてください.方法 は,

      include Math

      という記述を加えるだけです.これにより,数学関数の利用が可能になります. では,どのような関数が用意されているのでしょうか.以下に例を示します.

      関数atan2(x,y)逆正接
      cos(x)余弦
      sin(x)正弦
      tan(x)正接
      exp(x)指数
      log(x)自然対数
      log10(x)常用対数
      sqrt(x)平方根
      定数PI円周率
      E自然対数の底

      この中で,atan2(x,y) に関しては,説明が必要だと思いますので,図 3に座標系を示しておきます.

      図3 atan2(x,y)の考え方

      また,三角関数を使用する際に,引数として 与える数値は弧度法によるラジアン単位のものです.注意してください.

      以下では,実際の例として,図4に示すように,半径10の円において引数として与えた角度 (単位は 度) の弧の長さを求めてみましょう.

      図4 中心角から円弧の長さを求める方法

      
      #arc.rb
      
      include Math
      angle = ARGV[0].to_f
      arc = 10 * angle * PI / 180
      printf "Arc is %f \n", arc
      

      実行する場合には,

      $ ruby arc.rb 45

      のようになります.ここで, 最後の行に注目してください.ただの %f では, 小数部分をデフォルトの6桁取るようになっています. 整数部分はあるだけ確保されます.小数部分の桁まで 指定したければ,たとえば, %1.3f のよう にすれば,小数部分は四捨五入して3桁になります.整 数部分を1桁と指定しても,あるだけ確保されるので無 視されます.

      実験値のように有効数字が問題になる場合には全部の桁を考慮しなければなりま せん.その場合には,%e が使えます.この場合には,桁指定が大事に なります.最後の行を

      printf "Arc is %e \n", arc

      に変えて先ほどの180度で実行すると,出力は,

      Arc is 3.141593e+01

      のようになり,整数部分を一桁とり,10の1乗をかけるという表現に変ります. ここでも,桁数の指定が可能で,%1.3e のようにして,有効数字を規 定することが出来ます.

      もうひとつ例を試してみましょう.双曲線関数を計算してみます.様々な x の値に対してcosh( x )を計算してみましょ う.

      
      #cosh.rb
      
      include Math
      x0 = ARGV[0].to_f
      x = x0 * PI / 180
      cosh = ( exp(x) + exp(-x)) / 2
      printf "cosh(%f) = %f\n", x0, cosh
      

  3. 実習作業

    この時間に学習したスクリプトを自分で変更を加えたりしながら応用してみて下 さい.

  4. 小テスト

    授業の残り20分くらいでAクラスBクラス別々の小テストを行いますので,アナウンス に注意してください.

  5. 宿題

    授業の最後にAクラスBクラス別々の宿題の案内も出しますので,アナウンスに注意してください.


目次ページに戻る