Loops.

Slides:



Advertisements
Similar presentations
CSIM, PU C Language Introduction to the C Programming Language 重覆敘述 (for,while,break,continue) 適合重複性的計算或判斷.
Advertisements

TQC+ 物件導向程式認證-JAVA.
補充: Input from a text file
C语言程序设计 第八章 函数.
第九章 系 统 安 全 性 9.1 结构体 9.2 结构体型数组  9.3 结构体型指针 9.4 内存的动态分配 9.5 共用体
C语言程序设计 第十二章 位运算.
第一章 程序设计入门.
Introduction to the C Programming Language
第一章 C语言概述.
C++程序设计 第二讲 清华大学软件学院.
If … else 選擇結構 P27.
C 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
Chap 2 用C语言编写程序 2.1 在屏幕上显示 Hello World! 2.2 求华氏温度 100°F 对应的摄氏温度
Introduction to the C Programming Language
Introduction to the C Programming Language
C++ 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
STRUCTURE 授課:ANT 日期:2010/5/12.
计算概论 第十八讲 C语言高级编程 结构与习题课 北京大学信息学院.
Function.
Chap 8 指针 8.1 寻找保险箱密码 8.2 角色互换 8.3 冒泡排序 8.4 电码加密 8.5 任意个整数求和*
Introduction to the C Programming Language
作弊是否很有诱惑性? 上堂课已经讲了 作业不一定在两个小时里都能完成 答疑没有一个人? 作弊是有记录的 心理系很多同学集体作弊,让人震惊
Chap 3 分支结构 3.1 简单的猜数游戏 3.2 四则运算 3.3 查询自动售货机中商品的价格.
第四章 C 语言中的输入和输出.
1. 說明一個一維整數陣列passwd,下標範圍0至49 2. 在屏幕顯示 "Enter password"
C语言 程序设计基础与试验 刘新国、2012年秋.
THE C PROGRAMMING LANGUAGE
本章中將會更詳細地考慮有關重複的概念,並且會 介紹for和do…while等兩種用來控制重複的敘述 式。 也將會介紹switch多重選擇敘述式。 我們會討論直接和迅速離開某種控制敘述式的 break敘述式,以及用來跳過重複敘述式本體剩餘 部份的continue敘述式。 本章會討論用來組合控制條件的邏輯運算子,最後.
計數式重複敘述 for 迴圈 P
切換Dev c++顯示語言 工具->環境選項(V)->介面->language (Chinese TW)
2.1 C语言的数据类型 2.2 常量与变量 2.3 变量赋初值 2.4 各类数值型数据间的混合运算 2.5 C语言的运算符和表达式
第5讲 结构化程序设计(Part II) 周水庚 2018年10月11日.
第七章 函数及变量存贮类型 7.1 函数基础与C程序结构 7.2 函数的定义和声明 7.3 函数的调用 7.4 函数的嵌套与递归
第4章 顺序程序设计.
第0章作业: 教材P12-练习与实践 1.写出用符号’*’输出描绘汉字”大”的流程图。
自我參考結構 (self-reference – 1)
C语言概述 第一章.
第1讲 C语言基础 要求: (1) C程序的组成 (2) C语言的标识符是如何定义的。 (3) C语言有哪些基本数据类型?各种基本数
程式結構&語法.
Introduction to the C Programming Language
第11章 位运算 为了节省内存空间,在系统软件中常将多个标志状态简单地组合在一起,存储到一个字节(或字)中。C语言是为研制系统软件而设计的,所以她提供了实现将标志状态从标志字节中分离出来的位运算功能。 所谓位运算是指,按二进制位进行的运算。 11.1 数值在计算机中的表示 11.2.
Instructor:Po-Yu Kuo 教師:郭柏佑
指標
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
Chap 5 函数 5.1 计算圆柱体积 5.2 数字金字塔 5.3 复数运算.
程式的時間與空間 Time and Space in Programming
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
輸出與輸入(I/O).
第十四章 若干深入问题和C独有的特性 作业: 函数指针 函数作参数 函数副作用 运算 语句 位段 存储类别 编译预处理
C程序设计.
C语言程序设计 李祥 QQ:
C++程式設計入門 變數與運算子 作者:黃建庭.
第3章 数据类型、运算符与表达式.
第二章 类型、对象、运算符和表达式.
Introduction to the C Programming Language
第二章 基本数据类型 ——数据的表示.
第三章 基本的輸出與輸入函數 (Basic Output & Input Function)
第四章 C 语言中的输入和输出.
第3章 最简单的C程序设计 3.1 顺序程序设计举例 3.2 数据的表现形式及其运算 3.3 C语句 3.4 数据的输入输出.
Introduction to the C Programming Language
結構、檔案處理(Structure, File)
第二章 数据类型、运算符和表达式 §2.1 数据与数据类型 §2.2 常量、变量和标准函数 §2.3 基本运算符及其表达式 目 录 上一章
變數、資料型態、運算子.
C/C++基礎程式設計班 C語言入門、變數、基本處理與輸入輸出 講師:林業峻 CSIE, NTU 3/7, 2015.
C/C++基礎程式設計班 陣列 講師:林業峻 CSIE, NTU 3/14, 2015.
變數與資料型態  綠園.
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
Q1(a) 小偉打算編寫一個程序。該程序把兩個44的表內的數字相加。表3內的數字是由表1和表2應格子內的數字相加而成。例如:
Introduction to the C Programming Language
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
Presentation transcript:

