第 1 章 C 程式簡介

本章的目的是在介紹一些簡單的 C 程式,並熟悉其架構及 一些指令。

於此,注意一下,C 程式中 英文 的 大小寫 是 有區別的。

第 1.1 節 最短的 C 程式

C 程式:

         main(){}

第 1.2 節 最短且沒有提示 (warning) 的 C 程式

C 程式: 其中 void 表示 main() 是不具有 函數值 的 procedure。

         void main(){}
另一個 相當短 的 沒有 提示 (warning) 的 C 程式 :

C 程式:

         main(){return;}  /* 或使用 return 0; */
第 1.3 節 輸出 指令 printf( )

C 程式:

         #include <stdio.h>
         main()
         {
            printf("嗨! 我是小明, 您好!\n");
            printf("請問大名?\n");
         }
說明:
  1. 執行此程式的結果將會在螢幕上顯示出
    嗨! 我是小明, 您好!
    請問大名?
  2. 指令 printf( ); 會將括號內兩個引號 " " 中的字串列印在螢 幕上。

  3. 指令 printf( );是定義在檔案 include\stdio.h 中,我們須加上 #include <stdio.h> 方能使用敘述 printf( );。#include 是前置處理指令,將於第8.2節討論。
  4. \n 是 一個 字元, 表示 跳行。

第 1.4 節 辨識名稱 (identifiers)

辨識名稱宣告語法 :
第一個 字元 必須是 字母 或 是 底線 (_), 其後 可 連續 接上 幾個 字母、 底線 或 數字。

注意事項 :
字母 大小寫 是有 區別的, 不可有 空格, 名稱 不可 採用 保留字 , 儘量 使用 與 上下文 有關 名稱。

例 (正確名稱) :
c、 ch、 i、 j、 count、 sum。

例 (錯誤名稱) :
this is、 char、 total-amount。

使用範圍 :
變數名、 函數名、 符號常數等。

第 1.5 節 資料型態 與 變數 (variables)

變數宣告語法:
資料型態 變數名稱[, 變數名稱];

變數宣告處:
(1) 在一個檔案任何函數(包括main)之前,
(2) 在任一括號{ ... }內的起頭。

例:
int i, j, k, sum = 0;
char c ='0', C ='c', ch;
float x, y, z, area = 0.0, radius;

說明:
  1. 資料型態 int 佔有 2 bytes, 其 範圍 為 -32768 至 32767。

  2. 資料型態 char 佔有 1 byte, 其 範圍 為 -128 至 127。 其 字元 常數 以 兩個 單引號 ' ' 包含之。 例 '0'、 '1'、'A'、 'B'、 'Z'、 'a'、 'b'、 'z'、 ' '、 '\x41'、 '\141' 等。

  3. 資料型態 float 佔有 4 byte, 其 範圍 為 3.4E-38 至 3.4E+38。

  4. 上例 中 c 與 C 是 不同 變數。

  5. 在同一 括號內, 即 {...}, 不可 重複宣告 變數。

  6. 宣告 int sum = 0; 即 宣告 變數 sum, 其資料型態 為 int, 值為 0。

  7. C = c; 與 C = 'c'; 是 不同 義意, C = c; 是 將 變數 c 的值 指派 給 變數 C,C = 'c'; 是 將 字元 'c' 值 指派 給 變數 C。

第 1.6 節 指派敘述

指派敘述的語法:
變數 = [ 變數 = ] 運算式子;

指派敘述的語意:
將變數的值改為運算式的值。

例:
x = y = z = x + y * z;
上式 與 下式 同義 :
z = x + y * z;
y = z;
x = y;

註:
指派敘述可視為運算式,其值為最左邊變數的值。

第 1.7 節 字元輸入指令 getchar( ), 字元變數及指派敘述

如果 我們 設計 一 編輯 應用軟体 如 PE2 或 其它, 當 使用者 修改 了 一文件 後 沒有 存檔, 且 鍵入 離開 指令, 我們 應給 使用者 一個 提示 如下 :

         您想要存檔嗎?(y/n)
讓 使用者 去按 y 或 n 以作 決定。 以下 程式 就是 在 做 類似 工作。

C 程式:

         main()
         {  char c;
            printf("您想要存檔嗎?(y/n)");
            c = getchar();  /* if (c=='y'){...}
                               else {...}       */
         }
