|
|
何謂陣列 ( Array)1. 有限個相同資料型態之元素組成之集合 2. 一大塊連續之記憶體 3. 一組索引與資料對映 l 一 維 陣 列 <1> 一 維 陣 列 的 宣 告 方 式 如 下 所 述 :
陣列的資料型態 陣列的名稱 [ 陣列的大小 ] ; int
array1 [ 20 ] ;
float array2 [ 25 ] ;
char array3 [ 50 ] ; <2> 宣 告 陣 列 的 位 置 為 程 式 之 最 上 端 .
<3> 一 維 陣 列 的 排 列 結 構 如 下 圖 所 述 . 我 們 舉 例 一 陣 列 名 叫 A 的 陣 列 , 其 陣 列 大 小 有 n 個 , 即 為 A[n] .
範例:有一陣列宣告如下:int
A[ 20 ] ;
|
陣列名稱®
|
A[0]
|
A[1]
|
A[2]
|
.....
|
A[19]
|
| 記憶體® |
|
|
|
|
|
|
記憶體位址®
|
m
(陣列第一元素之位址)
|
m+2
|
m+4
|
|
m+2*(19)
| <4> 我 們 可 以 在 宣 告 陣 列 時 , 指 定 數 值 給 陣 列 . 例 如 :
陣列的資料型態 陣列的名稱 [ 陣列的大小 ]= {´´,´´,…´´}; 範例: int score[5]={ 2, 5, 7 ,9 ,10 };
|
陣列名稱®
|
score[0]
|
score[1]
|
score[2]
|
score[3]
|
score[4]
|
| 記憶體® |
2
|
5
|
7
|
9
|
10
|
Example: #include < stdio.h >
void main(void) {
int count,total=0; int number[10]={ 1,2,3,4,5,6,7,8,9,10 }; for( count=0 ; count < 10 ; ++count ){printf("number[%d]=%d\n",count,number[count]); total=total + number[count];}printf("1+2+3+4+5+6+7+8+9+10=%d\n",total); }
|
執 行 結 果 :
number[0]=1number[1]=2number[2]=3number[3]=4number[4]=5number[5]=6number[6]=7number[7]=8number[8]=9number[9]=101+2+3+4+5+6+7+8+9+10=55
| l
二 維 陣 列 <1> 二 維 陣 列 的 宣 告 方 式 如 下 所 述 :
陣列的資料型態 陣列的名稱[ 列陣列的大小 ][ 行陣列大小 ] ; For example:
int array1 [ 10 ][ 20 ] ;
float array2 [ 5 ][ 25 ] ;
char array3 [ 100 ][ 50 ] ; <2> 宣 告 陣 列 的 位 置 為 程 式 之 最 上 端 .
<3> 二 維 陣 列 的 排 列 結 構 如 下 圖 所 述 . 我 們 舉 例 一 陣 列 名 叫 A 的 陣 列 , 其 列 陣 列 大 小 有 m 個 , 行 陣 列 大 小 有 n 個 , 即 為 A[m][n] .
|
行 (column) |
|
|
|
|
列 |
A[0][0] |
A[0][1] |
A[0][2] |
...... |
A[0][n-1] |
| (row) |
A[1][0] |
A[1][1] |
A[1][2] |
...... |
A[1][n-1]
|
|
A[2][0] |
A[2][1]
|
A[2][2] |
...... |
A[2][n-1]
|
|
.
|
.
|
.
|
.
|
.
|
|
.
|
.
|
.
|
.
|
.
|
|
A[m-1][0] |
A[m-1][1] |
A[m-1][2] |
|
A[m-1][n-1] | <4> 我 們 可 以 在 宣 告 陣 列 時 , 指 定 數 值 給 陣 列 . 例 如 : int score1[2][5]={{ 1, 2, 3, 4, 5 },{ 5, 4, 3, 2, 1 }}; 或 是 在 程 式 過 程 中 指 定 數 值 給 陣 列 . 例 如 :
void main(void)
{ int score1[2][5]; /* 陣列宣告 */ score1[0][0]=1; /* 程式本體 */ score1[0][1]=2; score1[0][2]=3; score1[0][3]=4; score1[0][4]=5;
score1[1][0]=5; score1[1][1]=4; score1[1][2]=3; score1[1][3]=2; score1[1][4]=1; …… } 【實例探討】某學生之功課表如下,(每個課程名稱皆以代碼表示)
|
一 |
二 |
三 |
四 |
五 |
| 1 |
|
2 |
|
2 |
|
| 2 |
1 |
4 |
1 |
4 |
1 |
| 3 |
5 |
|
5 |
|
5 |
| 4 |
|
|
|
|
|
| 5 |
3 |
|
3 |
|
3 |
| 6 |
|
|
|
|
|
| 課程名稱 |
代碼 |
| 計算機概論 |
1 |
| 離散數學 |
2 |
| 資料結構 |
3 |
| 資料庫概論 |
4 |
| 上機實習 |
5 | 此課表可以以一個二維陣列表示,其宣告方式如下: int course [6][5];
|
記憶體位址
|
記憶體 |
|
a (陣列起始位址)
|
course [0][0] |
|
a + 2
|
course [0][1] |
|
a + 4
|
course [0][2] |
|
|
|
|
a + 4
|
course [5][3] |
|
a + 4
|
course [5][4] |
|
|
| 此課表之抽象表示如下:
| (0,0) |
(0,1) |
(0,2) |
(0,3) |
(0,4) |
| (1,0) |
(1,1) |
(1,2) |
(1,3) |
(1,4) |
| (2,0) |
(2,1) |
(2,2) |
(2,3) |
(2,4) |
| (3,0) |
(3,1) |
(3,2) |
(3,3) |
(3,4) |
| (4,0) |
(4,1) |
(4,2) |
(4,3) |
(4,4) |
| (5,0) |
(5,1) |
(5,2) |
(5,3) |
(5,4) |
/* ================================================== *//* 程式實例: 查詢上課的課目,其中課程以代碼表示. *//*
0 表示沒課 *//*
1 表示計算機概論 *//*
2 表示離散數學 *//*
3 表示資料結構 *//*
4 表示資料庫概論 *//*
5 表示上機實習; *//* ==================================================*/void main(){ int course[6][5] = { 0, 2, 0, 2, 0, /* 課程定義 */ 1, 4, 1, 4, 1, 5, 0, 5, 0, 5, 0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0, 0, 0, 0, 0 }; int week;
/* 星期資料變數 */ int class;
/* 第幾節課的變數 */ int class_no; /* 課程代碼變數 */ printf("請輸入星期(1 到 5). ==> "); scanf("%d",&week); /* 讀取星期資料 */ printf("請輸入第幾節課(1 到 6). ==> "); scanf("%d",&class); /* 讀取第幾節課 */ class_no = course[class-1][week-1]; /* 課程查詢 */ switch ( class_no ) /* 印出課程名稱 */ { case 0: printf("這節沒課\n"); break; case 1: printf("計算機概論\n"); break; case 2: printf("離散數學\n"); break; case 3: printf("資料結構\n"); break; case 4: printf("資料庫概論\n"); break;
case 5: printf("上機實習\n"); break; }} |
/* ======================================== *//* 計算出一星期的課程總數 *//* ======================================== */ void main(){ int course[6][5] = { 0, 2, 0, 2, 0, /*課程定義 */ 1, 4, 1, 4, 1,
5, 0, 5, 0, 5, 0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0, 0, 0, 0, 0 }; int sum; /* 課程總數 */ int i,j; sum = 0;
/* 設定課程總數初值 */ for ( i = 0; i < 6; i++ ) /* 二維陣列的走訪 */ for ( j = 0; j < 5; j++ ) if ( course[j] != 0 ) /* 檢查有沒有課 */ sum++; printf("課程總數: %d\n",sum); /* 印出課程總數 */} | l 陣 列 表 示 法 陣列之表示法有兩種: 1. 以列為主或行為主之表示法 2. 使用指標陣列 (指標單元再介紹) à 以列為主或以行為主之表示法
|
行 |
|
| 列 |
(0,0) |
(0,1) |
(0,2) |
(0,3) |
(0,4) |
列一 |
| (1,0) |
(1,1) |
(1,2) |
(1,3) |
(1,4) |
列二 |
| (2,0) |
(2,1) |
(2,2) |
(2,3) |
(2,4) |
列三 |
| (3,0) |
(3,1) |
(3,2) |
(3,3) |
(3,4) |
列四 |
| (4,0) |
(4,1) |
(4,2) |
(4,3) |
(4,4) |
列五 |
| (5,0) |
(5,1) |
(5,2) |
(5,3) |
(5,4) |
列六 |
|
行一 |
行二 |
行三 |
行四 |
行五 |
| 陣列共有6*5=30元素。然而,記憶體實際以宣告一個長度為30之一維陣列儲存之,其宣告方式如下: int class [30];以列為主所見之陣列表示方式如下:
| 列一 |
|
列二 |
|
列六 |
| (0,0) |
(0,1) |
(0,2) |
(0,3) |
(0,4) |
|
(1,0) |
(1,1) |
(1,2) |
(1,3) |
(1,4) |
… |
(5,0) |
(5,1) |
(5,2) |
(5,3) |
(5,4) |
| 0 |
1 |
2 |
3 |
4 |
|
5 |
6 |
7 |
8 |
9 |
|
25 |
26 |
27 |
28 |
29 | 以行為主所見之陣列表示方式如下:
| 行一 |
|
行二 |
|
行六 |
| (0,0) |
(1,0) |
(2,0) |
(3,0) |
(4,0) |
(5,0) |
|
(0,1) |
(1,1) |
(2,1) |
(3,1) |
(4,1) |
(5,1) |
… |
(0,4) |
(1,4) |
(2,4) |
(3,4) |
(4,4) |
(5,4) |
| 0 |
1 |
2 |
3 |
4 |
5 |
|
6 |
7 |
8 |
9 |
10 |
11 |
|
24 |
25 |
26 |
27 |
28 |
29 | 【公式】:假設有一二維陣列A[r,c] 之大小為r*c,則此二維陣列A[i,j]以一維陣列表示之索引值為:
1. 以列為主:i*c+j
2. 以行為主:j*r+i
l 字 元 陣 列 <1> 字 元 陣 列 的 宣 告 方 式 如 下 所 述 :
char 陣列的名稱 [ 陣列的大小 ] ;or char 陣列的名稱 [ 列陣列的大小 ][ 行陣列大小 ] ; For example: char array1 [ 10 ] ;
char array2 [ 5 ][ 25 ] ; <2> 宣 告 陣 列 的 位 置 為 程 式 之 最 上 端 . <3> 我 們 可 以 在 宣 告 陣 列 時 , 指 定 字 元 給 陣 列 . 例 如 :
例一 : int string[6]={'A','B','C','D','E','\0'}; 或 int string[5]="ABCDE"; 例二 : int string1[2][6]={{'A','B','C','D','E','\0'}, {'F','G','H','I','J','\0'};
或 int string1[2][5]={ "ABCDE","FGHIJ" }; 或 是 在 程 式 過 程 中 指 定 數 值 給 陣 列 . 例 如 :
void main(void)
{ int string[6]; /* 陣列宣告 */ . . score1[0]='M'; /* 程式本體 */ score1[1]='E'; score1[2]='R'; score1[3]='R'; score1[4]='Y'; score1[5]='\0'; strcpy(string,"MERRY"); /* 將 "MERRY" 字串拷貝至 string 陣列中 */
. }
<4> 由 於 以 上 敘 述 , 我 們 知 道 如 果 字 元 陣 列 以 字 元 的 方 式 來 存 取 陣 列 , 則 須 加 結 束 字 元 \0 於 陣 列 的 最 末 端 , 表 示 此 字 元 陣 列 的 結 束 . 例 如 <3> 項 例 一 所 述 . 如 果 字 元 陣 列 以 字 串 的 方 式 來 存 取 陣 列 , 則 C 編 譯 器 會 自 動 在 字 串 最 末 端 加 上 結 束 字 元 \0 表 示 此 字 元 陣 列 的 結 束 , 所 以 我 們 不 需 自 行 加 入 . 例 如 <3> 項 例 二 所 述 . ( \0 表 式 零 的 八 進 位 數 )
Example: #include < stdio.h > void main(void){ char string1[5]={'A','B','C','D','E'}; char string2[6]={'A','B','C','D','E','\0'};char string3[6]="ABCDE\0";char string4[5]="ABCDE"; printf("string1 = \"%s\"\n",string1);printf("string2 = \"%s\"\n",string2);printf("string3 = \"%s\"\n",string3);printf("string4 = \"%s\"\n",string4);} |
執 行 結 果 : string1="ABCDE?ABCDE" string2 = "ABCDE" string3 = "ABCDE" string4 = "ABCDE" | l 陣 列 與 基 本 輸 出 / 輸 入 函 數 的 搭 配 無 論 是 整 數 , 浮 點 數 或 字 元 陣 列 (字串 ) 均 可 與 基 本 輸 出 / 輸 入 函 數 的 搭 配 . 例 如 一 名 叫 array1 的 字 元 陣 列 : printf("%s\n",array1);
puts(array1); scanf("%s",array1); gets(array1); 所 以 USER 可 以 自 行 參 考 相 關 的 章 節 使 用 之 . 在 此 補 充 一 點 , 上 述 所 敘 述 scanf 函 數 是 乎 少 一 個 & (位址運算元 ) ? ? ? 沒 錯 ! 那 是 因 為陣 列 本 身 的 名 稱 即 代 表 其 位 址 之 所 在 , 所 以 不 需 在 陣 列 名 稱 前 加 上 & 符 號 來 代 表 位 址 .
l 指 標 ( Pointer ) 何謂 指 標 呢 ? 簡 單 的 說 " 它 是 一 個 用 來 指 示 資 料 存 在 於 記 憶 體 中 的 位 址 標 示 器 " , 簡 稱 指 標 . 由指 標 的 運 用 裡 , 使 我 們 瞭 解 到 資 料 與 位 址 間 的 關 係 , 進 而 對 記 憶 體 配 置 有 很 大 的 幫 助 . l 指 標 的 基 本 觀 念 <1>在 C 語 言 中 , 若 某 變 數 所 含 的 是 一 個 記 憶 體 位址,此 變 數 稱 為 指 標 變 數。如 下 圖 所 示 <2> 在 C 語 言中 , 指 標 變 數 的 宣 告 方 式 如 下 :
變數資料型態 *變數名稱 ;For example
int *ptr ;如 下 圖 所 示
|
ptr為 指 標 變 數
|
|
|
|
®
變數ptr ®
|
1010 H |
|
|
|
|
| 0800H |
|
|
|
0802H
|
|
|
|
…..
|
… |
|
|
1010H
|
16 |
¬*ptr |
|
|
記憶體
|
| 由 以 上 的 宣 告 , 表 示 了 三 件 事: l ptr 為 指 標 變 數 , ptr 代 表 一 個 位 址 , l *ptr 代 表 此 位 址 內 的 資 料 . l ptr 所 指 向 此 位 址 之 變 數 型 態 為 整 數 ( int ) .
<3> 指 標 變 數 宣 告 的 關 鍵 字 為 " * " , 而 指 標 變 數 的 資 料 型 態 也 分 為 整 數 ( int ) , 浮 點 數 ( float ) , 字 元 ( char ) 三 種 .
<4> "&" 為另一重要符號,"&"為一個特殊運算子,目的為傳回運算元之位址
<5>為什麼scanf() 中之所有引數變數一定要加上"&"符號???……….
Example: #include < stdio.h > void main(void){int x=10;int *y;y=&x;printf(" x = %d\n", x);printf("&x = %x\n",&x);printf("*y = %d\n",*y);printf(" y = %x\n", y);} |
執行結果 : x = 10 &x = ffda *y = 10 y = ffda
| l 指 標 與 函 數 間 的 關 係 關於 函 數 呼 叫 的 方 式 中 , Call by value 的 引 數 傳 遞 方 式 , 被 呼 叫 函 數 不 能直 接 更 改 呼 叫 函 數 中 的 變 數 , 但 如 果 是 以 指 標 當 作 函 數 的 引 數 ( Call by reference ) , 則上 述 的 狀 況 均 迎 刃 而 解 , 而 且 也 不 受 函 數 返 回 值 ( return ) 只 能 有 一 個 的 影 響 .
Example: #include < stdio.h > change(x,y) int *x,*y; {int temp; temp=*x; *x=*y;*y=temp; } void main(void){ int m=3,n=4;printf(" m = %d n= %d \n\n",m,n);printf(" m = %d n= %d \n\n",m,n); change(&m,&n); printf(" m = %d n= %d \n",m,n); } |
執行結果 : m = 3 n= 4m = 4 n= 3 |
l 指 標 與 陣 列 的 關 係 我們 可 以 將 指 標 與 陣 列 的 關 係 來 做 一 對 比 . 例 如 : 有 一 整 數 陣 列 名 為 array , 其 陣 列 大 小 為 五 個 , 其 內 容 分 別 是 1,2,3,4,5 .
For example: int array[5]={ 1,2,3,4,5 };
| 陣列位址 |
|
指標相對位址 |
| array[0] |
1 |
*(array+0) |
| array[1] |
2 |
*(array+1) |
| array[2] |
3 |
*(array+2) |
| array[3] |
4 |
*(array+3) |
| array[4] |
5 |
*(array+4) |
Example: #include < stdio.h > void main(void) { int array[5]={ 1,2,3,4,5 }; int count; for ( count=0 ; count<5 ; ++count ) printf("array[%d]=%d<-->*(array+%d\)=%d\n",count,array[count], count,*(array+count)); } |
執行結果 : array[0]=1 <--> *(array+0)=1array[1]=2 <--> *(array+1)=2array[2]=3 <--> *(array+2)=3array[3]=4 <--> *(array+3)=4array[4]=5 <--> *(array+4)=5
| l 指 標 與 字 元 陣 列 ( 字 串 ) 間 的 關 係
Example: #include < stdio.h > void main(void) { char string[7]="POINTER"; int count; for (count=0 ; count<7 ; ++count ) printf("string[%d]=%c <--> *\(string+%d\)=%c\n", count, string[count], count,*(string+count)); } |
執行結果 : string[0]=P <--> *(string+0)=Pstring[1]=O <--> *(string+1)=Ostring[2]=I <--> *(string+2)=Istring[3]=N <--> *(string+3)=Nstring[4]=T <--> *(string+4)=Tstring[5]=E <--> *(string+5)=Estring[6]=R <--> *(string+6)=R |
l 指 標 與 陣 列 的 混 合 應 用 指標之運算有兩種: (+) 、 (-) 。
| 假設指標ptr所指資料為整數,且其為指為1666 |
指令 |
執行結果 |
執行動作 |
| ptr++ |
1668 |
指向下一個整數位址 |
| ptr-- |
1664 |
指向前一個整數位址 |
| ptr+7 |
1676 |
指向第七個整數位址 |
|
|