鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所

Slides:



Advertisements
Similar presentations
软件编程基础 一、程序的编辑 Java 源程序是以 Java 为后缀的简单的文本文件,可以用各种 Java 集成开发环境中的源代码编辑器来编写,也可以用其他文 本编辑工具,如 Windows 中的记事本或 DOS 中的 EDIT 软件等。 利用文字编辑器编写下列程序 public class Hello.
Advertisements

单元二:面向对象程序设计 任务二:借书卡程序设计.
3.2 Java的类 Java 类库的概念 语言规则——程序的书写规范 Java语言 类库——已有的有特定功能的Java程序模块
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
四資二甲 第三週作業 物件導向程式設計.
C#程序设计案例教程 第3章 程 序 结 构.
AI人工智慧報告 黑白棋 班級:資工四乙 學號:498G0009 姓名:盧冠妤.
第7章 C#函數與.NET Framework類別函數庫
算法设计与分析 Algorithm Design and Analysis
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
第二章 JAVA语言基础.
第三章 控制结构.
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
C# 程式設計 第一部分 第1-4章 C# 程式設計 - 南華大學資管系.
程式設計實作.
第5章 异常处理 王德俊 上海交通大学继续教育学院.
C#程序设计 c# programming 泛型 C#程序设计课程组.
控制流程 邏輯判斷 迴圈控制.
.NET 程式設計入門(使用 C#) 講師:鄧智鴻.
第二章 C# 基础知识.
第四章 在 C# 中实现 OOP 概念.
程序與函數的類別方法 目的:模組化程式設計 方法:由上而下設計 注意事項:(1)獨立性 (2)結合問題 (3)子問題間的溝通.
程式敘述執行順序的轉移 控制與重複、方法 Lecturer:曾學文.
第3章 語法入門 第一個Java程式 文字模式下與程式互動 資料、運算 流程控制.
第三章 C#面向对象初级编程 面向对象得程序设计越来越受到编程人员的喜爱。类和对象是面向对象程序设计中的重要概念。封装性、继承性和多态性是面向对象的特点,本章旨在全面说明C#编写面向对象程序设计的方法。
程式設計實作.
第2章回顾 标识符:不用记,动手 关键字:if, else, switch, for, while, do, break, continue, void, …… 局部变量和成员变量 ①变量作用域 ②内存布局 基本数据类型 ①4类8种 ②互相转换 流程控制语句 ①分支 if……else, switch.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
C#程序设计基础 $3 成员、变量和常量.
程序设计期末复习 黎金宁
第12章 從C到C++語言 12-1 C++語言的基礎 12-2 C++語言的輸出與輸入 12-3 C++語言的動態記憶體配置
程式撰寫流程.
第9章 多线程 王德俊 上海交通大学继续教育学院.
第4章 数组和集合 4.1 一维数组 4.2 二维数组 4.3 Array类 4.4 交错数组 4.5 ArrayList类
第三章 流程控制與例外處理 資訊教育研究室 製作 注意:本投影片僅供上課使用,非經同意,請勿散播或轉載。
實作輔導 3 日期: 4/14(星期六) 09:10~12:00、13:10~16:00
例外處理與 物件序列化(Exception Handling and Serialization of Objects)
檔案讀寫與例外處理 (File IO and Exception Handling)
3.1 数据类型 3.2 标识符与关键字 3.3 常量 3.4 变量 3.5 运算符与表达式 3.6 一个编程实例
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
2019/1/17 Java语言程序设计-程序流程 教师:段鹏飞.
C/C++/Java 哪些值不是头等程序对象
$10 可空类型.
C#程序设计基础 第二章 数据类型.
第六章 属性、索引器、委托和事件.
類別與物件 I (Classes and Objects I)
第三章 C# 基础知识.
辅导课程八.
《JAVA程序设计》 语音答疑 辅导老师:高旻.
第二章Java基本程序设计.
程式結構&語法.
C#程序设计基础 $3 成员、变量和常量.
第二章 Java基本语法 讲师:复凡.
Java程式初體驗大綱 大綱 在學程式之前及本書常用名詞解釋 Hello Java!程式 在Dos下編譯、執行程式
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第二章 Java语法基础.
本节内容 Lua基本语法.
龍老師我不會Debug QQ.
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
PPT注意事项: 当前PPT课件文件必须和提供的源代码文件夹“代码”在同一目录中即不要移动文件夹“代码”的默认位置。
JAVA 程式設計與資料結構 第三章 物件的設計.
第2章 Java语言基础.
迴圈(重複性結構) for while do while.
判斷(選擇性敘述) if if else else if 條件運算子.
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
第二章 Java基础语法 北京传智播客教育
第二章 Java基本语法 讲师:复凡.
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
Presentation transcript:

鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所 函式 鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所

綱要 函式呼叫 傳值函式 傳址函式 out參數 陣列作為函式參數與傳回值 井字遊戲Tic-tac-toe函式版

函式 集中重複或類似的程式碼片段為一個函式 縮短簡化原程式,使程式較容易閱讀,也比較不會出錯 各函式的資料相互獨立,讓程式開發團隊成員可以同時各自撰寫偵錯不同函式,方便合作 下一章再介紹較複雜程式的規畫與函式導向的程式設計方法

綱要 函式呼叫 傳值函式 傳址函式 out參數 陣列作為函式參數與傳回值 井字遊戲Tic-tac-toe函式版

呼叫函式一例 Random rand = new Random(); int k = rand.Next() % 30 + 1; for (int i = 0; i < k; ++i) { for (int j = 0; j < 50; ++j) Console.Write("*"); } Console.WriteLine();

函式呼叫流程 class Program { static void Main(string[] args) int k = rand.Next() % 30 + 1; } public class Random { . . . public int Next() } }