Loops

while loop

範例輸出: 這個程式會不斷要求使用者輸入整數, 然後當使用者輸入的資料不是數字時, 迴圈就會結束,並且把所有數目的總 和算出來。 範例2-1 #include <stdio.h> int main(void) {    long num;    long sum = 0L;    int status;    printf("Please enter an integer to be summed ");    printf("(q to quit): ");    status = scanf("%ld", &num); /* %ld for long, status is the return value */    while (status == 1) { /* == means "is equal to" */       sum = sum + num;       printf("Please enter next integer (q to quit): ");       status = scanf("%ld", &num);    }    printf("Those integers sum to %ld.\n", sum);    return 0; } 這個程式會不斷要求使用者輸入整數, 然後當使用者輸入的資料不是數字時, 迴圈就會結束,並且把所有數目的總 和算出來。 Please enter an integer to be summed (q to quit): 12 Please enter next integer (q to quit): 34 Please enter next integer (q to quit): -56 Please enter next integer (q to quit): 789 Please enter next integer (q to quit): q Those integers sum to 779. 範例輸出:

範例2-1 #include <stdio.h> int main(void) {    long num;    long sum = 0L;    int status;    printf("Please enter an integer to be summed ");    printf("(q to quit): ");    status = scanf("%ld", &num); /* %ld for long, status is the return value */    while (status == 1) { /* == means "is equal to" */       sum = sum + num;       printf("Please enter next integer (q to quit): ");       status = scanf("%ld", &num);    }    printf("Those integers sum to %ld.\n", sum);    return 0; } 宣告為 long 的變數可以儲存更大範圍的整數值。 因為要讀的是 long,所以用 %ld。另外有個新東 西是我們用到了 scanf() 的回傳值。其實每次呼叫 scanf() ,它除了把輸入的資料存入參數之外,還 會回傳一個整數值給呼叫者,回傳的是它成功讀取 的資料數目。 以這個例子來說,如果 scanf() 能成功讀到 1 個長整 數 (對應到 %ld),它就會回傳 1,如果使用者輸入的 不是整數 (譬如輸入英文字母 'q'),則 scanf() 會回 傳 0 表示沒有讀到任何整數。

#include <stdio.h> int main(void) {    long num;    long sum = 0L;    int status;    printf("Please enter an integer to be summed ");    printf("(q to quit): ");    status = scanf("%ld", &num); /* %ld for long, status is the return value */    while (status == 1) { /* == means "is equal to" */       sum = sum + num;       printf("Please enter next integer (q to quit): ");       status = scanf("%ld", &num);    }    printf("Those integers sum to %ld.\n", sum);    return 0; } 範例2-1 當進入 while 迴圈的時候,會先判斷 status 是否 等於 1,等於 1 才表示 scanf() 有讀到整數資料。 在 C 語言裡判斷兩個數是否相等要用 == 符號, 也就是兩個等號連在一起。 注意!千萬不要錯用成一個等號,因為 = 的意義是 assignment,也就是設定變數值,剛開始學 C 語言 最常犯的錯誤之一就是把 == 寫成 =,大多數時候 如果有這樣的誤用,程式 compile 還是會通過,而 且也可以執行,但是意義完全不同,所以得到的結 果會是錯的。

