☛ 一個簡單的 C 程式

從未寫過 C 程式的人可能會對 C 語言中的某些符號感到陌生,不過我們將會從最簡單的例子開始。 第一個例子是列印一行文字。 此程式的本體及其輸出如下:

/* A first program in C */
#include<stdio.h>

/* function main begin program execution */
int main()
{
    printf("Welcome to C!\n";
    return 0;    /* indicate that program ended successfully */
}                /* end fuction main */
Welcome to C!

程式說明:

以 /* 開頭而以 */ 結尾,代表這是一行注解 ( comment )。 程式設計師通常會在程式中加入一些註解,使程式較容易閱讀。 當程式在執行時,電腦會跳過注解的部分。

第二行,#include<stdio.h> 是 C 前置處理器 ( C preprocessor ) 命令。 以 # 開頭的行都會在程式被編譯前由前置處理器進行處理。 這一行告訴前置處理器將標準輸入/輸出標頭檔 ( stdio.h ) 引入到程式裡面。 這個前置檔含有編譯器在編譯標準函式庫函式 ( 如 printf  ) 時,所用到的資訊與宣告。 它也含有協助編譯器判斷函式庫函式的呼叫是否撰寫正確。

第五行,int main() 是每個 C 程式都必須要有的敘述式。 main 之後的括號代表main是個函式 ( function )。 C 程式中可含有一個或多個函式,不過其中一個必須是main。 每個 C 程式都是從 main 函式開始執行。

程式接下來是個左大括弧 ( left brace ) ( { ),每個函式的本體都是以此符號開始,而以右大括弧 ( right brace ) ( } ) 結束。 在這兩個括號之間的程式也稱為一個區塊 ( block )。

第七行,printf(“Welcome to C!\n”); 指示電腦將雙引號內的字串顯示在螢幕上。 字串有時候稱為字元字串 ( character string ),資訊 ( message ) 或是字面常數 ( literal )。 這一行 ( 包括 printf、括弧、括弧裡面的引數及分號等 ) 稱為一道敘述式 ( statement )。 每一個敘述式必須以分號為結尾。 此敘述的執行結果是在螢幕上印出 Welcome to C!。 不過我們發現 \n 並沒有出現在螢幕上。 反斜線 ( \ ) 稱為脫序字元 ( escape character ),它可以用來指示 printf 印出一些特殊字元,亦即當 printf 看到 \ 時,會將 \ 和其後的字元看成是脫序串列 ( escape sequence )。 常見的脫序串列如下:

脫序串列 說明
\n Newline 換行,將游標移到下一行開頭。
\t 水準定位,將游標移到下一個定位點。
\a 示警,系統發出警告鈴聲。
\\ 反斜線,在 printf 敘述式中印出反斜線字元。
\” 雙引號,在 printf 敘述式中印出雙引號字元。

 

第九行,return 0; 位於每一個main函式的結束處。 關鍵字 return 的其中一種用途就是用來離開函式 ( exit a function )。

☛ 將兩個整數相加的 C 程式

這個程式使用了標準函式庫函式 scanf,來讀進使用者鍵入的兩個整數,然後計算這兩個值的和,再以 printf 將結果印出來。 如下所示:

/* Addition program */
#include <stdio.h>

/*function main begins program execution */
int main()
{
    int integer1;                    /* first number to be input by user */
    int integer2;                    /* second number to be input by user */
    int sum;                         /* variable in which sum will be stored */

    printf("Enter first integer\n"); /* prompt */
    scanf("%d",&integer1);           /* read an integer */
    printf("Enter second integer\n); /* prompt */ 
    scanf("%d",&integer2);           /* read an integer */

    sum=integer1+integer2;           /* assign total to sum */
    printf("Sum is %d\n",sum);       /* print sum "/
    return 0;                        /* indicate that program ended successfully */

}                                    /* end function main */
Enter first integer
45
Enter second integer
72
Sum is 117

程式說明:

第七至第九行,都是定義 ( definitions )。 integer1、integer2 及 sum 代表了變數 ( variables ) 的名稱。 變數是記憶體中的一塊位置,可以將程式裡會使用到的數值存在裡面。 C 語言當中變數名稱可以是任意合法的識別字 ( identifier )。 識別字是一串字元 ( 包括了字母、數位和底線 ),但是第一個字元不可以是數位。 識別字的長度沒有限制,不過 ANSIC 規定編譯器只需辨認前 31 個字元。 在 C 語言裡,大小寫字母是不同的,所以 a1 與 A1 代表的是不同的識別字。

相同型別的變數除了分數行宣告外,也可以宣告在同一行,如下所示:

int integer1, integer2, sum;

第十二行,scanf(“%d”,&integer1); 敘述式,是使用 scanf 來讀取一個數值。 scanf 函式由標準輸入 ( 通常是鍵盤 ) 讀取數值。 這一個 scanf 有二個引數 %d 和 &integer1。

第一個引數是格式控制字串 ( format control string ),它顯示出消費者應該輸入的資料型別。 %d 這個轉換指定詞 ( conversion specifier ) 表示資料應該是整數 ( 字母 d 代表十進位整數 )。 此處的 % 被 scanf ( printf 亦然 ) 視為一個脫序字元。 而 %d 則被視為一個脫序字串。

第二個引數以 & 為開頭,後接一個變數名稱。 & 在 C 裡面被稱為位址運算子。 這個引數的目的是告訴 scanf,變數 integer1 存放在記憶體中的什麼地方,然後電腦儲存 integer1 值在那個位置。

☛ 記憶體的概念

上述程式碼範例中的 integer1、integer2 和 sum 這樣的變數名稱都會對應到電腦里的記憶體位置。 每個變數都具有一個名稱 ( name )、一個型別 ( type ) 及一個數值 ( value )。

執行時,消費者鍵入的數值會被放在 integer1 所對應的記憶體位置。 假設消費者輸入的數值為 45,那麼電腦會將 45 放在 integer1 的記憶體位置。 如下圖所示:

當數值被放到某個記憶體位置時,此數值會蓋掉先前存放在這個位置的值。 由於原先的資訊會被破壞,因此將資訊讀入記憶體位置的過程便稱為破壞性的讀入 ( destructive read-in )。

在上述程式第十六行的敘述式,程式在讀取 integer1 和 integer2 後,它會將這兩個值相加,然後將其結果存放到變數 sum。 執行加法運算同時也進行了破壞性讀入。 發生在將 integer1 和 integer2 相加後的結果放到 sum 的位置 ( 破壞了 sum 中可能已有的數值 )。

執行相加之後,這個時候的記憶體將如下圖所示,integer1 和 integer2 的值和他們被相加之前是一樣的,並沒有遭到破壞。 所以,當從某個記憶體位置讀出數值時,這個過程稱為非破壞性的讀出 ( nondestructive read-out )。