1.2k likes | 1.64k Views
第一篇 C 語言基礎入門應用程式設計. 本篇內容精緻實用、由淺入深、並參佐實作範例。為初學者作基礎入門學習、易學易懂、且建立實作能力。特別適用於各級學校、作為教學教材。. 第一章 導述. 本章目的在導引您迅速窺得 C 之架構全貌。 輕鬆了解、進而寫出 C 語言程式。至於細節道理、將於爾後各章節作有系統的介紹。. 1-1 第一個 C 程式 1-2 變數 (Variables) 與 運算 (Arithmetic) 1-3 For 敘述式 1-4 符號常數 (Symbolic Constants) 1-5 Unix(or Linux) 系統中一些應用程式
E N D
第一篇 C語言基礎入門應用程式設計 本篇內容精緻實用、由淺入深、並參佐實作範例。為初學者作基礎入門學習、易學易懂、且建立實作能力。特別適用於各級學校、作為教學教材。
第一章 導述 本章目的在導引您迅速窺得C之架構全貌。 輕鬆了解、進而寫出C語言程式。至於細節道理、將於爾後各章節作有系統的介紹。
1-1 第一個C程式 • 1-2 變數(Variables) 與 運算(Arithmetic) • 1-3 For 敘述式 • 1-4 符號常數(Symbolic Constants) • 1-5 Unix(or Linux)系統中一些應用程式 • 1-6 陣列(Arrays) • 1-7 函數程式(Function) • 1-8 傳值參數(Argument—Call by Value) • 1-9 字元陣列(Character Arrays) • 1-10 區域觀念(Scope):外部變數(External Variables) • 1-11 實作範例
1-1 第一個C程式 • 寫電腦程式時、我們會面臨 (1)程式寫在那裡(Create program text)? (2)如何編譯(Compile)? (3)如何執行(Run)? • 本書鼓勵讀者、以Unix/Linux為研習環境,如果讀者沒有Unix/Linux系統之環境,或無需演練本書網路程式,為了簡單方便、亦可使用Turbo C編譯器,有關執行步驟、請參酌附錄B。 • 若讀者、對Unix (Linux)不熟習。可先閱讀演練本書 “附錄 A”。在很短時間內、您將能在Unix (Linux)系統內、操作自如。本節將以Unix/Linux環境、導引讀者演練您的第一個C程式。
1-2 變數(Variables) 與 運算(Arithmetic) 變數宣告型態有: • int 為整數(Integer) • float 為浮點數(Floating point) • char 為字元(Character) • short 為短整數(Short integer) • long 為長整數(Long integer) • double 為倍精浮點數(Double precision floating point) • 其他將在爾後詳述。
1-3 For 敘述式 for迴圈之三個條件參數(於本節範例中): • fahr = 0、是迴圈之起始條件、僅執行一次。 • fahr <= 300、是測試條件,當達到此條件時、迴圈即停止再執行。 • fahr = fahr + 20、每次執行迴圈一次、即再設定fahr一次,每次加20。
1-4 符號常數(Symbolic Constants) • 在程式中、總是有一些特別數值(Magic Number)。為了增加可讀性與記憶性,可於函數式前、以 “#define” 先行定義之。
1-5 Unix/ Linux系統中一些應用程式 • 在Unix/ Linux/系統中、我們可看到許許多多精彩的C程式。本節僅將一些有關字元之簡單程式、摘錄供您參考了解。至於細節詳述、留待爾後各章節再述。
1-6 陣列(Arrays) • 陣列宣告,其元素是ndigit[0]、ndigit[1]、‧‧‧、ndigit[9]。
1-7 函數程式(Function) • 在C程式語言、函數程式部份、可將繁長之程式作有條理的分解,增加其可讀性與方便性。 • 並非所有C程式都要有傳回值,若無傳回值、即如其他程式語言所稱之 “副程式(Subroutine)”。Unix/ Linux C均稱之為函數程式(Function),並不強調副程式(Subroutine)此名稱。
1-8 傳值參數(Argument—Call by Value) • 在一般語言程式設計、主程式(main)與函數程式(function)間之參數(argument)傳遞、有(1)参數傳值(call by value) (2)參數傳址(call by reference) (3)參數拷貝結果(copy restore) (4)参數傳名(call by name)。 • C語言則僅為 “参數傳值(call by value)”。當主程式呼叫函數程式時、參數值僅可從主程式傳遞至函數程式,不可從函數程式直接傳回至主程式。
1-10 區域觀念(Scope):外部變數(External Variables) • 於1-9節上述程式中、main程式內的變數(如line、save等)、因其是在main區域內作的宣告,故僅提供在main之區域(Scope)內使用,其他函數程式則不得直接使用。同理、在其他函數內宣告的變數、也僅提供於該函數區域內使用。例如、在getline內宣告的i與在copy內宣告的i、彼此間是毫無關係的。這些當地變數(Local Variables)是隨所屬函數之存在而存在,即當所屬函數被呼叫時、其內所宣告的變數才隨之產生,當所屬函數執行結束時、其內所宣告的變數也隨之消失。我們可稱之謂 “自動變數(Automatic Variables)”,相較於其他程式語言稱之為 “機動變數(Dynamic local Variables)在名稱上有所不同,我們將於第四章解述。 • 本節下述程式、將以 “全域變數(Global Variables)” 比較 “自動變數(Automatic Variables)”。其功能與1-9節之例程完全一樣。 宣告全域變數(Global Variables)於各函數之外端(Extern),各函數程式共用存取,也不隨函數之存在而存在,並取代參數在兩函數間之傳遞功能。
第二章資料型態(Types),運算元(Operators) 和運算式(Expressions) C程式的變數和常數、須在宣告中、歸類於適當之型態,稱為資料型態(Type)。運算元(Operator)是運算機制,如 + - * / 等。運算式(Expression)是將常數、變數、運算元、依其運算意義、產生新值。
2-1 變數名稱(Variable Names) C程式之變數名稱、有下列不可越軌之限制: (1) 名稱由字元和數字組成,但數字不得置於最前端。 (2) 英文字母大小寫、代表不同之名稱。通常變數用小寫;符號常數用大寫。 (3) 名稱長度不超過八個字元。 (4) 凡已被系統採用之保留字、要避讓。 (5) 當設定名稱時、要考量其可讀性與代表性。
2-2 資料型態(Data Types) Unix (or Linux)系統中、變數型態種類並不繁雜。一般計有: • char 字元,長度為本機系統、含恃一個字元的位元數。(一般電腦均是8個位元,但Honeywell 6000 是9個位元)。 • int 整數,長度為本機系統、含恃一個常用數字的位元數。(一般電腦是16個位元,但Honeywell 6000 是36個位元,IBM 370是32個位元)。 • float 浮點數,含有小數點的數。長度為本機系統、含恃一個常用浮點數的位元數。(一般電腦是32個位元,但Honeywell 6000 是36個位元)。 • double 倍精浮點數。(一般電腦是64個位元,但Honeywell 6000 是72個位元)。 • 為增加效果性、另增列 short int 與 long int。其長度分別為16 與 32 位元。
2-3 常數(Constants) • 整數常數(int)、小數常數(float)己於前節解釋。尚有指數常數(float)如 123.456e-7或 0.12E3。 • 八進位整數是以“零(0)”前導、如0123。十六進位整數是以“零(0)x”前導、如0x123。 • 一些操作字元常數、如 \n(新行列new line)、\t(空格tab)、\0(無null)、\\(返程backslash)、\’(單引號single quote)、等等,看似兩個字元、實以一個字元計之。 • 字串常數如“abcd123”、須以雙引號(“ ”)括含。在技術上、字串是一種陣列,且編譯程式會自動加置\0於其尾端。‘x’相較於“x”、前者是一字元、後者是一字串、且尾端有\0。
2-5 數學運算元 • 常用數學運算元有 加(+)、減(-)、乘(*)、除(/)、餘數(%)、負號(-)。 • 整數相除,設若x為整數、y為整數,則 餘數(x%y) 亦為整數,小數部份自動沖失。%運算元將不援引float或double。 • 運算元之運算優先次序以正負號(+)(-)最優先;其次是乘(*)、除(/)、餘數(%);再其次是加(+)、減(-)。若同級者同時出現時、式中位置在左端者優於在右端者(Left to Right)。在本章結尾、將展列一圖表,提供參照。
2-6 關係運算元(Relational Operators) 與 邏輯運算元(Logical Operators) • 關係運算元、有 “ >、>=、<、<=” 與 “==、!=”,其運算優先次序為、後組優於前組。 • 邏輯運算元、有 “&&” 與 “| |”、其運算優先次序為、前者優於後者。 • “關係運算元” 之運算優先次序優於 “邏輯運算元”。 • 設有一式: (i < lim-1) && ((c = getchar()) != ‘\n’) && (c != EOF) • 可改為: i < lim-1 && (c = getchar()) != ‘\n’ && c != EOF • 因“關係運算元” 之運算優先次序優於 “邏輯運算元”。
2-7 轉型(Type Conversions) • 當運算式中之各運算資料(Operands)為不同型態時、其中部份資料會自動轉型、成為一致相同的資料型態、如此才可完成運算。
資料轉型、可以下列三大法則轉換之: 1, 以下列規則與優先次序作轉換: • (1), char、short 轉型至 int; float轉型至 double。 • (2), 然後、若有任一double、則其他均轉為double、結果亦是double。 • (3), 否則、若有任一long、則其他均轉為long、結果亦是long。 • (4), 否則、若有任一unsigned、則其他均轉為unsigned、結果亦是unsigned。 • (5), 否則、運算資料必為int、結果亦是int。 2, 除此之外、等於符號(=)之右端運算資料、隨著其左端運算資料之型態而轉換 3, 最後、可以 (type_name) expression強力轉型
2-8 增加1(Increment) 與 減少1(Decrement) 運算元 • C提供兩組特殊運算元 “+ +” 與 “- -”。前者是將運算資料加1、後者是將運算資料減1。位置有置於前端(Prefix)、如 ++n、--n;有置於後端(Postfix)、如 n++、--n。 • ++n指當使用n前、先將n加1;n++指當已使用n後、才再將n加1。--n n—亦同。設 n = 5 則於 x = ++n 中、x之值是6;於 x = n++ 中、x之值為5。
2-9 位元邏輯運算元(Bitwise Logical Operators) C提供位元邏輯運算元如下,但這些邏輯運算元、無法作用於float或double: • & 位元AND • | 位元inclusive OR • ^ 位元exclusive OR • << 位元左移 • >> 位元右移 • ~ 1’ 補數
2-10 指定運算元(Assignment Operators) 與 運算式(Expression) 可設置通用式如下: • e1 op= e2 (其意為 e1 =( e1) op( e2)) • 其中e1、e2是運算式;op有 +、-、*、/、%、<<、>>、&、^、|;op= 為指定運算元。
2-11 條件運算式(Conditional Expressions) 條件運算式如下: • if (a > b) • z = a; • else • z = b;
2-12 運算優先次序(Precedence and Order of Evaluation) Precedence Operator 1 ( ) [ ] -> . 2 ! ~ ++ - - (type) * & sizeof 3 * / %4+ - 5 << >> 6 < <= > >= 7 == != 8 & 9 ^ 10 | 11 && 12 | | 13 ?: 14 = += -=. 15 ,
第三章程式流程控制(Control Flow) 對任何一種程式語言而言、程式流程控制(Control Flow)是安排運算式之執行次序、並使其順利完成執行。C之某些程式流程控制形態、我們已在前述章節範例見識一些,本章將再完全針對這個項目、作精僻解述。
3-1 敘述式(Statements) 與 區塊(Blocks) • 運算式、如 x = 0 或 i++ 或 printf(“abce\n”)等。若在每一式尾端加上分號,即改稱作敘述式、如 x = 0; 或 i++; 或 printf(“abce\n”);。在C、分號是敘述式之結束符號;相較於其他如Algol類語言、分號是分隔符號。 • 括弧{ }、是將一組宣告變數(Declarations)和敘述式(Statements)、組括在一起、稱之謂組合敘述式(Compound Statement)、或謂區塊(Block)。 • 括弧{ }、用於函數程式區塊;及用於 if、else、while、for 等區塊。分號不得置於括弧{ }之右端。
3-2 if-else 敘述式 if-else敘述式是用於做決策,其語法如下: • if (expression) • statement-1 • else • statement-2
3-3 else-if敘述式 語法結構如下: • if (expression) • statement • else if (expression) • statement • else if (expression) • statement • else • statement
3-4 switch 敘述式 • switch 敘述式、亦是一多重多層作決策之敘述式。 • 請參考範例。
3-5 while 迴圈(Loop) • while (expression) statement • 當條件expression被測試、若是“真(non-zero)”、將執行statement、然後再重覆測試expression。直到expression被測試為“非(zero)”為止。而執行指標(point execution)也移至statement的下一式。
3-5 for 迴圈(Loop) • for (expr1; expr2; expr3) statement • for-loop的此三expressions、expr1是初始條件; expr2是結束條件; expr3是變化運算式。在型態上、expr1和expr3可以是指定運算式(Assignments)、或是函數呼叫程式(Function calls); expr2是關係運算式(Relational expression)。三者於必要時、均可省略,但逗點 “;” 不可省略。
3-6 do-while迴圈(Loops) • do statement while (expression) • 主體敘述式(Statement)執行後,再作expression條件測試,測試如果是真(True)、則再一次執行主體敘述式(statement);測試如果是非(False)、則結束並跳離loop。
3-7 break之應用 • for-loop、while-loop經過頂端測試,do-while-loop經過底端測試,才得進入loop區塊。一旦進入後、須將區塊內敘述式執行完畢、才可離開。C提供break、可在區塊內、尚未將區塊內敘述式執行完畢前、跳離loop區塊。
3-8 continue 之應用 • continue之應用、與break類似,不同之處、break在跳離loop後、將不再回頭測試loop、不再進入loop;而continue在跳離loop後、立即回頭測試loop、進入loop。下列片斷程式、是以continue作有關正值(positive value)之事宜;跳過有關負值(negative value)之事宜。
3-9 goto 與 label 之應用 • C提供了無限橫衝直撞(Infinitely abusable)的goto敘述,以及導引標號label。使用goto、可到達任意指定之label位置,很是好用且方便,也因如此、可能會破壞程式之區塊架構。本書建議、非不得已、不輕易使用。
第四章函數程式 與 程式設計架構(Functions and Program Structure) • 將一個大程式、按其功能、分割成一些小程式,這些小程式即謂函數程式。當程式設計師設計程式時、對有些已寫好完成的函數程式、無須再展開寫入,可就其功能需要、撿取其函數名稱、置於程式中即可。 • 一個完整的程式、本就應是由呼叫其所需之函數程式、繫組而成的。而非是僅僅一個費神費力的龐大單一程式。C將一些有用的函數程式、先寫好置入程式庫(Library)中。程式設計師設計程式時、由Library中、撿取所需函數之名稱、置於程式中即可。例如我們熟悉的I/O(input/output)函數getchar、putchar;數學運算函數sin、cos、sqrt等皆是。
4-1 基礎架構 下列程式、為主程式呼叫一函數之基礎型態: • 1 main() • 2 { • 3 testsub(); • 4 } • 5 • 6 testsub() • 7 { • 8 printf("This is the string from testsub"); • 9 } • 列1~4 是主程式。 • 列3 由主程式呼叫函數testsub( )。 • 列6~9 是函數、由主程式列3 呼叫執行。
4-2 非數值(int)之函數回傳值(Functions Returning Non-Integers) • 本書到目前為止、我們都不曾對函數、作任何資料型態之宣告。並非函數不需作宣告、函數是應該作資料型態宣告的,祗是我們暫時作了省略。凡是函數省略了資料型態宣告、即以int執行。 • 本節將討論非數值(int)之函數回傳值。
4-3 函數之參數(Function Arguments) • 一般語言程式設計、有(1)参數傳值(call by value) (2)參數傳址(call by reference) (3)參數拷貝結果(copy restore) (4)参數傳名(call by name)。 • C語言則僅為 “参數傳值(call by value)”。當呼叫程式呼叫函數程式時、參數值僅可從呼叫程式傳遞至被呼叫之函數程式,不可從函數程式傳回至呼叫程式。
4-4 外部變數(External Variables) • 一個C語言程式、都會搭配一些外部項目(External Objects),通常這些外部項目、是變數(Variables)或是函數程式(Functions)。 • 外部(External)之相對者、是內部(Internal),亦即將參數(Arguments)與自動變數(Automatic Variables)定義於函數之內部。外部變數(External Variables)定義於函數之外部、且提供給多處函數程式使用,即謂全域(Global)變數。至於函數程式、祗有外部函數、並無內部函數。
4-5 區域規則(Scope Rules) • 因為有了函數與外部變數、讓C程式可不必限制在同一時間內、作編譯(be compiled),也不必要放置在同一檔案(File)內。當時之程式、可將先前已編譯完成之程式碼、或別處檔案之程式碼、轉載過來、共同完成當時程式預期要求之結果。 • 每一區域(Scope)、可以一個名稱(Name)定義之。對宣告在一個函數內的自動變數(Automatic Variable)來說、該函數的名稱、即是其區域,這些變數、與其他別的區域無關係。同理、在這區域函數名稱內之參數(Arguments)也是一樣。
4-6 靜態變數(Static Variables) • 在自動變數(Automatic Variables)、外部變數(External Variables)之外、第三種變數、是謂靜態變數(Static Variables)。靜態變數可分為兩種、內部靜態變數(Internal Static Variables)與外部靜態變數(External Static Variables)。 • 內部靜態變數、與內部變數(Internal Variables)一樣、宣告於函數內,僅供該函數使用,而不同之處、是並不隨函數之存在而存在,是一直獨立存在的。
4-7 暫存器變數(Register Variables) • 暫存器(Register)是一種最快速存取的記憶體,通常罝於CPU內,且數量有限。 • 當要處理資料時、資料及運算元將被拮取(Fetch)至CPU、並置於功能暫存器內加以處理,處理結束後、暫存器再換進另一組待處理的資料及運算元,若某一資料的使用率非常高、其編譯程式(Compile)會考量該資料不必從暫存器換出,以節省常常換進換出所付的代價。
4-8 區塊架構(Block Structure) • C並非是一個完完全全的區塊架構(Block Structure)語言。變數(Variables)可在區塊內作定義(Be defined)或作宣告(Be declared); • 函數却有所不同、僅可在區塊內作宣告(Be declared)、而不可作定義(Be defined)。
4-9 變數初值之設定(Initialization) • 當變數未作初值設定時、外部變數(External Variables)與靜態變數(Static Variables)將自動被設定0為初值; • 而自動變數(Automatic Variables)與暫存器變數(Register Variables)則無初值設定。
4-10 遞迴(Recursion) • C之函數、可直接或間接的自己呼叫自己、此謂遞迴(Recursion)。 • 當函數自己呼叫自己時、將會不停的呼叫下去。因此、遞迴函數至少有兩個基本設計,一是停止機制區;一是呼叫區。
4-11 前罝處理程式(Preprocessor) 在程式設計上、C提供了程式延伸方法: • (1)#include為延伸使用曾經完成的程式檔案; • (2)#define為簡單巨集代入。因寫在檔案之前端、全域性(Globe)的供同一檔案內之各函數使用。
第五章指標 與 陣列(Pointers and Arrays) • 指標(Pointer)是一種變數、是另外一個變數的地址(the address of another variable)。 • 在指標之使用上、C語言特別靈巧、往往能因此寫出令人難以相信的絕佳程式風格。也往往會產生一些不易了解的困擾。
5-1 指標與地址(Pointers and Addresses) • 因指標(Pointer)含著另一個資料的地址,故由指標、可間接(Indirectly)存取該資料。對初學者來言、指標型態往往不易了解。 • 設x 為變數、亦即記憶體名稱;6 為記憶體的內容;pi 為指標。當指標指向變數之記憶體時,指標內容為該記憶體變數之地址(address),因此、經由該指標可間接存取(Access)該記憶體。