這會是一個不確定次數迴圈的應用,我們另以英文句子的結尾句點 '.' 當成停止輸入的警示值。我們提供的範例如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include <stdio.h> int main( void ) { char ch; char saying[100]; char *s = saying; int i = 0; printf ( "請輸入文字,結束請按 . \n" ); while ((ch = getchar ()) != '.' ) { saying[i] = ch; i++; } printf ( "\n\n剛剛輸入的句子是 " ); while (*s != '\0' ) { putchar (*s); s++; } printf ( "\n" ); return 0; } /* 《程式語言教學誌》的範例程式 檔名:we.c 功能:示範 while 迴圈的典型應用 作者:張凱慶 時間:西元2010年7月 */ |
編譯執行,結果如下

這個例子很簡單,就是要求使用者輸入一段文字,而且是以字元的方式輸入,第 11 行
11 | while ((ch = getchar ()) != '.' ) { |
函數 getchar() 是標準函數庫中 stdio.h 用來取得輸入字元的函數,這個函數不需要用到參數,回傳值就是得到的字元。因此在這個 while 迴圈的結束條件就是用小括弧圍起來的 ch = getchar() 先被執行,得到的字元被儲存在變數 ch 後, ch 再跟字元 '.' 進行相等性測試,若是不相等, while 迴圈就會繼續執行。
我們用字元 '.' 作為迴圈結束的警示值,一旦發現使用者輸入英文句點,也就代表這個句子結束了。由於我們不知道使用者何時輸入結束,可是通常句點為句子的結束,所以我們將句點當作迴圈結束的警示值。
利用指標操作字元陣列(字串)是很常見的寫法,第 17 行到第 20 行
11 12 13 14 | while (*s != '\0' ) { putchar (*s); s++; } |
陣列宣告後,沒有被給值的元素會被塞進字元 '\0' ,這個字元在 ASCII 表示空字元,就是什麼都沒有的意思。因此我們可以用 '\0' 當成有儲存資料的字元陣列,內容結束的警示值。注意,這裡的變數 s 為第 7 行宣告的指標,同時被指派字元陣列 saying ,意思就是把 saying 指向的位址給 s
7 | char *s = saying; |
會這麼做是因為陣列名稱等同指標沒錯,就把陣列名稱當作是指標來看也沒關係,但是陣列名稱不能如指標變數一樣做算術運算。因此我們要用指標的方式操作陣列元素的話,就必須另外宣告一個指標變數來進行處理。
第 7 行的星號是宣告指標用的運算子,第 17 行的星號則是取值運算子,或稱反參考運算子,因為指標儲存的是某個變數的記憶體位址,若要由該變數的記憶體位址反參考該變數的值,就必須用取值運算子。下圖說明這個關係

用取值運算子才能取得指標指向變數的值,所以接下來在 stdio.h 的輸出字元函數 putchar() ,也須以 *s 當作參數。
問題與討論
- 我們用 '.' 作為結束輸入的警示值,如果我們在句子結束仍是希望加入 '.' ,這該怎麼做呢?
- 函數 scanf() 不是也可以輸入字元嗎?為什麼要有另外一個專門輸入字元的函數 getchar() ?
- 函數 printff() 不是也可以印出字元嗎?為什麼要有另外一個專門輸出字元的函數 putchar() ?
- 說明取值運算子的運作方式。
- 為什麼要另外宣告指標變數操作字元陣列?
- 有哪些運算子都用到星號,想一想,為什麼可以用相同符號當不同功能的運算子?
沒有留言:
張貼留言