C 程式設計— 陣列 台大資訊工程學系 資訊系統訓練班
課程大綱 C語言簡介 基本資料型態, 變數, 基本輸入輸出 控制敘述- 選擇控制與重覆控制 陣列 函式 指標 字元與字串 結構 檔案處理
本次課程大綱 陣列定義 一維陣列的宣告和使用 多維陣列的宣告和使用 巨集 字元陣列與字串 陣列與函式 基礎排序
陣列 陣列 結構性的資料儲存空間 結構可分為一維陣列和多維陣列 記憶體中儲存位址是線性關係的相臨位置 一個變數名稱代表一連串同樣型態或結構的資料 每個陣列元素以陣列中的索引來存取 使資料處理的技巧較為簡潔
宣告陣列 資料型態 陣列名稱[第1維度元素個數] [第2維度元素個數] 例子:假設我們有12個月的營業額要記錄、而營業額為整數 int Trade[12]; 月份 Trade[7]代表8月份的營業額。 因為C語言的陣列從索引0開始計算 例子:假設我們有兩年的每月營業額要記錄,則可以如下宣告2維陣列: int Trade [2][12]; 年 月份 Trade[1][7]代表第2年8月份的營業額。
一維陣列宣告 資料型態 陣列名稱[元素個數]; 定義多個相同資料型態的陣列 資料型態:陣列元素的資料型態 陣列名稱:不可與識別字相同 元素個數:表示陣列中的元素最多有幾個 舉例 int c[ 10 ]; float myArray[ 3284 ]; 3284*4 bytes! 定義多個相同資料型態的陣列 與一般變數相同 舉例: int b[ 100 ], x[ 27 ];
一維陣列記憶體配置 (1) 陣列的各個元素依照次序存放在連續的記憶體中
一維陣列記憶體配置(2) 例子 name陣列 score陣列 avg陣列 char資料型態的變數佔用1個byte 四個元素 : 4* 1= 4 bytes score陣列 int資料型態的變數佔用4個bytes 五個元素 : 5* 4= 20 bytes avg陣列 double資料型態的變數需佔用8個bytes 五個元素 : 5* 8= 40 bytes
一維陣列的初始化 初始化 如果未指定元素個數,會依據初始值決定 例子 C 語言內的陣列不會有邊界檢查 五個初始值代表會有五個陣列元素 資料型態 陣列名稱 [ 陣列大小 ] = { data1, data2, …, dataN } int n[ 5 ] = { 1, 2, 3, 4, 5 }; C 語言內的陣列不會有邊界檢查 如果未指定元素個數,會依據初始值決定 int n[ ] = { 1, 2, 3, 4, 5 }; 五個初始值代表會有五個陣列元素 例子
一維陣列元素的存取 存取格式 陣列名稱就是陣列起始位置的位址. 索引值就是陣列起始位置的位移. arr[5]; 代表索引值為5的元素. 陣列名稱[索引值] arr[5]; 代表索引值為5的元素. 第一個元素在 位置0 C是一個n個元素的陣列 c[ 0 ], c[ 1 ]...c[ n – 1 ] 陣列名稱就是陣列起始位置的位址. 索引值就是陣列起始位置的位移.
Copyright 1992-2004 by Deitel & Associates, Inc Copyright 1992-2004 by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.
Element Value 0 32 1 27 2 64 3 18 4 95 5 14 6 90 7 70 8 60 9 37 Copyright 1992-2004 by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.
Copyright 1992-2004 by Deitel & Associates, Inc Copyright 1992-2004 by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.
Element Value 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 Copyright 1992-2004 by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.
超出範圍的使用 程式設計師不小心使用的 a[10] 去存取一個不存在的記憶體空間 這個錯誤將會在執行時間時才被偵測到 int a[10]; for(i=0;i<=10;i++) a[i]=0; 這個錯誤將會在執行時間時才被偵測到
練習時間 輸入6個實數, 並求其平均數. 一個超過陣列界限的錯誤函數.
Use the value of an array element in the loop condition Copyright 1992-2004 by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.
Element Value Histogram 0 19 ******************* 1 3 *** 2 15 *************** 3 7 ******* 4 11 *********** 5 9 ********* 6 13 ************* 7 5 ***** 8 17 ***************** 9 1 * Copyright 1992-2004 by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.
Copyright 1992-2004 by Deitel & Associates, Inc Copyright 1992-2004 by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.
Rating Frequency 1 2 2 2 3 2 4 2 5 5 6 11 7 5 8 7 9 1 10 3 Copyright 1992-2004 by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.
多維陣列 二維陣列 int arr[2][3]; 三維陣列 int arr[2][3][4]; N維陣列
二維陣列記憶體空間 『列』是二維陣列的第一維索引 『行』是二維陣列的第二維索引 第一學年 第二學年 第三學年 資工系(第1列) A[0][0] A[0][1] A[0][2] 電機系(第2列) A[1][0] A[1][1] A[1][2] 電信系(第3列) A[2][0] A[2][1] A[2][2]
二維陣列的初始化 資料型態 陣列名稱[列的大小][行的大小]= { {D00,D01, D02,…, D0j-1}, {D10,D11, D12,…, D1j-1}, : : {D(i-1)0, D(i-1)1, D(i-1)2,…, D(i-1)(j-1)} }; 陣列元素必須依序指定每一列元素的內容,而列元素的內容則將之以{ }包裝起來 例子
二維陣列的例子 基本二維陣列的加法運算. 二維陣列的記憶體位址 將九九乘法表的乘法結果儲存在9×9的二維整數陣列
巨集指令: Define 『巨集指令』又稱為『替換指令』,可替換內容的有「常數」、「字串」或「函式」 格式一: 格式二: 範例: #define PI 3.14159 格式二: #define 巨集名稱(參數列) 替換內容 範例:#define Sum(x,y) x+y
巨集指令: Define 巨集取代常數 巨集取代字串 巨集取代函式 編譯時,『c=a+b;』會變成『c=5+10;』 例子 #define a 5 #define b 10 c=a+b; 編譯時,『c=a+b;』會變成『c=5+10;』 巨集取代字串 例子 巨集取代函式
巨集與函式 處理『巨集』是前置處理階段的工作,而編譯『函式』則是編譯階段的工作。 空間上的差異 時間上的差異 巨集將被取代為程式碼加入到程式中, 函式只會佔用一塊記憶體空間來存放函式定義 時間上的差異 呼叫函式及返回函式時,需要對堆疊進行疊入(push)與疊出(pop)的動作 巨集沒有這些動作,執行速度比較快。
字元陣列 char str[7]=“String”; char str[]=“String”; 例子: 字元陣列的應用
字元陣列與字串的宣告 (1) 宣告一般的一維字元陣列範例如下: 宣告字串(即字元字串;特殊的字元陣列)範例如下: 一般字元陣列與字串 (特殊字元陣列)的區別 char string1[]={'W','e','l','c','o','m','e'}; char string2[]="Welcome";
字串陣列的宣告 (2) [0] [1] [2] [3] [4] StringArray[0] h u m a n char StringArray[ ][6] ={"human","dog","cat","bird"}; [0] [1] [2] [3] [4] StringArray[0] h u m a n StringArray[1] d o g \0 $ StringArray[2] c t StringArray[3] b i r
字串的例子 計算字串長度 反向字串的產生
以一維陣列為參數的函數呼叫(1) 回傳值資料型態 函式名稱(int *); 回傳值資料型態 函式名稱(int []); 回傳值資料型態 函式名稱(int [n]);
以一維陣列為參數的函數呼叫(2) 參數為一維陣列 例子: 如果修改傳入的陣列內容會如何? int fun(int array[]); int main() { int arr[10]; fun(arr); } int fun(int array[]) ……………. 例子: 如果修改傳入的陣列內容會如何?
array = 0012FF78 &array[0] = 0012FF78 &array = 0012FF78 Avoid using this notion to prevent from ambiguity. Copyright 1992-2004 by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.
以陣列為參數的函數呼叫 參數為二維陣列 int fun(int array[][3]); int main() { fun(arr); } int fun(int array[][3]) …………….
搜尋與排序 搜尋與排序是程式設計基本且重要的問題。 『搜尋』(Searching),指的是在一堆資料中,尋找您所想要的資料。 例如:在英文字典中找尋某一個單字。 『排序』(Sorting)則是將一堆雜亂的資料,依照某個鍵值(Key Value)依序排列,方便日後的查詢或使用。 例如:英文字典中每個單字就是已經排序後的結果『從a~z』。
線性搜尋法 簡單 將關鍵值與陣列中每一個元素相比 通常使用在小型且未排序過的陣列 例子
二元搜尋法 針對排序過的陣列 只比較中間值 如果相等,則回報此答案 若關鍵值小於中間值,則搜尋前半部 若關鍵值小於中間值,則搜尋後半部 例子
泡沫排序法(1) 將相鄰兩個資料一一互相比較,依據比較結果,決定資料是否需要對調,由於整個執行過程,有如氣泡逐漸浮上水面,因而得名
泡沫排序法(2) 假設我們有{24,7,36,2,65}要做氣泡排序,最後的排序結果為{2,7,24,36,65}
泡沫排序法(3) –Pseudo-code 輸入:未排序的資料x[0]~x[n-1] 輸出:已排序的資料 k ← n-1; while(k!=0) { t=0; for(i=0;i<=k-1;i++) if(x[i]>x[i+1]) x[i] ←→ x[i+1]; /* x[i]與x[i+1]互換 */ t=i; } k=t;
泡沫排序法(4) 第一回合 A[0]和A[1]比較,若A[0]>A[1]則資料互換,否則資料不交換。
泡沫排序法(5) 第二回合….第五回合 在第一回合時,A[0]~A[4]的最大值已經在A[4]
練習題: 設計泡沫排序法(Bubble Sort)的函數, 以陣列做為函數的參數. 先寫在main函式 將相關程式碼變成函式 設計選擇排序法(Selection Sort)的函數, 以陣列做為函數的參數. 永遠先找出最小的值
今天學到了什麼 什麼是陣列定義 如何使用一維陣列的宣告 如何使用多維陣列的宣告 什麼是巨集 如何分辨字元陣列與字串 如何使用陣列與函式 如何搜尋和排序