一個C語言程式長得如下的範例:

/*
 * 註解
 */
#include <stdio.h>
int x;
int main() {
    int y; // main裡的y
    x = 1;
    y=foo(x); // 這裡的y是main裡的y
    printf("I have done\n");
    return 0;
}
int foo(int z) {
    int y; // foo裡的y
    return z;
}

C語言是由一個以上的函數所組成的,函數的名稱只能宣告一次,其中有個特別的函數叫做main,是C程式開始執行的地方。以/* 註解 */括起來的部分,以及//後面直到行尾的部分是註解,所謂註解是指該部分只是給人看的,並不會影響Compiler的編譯結果。原始程式碼由#號開頭的部分,是交由前置處理器來處理;#include這個前置處理器命令,是把Source code file和其後的Header file合成為另一個修改過的Source code file。換言之,#include <stdio.h>其功能就好比我們用文字處理器將系統目錄內的stdio.h檔案插入到#include的位置上。

C語言並不要求一定要引入stdio.h,此範例要寫#include <stdio.h>的原因在於程式內使用了printf函數,這個函數是存在於系統程式庫內,為了讓Compiler了解printf是在別的地方定義的,因此要將宣告printf長相的stdio.h包含進來。

有時候你會看到

#include "my.h"

#include後面的檔名可用<>或""括起來,其差別在於<>表示系統的引入檔, 在UNIX的gcc會去目錄/usr/include下面找,""則表示使用者的引入檔,preprocessor會在和這個.c一樣的目錄下尋找。為甚麼要分 <>或""這兩種呢? 硬碟上的空間被分成很多樹狀的目錄, 不同的目錄下可以存在同名的目錄, 這就像每個系每個年級都有26號同學, 要區分這些26號同學, 我們得說 資管大一26號』或『跟我在同一個房間內的26號』. #include <26號>就像說 『資管大一26號』, #include "26號" 則像『跟我在同一個房間內的26號』。

第二行的

 
int x;

是宣告全域(global)變數x的型態為int(整數)。合法的變數名稱是由英文字母或底線開頭,後面可加上不定長的文數字和底線,如_x123。所謂變數宣告是要求compiler在某個記憶體上配置足夠容納該型態的空間,對C語言來說,int型態比較複雜一點,其大小在不同的平台上可能不同,但以目前32 bits的機器而言,int一般為4個bytes大小,因此int x;這個指令,是要compiler在某塊記憶體上(對程式設計師而言不用管實際上在哪裡)分配4個bytes準備放資料,而這4個bytes的記憶體我們在程式內就以x這個符號來代表他。凡是宣告在函數之外的變數,都可稱為全域變數。

函數的宣告包含幾個部分:傳回值,函數名稱,()內的參數列,以及{}內的程式碼.

int main() {}

表示main這個函數不需要參數,其傳回值的型態為int

每一個函數寫作的開始和結束點,是由{}來表達。函數可以有多行的敘述(statement)。每一個敘述由分號;或右大括弧}結尾。敘述分成兩大類,第一類是變數宣告,第二類是運算指令,運算指令可以是運算式流程控制敘述。敘述只能寫在函數裡面,不像變數可以宣告在函數外面成為全域變數。C語言要求運算指令內所用到的變數必須在該運算指令前宣告。變數宣告的寫法為

型態名稱 變數名稱 ;

C語言的合法型態名稱及意義請參見型別的詳細說明

    int y;

要compiler準備4個bytes的空間,以存放int,並將該空間以y這個符號代表。

    x = 1;

表示將整數1複製到x所代表的記憶體。此處的x指的是宣告在main函數之前的x

    y=foo(x);

表示將整數x的值複製到堆疊上,CALL foo,然後將傳回值(可能是放在暫存器或某塊記憶體上面)複製到整數y。詳情見函數與遞迴

    return 0;

表示將整數0回傳給呼叫main的函數。是誰呼叫main呢?這就由作業系統負責了,此處不做詳述。

int foo(int z){}