CallingFunctions.Program.Main static void Main(string[] args) { Random rand = new Random(); int k = rand.Next() % 30 + 1; for (int i = 0; i < k; ++i) PrintALineOfStars(); }

CallingFunctions.Program. PrintALineOfStars static void PrintALineOfStars() { for (int j = 0; j < 50; ++j) Console.Write("*"); } Console.WriteLine();

函式呼叫流程 class Program { static void Main(string[] args) A(); . . . } static void A() B(); static void B()

偵錯器的進一步應用 “逐步執行”與”不進入函式”的差別 目前類別與函式顯示 監看式的應用 呼叫堆疊的應用 即時運算視窗的應用

有回傳值的函式宣告與呼叫 static int ARandomNumber() { Random rand = new Random(); int result = rand.Next(); return result; } . . . . . . int k = ARandomNumber() % 30 + 1;

產生多個亂數時的問題 int k1 = ARandomNumber(); int k2 = ARandomNumber();

函式名稱的商榷 動詞片語 名詞片語 宣告為void , 沒有回傳值 內容為執行一些動作 呼叫時可以呈現出一個祈使句的形式 例:PrintALineOfStars 名詞片語 描述傳回值的內涵 例:ARandomNumber

綱要 函式呼叫 傳值函式 傳址函式 out參數 陣列作為函式參數與傳回值 井字遊戲Tic-tac-toe函式版

數學函數 函數與自變數 sin(x), x = p/6, x = p/2 真實參數, 形式參數, 傳回值

數學函式呼叫流程 double y = Math.Sin( Math.PI/6 ); class Math { static double Sin( double x ) . . . return result; }

傳值呼叫及以值回傳 形式參數 呼叫函式記憶區 區域變數 真實參數 結果變數 傳回值 形式參數 被呼叫函式記憶區 區域變數 傳回值

水平拋體計算 老鷹抓著石頭水平飛行 老鷹放開石頭攻擊地面目標 在主控台螢幕上看到石頭落下 水平方向的移動距離為 x = v0 t 垂直落下距離為 y = g t2/2

