関数(静的メソッド:static method) 基礎プログラミング 第11回(2007年5月21日) 関数(静的メソッド:static method) Main(){}の殻を打ち破る
数学における関数 たとえば2次関数は x = 2 を入力すると -2 が出力される たとえば「平面」の関数は x = 2, y = 3 を入力すると 13 が出力される
プログラミングにおける関数とは? 何かを入力すると あらかじめ定められた処理をその入力に対して施し 結果を出力する 関数 入力 (引数) (返値)
プログラミングでは, どういう場合に関数を使うか 同じような処理をまとめておき再利用したい場合 ある意味をもつ処理をひとくくりにまとめることが多い 関数としてまとめて行う処理の例: 身長と体重を入力すると,BMI値を返す関数 3辺の長さを入力すると,三角形の角を判定する関数 入力された秒数だけSleep()で待つ関数 ユーザに正の数値を入力させる(入力してもらうまで何度でも聞き直す)関数 黄金比を返す関数 累乗を計算してくれる関数 文字列をコピーしてくれる関数 何もしない関数...
関数を使うとなにがうれしい? プログラムのコードが短く,シンプルになる Array.Sort(ary); //配列を並べ替える関数を使う int a = Math.Pow(x,n); // xのn乗を計算する関数を使う 誰かが作ってくれた関数を使うのは簡単. データを準備しておいて,()内に渡すだけでよい 関数を自分で作るにはどうするか? 関数の定義を行う必要がある
関数の作り方(抽象的な説明) static 返値の型 関数名(引数の型1 引数1,引数の型2 引数2,・・・) { 関数の中身の記述; return 返値; } static ... =静的な(「クラスに属する」) 返値の型...=この型の返値を返す, 関数名... という名前の関数を定義する. 引数は[引数の型1]の引数1,[引数の型2]の引数2,... をとり,最後に返値を返す.
関数の作り方(返値がintのとき) 以下のように定義する static int 関数名(引数型1 引数1,・・・) { 関数の中身の記述; return 返値; } static int Func(int x, int y){ // 例(スライド 2p) int temp; temp = 5 * x + 4 * y; return temp; }
関数の作り方(返り値なし: void) 以下のように定義する static void 関数名(引数型1 引数1,・・・) { 関数の中身の記述; return; //return; は省略可能 } 例:指定した秒数だけ待つ関数 static void WaitSec(int sec){ System.Threading.Thread.Sleep(sec*1000); } //returnは省略
作成した関数の使い方 作成した関数を引数をつけて呼び出す int retvalue = Func(2,3); Console.WriteLine(“f(2,3)={0}”, retvalue); WaitSec(10); //10秒まつ
関数を作るときの注意 関数の中には関数を定義できない Main(){} 関数の{ }の外で,かつ class XXX { } の中にしか書けません namespace NS class A class B static void Main() static void Bar() static int Foo()
関数呼び出しの入れ子 return では必ず呼び出した箇所の次の位置に処理が戻る 別の場所に飛んだり,戻らなくすることはできない class A return では必ず呼び出した箇所の次の位置に処理が戻る 別の場所に飛んだり,戻らなくすることはできない static void Main() float f = Dist(1,1,4,5); Console.WriteLine(“dist: ”+f); static float Dist(x1,y1,x2,y2) float d = Sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)); return d; static float Sqrt(float x) float sqrt = Math.Sqrt(x); return sqrt;
参考:Main()も関数のひとつです プログラム実行時に,最初に呼ばれる関数がMain() 途中終了するのに,以前 return; を使った breakに似ているが,breakはループを抜ける命令 Main()関数に渡す引数とは?(参考) コマンドプロンプトから実行するときの「コマンドライン引数」が渡される
本講義では「関数」=「静的メソッド」 用語の定義はプログラミング言語によってまちまち メソッド(Method) =手段 ファンクション(Function)=関数 プロシージャ(Procedure)=手続き サブルーチン(Subroutine) =副次処理 オブジェクト指向プログラミング言語では「Function」や「Procedure」より「Method」のほうが一般的 FunctionとProcedure/Subroutineの違いは,返値があるかないか,といったニュアンス(どちらも古い言葉) 本講義では今後,簡単のため「静的メソッド」のことを「関数」と呼ぶ 以前の資料では単に「メソッド」と呼んでいたこともある
関数とのデータ受け渡し方法 関数内部で使えるように渡す方法 関数内部で処理したデータを外に渡す方法 「引数」として渡す (静的変数を介する) 「返値」として渡す
引数と返値について Call by Value (値渡し) Call by Reference (参照渡し) 渡すときに中身をコピーして渡す 数値の場合 Call by Reference (参照渡し) 渡すときにはコピーせず,リンクのみ渡す 文字列や配列,List,Dictionary等の場合 どうしても数値を「参照渡し」したいという 場合は上のキーワードを覚えておくとよい. 滅多に使わないので,引数と返値は 「 = と同じルールで受け渡す」と覚えれば十分.
確認プログラム static void Double(int[] x) { for( int i=0; i<x.Length; i++) x[i] *= 2; } static void Main(...){ int[] a = new int[3]{2,3,5}; Double(a); //参照渡し for(int i=0; i < 3; i++) Console.WriteLine(a[i]); static void Double(int x){ x *= 2; } static void Main(...){ int a = 5; Double(a); //値渡し Console.WriteLine(a);
(無理に数値を参照渡ししなくても) 返値で結果を返せばよい static void Double(int x){ x *= 2; } static void Main(...){ int a = 5; Double(a); //値渡し Console.WriteLine(a); static int Double(int x){ x *= 2; return x; } static void Main(...){ int a = 5; a = Double(a); Console.WriteLine(a);
関数のオーバーロード 引数の数は同じで,引数の型が異なる関数をつくることをオーバーロードといいます static void PrintType(int value){ Console.WriteLine(“int: {0}”,value); } static void PrintType(String value){ Console.WriteLine(“String: {0}”,value);
静的変数とメソッドローカル変数 静的変数:すべての関数(Main()含む)から 参照できる変数 関数外で 「static 変数名」として定義する メソッドローカル(method local)変数:関数内{}からのみ参照できる変数 関数内で定義する(staticはつけない) 同じ変数名の静的変数とメソッドローカルな変数があったら,メソッドローカル変数が優先される
静的変数を使った例 (count) class CountMethodCall { static int Count = 0; // メソッドの呼出し回数カウンタ static void Main(string[] args) { Console.WriteLine(“{0}”, Double(5)); // =>[10] Console.WriteLine(“{0}”, Count); // =>[1] Console.WriteLine(“{0}”, Double(7)); // =>[14] Console.WriteLine(“{0}”, Count); // =>[2] } static int Double(int x) { Count++; // カウンタを1つ増やす return x*2;
練習問題11-1 (コミット不要:プロジェクトは各自作成すること) (1)ユーザに正の数を入力してもらい,その数を返値として返す関数を定義しなさい(引数なし) static int InputPositiveInt() ただし,0以下の数が入力されたら,再度入力してもらうこと (2)引数に指定した秒数だけ待つ関数 static void WaitSec(int sec) を作成し,(1)(2)をMain()関数から順次呼ぶことで,入力秒数だけ待つプログラムをつくりなさい
練習問題11-2 (コミット不要:プロジェクトは各自作成) 練習問題11-2 (コミット不要:プロジェクトは各自作成) xのn累乗(べき乗)を返す関数MyPowをつくってください ただし,引数(x, n), 返値 はすべて整数とします static int MyPow(int x, int n) 動作確認プログラムもつくり,動作確認しなさい ちなみに,Math.Pow(x,n) と同じ答えが返れば,計算は合っている
プロジェクトの(新規)作成方法 (1)VS2005を起動 (2)メニューから「ファイル」>「新規作成」>「プロジェクト」を選ぶ (3)「新しいプロジェクト」で「コンソールアプリケーション」を選び,プロジェクト名と場所を入力してOKを押す
Report-F [17CopyAry] (配点4) コミットの締切は 5月26日(土)23:59 intの配列を引数とし,その配列のコピーを 返す関数CopyArrayをつくってください static int[] CopyArray(int[] ary) ★動作確認プログラムもつくること!! 動作確認プログラムは, 9回目(5月14日)のプリントを参考に,本当に「コピー」できているかどうか,までを 確認可能なものにすること (注)Array.Copy()関数の使用は禁止 (ヒント)関数内部で新しい配列の『容器』を作成し,ループで1つ1つintの数値をコピーしたあと,return 文で「作成した配列」を返す