說明:
  1. char c; 即 宣告 (定義) 一變數, 其名 為 c, 其 屬性 為 一個 字元 (char), 該 變數 可用來 存、 取 或 修改 一字元 等。

  2. 執行 getchar( ); 時, 當 使用者 鍵入 y 或 n 後, 再 鍵入 <enter> 則 函數 getchar( ) 值 為 該 鍵入值。 執行 該函數時, 電腦 會 一直 等到 使用者 鍵入 <enter>。 使用者 至多 能 輸入 127 個字元。 如果 使用者 輸入 超過 一個 字元, 則 電腦 僅取 第一個 字元 作為 getchar( ) 的 值, 其餘 的 留給 以後 的 輸入 指令。

  3. c = getchar(); 為 一 指派 敘述, 將 getchar( ) 的 值 定為 變數 c 的值。

  4. /* ... */ 為 程式 註釋, 不屬於 程式的 一部份。

  5. getche( ) 可 代替 getchar( ), 輸入時 不需 鍵入 <enter>, 且 螢幕 有回應, 即 鍵入的 字 立即 顯示 在螢幕上。

  6. getch() 亦可 代替 getchar( ), 輸入 時 不需 鍵入 <enter>, 且 螢幕 沒有 回應。

第 1.8 節 字元 輸出指令 putchar(char) 及 while 指令

下一個程式 是在 模擬 DOS 的 type 指令, 在 DOS 下 鍵入 type file, 則 檔案 file 將 被列印 在螢幕上, type file >out 如同 copy file outtype file >>out 即將 file 附加在 out 之後。

將此程式 編譯 成 執行檔 如 list.exe, 則 list <file 就如同 type file 一樣。

         #include <stdio.h>

         main()
         { char c;
           c = getchar();
           while ( c != EOF )
           { putchar(c);
             c = getchar();
           } /* end of while loop */
         } /* end of main */
整個程式 亦可 改成
         #include <stdio.h>

         main()
         { char c;
           while( ( c = getchar() ) != EOF )
              putchar(c);
         }
說明:
  1. EOF 是定義在 檔案 \tc\include\stdio.h 中, 其值為 -1。

  2. while 指令 型式 為 while ( 條件 ) { 敘述; ...; 敘述; } 或 while ( 條件 ) 敘述; 其中, 條件 為 一運算式, 當 條件 成立時,即 條件值 不為 0, 則 執行 括號內 的 敘述 或 緊接 while 的敘述。

  3. 雖然 c = getchar( ); c != EOF; 與
    ((c = getchar( )) != EOF) 同義意, 但 卻 不可 當做 while 的條件式子。

  4. 若 執行 該程式 時 不設定 輸入檔, 則 輸入檔 為 stdin 即 由 鍵盤輸入, 若 欲 產生 EOF 則 須 按鍵 ^z<enter>, 其 ASCII 碼為 26。

第 1.9 節 ASCII 表格 與 for 敘述

下一程式 是 在 列印出 255 個 ASCII 字元。

         main()
         {  char c;
            for ( c = -128; c < 127 ; c++)
              printf("字元 %c 的值為 %d\n", c, c);
         }
說明:
  1. 一個 字元 是 一個 位元組 (byte), 即 8 個位元 (bit), 其值 是 介於 -128 與 127 之間, 因此 共有 256 個字元, 有可見 字元 如 、 0、 1、 2、 A、 B、 C、 a、 b、 c等, 及 不可見 字元 如 ' '、 '\n'、 '\t'、 '\007'等。 一個 字元 佔 8 個位元(bit), 因此 每一 字元 都有 其 相對應 的 數值, 即 內碼, 如 'A' 的 內碼 為 65 或 x41 (x 表 16 進位), '0' 的 內碼 為 48 或 x30。 一個 ASCII 文件 其檔尾值 為 -1,即 EOF。

  2. printf 為 一格式化 輸出 指令, 其 指令 型式 為
    printf("..%x..%y..%..", ex1, ex2, ex3);
    其中 %x、 %y 為 控制碼, ex1、 ex2 及 ex3 為 列印值, ex1 將以 %x 方式 列印在 %x 的位置。 控制碼 個數 與 列印值 個數 必須 相同, x 可為 c、 d、 f 等, 即 ex1 將 以 字元(char)、 整數(int)、或 浮點 (float)方式列印。

  3. for ( c = -128; c < 127; c++)
    printf("字元 %c 的值為 %d\n", c, c);

    與 下列 while 敘述 同意義
                  c = -128;
                  while (c < 127)
                      {  printf("字元 %c 的值為 %d\n", c, c);
                         c++;
                      }
    
  4. c++; 與 c = c + 1; 同意義。

  5. 上一程式 只 列印 255 個字元, 如要列印 所有 256 個字元 該如何做?

  6. 欲表示 中文字, 則 需 多少位元 (bit)?

