基礎プログラミング 第13回(2007年5月28日) 「関数」の補足説明 Report-Fの解説.

Slides:



Advertisements
Similar presentations
プログラミング第5回 1 while ループ 文字列の操作
Advertisements

関数(静的メソッド:static method)
プログラミング入門2 第4回 配列 for文 変数宣言 初期化
プログラミング基礎I(再) 山元進.
前回のおさらい copy = original; 「=」の意味は「コピー」か?
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
~手続き指向からオブジェクト指向へ(Ⅰ)~
プログラミング基礎I(再) 山元進.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング基礎I(再) 山元進.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
情報処理Ⅱ 2005年12月9日(金).
第8回 プログラミングⅡ 第8回
プログラミング実習 1・2 クラス 第 1 週目 担当教員:  渡邊 直樹.
構造体.
繰り返し プログラミング 第4回 繰り返し プログラミング第4回.
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
精密工学科プログラミング基礎 第9回資料 (12/11 実施)
第20章 Flyweight ~同じものを共有して無駄をなくす~
精密工学科プログラミング基礎Ⅱ 第3回資料 今回の授業で習得してほしいこと: 2次元配列の使い方 (前回の1次元配列の復習もします.)
第10回 プログラミングⅡ 第10回
~手続き指向からオブジェクト指向へ[Ⅱ]~
プログラミング言語入門 手続き型言語としてのJava
プログラミング2 関数
第9章 例外処理,パッケージ 9.1 例外処理 9.2 ガーベッジコレクション.
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
マルチスレッド処理 マルチプロセス処理について
アルゴリズムとプログラミング (Algorithms and Programming)
第10章 これはかなり大変な事項!! ~ポインタ~
オブジェクト指向 プログラミング 第七回 知能情報学部 新田直也.
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
第11回 プログラミングⅡ 第11回
精密工学科プログラミング基礎Ⅱ 第4回資料 今回の授業で習得してほしいこと: 文字列の扱い ファイル入出力の方法 コマンドライン引数の使い方
オブジェクト・プログラミング 第8回.
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
C言語ファミリー C# 高級言語(抽象的) Java オブジェクト指向 C++ C 機械語(原始的)
アルゴリズムとプログラミング (Algorithms and Programming)
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
C#プログラミング実習 第3回.
計算機プログラミングI 木曜日 1時限・5時限 担当: 増原英彦 第1回 2002年10月10日(木)
アルゴリズムとプログラミング (Algorithms and Programming)
計算機プログラミングI 第4回 2002年10月31日(木) 問題解決とアルゴリズム クラスメソッドと手続きの抽象化 最大公約数
第5回 プログラミングⅡ 第5回
JAVA入門⑥ クラスとインスタンス.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
プログラミング 4 文字列.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング演習II 2004年11月 2日(第3回) 理学部数学科・木村巌.
プログラミング入門2 第5回 配列 変数宣言、初期化について
情報処理Ⅱ 小テスト 2005年2月1日(火).
値渡しと参照渡しについて.
printf・scanf・変数・四則演算
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
オブジェクト指向言語論 第十回 知能情報学部 新田直也.
計算技術研究会 第5回 C言語勉強会 関数(function)を使う
C言語講座第5回 2017 構造体.
プログラミング演習I 補講用課題
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング 3 ポインタ(1).
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
計算機プログラミングI 第10回 2002年12月19日(木) メソッドの再定義と動的結合 クイズ メソッドの再定義 (オーバーライド)
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
Presentation transcript:

基礎プログラミング 第13回(2007年5月28日) 「関数」の補足説明 Report-Fの解説

ループを使わない場合,似た処理を繰り返し書く必要があった static void Main(string[] args){ int a,b,c; do { Console.WriteLine(“正の数を入力して”); a = int.Parse(Console.ReadLine()); } while (a <= 0); b = int.Parse(Console.ReadLine()); } while (b <= 0); c = int.Parse(Console.ReadLine()); } while (c <= 0); }