邏輯運算跟位元運算 &&與&、││與│的差別? 邏輯運算子:&&、││ 運算結果只會有1跟0兩種情況,做為判斷True or False。 例如:while(i > 10 && i < 20),這是當10<i<20的時候 會繼續執行while迴圈,反之則跳出迴圈。 位元運算子:&、│ 位元運算則是將運算子兩邊的運算元的每個bit做運算。 例如:a = 7 & 2,則a = 2。 邏輯運算子大部份應用在需要做判斷的情況,例如迴圈的判斷, 而位元運算子則大部份做為一般的計算。更多的應用將會往後 的例子中提到。 注意不要將位元運算的&與scanf用到的&搞混。

C-style loop 前面範例的迴圈,在寫法上通常會被簡化。譬如,原來是 會習慣寫成 這樣的寫法可以省去變數 status。這樣的用法等於一次做兩 個動作,先利用 scanf()讀入資料,同時判斷回傳值是否等於 1。熟練之後,這樣的寫法會蠻簡潔方便。如果還不熟練,寫 的時候就要稍微小心不要造成迴圈停不下來。 status = scanf("%ld", &num); while (status == 1) {     sum = sum + num;     printf("Please enter next integer (q to quit): ");     status = scanf("%ld", &num); } while (scanf("%ld", &num) == 1) {     sum = sum + num;     printf("Please enter next integer (q to quit): "); }

注意停止條件 使用 while 迴圈要注意停止條件,看看底下這個錯誤示範 執行這個程式會發生什麼事? 迴圈裡面完全沒有更改 i 的值, 所以 i < 5 的條件會一直成立,迴圈無法停下來,只能用暴 力手段把程式停掉。而如果程式改成 程式還是錯的,但是有可能會自己停止。當 i 不斷遞減變成 絕對值越來越大的負數,到了極限之後反而變成絕對值最大 的正數,等於繞了一圈循環回來,所以 i 的值就比 5 大,迴 圈就停止了。下頁的程式碼可以看出循環的現象。 int i = 1; while (i < 5) {    printf("Hello!\n"); } int i = 1; while (--i < 5) {    printf("Hello!\n"); }

注意停止條件 上面的三個範例可看出循環的現象。 由於 char 型別只佔一個 byte 所以可以比較快停下來。 如果換成 int 就要跑比較久。 範例2-2 範例2-3 範例2-4 #include <stdio.h> int main(void) {    char i = 1;    while (--i < 1) {       printf("%d\n", i);    }    printf("%d\n", i);    return 0; } #include <stdio.h> int main(void) {    char i = 1;    while (++i > 0) {       printf("%d\n", i);    }    printf("%d\n", i);    return 0; } #include <stdio.h> int main(void) {    unsigned char i = 1;    while (++i > 0) {       printf("%d\n", i);    }    printf("%d\n", i);    return 0; }

我們來看看如果是上面的範例 (把範例 2-1 更改了一個小地 方),執行結果會如何。 #include <stdio.h> int main(void) {    long num;    long sum = 0L;    int status;    printf("Please enter an integer to be summed ");    printf("(q to quit): ");    status = scanf("%ld", &num); /* %ld for long, status is the return value */    while (status = 1) { /* == means "is equal to" */       sum = sum + num;       printf("Please enter next integer (q to quit): ");       status = scanf("%ld", &num);    }    printf("Those integers sum to %ld.\n", sum);    return 0; } 我們來看看如果是上面的範例 (把範例 2-1 更改了一個小地 方),執行結果會如何。 當我們輸入整數時,程式看起來還正常,但是當我們輸入 ‘q’則程式就掉進了無止境的迴圈,自己不停的印出 printf() 裡的資訊。

總之,在寫停止條件時要特別小心,尤其是 == 和 = 不要錯用。 #include <stdio.h> int main(void) {    long num;    long sum = 0L;    int status;    printf("Please enter an integer to be summed ");    printf("(q to quit): ");    status = scanf("%ld", &num); /* %ld for long, status is the return value */    while (status = 1) { /* == means "is equal to" */       sum = sum + num;       printf("Please enter next integer (q to quit): ");       status = scanf("%ld", &num);    }    printf("Those integers sum to %ld.\n", sum);    return 0; } 這個 while 迴圈跟 while(1) 沒兩樣,會不斷要求輸入整數。當你在 scanf() 的地方輸入‘q’ 的時候,雖然 scanf() 會回傳 0 給 status,但是到了 while (status = 1) 的地方 status 又被設成 1。 而為什麼程式會開始不再等待使用者輸入一直做printf,這就和 scanf()有關。 當 scanf() 讀不到要讀的東西(此範例為long)它會把讀到但格式不符的資料 丟回 buffer,暫時保留在那裡下次再處理。所以下次再呼叫 scanf() 的時候 ‘q’ 依舊在那裡,而依舊回傳 0。 總之,在寫停止條件時要特別小心,尤其是 == 和 = 不要錯用。