虛擬碼 1 Screen[0,0]~Screen[NY-1,NX-1]設為空白 2 for(t=0; t<NT; ++t) { 2.1 Screen[y, x] = ' ' 2.2 x = HorizontalDistance(v0, t) 2.3 y = VerticalDistance(g, t) 2.4 Screen[y, x] = 'o' 2.5 重新顯示Screen // 動畫效果 }

函式虛擬碼 HorizontalDistance( v0, t ) 1 x = v0*t 2 return x

函式虛擬碼 VerticalDistance( g, t ) 1 y = 0.5*g*t*t 2 return y

PlottingTrajectory.Program.Main 片段 for (t = 0; t < NT; ++t) { Screen[y, x] = ' '; x = HorizontalDistance(v0, t); y = VerticalDistance(g, t); if (x >= NX || y >= NY) break; Screen[y, x] = 'o'; Console.Clear(); for (i = 0; i < NY; ++i) { for (j = 0; j < NX; ++j) { Console.Write(Screen[i, j]); } Console.WriteLine();

PlottingTrajectory.Program. HorizontalDistance static int HorizontalDistance(double v0, int t) { double x = v0 * t; return (int) x; }

PlottingTrajectory.Program. VerticalDistance static int VerticalDistance(double g, int t) { double y = 0.5 * g * t * t; return (int) y; }

綱要 函式呼叫 傳值函式 傳址函式 out參數 陣列作為函式參數與傳回值 井字遊戲Tic-tac-toe函式版

SwappingIntegers.Program 片段 int x = 3; int y = 5; Swap(x, y); Debug.Assert(x == 5 && y == 3); . . . static void Swap(int x, int y) { int temp = x; x = y; y = temp; }

正確版本片段 int x = 3; int y = 5; Swap(ref x, ref y); Debug.Assert(x == 5 && y == 3); . . . static void Swap(ref int x, ref int y) { int temp = x; x = y; y = temp; }

Euclid.Program.Main static void Main(string[] args) { Debug.Assert(GCD( 1, 5 ) == 1); Debug.Assert(GCD( 12, 18 ) == 6); Debug.Assert(GCD(17, 13) == 1); Console.Write("輸入第一個正整數: "); int x = Convert.ToInt32(Console.ReadLine()); Console.Write("輸入第二個正整數: "); int y = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("兩數的最大公因數為{0}", GCD(x, y)); }

Euclid.Program.GCD static int GCD(int x, int y) { if (x < y) Swap(ref x, ref y); // x 較小時, 需交換x 與 y int remainder; while (y != 0) { remainder = x % y; x = y; y = remainder; } return x;

Euclid.Program.Swap static void Swap(ref int x, ref int y) { int temp = x; x = y; y = temp; }

綱要 函式呼叫 傳值函式 傳址函式 out參數 陣列作為函式參數與傳回值 井字遊戲Tic-tac-toe函式版

應用傳址參數傳回多個變數值 同時以函式的多個計算結果來改變真實參數內容 閱讀程式時,不易區分使用傳址參數取得函式計算結果與利用傳址參數改變真實參數的兩種情況,不利了解與偵錯 需設定真實變數初值 改用out參數較佳 不必設定真實變數初值

UsingOutArguments.Program.Main static void Main(string[] args) { int a = 5; int perimeter1 = 0; int area1 = 0; GetAreaAndPerimeterOfASquare( a, ref area1, ref perimeter1); Debug.Assert(area1 == 25 && perimeter1 == 20); int perimeter2; int area2; GetAreaAndPerimeterOfASquareUsingOut( a, out area2, out perimeter2); Debug.Assert(area2 == 25 && perimeter2 == 20); }

UsingOutArguments.Program. GetAreaAndPerimeterOfASquare static void GetAreaAndPerimeterOfASquare( int a, ref int area, ref int perimeter) { area = a * a; perimeter = 4 * a; }

UsingOutArguments.Program. GetAreaAndPerimeterOfASquareUsingOut static void GetAreaAndPerimeterOfASquareUsingOut( int a, out int area, out int perimeter) { area = a * a; perimeter = 4 * a; }

綱要 函式呼叫 傳值函式 傳址函式 out參數 陣列作為函式參數與傳回值 井字遊戲Tic-tac-toe函式版

一維陣列記憶配置 p[0] p p[1] p[2] p[3] p[4]

PassingArray.Program.Main片段 int[] p = { 1, 2, 3, 4, 5 }; int[] pCopy = p; PassArrayElementByValue(p[2]); PassArrayElementByReference(ref p[2]); PassArrayElementAsOutParameter(out p[2]); PassArrayByValue(p); Debug.Assert(p == pCopy); PassArrayByReference(ref p); Debug.Assert(p != pCopy); PassArrayAsOutParameter(out p);

陣列p和pCopy的參考指向相同位置 p pCopy

PassingArray.Program. PassArrayElementByValue static void PassArrayElementByValue(int x) { x *= 2; }

PassingArray.Program. PassArrayElementByReference static void PassArrayElementByReference(ref int x) { x *= 2; }

PassingArray.Program. PassArrayElementAsOutParameter static void PassArrayElementAsOutParameter(out int x) { x = 3; }

PassingArray.Program. PassArrayByValue static void PassArrayByValue(int[] a) { for (int i = 0; i < a.Length; ++i) a[i] *= 2; } a = new int[] { 7, 8, 9 };

PassingArray.Program. PassArrayByReference static void PassArrayByReference(ref int[] a) { for (int i = 0; i < a.Length; ++i) a[i] *= 2; } a = new int[] { 7, 8, 9 };

PassingArray.Program. PassArrayAsOutParameter static void PassArrayAsOutParameter(out int[] a) { a = new int[] { 1, 2, 3, 4, 5 }; }

使用重構修改Array2D 擷取方法 AverageOfEachRow 重新命名 table

ReturningArray.Program.Main片段 double[] individualAverage = AverageOfEachRow(score); double[] subjectAverage = AverageOfEachColumn(score); for (int i = 0; i < N_STUDENTS; ++i) { Console.WriteLine("{0}: 兩科平均成績 {1}", registerNumber[i], individualAverage[i]); } for (int j = 0; j < N_SUBJECTS; ++j) { Console.WriteLine("{0}: 全班平均成績 {1}", subject[j], subjectAverage[j]);

ReturningArray.Program. AverageOfEachRow static double[] AverageOfEachRow(int[,] table) { int nRows = table.GetUpperBound(0)+1; double[] average = new double[nRows]; int nColumns = table.GetUpperBound(1)+1; for (int i = 0; i < nRows ; i++) { int sum = 0; for (int j = 0; j < nColumns; j++) { sum += table[i, j]; } average[i] = (double)sum / nColumns; return average;

以Random物件為參數 static int ARandomNumber( Random rand ) { int result = rand.Next(); return result; } . . . . . . Random rand = new Random(); int k1 = ARandomNumber( rand ); int k2 = ARandomNumber( rand );

綱要 函式呼叫 傳值函式 傳址函式 out參數 陣列作為函式參數與傳回值 井字遊戲Tic-tac-toe函式版

判斷使用者或電腦獲勝虛擬碼 判斷使用者或電腦獲勝 Won( i0, j0, board ) 1 設使用者或電腦最新位置在i0, j0 2 檢查是否成列 if( board[i0, 0] == board[i0, 1] == board[i0, 2] ) return true 3 檢查是否成行 if( board[0, j0] == board[1, j0] == board[2, j0] ) return true 4 檢查主對角線是否均為'x' 或 'o' if( board[0, 0] == board[1, 1] == board[2, 2] == board[i0, j0] ) return true 5 檢查次對角線是否均為'x' 或 'o' if( board[0, 2] == board[1, 1] == board[2, 0] == board[i0, j0] ) 6 return false

亂數產生‘o’位置虛擬碼 虛擬碼: 亂數產生'o'位置 TakeAPosition( board, io, jo ) 0 | 1 | 2 ---+---+--- 3 | 4 | 5 6 | 7 | 8 1 do { 1.1 產生一個0到8的亂數k 1.2 io = k / 3 1.3 jo = k % 3 } while( board[io,jo] 不是空白 ) 2 board[io, jo] = 'o'

TicTacToe2.Program.Main片段 do { Display(board); Console.Write("輸入x位置的座標, 以逗點分隔: "); string[] input = new string[2]; input = Console.ReadLine().Split(','); int ix = Convert.ToInt16(input[0]); int jx = Convert.ToInt16(input[1]); board[ix, jx] = 'x'; userWin = Won(ix, jx, board); hasVacancies = HasVacancies(board); if (userWin || !hasVacancies) break;

TicTacToe2.Program.Main片段 TakeAPosition(rand, board, out io, out jo); computerWin = Won(io, jo, board); if (computerWin) break; hasVacancies = HasVacancies(board); } while (hasVacancies); Display(board); if (userWin) { Console.WriteLine("使用者獲勝"); } else if (computerWin) { Console.WriteLine("電腦獲勝"); } else { Console.WriteLine("平手");

TicTacToe2.Program.Won static bool Won(int i0, int j0, char[,] board) { if ((board[i0, 0] == board[i0, 1]) && (board[i0, 1] == board[i0, 2])) return true; if ((board[0, j0] == board[1, j0]) && (board[1, j0] == board[2, j0])) return true; if ((board[0, 0] == board[i0, j0]) && (board[1, 1] == board[i0, j0]) && (board[2, 2] == board[i0, j0])) return true; if ((board[0, 2] == board[i0, j0]) && (board[2, 0] == board[i0, j0])) return true; return false; }

TicTacToe2.Program.TakeAPosition static void TakeAPosition(Random rand, char[,] board, out int io, out int jo) { do { int k = rand.Next() % 9; io = k / 3; jo = k % 3; } while (board[io, jo] != ' '); board[io, jo] = 'o'; }

TicTacToe2.Program.Display static void Display(char[,] board) { Console.Clear(); Console.WriteLine(" 0 1 2 "); Console.WriteLine(" "); Console.WriteLine("0 {0} | {1} | {2} ", board[0, 0], board[0, 1], board[0, 2]); Console.WriteLine(" ---+---+---"); Console.WriteLine("1 {0} | {1} | {2} ", board[1, 0], board[1, 1], board[1, 2]); Console.WriteLine("2 {0} | {1} | {2} ", board[2, 0], board[2, 1], board[2, 2]); }

TicTacToe2.Program.HasVacancies static bool HasVacancies(char[,] board) { bool hasVacancies = false; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { if (board[i, j] == ' ') { hasVacancies = true; break; } return hasVacancies;