第 1.10 節 以 字元 輸入 指令 getchar( ) 輸入 一整數

C 程式:

         main()
         {  int number = 0;
            char c;

            printf("請輸入一整數:");

            /* 去掉空白 */
            while ( (c = getchar()) == ' ');

            /* do
               while((c = getchar())== ' ');
            */

            while ( c >= '0' && c <= '9' )
            {     number = 10 * number + ( c - '0' );
                  c = getchar();
            }
            printf("輸入整數為: %d\n", number);
         }
說明:
  1. 我們 可在 變數 宣告時 設定 起始值, 如
    int number = 0;
    此 宣告 方式 與 下列 方式 相同
    int number; number = 0;。

  2. && 即 邏輯 運算 "且"。

  3. 0 為 一整數 常數, '0' 與 '9' 為 字元 常數。

  4. 輸入 □□□123, 其 輸出 為
    輸入整數為: 123

  5. 如果 每次 輸入 一整數 或 一浮點數 都必須 由此法 取得 這 畢竟是 太麻煩, 我們 可用 函數 scanf 取得。

第 1.11 節 輸入 指令 scanf( ) 與 整數 變數

C 程式:

         main()
         {
           int x, y;   /* 鍵入整數並存入變數 x,
                           x 的值即為該數        */

           printf("請輸入一個 3 位數:")
           scanf("%d", &x);
           y = x + 1;
           printf("%d + 1 = %d\n", x, y);
         }
說明:
  1. 執行 此程式 的結果 是 會在螢幕上 顯示出
    請輸入一個 3 位數:
    如果 我們 輸入 123 後, 螢幕上 會 顯示出
    123 + 1 = 124

  2. scanf("%d", &x); 這指令 含 控制碼 %d, 表示 以 整數 方式 輸入 整數 給 整數變數 x, &x 乃是 變數 x 於 記憶體的地址 [參閱 第 4 章]。

第 1.12 節 輸入 指令 scanf( ) 與 字元、 整數 和 浮點 變數

         main()
         {
           char  c;
           int   i;
           float x;

           printf("請輸入一個整數, 一個字元及一個浮點數:");
           scanf("%d%c%f", &i, &c, &x);
      /*   scanf("%d %c %f", &i, &c, &x);            */
           printf("[%c] [%d] [%f]\n", c, i, x);
         }

說明:
  1. 如果 輸入 12.3, 其輸出為 : [.] [12] [3.000000]。
    如果 輸入 12 .3, 其輸出為 : [ ] [12] [0.300000]。
    如果 輸入 12 . 3, 其輸出為 : [ ] [12] [-0.000000]。

  2. 如果 我們 使用 另一 scanf, 則 輸入中 的 空格 被忽略 不計。

第 1.13 節 if, if-else, 及 return 敘述。

輸入 一 正整數, 如果 該數 為 偶數 則 除2, 不然 就 乘 3 加 1, 再 依此方式 進行 直到 1 為止, 並 計算 進行 次數。

         main()
         { int x;            /* x 用來存輸入值         */
           int count = 0;    /* count 用來計算執行次數 */
           printf("請輸入一正整數: ");
           scanf("%d", &x);
           if (x <= 0 )
           {  printf("%d 不是正整數\n", x); return;
           }
           while ( x > 1 )
           { if ( x % 2 == 0 ) x /= 2;
             else x = 3 * x + 1;
             count++;
           }
           printf("共重複計算 %d 次\n", count);
         }

說明:
  1. 執行到 return; 時, 立即 停止 執行 該函數 而 返回到 原 呼叫函數處。

  2. x % 2 即 x 除以 2 的餘數。

  3. x /=2; 與 x = x / 2; 同義。 其 一般式 為
    變數 運算子= 運算式; 這與
    變數 = 變數 運算子 運算式;
    同義。

    例: x *= y + 2;x = x * ( y + 2 ); 同義。

第 1.14 節 有一 未知 正整數 x, 僅知 x 除 3 餘 1, x 除 5 餘 2, x 除 7 餘 3,試問 該數 最小 是多少?

類比: (平行演算法 parallel algorithm)
將兵 105 人 排成 一排, 報數後, 每人將 自己號碼 計算 一下, 若 滿足 上述 條件者, 自行報出 自己號碼。