32 bit in 32-bit OS 32 bit in 64-bit Windows and Mac 註:變數size大小 char 8 bit = 1 byte int 16 bit in 16-bit OS 32 bit in 32-bit OS 32 bit in 64-bit OS long 32 bit in 32-bit OS 32 bit in 64-bit Windows and Mac 64 bit in 64-bit Linux long long 64 bit short 16 bit in 32-bit OS compiler(編譯器)也會決定type(型別)的size大小

迴圈何時停止 輸出: n = 1 Now n = 2 n = 2 Now n = 3 The loop has finished. 範例2-5 #include <stdio.h> int main(void) {    int n = 1;    while (n < 3) {       printf("n = %d\n", n);       n++;       printf("Now n = %d\n", n);    }    printf("The loop has finished.\n");    return 0; } 輸出: n = 1 Now n = 2 n = 2 Now n = 3 The loop has finished. 當程式第二次執行到 n++; 之後,n 的值變成 3,雖然已經 不再滿足迴圈預期的條件,但是迴圈並不會在這個時候立刻 停止,要等到執行完接下來的 printf("Now n = %d\n", n); 然後回到 while 的開頭,再次判斷 (n < 3) 時,條件不成立, 才會整個跳出被 { } 所包含的 while 區域。

條件式判斷符號 總共有六種:小於 < 小於等於 <= 相等 == 大 於等於 >= 大於 > 不相等 !=。在比較兩個數 值的大小關係時,如果比較的是浮點數(float、 double),要特別注意,只能使用 > 和 <,因為 經過一些數學運算,兩個浮點數是否還能完全相 等往往會出乎我們意料之外。譬如 基本迴圈是停不下來的,照理說只要執行六次迴 圈 a 的值就會累加到 1.0,但是由於是以數值來儲 存 1.0/6.0,所以會有誤差,最後使得 a 不能精確 地等於 1.0。 範例2-6 double a = 0; while (a != 1.0) {     a = a + 1.0/6.0; }

當使用者輸入的值和 3.14159 的差異超過 0.0001,迴圈就會繼續要求 使用者輸入,直到誤差小於 0.0001 才能結束迴圈。 既然使用浮點數無法精確得到相等的數值,我們就只能用近似的方式, 當兩個數值的差異小於某個可容忍範圍,就應該接受,讓迴圈停止。在 math.h 檔裡有宣告一個叫做 fabs() 的 function,可以用來計算浮點數 的絕對值。我們用它來算兩個浮點數相減的絕對值。 當使用者輸入的值和 3.14159 的差異超過 0.0001,迴圈就會繼續要求 使用者輸入,直到誤差小於 0.0001 才能結束迴圈。 範例2-7 #include <math.h> #include <stdio.h> #define ANSWER 3.14159 int main(void) {    double response;    printf("What is the value of pi?\n");    scanf("%lf", &response);    while (fabs(response - ANSWER) > 0.0001) {       printf("Try again!\n");       scanf("%lf", &response);    }    printf("Close enough!\n");    return 0; }

範例2-8 #include <stdio.h> int main(void) {    int true_val, false_val;    true_val = (10 > 2);    false_val = (10 == 2);    printf("true = %d; false = %d \n", true_val, false_val);    return 0; } 輸出: true = 1; false = 0 這個程式的目的是要觀察 true 和 false 對應的整數值到底是多少。 描述兩個數值關係的 expression 如果成立 (true),則可以用整數 值 1 來表示,如果關係不成立 (false) 值就是 0。所以在 C 程式裡 我們可以用 1 來代表 true 而用 0 來代表 false。有時候程式為了 製造無窮迴圈,會用下面的寫法: 其實在 C 程式裡不只 1 可以代表 true,任何非零的數都代表 true, 但是只有 0 代表 false。看看下一頁的範例 while (1) {    ... }

