# 本共筆由服務學習程設小天使們共同製作
第四章 陣列與方法

:::success
本章由我鄧傑笙負責,會涵蓋到本章所有內容與老師提到的概念,若有錯誤可直接聯絡我修正。
:::
:::warning
那既然這單元說到陣列,我們先來看看宣告陣列的方法吧!
:::
### 宣告陣列的方法(4-1)
宣告並建立score為一個含有五個陣列的元素整數陣列,寫法:
```
int[]score;
score=new int[5];
```
合併成一行
```
int[]score= new int[5];
```
陣列 a1: int[]a1 = new int[5]{1,2,3,4,5};
| Index | Value |
|-------|-------|
| 0 | 1 |
| 1 | 2 |
| 2 | 3 |
| 3 | 4 |
| 4 | 5 |
陣列 a2: int[,]a2 = new int[2,4]{{2,4,6,8},{1,3,5,7}};
| Index | Col 0 | Col 1 | Col 2 | Col 3 |
|-------|-------|-------|-------|-------|
| 0 | 2 | 4 | 6 | 8 |
| 1 | 1 | 3 | 5 | 7 |
```
語法
一維陣列:資料型別 [] 陣列名稱 = new 資料型別[陣列大小];
ex: int []scores = new int[5];
二維陣列:資料型別[,] 陣列名稱 = new 資料型別[第一維陣列大小,第二為陣列大小];
ex:int [,]scores = new int[4,5];
```
:::info
int[] score = new int[5]; //score一個含有五個陣列元素的整數陣列
long[] score = new long[5]; //score一個含有五個陣列元素的長整數陣列
double[] score = new double[5]; //score一個含有五個陣列元素的倍精準度陣列
string[] score = new string[5]; //score一個含有五個陣列元素的字串陣列
object[] score = new object[5]; //score一個含有五個陣列元素的物件陣列
:::
---
### 重點表格
基本有5種應用方法, 分別為陣列初始化, 陣列加入值, 陣列更新值, 陣列刪除值, 陣列foreach迴圈, 為最基礎, 最重要, 最常使用, 以下就作出介紹.

參考資料:https://vocus.cc/article/62fa2fdbfd89780001140d44
一維陣列
```
int[] array = new int[5];
string[] weekDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
Console.WriteLine(weekDays[0]);
Console.WriteLine(weekDays[1]);
Console.WriteLine(weekDays[2]);
Console.WriteLine(weekDays[3]);
Console.WriteLine(weekDays[4]);
Console.WriteLine(weekDays[5]);
Console.WriteLine(weekDays[6]);
/*Output:
Sun
Mon
Tue
Wed
Thu
Fri
Sat
*/
```
多維陣列
```
using System;
class Program
{
static void Main()
{
// 宣告一個二維陣列
int[,] array2DDeclaration = new int[4, 2];
// 宣告一個三維陣列
int[,,] array3DDeclaration = new int[4, 2, 3];
// 初始化二維陣列
int[,] array2DInitialization = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// 初始化三維陣列
int[,,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
// 存取二維陣列元素
Console.WriteLine(array2DInitialization[0, 0]); // 輸出: 1
Console.WriteLine(array2DInitialization[0, 1]); // 輸出: 2
Console.WriteLine(array2DInitialization[1, 0]); // 輸出: 3
Console.WriteLine(array2DInitialization[1, 1]); // 輸出: 4
Console.WriteLine(array2DInitialization[3, 0]); // 輸出: 7
Console.WriteLine(array2DInitialization[3, 1]); // 輸出: 8
// 存取三維陣列元素
Console.WriteLine(array3D[1, 0, 1]); // 輸出: 8
Console.WriteLine(array3D[1, 1, 2]); // 輸出: 12
// 取得陣列總元素數量或特定維度的長度
var allLength = array3D.Length;
var total = 1;
for (int i = 0; i < array3D.Rank; i++)
{
total *= array3D.GetLength(i);
}
Console.WriteLine($"{allLength} equals {total}"); // 輸出: 12 equals 12
}
}
//輸出:
1
2
3
4
7
8
8
12
12 equals 12
```
## 基本題型練習
1.計算一維陣列中所有元素的總和
難度
```
int[] array = {1, 2, 3, 4, 5};
int sum = 0;
// 使用迴圈遍歷陣列中的每個元素
for (int i = 0; i < array.Length; i++) {
// 將每個元素加到總和中
sum += array[i];
}
// 輸出總和
Console.WriteLine("陣列中所有元素的總和為:" + sum);
```
2.找出一維陣列中的最大值和最小值
難度
```
int[] array = {1, 2, 3, 4, 5};
int max = array[0]; // 假設最大值是陣列中的第一個元素
int min = array[0]; // 假設最小值是陣列中的第一個元素
// 使用迴圈遍歷陣列中的每個元素
for (int i = 1; i < array.Length; i++) {
// 如果當前元素大於最大值,則更新最大值
if (array[i] > max) {
max = array[i];
}
// 如果當前元素小於最小值,則更新最小值
if (array[i] < min) {
min = array[i];
}
}
// 輸出最大值和最小值
Console.WriteLine("陣列中的最大值為:" + max);
Console.WriteLine("陣列中的最小值為:" + min);
```
3.將一維陣列中的所有元素倒序排列
難度
```
int[] array = {1, 2, 3, 4, 5};
// 使用內建函式將陣列倒序排列
Array.Reverse(array);
// 輸出倒序排列後的陣列
Console.WriteLine("陣列倒序排列後的結果為:");
foreach (int num in array) {
Console.Write(num + " ");
}
```
4.將一維陣列中的所有奇數值加倍
難度
```
int[] array = {1, 2, 3, 4, 5};
// 使用迴圈遍歷陣列中的每個元素
for (int i = 0; i < array.Length; i++) {
// 如果元素是奇數,則將其乘以2
if (array[i] % 2 != 0) {
array[i] *= 2;
}
}
// 輸出結果
Console.WriteLine("將奇數值加倍後的陣列:");
foreach (int num in array) {
Console.Write(num + " ");
}
```
.應用1:理解如何使用陣列進行四則運算
難度