宣告呼叫foo這個函數時,需要傳入一個int當參數(事實上此int是放在稱為Stack的某塊記憶體上),這個在堆疊上的變數我們稱之為z。

    int y;

在堆疊上產生新的變數y,此y和main裡面宣告的y是完全不同的變數。

    return z;

表示將整數z記憶體的內容複製到暫存器上,然後以此數值當做foo函數的傳回值。

如果一個變數定義在函數的外面(如範例裡的x),則此變數稱為global variable(全域變數)。全域變數的可見範圍(意思是哪些函數)是程式內的所有函數(前面有static, extern等修飾字的情況於後面的章節再討論);其存在期間從該程式執行就存在,程式結束該變數才會消失。

如果變數是定義在函數裡面(如範例裡的y),則此變數稱為local variable(區域變數)或auto variable(自動變數)。區域變數的可見範圍僅侷限於定義該變數的函數;其存在期間則是開始於該函數被呼叫時,結束於該函數return時。換言之,如果foo()被呼叫了兩次,則foo裡宣告的y就會產生兩次。在C語言的執行環境下,區域變數會存放在堆疊上。

寫作程式時,需注意以下風格:

以下是寫作的範例

/* 
 * Program Name: h2.c
 * Subject: "Introduction to Programming" Homework for practice of loop and I/O.
 * Since 1997/10/27
 * 2004/03/03, add more comment
 * 2008/09/28, correct comments typing error
 * ToolKit: gcc
 * Author: Shiuh-Sheng Yu
 *         Dept. of Information Management
 *         National ChiNan University
 */
#include <stdio.h>
 
/**
 * print out rectangle
 * @param size length of the rectangle
 */
void print_rectangle(int size) {
    int i, j;
    for (i = 1; i <= size; i++) {
        for (j = 1;  j <=  size; j++) {
            printf("*");
        }
        printf("\n");
    }
}

/**
 * Read size from keyboard as long as the size is between 1 and 40,
 * then call print_rectangel to print on screen
 */
int main() {
    int size = 0;
    while (scanf("%d",&size) > 0 && size > 0 && size < =  40) {
        print_rectangle(size);
    }
}

常用的IO函數

C語言沒有定義標準函數庫(Library),但因為IO是撰寫程式幾乎一定要用到的功能,因此我們在此說明不同平台上都會提供的printf和scanf函數,以方便讀者寫作程式。這兩個函數或許在不同平台上的某些特殊用法會有點小出入,但大致上是相同的。

最簡單的printf用法如下:

printf("Hello World.\n");

這會在標準輸出裝置(內定是螢幕)上印出Hello World.然後換行,'\n'表示換行字元。如果我們要印出變數的內容,可以使用如下的形式

#include <stdio.h>
int main() {
    int varInt = 0;
    long varLong = 0;
    float varFloat = 2;
    double varDouble = 0;
    char varChar = 'A';
    char *varString = "Hello";
    printf("varInt=%d, varLong=%ld, varFloat=%f, varDouble=%lf, varChar=%c, varString=%s\n",varInt, varLong, varFloat, varDouble, varChar, varString);
}

printf的第一個參數是一個字串,字串內以%開頭的符號有特別意義,表示此部份要用後面的參數取代。%d或%i以十進位數字表示int,%x以十六進位表示int,%f表示浮點數(float or double),%c表示字元,%s表示字串,%%表示%,%3d表示最少3個數字靠右不足3個填空白,%-3d表示最少3個數字靠左不足3個填空白,%03d表示最少3個數字靠右不足3個填0。如果要印出%號的話怎麼辦,那就用%%來代表了。printf相關參數如下

printf()傳回整數, 代表輸出的字元數

scanf用來做輸入,其參數和printf很類似,但要記得

scanf()傳回整數,代表有幾個成功讀入.

#include <stdio.h>
int main() {
    int varInt;
    long varLong;
    float varFloat;
    double varDouble;
    scanf("%d%l%f%lf", &varInt, &varLong, &varFloat, &varDouble);
}