輸出: 只要 while 迴圈繼續,就表示 n 的值相 當於 true。 3 is true 2 is true 1 is true 範例2-9 輸出: #include <stdio.h> int main(void) {    int n = 3;    while (n) {       printf("%2d is true\n", n--);    }    printf("%2d is false\n", n);        return 0; } 3 is true 2 is true 1 is true 0 is false 只要 while 迴圈繼續,就表示 n 的值相 當於 true。

for-loop 假如我們一開始就知道迴圈將會執行多少 次,可以使用 for 迴圈來達到反覆計算的 效果,使用上會比較方便。最標準的狀況 就是使用一個 counter 來計算迴圈執行次 數,當 counter 達到預定的次數迴圈就停 止。

輸出: 範例2-10 #include <stdio.h> int main(void) {    int num;    int i;        printf("Enter an integer: ");    scanf("%d", &num);    for (i = 0; i < num; i++) {       printf("$");    }    printf("\n");    return 0; } Enter an integer: 30 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 由於已經用 scanf() 讓使用者輸入迴圈執 行的次數,所以我們知道迴圈將會執行 num 所代表的次數。假設我們用變數 i 當 作 counter,變數 num 是要反覆執行的 次數,則 for 迴圈的語法就是 這個語法包含三個部份,用兩個分號隔開 成三個區域,第一個部份用來設定 counter 的初值。第二個部份判斷是否應 該繼續執行。第三個部分可用來更改 counter 的值,每跑回一次迴圈就會再被 執行一次。 for (i = 0; i < num; i++) {       ... }

輸出: 輸出: 底下這些範例做的事情都很容易理解,主要是讓大家熟悉 for 的語法。 #include <stdio.h> 範例2-11 輸出: #include <stdio.h> int main() {    int n;    for (n = 2; n < 60; n = n + 13) {       printf("%d \n", n);    }    return 0; } 範例2-12 #include <stdio.h> int main(void) {    char ch;    for (ch = 'a'; ch <= 'z'; ch++) {       printf("The ASCII value for %c is %d.\n", ch, ch);    }    return 0; } 輸出:

其中三個區域的每個區域所做的事情 還可稍加變化。譬如如果什麼都不做, 寫成 所以 for 迴圈的語法就是 其中三個區域的每個區域所做的事情 還可稍加變化。譬如如果什麼都不做, 寫成 作用則相當於無窮迴圈。 for ( 初始化 initialize ; 是否繼續執行的條件判斷 test ; 更新變數值 update ) {      ... } for ( ; ; ) {    printf("Do something.\n"); }

底下的範例是另一種for迴圈的無窮迴圈寫法: 這個程式會不斷讓使用者輸入數字,直到使用者猜到密 碼是 7 為止。在初始化的地方偷渡了一個 printf() 的動 作,所以剛進入迴圈時會顯示一次 "Keep entering numbers!"。第二部份條件判斷檢查是否輸入的數字等 於預設密碼。第三部份則沒有東西,因為 num 靠迴圈 裡的 scanf() 來做更新的動作。 範例2-13 #include <stdio.h> #define CODE 7 int main(void) {    int num = 0;    for (printf("Keep entering numbers!\n"); num != CODE; ) {       scanf("%d", &num);    }    printf("Bingo!\n");    return 0; } 輸出: Keep entering numbers! 1 6 3 7 Bingo!

其他 Assignment 符號: +=,-=,*=,/=,%= 這些可看成是簡寫的 assignment 符號, x += 5; 相 當於 x = x + 5; 而 y %= 7; 相當於 y = y % 7; 以此 類推。在 for 迴圈的第三部份 (更新變數值) 用這樣 的寫法會比較簡潔,但你不一定要用這樣的寫法, 只要順著自己的習慣就可以。 在 for 迴圈的第一部份 (初始化) 和第三部份 (更新變 數值),其實允許我們做兩個以上的 statements, 詳見下頁範例。

範例2-14 輸出: #include <stdio.h> #define FIRST_PACK 7 #define NEXT_PACK 5 int main(void) {    int n, cost;    printf(" packs costs\n");    for (n=1, cost=FIRST_PACK; n<=10; n++, cost+=NEXT_PACK) {       printf("%5d $%-5d\n", n, cost);    }    return 0; } packs costs 1 $7 2 $12 3 $17 4 $22 5 $27 6 $32 7 $37 8 $42 9 $47 10 $52 在初始化的部份做了兩個動作,兩個動作用逗號分開,分 別是設定 n=1 以及設定 cost=FIRST_PACK。更新變數值 的部份也做了兩個動作,先做 n++ 接著做 cost+=NEXT_PACK,這樣就能讓變數 n 的值被加一 (負責 累計迴圈反覆次數),而且也累計 cost 值。在這裡用逗號隔 開的兩個動作是以循序方式執行,也就是做完第一個動作 才做第二個。

