07 陣列與字串2. 7-1 陣列簡介
一維陣列(1)
在C語言,一維陣列的語法宣告如下:
資料型態 陣列名稱[陣列長度];
當然也可以在宣告時,直接設定初始值:
資料型態 陣列名稱[陣列大小]={初始值1,初始值2,…};
資料型態:表示該陣列存放的資料型態,可以
是基本的資料型態(如int,float,char…等),
或延伸的資料型態(如struct、union…等,這部
份在第九章會說明)。
2
3. 7-1 陣列簡介
陣列名稱:命名規則與變數相同。
元素個數:表示陣列可存放的資料個數,為一
個正整數常數。
若是只有中括號,即沒有指定常數值,則表示
是定義不定長度的陣列(陣列的長度會由設定初
始值的個數決定)。
例如底下定義的陣列Temp,其元素個數會自動
設定成3:
int Temp[]={1, 2, 3};
3
4. 一維陣列(2) 7-1 陣列簡介
程式範例:一維陣列的宣告應用範例:
CH07_01.c
4
6. 7-1 陣列簡介
程式解說
第6行宣告整數陣列時,直接設定學生成績初始值。
第9行中透過for迴圈,設定count變數從0開始計算,並
當作陣列的索引值,把使用者輸入的資料寫入陣列中。
第12行則使用整數變數Total_Score累計總分。
6
7. 一維陣列(3) 7-1 陣列簡介
程式範例:一維陣列的初始化應用範例:
CH07_02.c
7
10. 7-1 陣列簡介
程式解說
第6行中,設定Score[10]={0}。
因為指定的初始值個數少於陣列元素,所以都一律指定成0。
第16行由scanf()函數逐步把輸入的分數寫到 Score 陣列。
第18行則設定學號輸入 0 跳出迴圈。
10
11. 7-1 陣列簡介
命令列引數(1)
宣告範例如下所示:
int main(int argc, char *argv[])
{
……
}
其中第二個引數的宣告為一種宣告陣列作為引
數的方式,可以更明確地表達出它是一個一維
陣列,而且每個元素為ㄧ字串。
假設這個程式的名稱為read.c,而我們下達了
以下的指令:
read this is a test 11
14. 7-1 陣列簡介
程式解說
第4行是命令列引數的傳遞宣告,宣告後各位即可在執行
時傳遞參數。
第7行是用來判斷如果argc=1,表示未指定其它參數,只
有程式名稱。
第15行~第16行是列印出存放在argv[ ]陣列中的參數,由
於argv[0]是儲存程式名稱的字串,所以i從1開始執行。
14
15. 7-1 陣列簡介
二維陣列(1)
在C語言中,二維陣列的宣告格式如下:
資料型態 陣列名稱 [m] [n];
例如宣告陣列A的列數是2,行數是3,所有元
素個數為6。格式如下所示:
int A [2] [3];
此陣列共有2列3行的元素,也就是每列有3個
元素,也就是陣列元素分別是A[0][0],A
[0][],A[0][2],…,A[1][2]。
15
16. 7-1 陣列簡介
陣列中元素的分佈圖說明如下:
在存取二維陣列中的資料時,使用的索引值
(index)仍然是由0開始計算。
至於在二維陣列設初始值時,為了方便區隔行
與列,所以除了最外層的{}外,最好以{}括住每
一列的元素初始值,並以「,」區隔每個陣列
元素,例如:
int A[2][3]={{1,2,3},{2,3,4}}; 16
18. 7-1 陣列簡介
執行結果
程式解說
第7行在宣告二維陣列Tel_fee時,同步設定起始值。
第13行輸出每筆電話號碼與費用。 18
19. 二維陣列(3) 7-1 陣列簡介
程式範例:二維陣列與矩陣相加的應用範例:
CH07_05.c
19
21. 7-1 陣列簡介
程式解說
第7~8行分別設定了兩個3x3二維陣列來代表兩個矩陣。
第11~13行中則設計了雙層的巢狀for迴圈,來在兩陣列相
同的位置上做加法運算。
21
22. 7-1 陣列簡介
多維陣列(1)
定義方式如下所示:
資料型態 陣列名稱[元素個數] [元素個數] [元素個數]…….
[元素個數];
以下舉出C中幾個多維陣列的宣告實例:
int Three_dim[2][3][4]; /* 三維陣列 */
int Four_dim[2][3][4][5]; /* 四維陣列 */
22
23. 7-1 陣列簡介
三維陣列的表示法和二維陣列一樣皆可視為是
一維陣列的延伸,請看下圖:
例如:宣告一個int型態的三維陣列A
23
27. 7-1 陣列簡介
程式解說
在第7行中,宣告了一個2x2x2的三維陣列,各位可以
將其簡化為2個2x2的二維陣列,並同時設定初始值。
由於A是三維陣列,所以能夠利用第11-13行三層巢狀
迴圈將元素值讀出。
27
30. 7-1 陣列簡介
執行結果
程式解說
第6~8行分別宣告相同型態的變數與陣列。
在第10、12、14行中,各位發現陣列所佔用的空間大
小與資料型態與元素個數有關。
例如b_Array[5]陣列由整數型態組成(在此整數型態佔用
4位元組),其佔用的記憶體空間即為4*5=20位元組。
30
32. 7-1 陣列簡介
執行結果
程式解說
從第11、13行的輸出結果可以看出,陣列每移動一次索
引值,其實是在記憶體位移4個位元組(因為整數型態),
才取出陣列的下一筆資料。 32
33. 陣列記憶體配置簡介(3) 7-1 陣列簡介
程式範例:取址運算子與二維陣列的使用範例:
CH07_09.c
33
35. 7-1 陣列簡介
程式解說
第6行定義定義整數二維陣列,並直接設定初使值。
第11行我們利用for迴圈輸出陣列元素值及第13行輸
出該元素在記憶體中的位址。
從本程式中各位可發現二維陣列在記憶體中的儲存
方式仍是以線性的方式來處理。
35
36. 7-1 陣列簡介
陣列名稱其實可用來指出陣列的起始位址。例
如宣告以下指令:
int Num[5]={ 11, 22, 33, 44, 55 };
在撰寫程式時,也可以直接使用陣列名稱來取
得陣列的起始位址。如下圖所示:
36
37. 7-1 陣列簡介
陣列記憶體配置簡介(4)
程式範例:陣列名稱與位址的說明範例:CH07_10.c
37
39. 7-1 陣列簡介
程式解說
第13行,使用&運算子輸出每個陣列元素的位址,
第15行則輸出Num+count的值,雖然Num加的是
整數變數count,但編譯器會自動轉換成相對的偏
移位址計算。
39
40. 陣列記憶體配置簡介(5) 7-1 陣列簡介
程式範例:scanf()函數與陣列位址的說明範例:
CH07_11.c
40
41. 7-1 陣列簡介
執行結果
程式解說
第10行中使用三種方式傳入變數位址作為參數,
如此scanf()函數即可把鍵盤輸入的資料,儲存到
對應的記憶體中。
41
44. 7-1 陣列簡介
執行結果
程式解說
第4行宣告函數原型,第9行則宣告整數陣列,並給定
起始值。
第13行呼叫函數show(),並將陣列元素值以傳值呼
叫方式傳遞到函數中。
第24~25行,輸出num個*號。 44
45. 7-1 陣列簡介
程式範例:單一陣列元素的傳址呼叫參數傳遞
說明範例:CH07_13.c
45
47. 7-1 陣列簡介
執行結果
程式解說
第4行是傳址呼叫的原型宣告。
第13行則以A[i]位址當參數傳遞,並與第23行的num共
用位址,在第28行中*num的值改變時,主程式中A[i]
的值也會同步改變。 47
48. 函數與一維陣列參數(1) 7-1 陣列簡介
一維陣列參數傳遞的函數原型宣告:
(回傳資料型態or void) 函數名稱 (資料型態 陣列名稱[ ] ,…);
一維陣列參數傳遞的函數呼叫如下所示:
函數名稱 (資料型態 陣列名稱,…);
一維函數的基本架構如下:
(回傳資料型態or void) 函數名稱 (資料型態 陣列名稱[ ] ,…);
{
…
48
}
51. 7-1 陣列簡介
執行結果
程式解說
第 3行宣告Array_size為常數。
第5行中是函數的原型宣告,以arr[ ]參數及傳址呼叫傳遞,
其中在大括號[ ]中的數字可寫也可不寫,第12~13行印出
A陣列內容。
第15行直接用陣列名稱,呼叫函數Multiple2(),在第29
行會將每個元素值乘以2的陣列傳回主函數。
第17~18行中列印A陣列,元素值已改變了。
51
52. 函數與多維陣列參數(1) 7-1 陣列簡介
以下是二維陣列參數傳遞的函數原型宣告:
(回傳資料型態or void) 函數名稱 (資料型態 陣列名稱[ ] [行數] ,…);
二維陣列參數傳遞的函數呼叫如下所示:
函數名稱 (資料型態 陣列名稱,…);
二維函數的基本架構如下:
(回傳資料型態or void) 函數名稱 (資料型態 陣列名稱[ ][ ] ,…);
{
…
} 52
53. 函數與多維陣列參數(2) 7-1 陣列簡介
程式範例:二維陣列的參數傳遞與傳址呼叫範
例:CH07_15.c
53
55. 7-1 陣列簡介
執行結果
程式解說
第11行中第一維的大括號可以省略不用定義,其它維數
的註標都必須清楚定義長度。
第19行以傳值呼叫呼叫函數Multiple2()。
第32~38行則是定義Multiple2()函數的內容,在第32行處
特別請您注意的還是第二維大括號中必須有元素個素。 55
56. 7-2 字元與字串處理
字元陣列與字串(1)
在C中字串宣告方式有兩種:
方式1:char 字串變數[字串長度]="初始字串";
方式2:char 字串變數[字串長度]={'字元1', '字元
2', ...... ,'字元n', '0'};
例如以下四種宣告方式:
char Str_1[6]="Hello";
char Str_2[6]={ 'H', 'e', 'l', 'l', 'o' , '0'};
char Str_3[ ]="Hello";
char Str_4[ ]={ 'H', 'e', 'l', 'l', 'o', '!' };
56
59. 7-2 字元與字串處理
程式解說
第6~9行宣告了四種不同的字串及字元陣列方式,第
11行中輸出佔用的空間為6位元,因為多了‘0’字元。
而在第18行中所輸出了Str_4字元陣列,由於沒有以
'0'字元結尾,所以輸出時會出現奇怪的符號。
59
62. 7-2 字元與字串處理
執行結果
程式解說
第5行宣告以陣列呼叫的函數原型宣告,第14行呼叫
string_copy()函數。
第24~25行中,是執行逐一拷貝陣列中字元的過程。
62
63. 7-2 字元與字串處理
字串輸入與輸出函數(1)
gets()函數
– 原型宣告如下所示:
gets (字元陣列名稱);
– 當您輸入字串時,只有按下Enter鍵時,會讀取緩衝
區的所有字元並存放到指定字元陣列中,並且在結
尾處還會加上'0'字元。
– gets()函數中不用加上&運算子,這點和scanf()函數
不同,因為字元陣列名稱本身就可代表陣列位址。
63
64. 7-2 字元與字串處理
字串輸入與輸出函數(2)
puts()函數
– puts()函數可用來輸出指定字串,只需把字串的位
址(字元陣列名稱)傳入,就可以輸出字串到螢幕上,
直到遇到'0'字元為止,而且輸出之後還會自動換行。
– 以下程式範例是練習gets()函數與puts()函數的宣告
與應用,各位可以輸入"This is a book."字串,並比
較使用gets()函數與scanf()函數的不同。
64
65. 字串輸入與輸出函數(3) 7-2 字元與字串處理
程式範例:gets()函數與puts()函數的宣告與應
用範例:CH07_18.c
65
67. 7-2 字元與字串處理
程式解說
第6~7行宣告兩個字元陣列,並在第12行中使用 gets()
函數讀取“This is a book.”字串,整個字串都會被讀取。
第14行則使用scanf()函數讀取“This is a book.”字串,不
過只能讀取到“This”。
而第17行中利用puts() 函數輸出,結果會自動換行。
67
68. 7-2 字元與字串處理
字串陣列
字串陣列宣告方式如下:
char 字串陣列名稱[字串數][字元數];
上式中字串數是表示字串的個數,而字元數是表
示每個字串的最大自可存放字元數。
當然也可以在宣告時就設定初值,不過要記得每
個字串元素都必須包含於雙引號之內。例如:
char 字串陣列名稱[字串數][字元數]={ "字串常數1", "
字串常數2", "字串常數3"…};
68
71. 7-2 字元與字串處理
程式解說
第6行中宣告了一個字串陣列Name,而第14行中
直接將Name陣列以一維的方式即可輸出該字串,
不過如果要輸出第i字串的第j個字元,則必須使用
二維方式,如printf(Name[i-1][j-1])。
71
74. 7-2 字元與字串處理
程式解說
第16~17行是以while迴圈來計算該字串的長度,並以
二維方式逐一讀出字元,當字元為‘0’字元時則跳出迴
圈,不然就執行j++來計算長度。
第18行輸出字串及長度,這裏我們使用t字元來控制
輸出的對齊效果。
74
78. 7-3 字串處理函數簡介
程式解說
第6行宣告所輸入字串變數的長度,第10行使用gets()
函數,允許所輸入的字串中含有空白字元。
第12~13行中使用C的庫存函數strlen()來逐一反向印
出字元。
78
79. 7-3 字串處理函數簡介
strstr()函數與strncpy()函數(1)
char *strstr(char *str1, char *str2)
char *strncpy(char *d, char *s, int n)
strstr()函數的功用是搜尋str2 字串在 str1 字串
中第一次出現的位置,如果有找到則傳回該位
置的位址,沒有找到則傳回 NULL。
而strncpy()函數則是複製 str2 字串的前 n 個字
元到 str1字串。
79
82. 7-3 字串處理函數簡介
程式解說
第8行宣告並設定一字串,第13~14行當使用
strstr() 函數搜尋到字串"Tom"則使用 strncpy() 函
數替換成字串"Joe"。
82
83. 7-3 字串處理函數簡介
strlwr()函數與strcat()函數(1)
char *strlwr(char *str)
char *strcat(char *str1, char *str2)
strlwr()函數可將字串中的大寫字元全部轉換成
小寫,而strcat()函數則將 str2 字串連結到字串
str1使用方式如下:
strlwr(str);
strcat(str1,str2);
83
86. 7-3 字串處理函數簡介
程式解說
第12、14行以gets()函數輸入可含空白字元的字串。
第16行利用函數庫的strcat(str1,str2)函數將兩字串連結。
第17行則使用strlwr()函數將字串中的大寫字元都轉為小
寫字元。
86
87. 7-4 上機實習課程
上機實習課程(1)
上機實習範例:CH07_24.c
– 以下程式範例是利用main()函數的命令列引數
功能,讓程式可以從命令列讀入簡單的運算式,
並利用switch指令來判斷四則運算符號及計算
出相對應的運算結果。
– 當中使用到atof()函式將字串轉換為浮點數資料
型態,可查閱附錄A的型態轉換函數。
87
90. 上機實習課程(2) 7-4 上機實習課程
執行結果
上機實習範例:CH07_25.c
– 在字串的處理中,常會需要知道字串的長度,
以下程式範例是利用while迴圈逐一讀取字元,
並計算此字串的長度。
90
95. 7-4 上機實習課程
上機實習課程(4)
上機實習範例:CH07_27.c
– 有一個三維陣列,內容如下:
int num[2][3][3]=
{{{43,45,67},
{73,71,56},
{55,38,66}},
{{21,39,25 },
{38,89,18},
{90,101,89}}};
95
98. 上機實習課程(5) 7-4 上機實習課程
執行結果
上機實習範例:CH07_28.c
– 以下是數位新知公司三個業務代表2008年前六
個月每人的業績
業務員 一月 二月 三月 四月 五月 六月
1 112 76 95 120 98 68
2 90 120 88 112 108 120
3 108 99 126 90 76 98
單位:萬元
98
99. 7-4 上機實習課程
請設計一程式,計算以下結果:
(1).每個業務代表的前半年業績總額。
(2).1~6月每個月這三個業務代表的總業績。
99
102. 7-4 上機實習課程
上機實習課程(6)
上機實習範例:CH07_29.c
– 氣泡法的排序原理如下:
逐次比較2個相鄰的記錄,若大小順序有誤,則立即對
調,掃描一遍後一定有一個記錄被置於正確位置,就
彷彿氣泡逐漸由水底逐漸冒升到水面上一樣。
– 由此可知n個元素的氣泡排序法必須執行n-1次
掃瞄,以4個元素而言,共經過4次掃瞄。
– 第一次掃瞄需要作4次的比較;第二次掃瞄需要
作3次的比較,第三次掃瞄需要作2次的比較,
第四次掃瞄需要作1次比較。
102
106. 7-4 上機實習課程
上機實習課程(7)
上機實習範例:CH07_30.c
– 以下程式範例是字串陣列的應用,用來儲存由
使用者輸入的3筆學生姓名資料及每位學生的三
科成績,請以橫列方式是輸出每位學生的姓名、
三科成績及總分。
106
109. 7-4 上機實習課程
上機實習課程(8)
上機實習範例:CH07_31.c
– 假設一個三維陣列元素內容如下:
A[4][3][3]={{{1,-2,3},{4,5,-6},{8,9,2}},
{{7,-8,9},{10,11,12},{0.8,3,2}},
{{-13,14,15},{16,17,18},{3,6,7}},
{{19,20,21},{-22,23,24},(6-,9,12)}};
– 請計算原有陣列中的每個元素值總和,並將值
為負數的元素值都換為0,再輸出新陣列的所有
內容。
109