.應用2:將Randim產生十個亂數存入陣列,並計算陣列中的平均值
難度

.進階寫法:更有彈性的寫法,將個數宣告為常數

.進階寫法:列出陣列的個數 num.Length

應用3:將學生各科成績寫入陣列,並計算各科的平均值
難度

示意圖

_____
## ▸foreach...敘述(4-1-4)
用法:將某個集合物件的元素逐一指定給變數
```
語法
foreach (資料型別 變數 in 集合物件)
{
[敘述區段]
[break;]
[敘述區段]
}
```
課本例題
請輸入總人數:3
請輸入第一位身高(公分): 169.3
請輸入第二位身高(公分): 178.5
請輸入第三位身高(公分): 181.2
三位平均身高: 176.33
```
using System;
class Program
{
static void Main(string[] args)
{
Console.Write("請輸入總人數: ");
int totalPeople = int.Parse(Console.ReadLine());
double sum = 0;
// 使用 foreach 迴圈逐一計算每位人士的身高加總
foreach (int i in Enumerable.Range(1, totalPeople))
{
Console.Write($"請輸入第{i}位身高(公分): ");
double height = double.Parse(Console.ReadLine());
sum += height;
}
double averageHeight = sum / totalPeople;
Console.WriteLine($"三位平均身高: {averageHeight:F2}");
}
}
```
:::info
承陣列應用3,改寫:將學生各科成績寫入陣列,並計算各科的平均值
foreach (Student student in students):
第一個Student:為Struct所宣告的資料型別集合,也稱為結構資料型別(不同類型)
第二個student:在此宣告的變數
第三個students:為陣列名稱
用意:將students陣列裡的元素(數學及英文成績),逐一指定給student變數
:::
```
struct Student
{
public int math; // 用來存儲學生的數學成績
public int english; // 用來存儲學生的英文成績
}
static void Main(string[] args)
{
Student[] students = new Student[3]; // 建立一個能夠存儲三個學生成績的陣列
// 取得學生成績
for(int i=0; i<3; i++)
{
Console.WriteLine("請輸入第" + (i+1) + "個學生成績");
Console.Write("數學分數:");
students[i].math = int.Parse(Console.ReadLine()); // 使用者輸入學生的數學成績並存儲到對應的 Student 結構成員中
Console.Write("英文分數:");
students[i].english = int.Parse(Console.ReadLine()); // 使用者輸入學生的英文成績並存儲到對應的 Student 結構成員中
}
// 計算各科成績
int avgMath = 0, avgEnglish = 0; // 初始化變數來累加所有學生的成績
foreach (Student student in students) // 逐一遍歷所有學生
{
avgMath += student.math; // 將每個學生的數學成績加總到 avgMath 中
avgEnglish += student.english; // 將每個學生的英文成績加總到 avgEnglish 中
}
avgMath /= 3; // 計算數學平均成績
avgEnglish /= 3; // 計算英文平均成績
// 顯示成果
Console.WriteLine("數學平均分數:" + avgMath); // 輸出數學平均成績
Console.WriteLine("英文平均分數:" + avgEnglish); // 輸出英文平均成績
Console.Read(); // 等待使用者按下任意鍵以結束程式
}
```
___
## ∎ 方法(Method)
▸何謂方法?
程序(Procedure) :不傳回值
函式(Function):會傳回值
功能: 讓程式設計者將程式模組化 ,達成程式可再利用(reuse)
方法中所宣告的變數均為==區域變數(local variables)==