使用 do ... while 迴圈 某些情況下,迴圈會保證至少被執行一次,這時候就適合用 do ... while 迴圈,它的效果是先做迴圈內容,最後在判斷條 件是否要繼續,譬如下面的例子,要求使用者要輸入密碼, 直到輸入正確為止。要注意while 的條件判斷之後有個分號。 範例2-15 #include <stdio.h> #define CODE 13 int main(void) {    int code_entered;    do {       printf("Please enter the secret code number: ");       scanf("%d", &code_entered);    } while (code_entered != CODE);    printf("Bingo!\n");    return 0; }

這是 do. while 和標準 while 的語法不同之處。 可以比較看看,如果用 while 而不是 do 這是 do ... while 和標準 while 的語法不同之處。 可以比較看看,如果用 while 而不是 do ... while, 寫起來會有點累贅: 範例2-16 #include <stdio.h> #define CODE 13 int main(void) {    int code_entered;    printf("Please enter the secret code number: ");    scanf("%d", &code_entered);    while (code_entered != CODE) {       printf("Please enter the secret code number: ");       scanf("%d", &code_entered);    }    printf("Bingo!\n");    return 0; }

Nested Loops 多重迴圈 更複雜的迴圈使用方法是用一個迴圈包住另一層迴圈。使用 雙重迴圈最常用來處理以二維或表格方式呈現的資料。譬如 我們想要輸出一個用 * 號填滿的長方形,寬和高分別是 25 和 7。我們已經學過用一層迴圈反覆輸出,所以要印出一排 25 個星號可以用下面的寫法 顯示了一串 25 個 * 之後,再用 printf("\n"); 換行。接下來如 果我們再用一個迴圈把上面的程式碼包起來,變成 就會重複做 7 次,而每次都會顯示一排 25 個 * 號。 for (j = 0; j < 25; j++) {    printf("*"); } printf("\n"); 範例2-17 for(i = 0; i < 7; i++) {    for (j = 0; j < 25; j++) {       printf("*");    }    printf("\n"); } 輸出:

輸出: 外層迴圈負責反覆六次印出六行字串,內層 迴圈則負責在每一行顯示連續的英文字母, 每一行顯示的字母範圍都不一樣。 ABCDEFGHIJ 範例2-18 #include <stdio.h> int main(void) {    int row;    char ch;    for(row = 0; row < 6; row++) {       for (ch = ('A' + row); ch < ('A' + 10); ch++) {          printf("%c", ch);       }       printf("\n");    }    return 0; } 輸出: ABCDEFGHIJ BCDEFGHIJ CDEFGHIJ DEFGHIJ EFGHIJ FGHIJ 外層迴圈負責反覆六次印出六行字串,內層 迴圈則負責在每一行顯示連續的英文字母, 每一行顯示的字母範圍都不一樣。

陣列 (Arrays) 使用方法簡介 我們在後面的課程會詳細介紹陣列。但是這裡我們先簡介陣 列的使用方法。陣列就是一連串相同型別的資料存放在連續 的空間中,整個陣列的內容只需要用一個名字來統稱,而其 中每個元素可以藉由索引 index 方式取出。宣告陣列的方法 如下 這樣就表示 nums 是一個陣列,包含 20 個元素,每個元素 可用來記錄一個型別為 float 的數值。陣列的第一個元素叫 做 nums[0],第二個元素是 nums[1],以此類推,最後一個 元素是 nums[19]。所以 C 的陣列編號方式是從 0 開始編號 而不是從 1 開始,這一點要特別注意。每個元素可以當作一 個變數來使用,譬如 或是 float nums[20]; nums[3] = 3.4; nums[9] = 18.5; scanf("%f", &nums[4]); /* 讀入一個小數存放在第五個元素裡 */