依此 方式 稍做修改 的 C 程式 (循序演算法 sequential algorithm), 如下 :

         main() { int i;
           for (i=1; i<=105; i++)
               if ( i%3==1 && i%5==2 && i%7==3)
               {  printf("此數為 %d\n", i); break;
               }
         }

說明:
  1. && 為 布林 運算子, 即 "且"。

  2. 執行 break; 則 跳出 迴圈, 亦可 用 return 代替, 以 結束 執行。

第 1.15 節 設計一 程式 以 計算 學生 總成績

輸入檔 的 架構 如下:

第一行 含 學生總數,其後 每一行 含 學生姓名 (佔 8 個 字元) 及 第一段考、 第二段考 和 期考成績。 例如:

3
張  三    85 92 88
李  四    78 83 76
江小魚    60 70 80
其 輸出 如下 :
          姓  名      第一段考   第二段考    期末考    總成績

          張  三          85         92         88       265
          李  四          78         83         76       237
          江小魚          60         70         80       210

          學生總平均是 237.3
其程式如下:
         #include <stdio.h>
         #define NAMELEN 8  /* 姓名佔有 8 位元 */
         #define TESTNO  3  /* 3 次考試        */
         void main() {
            float sum;     /* 單一學生總成績 */
            float total=0; /* 全班學生總成績 */
            float score;   /* 一科科目成績   */
            int no;        /* 學生總數       */
            int i, j;      /* 索引           */
            scanf("%d", &no); /* 輸入學生總數 */
            printf("          ");
            printf("姓  名      第一段考   第二段考    期末考");
            printf("    總成績\n");
            for (i = 1; i <= no; i++)
            {  printf("          ");
               for (j =1; j<=NAMELEN; j++)  /*讀取姓名,並列印出*/
                    putchar( getchar() );
            /* 以score讀取3次考試成績,並列印出,以sum累計總分 */
                sum = 0.0;
                for (j = 1; j<=TESTNO; j++)
                {   scanf("%f", &score);
                    printf("%11.0f", score);
                    sum += score;
                } /* nested for loop */
                total += sum;             /* 累計所有學生總分 */
                printf("%10.0f\n", sum);  /* 列印總成績       */
            } /* outer loop */
            printf("\n          ");
            printf("學生總平均是 %5.1f\n",total/no);/*列印總平均*/
         }/* end of main */                                           

第 1.16 節 本章重點

  1. 辨識 名稱, 變數 的 宣告, 變數 起始值 的 設定。

  2. 程式的 註釋 /* .... */ 是 用來 說明 程式 的目的 或 其它。

  3. 輸入/輸出 敘述 (或指令) 有 下列 幾種:

    方式檔案字元格式化charintfloat
    輸入stdin getchar( )scanf( )%c%d%f
    getche( )    
    getch( )    
    輸出stdoutputchar( )printf( )%c%d%f

  4. break 為 迴圈中斷, return 為函數中斷。

  5. 選擇 敘述 有 ifif-else

  6. 迴圈 敘述 有 whiledo whilefor

  7. 算數 運算 有 + - * / %

  8. 算數 比較 有 < > = <= >= !=

  9. 邏輯 運算 有 &&(且)、 ||(或)、 !(非)。

  10. 簡式 :
    x *= 2;x = x * 2; 相同。
    x = (x%2==1)? 3*x+1: x/2;
    if (x%2==1) x=3*x+1;
    else x=x/2;
    相同。

  11. 加/減 1 運算: x++ x-- ++x --x
    如果 x=2; y=x++; 則 x 與 y 的值 分別 為 3 與 2;
    如果 x=2; y=x--; 則 x 與 y 的值 分別 為 1 與 2;
    如果 x=2; y=++x; 則 x 與 y 的值 分別 為 3 與 3;
    如果 x=2; y=--x; 則 x 與 y 的值 分別 為 1 與 1;

第 1.17 節 作業 1

作業 1:

  1. 求 兩正整數 的 最大 公因數。
  2. 求 第 n 個 費氏數。
  3. 試 繪出 自 攝氏 0°C 至 100°C 與 華氏的 對 照表。
  4. 試 列出 1 至 30000 的 質數 並 計算 多少個 質數。
  5. 試 利用數學公式 修改 第 1.14 節 中的 程式, 其輸入 為 3 個 互為 互質 的數, 及其 相對應餘數, 求 滿足 該條件 的 最小 正整數。
  6. 輸入 50 個整數, 求其平均值。

回第 0 章
至第 2 章
回 C 程式 主目錄