ループを使うと,似た処理をまとめることができた static void Main(string[] args){ int[] a = new int[3]; for(int i=0; i<3; i++){ do { Console.WriteLine(“正の数を入力して”); a[i] = int.Parse(Console.ReadLine()); } while (a[i] <= 0); }

関数を使っても,似た処理をまとめることができる static int InputPositiveInt(){ int x = 0; do { Console.WriteLine(“正の数を入力して”); x = int.Parse(Console.ReadLine()); } while (x<=0); return x; } static void Main(string[] args){ int[] a = new int[3]; for(int i=0;i<3;i++) a[i] = InputPositiveInt();

関数の「引数」と「返値」 Mainの中の「似た処理」を,まとめて関数に追い出したい 関数にデータを渡すときには「引数」で渡す 関数内で処理したデータをMain(呼び出し元)で 受け取るときには「返値」を受け取る 関数は,返値を返すときにreturn [変数]; を用いる

数値(値型)の場合,【値渡し】 1: static void Main(string[] args){ 2: int a = Double(2); 3: int b = Double(a); 4: Console.WriteLine(“a={0}, b={1}”, a, b); 5: } 6: static int Double(int x){ 7: x = x * 2; 8: return x; 9: }

3: int b = Double(a); 2: int a = Double(2); 8 4 4 4 8 2 Double(2); 4; 8; b = Double(a); 変数の世界(Main) static int Double(int x = 2); static int Double(int x = a); int x 8 4 4 4 8 2 x = x * 2; x = x * 2; 変数の世界(Double) return x; return x;

配列(参照型)の場合, 【参照渡し】 1: static void Main(string[] args){ 2: int[] a = new int[]{2,3,5}; 3: Double(a); 4: for(int i=0;i<3;i++) Console.WriteLine(“a[{0}]= {1}”, i, a[i]); // 確認用の出力 5: } 6: static void Double(int[] x){ 7: for(int i=0;i<x.Length; i++) x[i] = x[i] * 2; 8:}

3: Double(a); Double(a); static void Double(int[] x = a); 1 2 int[] a 4 2 3 6 10 5 参照型の=は リンクを張る という意味 変数の世界(Main) static void Double(int[] x = a); int[] x x[1] = x[1] * 2; x[2] = x[2] * 2; x[0] = x[0] * 2; 変数の世界(Double) return;

引数の「値渡し/参照渡し」について 結局,=のときと同じ考え方でよいことになる 引数の型が値型(int, double, float, bool, etc...) なら,引数の変数(x)は関数呼出しの値(a)を 「コピーする」 引数の型が参照型(配列,String, etc...) なら,引数の変数(x)は関数呼出しの値(a) (データ)に「リンクを張る」 値型のデータを無理矢理「参照渡し」する方法も用意されてはいる (ref, outキーワード) 基礎プロの範囲外なので説明省略

11回講義スライド17枚目の意図:Main関数が 値型のデータを関数に渡し,さらに関数内で処理してもらった結果を受取るときはreturnが必要 static int Double(int x){ x = x * 2; return x; } static void Main(...){ int a = 5; a = Double(a); //返値をaで受取った Console.WriteLine(a); // 画面には[10]と表示される static void Double(int x){ x = x * 2; } static void Main(...){ int a = 5; Double(a); //渡しっぱなし Console.WriteLine(a); // 画面には[5]と表示される

例1: 自作の Array.Copy() 関数 (ただしint[] のみを受け付ける簡易版) class Array { static void Copy(int[] orig, int[] copy, int length) { for(int i=0; i< length; i++) copy[i] = orig[i]; } } // 使い方は,第9回の6枚目のスライドを参照すること

例2:引数に渡した配列のコピーを作成して返す関数 (ただし,配列要素の並び順を逆にして返す) static int[] CopyAndReverseAry(int[] x) { int[] revcopy = new int[x.Length]; for(int i=0;i<x.Length;i++) revcopy[i] = x[x.Length - i - 1]; return revcopy; } //この関数は,Report-Fのヒントになっています static void Main(...){ int[] a = new int[3]{2,3,5}; int[] reva = CopyAndReverseAry(a); }

もう一度,“=”の意味を再確認 3 =の左右は同じ型, (ただし,左は変数,右はデータとみなす) =の左右が「値型」(int, float, etc...)なら =の右側(データ)を,=の左側の変数(箱)に 「代入」する =の左右が「参照型」(String, 配列, String Builder, その他のオブジェクト)なら =の左側にある「変数」のリンク先を,=の右側(データ)に結びつける(またはリンクを張りなおす) 3

Report-F の復習[17CopyAry] intの配列を引数とし,その配列のコピーを 返す関数CopyArrayをつくってください static int[] CopyArray(int[] ary) ★動作確認プログラムもつくること!! 動作確認プログラムは, 9回目(5月14日)のプリントを参考に,本当に「コピー」できているかどうか,までを 確認可能なものにすること (注)Array.Copy()関数の使用は禁止 (ヒント)関数内部で新しい配列の『容器』を作成し,ループで1つ1つintの数値をコピーしたあと,return 文で「作成した配列」を返す

Report-F 課題の意図 intの配列をコピーするCopyAry()関数をつくる Main()関数からCopyAry()関数を呼ぶ ここでの「コピー」とは,同じ値が入ったデータの実体を,オリジナルとは別に作ってください,という意味 「同じ数値が入っていることを確認してくれ」という意味ではない 「コピー」よりも,「バックアップ」と表現したほうがわかりやすかったかもしれない 言い換えると,「きちんと配列がバックアップされているかどうか」を調べればよい. そのためには,仮にバックアップデータを変更してみて,オリジナルが変更されないことを確かめればよい

Report-F 残念なプログラム (CopyAry()関数) static int[] CopyAry(int[] ary){ int[] copy = new int[ary.Length]; for(int i=0 ; i < ary.Length; i++) copy[i] = ary[i] * 2; //2倍を代入 return copy; } //CopyAry()関数の内部では,純粋に 配列要素のコピーだけを実行してほしかった

Report-F あとひといきのプログラム (CopyAry()関数) static int[] CopyAry(int[] ary){ //配列サイズ制限有 int[] copy = new int[3]; for(int i=0 ; i < 3 ; i++) copy[i] = ary[i]; return copy; } static int[] CopyAry(int[] ary){ //配列サイズ制限無し int[] copy = new int[ary.Length]; for(int i=0 ; i < ary.Length; i++) copy[i] = ary[i];

Report-F 多かった間違い(1) (Main()での確認プログラム) int[] orig = new int[3]{2,3,5}; int[] backup; backup = CopyAry(orig); // バックアップ実行 for(int i=0;i<3;i++) Console.WriteLine( “orig[{0}] = {1}”, i , orig[i]); for(int i=0;i<3;i++) Console.WriteLine( “backup [{0}] = {1}”, i , backup[i]*2);

Report-F 多かった間違い(2) (Main()での確認プログラム) int[] orig = new int[3]{2,3,5}; int[] backup; backup = CopyAry(orig); // バックアップ実行 for(int i=0;i<3;i++) Console.WriteLine( “orig[{0}] = {1}”, i , orig[i]); for(int i=0;i<3;i++) backup[i]*=2; for(int i=0;i<3;i++) Console.WriteLine( “backup [{0}] = {1}”, i , backup[i]);

Report-F 正解例 ( Main()での確認プログラム部分) int[] orig = new int[3]{2,3,5}; int[] backup; backup = CopyAry(orig); // バックアップ実行 for(int i=0;i<3;i++) backup[i]*=2; for(int i=0;i<3;i++) Console.WriteLine( “orig[{0}] = {1}”, i , orig[i]); for(int i=0;i<3;i++) Console.WriteLine( “backup [{0}] = {1}”, i , backup[i]);

練習問題13-1 (各自プロジェクトを作成すること) StringBuilderの配列を1つ受け取り,その 完全なコピー(フルバックアップ)を作成して返す 関数CopyStrBuildAry()を作成しなさい. static StringBuilder[] CopyStrBuildAry(StringBuilder[] sbary){ ... } 完全なコピー(フルバックアップ)とは,オリジナル,コピーそれぞれが完全に独立したデータ実体を持っている状態を指すものとする. Main()関数では,関数CopyStrBuildAry()の動作を確認する処理を記述しなさい. ヒント:intの場合はcopy[i]=ary[i]でコピーできたが,StringBuilderの場合は=で実体コピーできないので new StringBuilder(sbary[i].ToString()) (新規作成)

13-1 完全なコピーになっていない駄目な例 (配列の要素が共有されている) StringBuilder[] 型の変数 orig StringBuilder[] 型の変数 backup Main() StringBuilder[] 型の変数 copy (返値用) StrBuildAry()

13-1 期待する状態(完全なコピー) (配列の要素を共有していない.独立したデータ実体) 13-1 期待する状態(完全なコピー) (配列の要素を共有していない.独立したデータ実体) StringBuilder[] 型の変数 orig StringBuilder[] 型の変数 backup Main() StringBuilder[] 型の変数 copy (返値用) StrBuildAry()