| 存取修飾詞 | 功能 |
|------------------|----------------------------------------------------------------------------|
| public | 未限制存取。 |
| protected | 存取限於包含類別或衍生自包含類別的型別。 |
| internal | 存取限於目前組件。 |
| protected internal | 存取限於目前組件或衍生自包含類別的型別。 |
| private | 存取限於包含型別。 |
* 當類別內的方法加上**static**修飾詞為「靜態方法」,可直接呼叫使用(不必使用new保留字來建立物件實體)
* 傳回值可以是數值字元字串結構列舉類別等資料型別,若不回傳任何值,可以使用==void==
* 詳細內容記載在4-23記得翻閱
## |▸參數的傳遞方式
>.傳值呼叫(Call By Value)
>
變數會複製一份給被呼叫方法的參數,呼叫完==不會影響==原本的變數

程序內的變數值改變,但程序前後值不變

## 傳址呼叫(Call By Reference)
直接將變數的為址傳遞給被呼叫方法的參數 , 呼叫完會影響原本的變數
程序內的變數值改變,但程序後的值也改變
==備註:變數前要加上 「ref」==

## .傳出呼叫(CallOut)
不用給值

參考資料:https://medium.com/sally-thinking/%E7%A8%8B%E5%BC%8F%E5%AD%B8%E7%BF%92%E4%B9%8B%E8%B7%AF-day12-c-%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88-%E9%99%A3%E5%88%97-%E6%96%B9%E6%B3%95-b8b2cad3e753
## 牛刀小試
難度
:::warning
開發一個圖書管理系統,其中包括一個 Book 類別來表示書籍。你需要實現以下功能:
Book 類別具有以下屬性:
書籍標題(Title)
書籍作者(Author)
書籍類別(Category)
書籍價格(Price)
Book 類別具有一個建構函式,可以初始化這些屬性。
Book 類別具有一個方法 DisplayInfo,用於顯示書籍的詳細信息,包括標題、作者、類別和價格。
在主程式中,創建一個 Book 對象,並呼叫其 DisplayInfo 方法,以顯示書籍的詳細信息。
這個程式的目標是展示如何使用類別和屬性來建立一個簡單的圖書管理系統,並展示如何使用存取修飾詞 public 來使類別成員可以被其他程式中的類別訪問。
:::
```
using System;
public class Book
{
// 書籍標題屬性
public string Title { get; set; }
// 書籍作者屬性
public string Author { get; set; }
// 書籍類別屬性
public string Category { get; set; }
// 書籍價格屬性
public decimal Price { get; set; }
// 建構函式
public Book(string title, string author, string category, decimal price)
{
Title = title;
Author = author;
Category = category;
Price = price;
}
// 顯示書籍詳細信息的方法
public void DisplayInfo()
{
Console.WriteLine($"書名: {Title}");
Console.WriteLine($"作者: {Author}");
Console.WriteLine($"類別: {Category}");
Console.WriteLine($"價格: {Price:C}");
}
}
class Program
{
static void Main(string[] args)
{
// 創建 Book 對象
Book myBook = new Book("C# Programming", "John Smith", "Programming", 29.99m);
// 使用 public 方法顯示書籍詳細信息
myBook.DisplayInfo();
}
}
```
---
:::info
以上是Chapter 4大致重點內容,如有問題都歡迎詢問~
製作者:鄧傑笙
Email: <s112213062@mail1.ncnu.edu.tw>
:::