程式 compile 之後,執行到像是上面那兩行的時候,程式 非常可能就會當掉,因為它試圖去讀取錯誤的記憶體位置中 的東西。 由於 C 並不會去檢查我們給的 index 是否超出當初宣告的陣 列大小範圍,所以可能會寫出下面有 bug 的程式而沒有察 覺,compiler 也不會跟我們說程式有 error 程式 compile 之後,執行到像是上面那兩行的時候,程式 非常可能就會當掉,因為它試圖去讀取錯誤的記憶體位置中 的東西。 我們還可以宣告其他類型的陣列,譬如: 這裡順便複習一下,字元陣列和字串的差別只在最後是否有 '\0' 結束符號,如果要當作字串來使用,字元陣列要加入 '\0' 當作結束字元。不同型別的陣列佔用的記憶體空間也不 同,例如 int 陣列每個元素佔用四個 bytes,而 char 陣列每 個元素只佔一個 byte。 nums[20] = 2.5; /* A BUG */ nums[30] = 3.6; /* A BUG */ a[2] a[1] a[0] int a[3]; long long c[3]; char b[3]; c[1] c[0] b[2] b[1] b[0]

字元陣列 character array 與字串 字串裡的字元必須連續地存放在記憶體中,所以剛好可以用 陣列來儲存,因為陣列就是一連串的記憶體空間 字元陣列的每一格空間可以存放一個字元 (char) 當我們宣告 char name[10]; 表示要保留十格空間存放十個 字元,每一格可以容納一個 char 型別的資料 為了標記整個字串究竟在哪裡算是結尾,C 語言使用一個特 殊的字元 '\0' 來表示字串結尾。字元 '\0' 對應到的 ASCII 值 是 0。我們也可以用整數 0 來代替字元 '\0',但為了有所區 別,當字元使用時最好寫成 '\0' 宣告一個字元變數和宣告一個陣列的差別可以用下圖來表示 char ch; char name[10];

宣告陣列產生一個可以容納十個字元的 array,準 備用來記錄使用者輸入的,因為要保留一格給 ‘\0’ 字元來標示字串結尾,所以其實真正能用 來記錄字串的長度,最多只能包含九個字元。 如何把字串存入陣列中呢? 最簡單的方法是 scanf("%s", name); 讀取使用者輸入的字串。所以 %s 就表示要把使 用者輸入的東西當作 "字串" 讀進來,然後參數 name 就是要存放字串的陣列名稱,這個名稱所 代表的意義是整個字串的開頭位址。因此 scanf() 就能由 name 找到陣列開頭位址,一格一格把字 元填進去,而且會自動在最後加上 '\0' 當作結束。 字元陣列和字串陣列的差別只在最後是否有 '\0' 結束符號。不同型別的陣列佔用的記憶體空間也 不同,例如 int 陣列每個元素佔用四個 bytes,而 char 陣列每個元素只佔一個 byte。

搭配陣列來使用迴圈 範例2-19 #include <stdio.h> int main(void) {    int i;    float hours[7], average;    printf("Enter the hours of sleep per night last week\n");    for(i = 0; i < 7; i++) {       scanf("%f", &hours[i]);    }    printf("The numbers you entered are as follows:\n");       printf(" %4.1f", hours[i]);    printf("\n");    for(i = 0, average = 0; i < 7; i++) {       average += hours[i];    average /= 7;    printf("Your average hours of sleep per night were %.1f hours.\n", average);    return 0; } Enter the hours of sleep per night last week 9 10 4 12 13 14 3.5 The numbers you entered are as follows: 9.0 10.0 4.0 12.0 13.0 14.0 3.5 Your average hours of sleep per night were 9.4 hours. 輸出: 此範例先用迴圈讓使用者輸入 七個數字存在陣列裡,然後再 用迴圈一一把陣列裡的元素再 顯示出來,然後再用迴圈把元 素的值累加起來,最後計算出 平均值。 有幾個要注意的地方,第一是 迴圈裡的用來當陣列 index 的變數要從 0 開始;第二是 用來累加總和並計算平均的變 數 average 要先設定初值等 於 0;第三是 scanf() 裡陣列 元素的寫法,當我們要把值存 入某個陣列元素時,別忘了加 & 符號。

使用for or while 在一開始使用迴圈時,一定會對於要用哪 一種迴圈產生疑惑,以下對for與while做一 個分析。

Appendix

for的特殊語法 也可以寫為 當參數i只在此for迴圈使用的時候,下面的寫法會讓compiler將記憶體空間做較好的分配。 int i; for(i = 0; i < 10; i++) { … } 也可以寫為 for(int i = 0; i < 10; i++) { … } 當參數i只在此for迴圈使用的時候,下面的寫法會讓compiler將記憶體空間做較好的分配。 不過這僅限於C99以後的標準。