subroutine
サブルーチン

4章

4.1

p.61 (第6版はp.78) の例のように "sub" キーワードの次に名前を書き, サブルーチンを定義できる.サブルーチン定義はグローバルである.

Perl では変数はデフォルトでグローバル変数である. サブルーチン内で全てのグローバル変数にアクセスできる. p.61 (第6版はp.78) の例はグローバル変数を読み書きし, 戻り値を使わないサブルーチンである. 多数のサブルーチンからグローバル変数を利用できることは 便利な点も多いがデバッグを困難にする場合もあるので注意すること. プライベートな変数の作り方は後述する.

Perl ではメインルーチンを囲むブロックに名前がない.

4.2

サブルーチン名の前に & をつけて呼び出す. & は省略できる場合が多いが,組込み関数と名前が ぶつかったときのために書いておくほうがよい.

4.3

最後に計算された式の値が戻り値となる. 場所的にサブルーチンの最後にある式ではないことに注意.

他の言語と同様に return 文で明示的に値を返すこともできる.

サブルーチンを呼び出した側ではその値を使わなくてもよい.

4.4

$n = &max(10, 15);

上の形でサブルーチンを呼び出すことで,第 1 引数として 10, 第 2 引数として 15 が与えられる.これらは max サブルーチン内では $_[0], $_[1] としてアクセスできる.すなわち,サブルーチン内では 引数リストは配列 @_ に代入されている.

p.65 (第6版はp.82) 上のサブルーチン max とそれを使うメインルーチンを書き, 動作させてみよ.

4.5

my を使ってサブルーチン内にローカルなプライベート変数を作ることができる. プライベート変数はアクセス範囲が制限されるため,デバッグに有利である.

サブルーチン冒頭で my を使ったプライベート変数に引数をコピーするという 書き方がよく用いられる.引数のあるサブルーチンではいつも最初に

my($a,$b) = @_;

のように書き,わかりやすい変数名をつけるとよい.

p.66 (第6版はp. 83) 上の例のパラメータに名前をつける部分を 一行にしたバージョンが p. 66下の例(第6版はp. 84 上の例) である.p.65 (第6版はp.82) のサブルーチン max をこの形に書き換え, 動作を確認せよ.

4.7

my は for ループの中などのサブルーチンよりも 小さい単位にも使うことができる.

4.8

Perl はいろいろな便利な自動変換がある半面,間違いをみつけにくい. プログラムの最初に use strict; と書くことでエラーが多く出力 されるようになる.プログラムの制限が厳しくなるため書きにくい面も あるが,よいプログラムを書く習慣がつくので毎回 use strict; を使うようにすべきである.

4.9

return はサブルーチンを即座に終了させる. 戻り値を強制的に返すこと(C言語のreturn と同様の使い方)が できる.

4 章補足

プログラミング言語でいう関数は

  1. 処理の一部を分割するためのものと
  2. 入力値から出力値を計算するためのもの(数学でいう関数)

の2種類に分けて考えるとよい。

教科書 p. 61 の marine は 1 のタイプの例である。 以下も処理を分割するための関数の形である.実行せよ.

#!/usr/bin/perl -w
use strict;

sub f1{
    print "Hello f1¥n";
}

sub f2{
    print "Hello f2¥n";
}

&f1;
&f2;
&f1;

教科書 p.64 の関数 max は 引数(入力値)から戻り値(出力値)を計算するタイプの例である. 以下もそのタイプの簡単な例である.実行せよ.

#!/usr/bin/perl -w
use strict;

my $out;

sub f3{
    my($x) = @_;

    return $x;
}

$out = &f3(1);
print "$out¥n";
$out = &f3(2);
print "$out¥n";
$out = &f3(3);
print "$out¥n";

上記の関数 f3 は引数の入力値をそのまま戻り値として返す関数である.

練習問題4.1

関数 f3 を参考に引数より 1 多い数値を戻り値として返す関数 f4 を f3 のすぐ下に定義せよ. メインルーチンで使用してテストを行え.

#!/usr/bin/perl -w
use strict;

my $out;

sub f3{
    my($x) = @_;

    return $x;
}

sub f4{
(ここを作成)
}

$out = &f3(1);
print "$out¥n";
$out = &f3(2);
print "$out¥n";
$out = &f3(3);
print "$out¥n";
$out = &f4(1);
print "$out¥n";
$out = &f4(2);
print "$out¥n";
$out = &f4(3);
print "$out¥n";

練習問題4.2

摂氏の温度の数値を引数とすると対応する華氏の温度を 戻り値として返す関数 fahrenheit を作成し,テストせよ.

練習問題4.3

下記プログラムの括弧内を埋めて摂氏0度から 45 度まで 5 度刻みの摂氏と華氏の対応表を出力せよ.

#!/usr/bin/perl -w
use strict;

my $i;
my $out;

sub fahrenheit{
    my($x) = @_;

    return $x*9/5 +32;
}

for ($i = 0 ; $i < 50 ; $i = $i + 5){
    $out = &fahrenheit($i);
(ここを作成)
}

練習問題4.4

練習問題4.2とは逆に華氏の温度を引数とすると摂氏の温度を戻り値として返す関数 celsius を作れ.作成関数celciusを使い,キーボードから入力された 華氏の温度を摂氏の温度に変換して出力するプログラムを作れ.

練習問題4.5

ここまでで作成した fahrenheit とcelcius は変更せずに そのまま使用するプログラムを作成する.

最初に以下のような画面を出力し,

Please input
1:C->F
2:F->C
0:quit

1 が入力されれば数値を入力して摂氏から華氏への変換, 2 が入力されれば数値を入力して華氏から摂氏への変換, 0 が入力されれば終了するプログラムを作成せよ. プログラムは 0 が入力されるまで繰り返し動作するものとする.

課題6

本日作成したプログラムを添付ファイルとしてメールで提出せよ. メールの宛先は <hiroshi@tokai.ac.jp> とし, Subject (件名)を Seminar 1-6 とせよ.


Updated in June 5, 2015, schedule, Yamamoto Hiroshi