C Primer Plus (第6版) 讀書筆記_Chapter 1

第 1 章 初識 C 語言
 
■ C 的歷史和特性
■ 編寫程序的步驟
■ 編譯器和連接器的一些知識
■ C 標準
 
 
1.1  C 語言的起源
 
    1972年,貝爾實驗室的 丹尼斯 • 裏奇(Dennis Ritch)肯 • 湯普遜(Ken Thompson)在開發 UNIX 操做系統 時設計了 C 語言。然而,C 語言不徹底是裏奇突發奇想而來,他是在 B 語言(湯普遜發明)的基礎上進行設計。至於 B 語言的起源,那是另外一個故事。C 語言設計的初衷是將其做爲程序員使用的一種編程工具,所以,其主要目標是成爲有用的語言。
    
1.2 C 語言的特性 
1) C 語言的設計理念讓用戶能輕鬆地完成 自頂向下 的規劃 結構化編程 模塊化設計
 
2)  C 是  高效 的語言。 C 代碼緊湊 運行速度很快C 語言具備一般是彙編語言才具備的  微調控制能力能夠根據具體狀況微調程序以得到最大運行速度或最有效地使用內存。
3) C 是 可移植 的語言。C 語言是可移植方面的佼佼者。從 8 位微處理器到克雷超級計算機,許多計算機體系結構均可以使用 C 編譯器(C編譯器是把 C 代碼轉換成計算機內部指令的程序)。可是要注意,程序中針對特殊硬件設備(如,顯示監視器)或操做系統特殊功能(如,Windows 8 或 OS X)編寫的部分,一般是不可移植的。
4) C 語言  功能強大且靈活
5) C 語言是爲了  知足程序員的需求 而設計的,程序員利用 C 能夠訪問硬件、操控內存中的位
6) 大多數 C 實現都有一個大型的  ,包含衆多 有用的 C 函數
7) C 缺點: C 語言使用指針而涉及指針的編程錯誤每每難以察覺。有句話說的好:想擁有自由就必須時刻保持警戒。
 
1.3 C 語言的應用範圍
    早在 20 世紀 80 年代, C 語言 就已經成爲小型計算機(UNIX系統)使用的 主流語言。從那之後,C 語言的應用範圍擴展到 微型機(我的計算機)和大型機(龐然大物)。許多軟件公司都用 C 語言來開發文字處理程序、電子表格、編譯器和其餘產品。由於用 C 語言編寫的程序緊湊而高效。更重要的是,C 程序很方便修改,並且移植到新型號的計算機中也沒什麼問題。
    愈來愈多的計算機用戶已轉而求助 C 語言解決一些安全問題。
    20 世紀 90 年代,許多軟件公司開始改用 C++ 來開發大型的編程項目。 C++ 在 C 語言的基礎上嫁接了面向對象編程工具(面向對象編程是一門哲學,它經過對語言建模來適應問題,而不是對問題建模以適應語言)。C++ 幾乎是 C 的超集,這意味着任何 C 程序差很少就是一個 C++ 程序。
 
    雖然這些年來 C++ 和 JAVA 很是流行,可是 C 語言還是軟件業中的核心技能。特別是, C 語言已成爲嵌入式系統編程的流行語言。C 語言是開發操做系統的卓越語言。
 
1.4 計算機能作什麼
    中央處理單元(CPU)承擔絕大部分的運算工做。隨機存取內存(RAM)是存儲程序和文件的工做區;而永久內存存儲設備(過去通常指機械硬盤,如今還包括固態硬盤)即便在關閉計算機後,也不會丟失以前儲存的程序和文件。另外,還有各類外圍設備(如,鍵盤、鼠標、觸摸屏、監視器)提供人與計算機之間的交互。
    CPU 的工做很是簡單,它從內存中獲取並執行一條指令,而後再從內存中獲取並執行下一條指令,諸如此類(一個吉赫茲的CPU一秒鐘能重複這樣的操做大約十億次,所以,CPU 能以驚人的速度從事枯燥的工做)。CPU 有本身的小工做區——若干個寄存器組成,每一個寄存器均可以儲存一個數字。一個寄存器儲存下一條指令的內存地址,CPU 使用該地址來獲取和更新下一條指令。在獲取指令後,CPU 在另外一個寄存器中儲存該指令,並更新第 1 個寄存器儲存下一條指令的地址。CPU 能理解的指令有限(這些指令的集合叫做 指令集)。並且,這些指令至關具體,其中的許多指令都是用於請求計算機把一個數字從一個位置移動到另外一個位置。例如,從內存移動到寄存器。
 
下面介紹兩個有趣的知識:
 
1) 其一,儲存在計算機中的全部內容都是數字。
    計算機以數字形式儲存數字和字符(如,在文本文檔中使用的字母)。每一個字符都有一個數字碼。計算機載入寄存器的指令也以數字形式儲存,指令集中的每條指令都有一個數字碼。
2) 其二,計算機程序最終必須以數字指令碼(即,機器語言)來表示。
 
簡而言之,計算機的工做原理是:若是但願計算機作某些事,就必須爲其提供特殊的指令列表(程序),確切地告訴計算機要作的事以及如何作。你必須用計算機能直接明白的語言(機器語言)建立程序。
 
1.5 高級計算機語言和編譯器
    高級編程語言(如,C)以多種方式簡化了編程工做。首先,沒必要用數字碼表示指令;其次,使用的指令更貼近你如何想這個問題,而不是相似計算機那樣繁瑣的步驟。使用高級編程語言,能夠在更抽象的層面表達你的想法,不用考慮 CPU 在完成任務時具體須要哪些步驟。
    編譯器是把 高級語言程序 翻譯成 計算機能理解的機器語言指令集 的程序。程序員進行高級思惟活動,而編譯器則負責處理冗長乏味的細節工做。
    編譯器還有一個優點。使用合適的編譯器或編譯器集,即可把一種高級語言程序轉換成供各類不一樣類型 CPU 使用的機器語言程序。
    簡而言之,高級語言(如 C、Java、Pascal )以更抽象的方式描述行爲,不受限於特定 CPU 或指令集。並且,高級語言簡單易學,用高級語言編程比用機器語言編程容易得多。
 
 
1.6 語言標準
 
    C 語言發展之初,並無所謂的 C 標準。1987 年,布萊恩 • 柯林漢(Brian Kernighan)和 丹尼斯 • 裏奇(Dennis Ritchie)合著的 The C Programming Language (《C 語言程序設計》) 第 1 版是公認的 C 標準,一般稱之爲 K&R C 或 經典 C 。特別是,該書的附錄中 「C 語言參考手冊」 已成爲實現 C 的指導標準。例如,編譯器都聲稱提供完整的 K&R 實現。雖然這本書中的附錄定義了 C 語言,但卻沒有定義 C 庫。與大多數語言不一樣的是, C 語言比其餘語言更依賴庫,所以須要一個標準庫。實際上,因爲缺少官方標準,UNIX 實現提供的庫已成爲了標準庫。
 
  1.6.1 第 1 個 ANSI/ISO C 標準
    美國國家標準協會(ANSI)於 1983 年組建了一個委員會(X3J11),開發了一套新標準,並於 1989 年正式公佈。該標準(ANSI C)定義了 C 語言和 C 標準庫。國際標準化組織於 1990 年採用了這套 C 標準(ISO C)。ISO C 和 ANSI C 是徹底相同的標準。ANSI / ISO 標準的最終版本一般叫做 C89 (由於 ANSI 於 1989 年批准該標準)或 C90 (由於 ISO 於 1990 年批准該標準)。另外,因爲 ANSI 先公佈 C 標準,所以業界人士一般使用 ANSI C。
    在該委員會制定的指導原則中,最有趣的多是: 保持 C 的精神。委員會在表述這一精神列出了一下幾點:
■ 信任程序員;
■ 不要妨礙程序員作須要作的事;
■ 保持語言精煉簡單;
■ 只提供一種方法執行一項操做;
■ 讓程序運行更快,即便不能保證其可移植性。
    在最後一點上,標準委員會的用意是:做爲實現,應該針對目標計算機來定義最合適的某特定操做,而不是強加一個抽象、統一的定義。在學習 C 語言過程當中,許多方面都反映了這一哲學思想。
 
1.6.2 C99 標準
    1994 年,ANSI / ISO 聯合委員會(C9X委員會)開始修訂 C 標準,最終發佈了 C99 標準。該委員會遵循了最初 C90 標準的原則,包括保持語言的精煉簡單。委員會的用意不是在 C 語言中添加新特性,而是爲了達到新的目標。第 1 個目標是,支持國際化編程。例如,提供多種方法處理國際字符集。第 2 個目標是,「調整現有實踐致力於解決明顯的缺陷」。所以,在遇到須要將 C 移至 64 位處理器時,委員會根據現實生活中處理問題的經驗來添加標準。第 3 個目標是,爲適應科學和工程項目中的關鍵數值計算,提升 C 的適應性,讓 C 比 FORTRAN 更有競爭力。
    這 3 點 (國際化、彌補缺陷 和 提升計算的實用性)是主要的修訂目標。在其餘方面的改變則更爲保守,例如,儘可能與 C90、C++ 兼容,讓語言在概念上保持簡單。用委員會的話說:「.……委員會很滿意讓 C++ 成爲 大型、功能強大的語言 」。
    C99 的修訂保留了 C 語言的精髓, C 還是一門簡潔高效的語言。本書指出了許多 C99 修改的地方。雖然該標準已發佈了很長時間,但並不是全部的編譯器都徹底實現 C99 的全部改動。所以,你可能發現 C99 的一些改動在本身的系統中不可用,或者只有改變編譯器的設置纔可用。
 
1.6.3 C11 標準
    維護標準任重道遠。標準委員會在 2007 年承諾 C 標準的下一個版本是 C1X,2011年終於發佈了 C11 標準。這次,委員會提出了一些新的指導原則。出於對當前編程安全的擔心,不那麼強調 「信任程序員」 目標了。並且,供應商並未像對 C90 那樣很好地接受和支持 C99 。這使得 C99 的一些特性成爲 C11 的可選項。由於委員會認爲,不該要求服務小型機市場的供應商支持其目標環境中用不到的特性。另外須要強調的是,修訂標準的緣由不是由於原標準不能用,而是須要跟進新的技術。例如,新標準添加了可選項支持當前使用多處理器的計算機。
 
 
1.7 使用 C 語言的 7 個步驟
    C 是編譯型語言。若是以前使用過 編譯型語言(如,Pascal 或 FORTRAN),就會很熟悉組建 C 程序的幾個基本步驟。可是,若是之前使用的是 解釋型語言(如,BASIC)面向圖形界面語言(如, Visual Basic),或者甚至沒接觸過任何編程語言,就有必要學習如何編譯。別擔憂,這並不複雜。首先,爲了讓讀者對編程有大概的瞭解,咱們把編寫 C 程序的過程分解成 7 個步驟。注意,這是理想狀態。在實際的使用過程當中,尤爲是在較大型的項目中,可能要作一些重複的工做,根據下一個步驟的狀況來調整或改進上一個步驟。
 
1) 定義程序的目標
2) 設計程序
3) 編寫代碼
4) 編譯
5) 運行程序
6)測試和調試程序
7) 維護和修改程序
 
1.7.1 第 1 步:定義程序的目標
    想要程序去作什麼首先本身要明確本身想作什麼,思考你的程序須要哪些信息,要進行哪些計算和控制,以及程序應該要報告什麼信息。在這一步驟中,不涉及具體的計算機語言,應該用通常術語來描述問題。
 
1.7.2 第 2 步:設計程序
    對程序應該完成什麼任務有概念性的認識後,就應該考慮如何用程序來完成它。例如,用戶界面應該是怎樣的?如何組織程序?目標用戶是?準備花多長時間來完成這個程序?
    除此以外,還要決定在程序(還多是輔助文件)中如何表示數據,以及用什麼方法處理數據。學習 C 語言之初,遇到的問題都很簡單,沒什麼可選的。可是,隨着要處理的狀況愈來愈複雜,須要決策和考慮的方面也愈來愈多,一般,選擇一個合適的方式表示信息能夠更容易地設計程序和處理數據。
    再次強調,應該用通常術語來描述問題,而不是用具體的代碼。可是,你的某些決策可能取決於語言的特性。例如,在數據表示方面,C 的程序員就比 Pascal 的程序員有更多選擇。
 
 
1.7.3  第 3 步:編寫代碼
    設計好程序後,就能夠編寫代碼來實現它。也就是說,把你設計的程序翻譯成 C 語言。這裏是真正須要使用 C 語言的地方。能夠把思路寫在紙上,可是最終仍是要把代碼輸入計算機。這個過程的機制取決於編程環境,咱們稍後會詳細介紹編程環境。通常而言,使用 文本編輯器 建立 源代碼 文件。該文件中內容就是你翻譯的 C 語言代碼。程序清單 1.1 是一個 C 源代碼的示例。
 
 
 1 #include <stdio.h>
 2 int main(void)
 3 {
 4     int dogs;
 5     
 6     printf("How many dogs do you have?\n");
 7     scanf_s("%d", &dogs);   
 8     // 原文爲 scanf("%d", &dogs),vs2015環境下爲 scanf_s("%d", &dogs)
 9     // 要使用 scanf("%d", &dogs); 的話 
10     // 請關閉項目屬性中的 C/C++ -> 常規 -> SDL檢查 -> 否
11     printf("So you have %d dog(s)!\n");
12     
13     return 0;
14 }
15 /*********************************************************
16 輸出結果爲:
17 -----------------------------------------------
18 How dogs do you have?
19 5
20 So you have 5 dog(s)!
21 -----------------------------------------------
22 **********************************************************/

 

 
 
        在這一步驟中,應該給本身編寫的程序添加文字註釋。最簡單的方式是使用 C 的註釋工具在源代碼中加入對代碼的解釋。
 
 
1.7.4 第 4 步:編譯
    前面介紹過,編譯器是把源代碼轉換成可執行代碼的程序。可執行代碼是用計算機的機器語言表示的代碼。這種語言由數字碼表示的指令組成。如前所述,不一樣的計算機使用不一樣的機器語言方案。C 編譯器負責把 C 代碼翻譯成特定的機器語言。此外,C 編譯器還將源代碼與 C 庫(庫中包含大量的標準函數供用戶使用,如 printf() 和 scanf() )的代碼合併成最終的程序(更精確地說,應該是由一個被稱爲 連接器 的程序來連接庫函數,可是在大多數系統中,編譯器運行連接器)。其結果是,生成一個用戶能夠運行的可執行文件,其中包含着計算機能理解的代碼。
    編譯器還會檢查 C 語言程序是否有效。若是 C 編譯器發現錯誤,就不生成可執行文件並報錯。理解特定編譯器報告的錯誤或警告信息是程序員要掌握的另外一項技能。
 
1.7.5 第 5 步:運行程序
    傳統上,可執行文件是可運行的程序。
 
1.7.6 第 6 步:測試和調試程序
    接下來,應該檢查程序是否按照你所設計的思路運行。 你會發現你的程序中有一些錯誤,計算機行話叫做 bug。查找並修復程序錯誤的過程叫 調試。
 
1.7.7 第 7 步:維護和修改代碼
    建立完程序後,你發現程序有錯,或者想擴展程序的用途,這時就要修改程序。
 
1.8 編程機制
    用 C 語言編寫程序時,編寫的內容被儲存在文本文件中,該文件被稱爲 源代碼文件(source code file)。大部分 C 系統,包括以前提到的,都要求文件名以 .c 結尾(如,wordcount.c 和 budget.c)。在文件名中,點號 (.) 前面的部分稱爲 基本名(basename),點號後面的部分稱爲 擴展名(extension)。所以,budget 是基本名,c 是擴展名。基本名與擴展名的組合(budget.c)就是文件名。文件名應該知足特定計算機操做系統的特殊要求。例如,MS-DOS 是 IBM PC 及其兼容機的操做系統,比較老舊,它要求基本名不能超過 8 個字符。所以,剛纔提到的 文件名 wordcount.c 就是無效的 DOS 文件名。有些 UNIX 系統限制整個文件名(包括擴展名)不超過 14 個字符,而有些 UNIX 系統則容許使用更長的文件名,最多 255 個字符。Linux、Windows 和 Macintosh OS 都容許使用長文件名。
    接下來,咱們來看一下具體的應用,假設有一個名爲 concrete.c 的源文件,其中的 C 源代碼如程序清單 1.2 所示
 
 
 1 #include <stdio.h>
 2 int main(void)
 3 {
 4     printf("Concrete contains gravel and cement.\n"):
 5     //      混泥土    包含    沙礫、碎石     水泥
 6     
 7     return 0;
 8  
 9 }
10  
11 /*********************************************
12 輸出結果:
13 ---------------------------------------------
14 Concrete contains gravel and cement.
15 ---------------------------------------------
16 **********************************************/
 
 
 
1.8.1 目標代碼文件、可執行文件和庫
    C 編程的基本策略是,用程序把源代碼文件轉換爲可執行文件(其中包含可直接運行的機器語言代碼)。典型的 C 實現經過編譯和連接兩個步驟來完成這一過程。編譯器把源代碼轉換成中間代碼,連接器把中間代碼和其餘代碼合併,並生成可執行文件。
C 使用這種分而治之的方法方便對程序進行模塊化,能夠獨立編譯單獨的模塊,稍後再用連接器合併已編譯的模塊。經過這種方式,若是隻要更改某個模塊,沒必要所以從新編譯其餘模塊。另外,連接器還將你編寫的程序和預編譯的庫代碼合併。
    中間文件有多種形式。咱們在這裏描述的是最廣泛的一種形式,即把源代碼轉換爲機器語言代碼,並把結果放在目標代碼文件(或簡稱目標文件)中(這裏假設源代碼只有一個文件)。雖然目標文件中包含機器語言代碼,可是並不能直接運行該文件。由於目標文件中儲存的是編譯器翻譯的源代碼,這還不是一個完整的程序。
    目標代碼文件缺失 啓動代碼(startup code)。啓動代碼充當着程序和操做系統之間的接口。例如,能夠在 MS Windows 或 Linux 系統下運行 IBM PC 兼容機。這兩種狀況所使用的硬件相同,因此目標代碼相同,可是 Windows 和 Linux 所需的啓動代碼不一樣。由於這些系統處理程序的方式不一樣。
    目標代碼還缺乏 庫函數。幾乎全部的 C 程序都要使用 C 標準庫中的函數。例如,concrete.c 中就是用了 printf() 函數。目標代碼文件並不包含該函數的代碼,它只包含了使用 printf() 函數的指令。printf() 函數真正的代碼儲存在另外一個被稱爲 庫 的文件中。庫文件中有許多函數的目標代碼。
    連接器的做用是,把你編寫的目標代碼、系統的標準啓動代碼 和 庫代碼這 3 部分合併成一個文件,便可執行文件。對於庫代碼,連接器只會把程序中要用到的庫函數代碼提取出來。
 
 
    簡而言之,目標文件和可執行文件都是由機器語言指令組成的。然而,目標文件中只包含編譯器爲你編寫的代碼翻譯的機器語言代碼,可執行文件中還包含你編寫的程序中使用的庫函數和啓動代碼的機器代碼。
    在有些系統中,必須分別運行編譯程序和連接程序,而在另外一些系統中,編譯器會自動啓動連接器,用戶只須要給出編譯命令便可。
 
1.8.2 UNIX 系統
    1. 在 UNIX 系統上編輯
    UNIX C 沒有本身的編輯器,可是可使用通用的 UNIX 編輯器,如 emacs、jove、vi 或 X Window System 文本編輯器。
    做爲程序員,要負責輸入正確的程序和爲儲存該程序的文件起一個合適的文件名。如前所述,文件名應該以 .c 結尾。注意,UNIX 區分大小寫。所以,budget.c、BUDGET.c 和 Budget.c 是 3 個不一樣但都有效的 C 源文件名。可是,BUDGET.C 是無效文件名,由於該名稱的擴展名使用了大寫  C 而不是小寫 c 。
    假設咱們在 vi 編譯器中編寫了下面的程序,並將其儲存在 inform.c 文件中:
 
1 #include <stdio.h>
2 int main(void)
3 {
4     printf("A .c is used to end a C program filename.\n");
5     return 0;
6 }

 

       以上文本就是源代碼,inform.c 是源文件。注意,源文件是整個編譯過程的開始,而不是結束。
 
    2. 在 UNIX 系統上編譯
    之前,UNIX C 編譯器要調用語言定義的 cc 命令。可是,它沒有跟上標準發展的腳步,已經退出了歷史舞臺。 可是,UNIX 系統提供的 C 編譯器一般來自一些其餘源,而後以 cc 命令做爲編譯器的別名。所以,雖然在不一樣的系統中會調用不一樣的編譯器,可是用戶仍能夠繼續使用相同的命令。
    編譯 inform.c,要輸入如下命令:
    cc inform.c 
    幾秒鐘後,會返回 UNIX 的提示,告訴用戶任務已完成。若是程序編寫錯誤,你可能會看到警告或錯誤消息,但咱們先假設編寫的程序徹底正確(若是編譯器報告 void 錯誤,說明你的系統未更新成 ANSI C 編譯器,只需刪除 void 便可)。 若是使用 ls 命令列出文件,會發現有一個 a.out 文件。該文件是包含已翻譯(或已編譯)程序的可執行文件。要運行該文件,只需輸入:
    a.out
    輸出內容以下:
    A .c is used to end a C program filename.
    若是要儲存可執行文件(a.out),應該把它重命名。不然,該文件會被下一次編譯程序時生成的新 a.out 文件替換。
    如何處理目標代碼?C 編譯器會建立一個與源代碼基本名相同的目標代碼文件,可是其擴展名是 .o 。在該例中,目標代碼文件是 inform.o。然而,卻找不到這個文件,由於一旦連接器生成了完整的可執行程序,就會將其刪除。若是原始程序有多個源代碼文件,則保留目標代碼文件。學到後面多文件程序時,你會明白到這樣作的好處。
 
1.8.3 GNU 編譯器集合和 LLVM 項目
    GNU 項目始於 1987 年,是一個開發大量免費 UNIX 軟件的集合(GNU 的意思是 「GNU‘s Not UNIX 」,即 GNU 不是 UNIX)。GNU 編譯器集合(也被稱爲 GCC,其中包含 GCC C 編譯器)是該項目的產品之一。GCC 在一個指導委員會的帶領下,持續不斷地開發,它的 C 編譯器緊跟 C 標準的改動。GCC 有各類版本以適應不一樣的硬件平臺和操做系統,包括 UNIX、Linux 和 Windows。用 gcc 命令即可調用 GCC C 編譯器。許多使用 gcc 的系統都用 cc 做爲 gcc 的別名。
    LLVM 項目成爲 cc 的另外一個代替品。該項目是與編譯器相關的開源軟件集合,始於伊利諾伊大學的 2000 份研究項目。它的 Clang 編譯器處理 C 代碼,能夠經過 clang 調用。有多種版本供不一樣的平臺使用,包括 Linux。2012 年,Clang 成爲 FreeBSD 的默認 C 編譯器。Clang 也對最新的 C 標準支持得很好。
    GNU 和 LLVM 均可以使用 -v 選項來顯示版本信息,所以各系統都使用 cc 別名來代替 gcc 或 clang 命令。如下組合:
    cc -v
    顯示你所使用的編譯器及其版本。
    gcc 和 clang 命令均可以根據不一樣的版本選擇運行時選項來調用不一樣 C 標準。
    gcc -std=c99    inform.c 【GCC 最基本的用法是:gcc [options] [filename], 其中 options 是所需的參數,filename 是文件名】
    gcc -std=c1x    inform.c
    gcc -std=c11    inform.c
    第 1 行調用 C99 標準,第 2 行調用 GCC 接受 C11 以前的草案標準,第 3 行調用 GCC 接受的 C11 標準版本。Clang 編譯器在這一點上用法與 GCC 相同。
 
1.8.4 Linux 系統
    Linux 是一個開源、流行、相似於 UNIX 的操做系統,可在不一樣平臺(包括 PC 和 Mac)上運行。在 Linux 中準備 C 程序與在 UNIX 系統中幾乎同樣,不一樣的是要使用 GNU 提供的 GCC 公共域 C 編譯器。編譯命令相似於:
    gcc inform.c
    注意,在安裝 Linux 時,可選擇是否安裝 GCC。若是以前沒有安裝 GCC,則必須安裝。一般,安裝過程會將 cc 做爲 gcc 的別名,所以能夠在命令行中使用 cc 來代替 gcc。
    欲詳細瞭解 GCC 和最新發布的版本, 請訪問 http://www.gnu.org/software/gcc/index.html。
 
1.8.5 PC 的命令行編譯器
 
    C 編譯器不是標準 Windows 軟件包的一部分,所以須要從別處獲取並安裝 C 編譯器。能夠從互聯網免費下載 Cygwin 和 MinGW,這樣即可在 PC 上經過命令行使用 GCC 編譯器。Cygwin 在本身的視窗運行。模仿 Linux 命令行環境,有一行命令提示。MinGW 在 Windows 的命令提示模式中運行。這和 GCC 的最新版本同樣,支持 C99 和 C11 最新的一些功能。Borland 的 C++ 編譯器 5.5 也能夠免費下載,支持 C90。
    源代碼文件應該是 文本文件,而不是字處理器文件(字處理器文件包含許多額外的信息,如字體和格式等。)所以,要使用文本編輯器(如,Windows Notepad)來編輯源代碼。若是使用字處理器,要以文本模式另存文件。源代碼文件的擴展名應該是 .c 。一些字處理器會爲文本文件自動添加 .txt 擴展名。若是出現這種狀況,要更改文件名,把 txt 替換成 c 。
    一般,C 編譯器生成的中間目標代碼文件的擴展名是 .obj (也多是其餘擴展名)。與 UNIX 編譯器不一樣,這些編譯器在完成編譯後一般不會刪除這些中間文件。有些編譯器生成帶 .asm 擴展名的彙編語言文件,而有些編譯器則使用本身特有的格式。
    一些編譯器在編譯後會自動運行連接器,另外一些要求用戶手動運行連接器。在可執行文件中連接的結果是,在原始的源代碼基本名後面加上 .exe 擴展名。例如,編譯和連接 concrete.c 源代碼文件,生成的是 concrete.exe 文件。能夠在命令行輸入基本名來運行該程序:
    C>concrete
 
1.8.6 集成開發環境(Windows)
    許多供應商(包括微軟、Embarcadero、Digital Mars)都提供 Windows 下的集成開發環境,或稱爲 IDE (目前,大多數 IDE 都是 C 和 C++ 結合的編譯器)。能夠免費下載的 IDE 有 Microsoft Visual Studio Express 和 Pelles C。利用集成開發環境能夠快速開發 C 程序。關鍵是,這些 IDE 都內置了用於編寫 C 程序的編輯器。這類集成開發環境都提供了各類菜單(如,命名,保存源代碼文件、編譯程序、運行程序等),用戶不用離開 IDE 就能順利編寫、編譯和運行程序。若是編譯器發現錯誤,會返回編輯器中,標出有錯誤的行號,並簡單描述狀況。
    初次接觸 Windows IDE 可能望而生畏,由於它提供了多種目標(target),即運行程序的多種環境。例如, IDE 提供了 32位 Windows 程序、64 位 Windows 程序、動態連接庫文件(DLL)等。許多目標都涉及 Windows 圖形界面。要管理這些(及其餘)選擇,一般要先建立一個項目(project),以便稍後在其中添加待使用的源代碼文件名。不一樣的產品具體步驟不一樣。通常而言,首先使用【文件】菜單或【項目】菜單建立一個項目。選擇正確的項目形式很是重要。本書中的例子都是通常示例,針對在簡單的命令行環境中運行而設計。Windows IDE 提供多種選擇以知足用戶的不一樣要求。例如,Microsoft Visual studio 提供 【Win32控制檯應用程序】選項。對於其餘系統,查找一個諸如【DOS EXE】、【Console】或 【Character Mode】的可執行選項。選擇這些模式後,將在一個類控制檯窗口中運行可執行程序。選擇好正確的項目類型後,使用 IDE 的菜單打開一個新的源代碼文件。對於大多數產品而言,使用【文件】菜單就能完成。你可能須要其餘步驟將源文件添加到項目中。
    一般,Windows IDE 便可處理 C 也能夠處理 C++,所以要指定待處理的程序是 C 仍是 C++ 。有些產品用項目類型區分二者, 有些產品(如,Microsoft Visual C++)用 .c 文件擴展名來指明使用 C  而不是 C++。
    你可能會遇到一個問題: 在程序執行完畢後,執行程序的窗口當即消失。若是不但願出現這種狀況,可讓程序暫停,直到按下 Enter 鍵,窗口才消失。要實現這種效果,能夠在程序的最後(return 這行代碼以前) 添加下面一行代碼:
    getchar();
    該行讀取一次鍵的按下,因此程序在用戶按下 Enter 鍵以前會暫停。有時根據程序的須要,可能還須要一個擊鍵等待。這種狀況下,必須用兩次 getchar():
    getchar();
    gerchar();
    例如,程序在最後提示用戶輸入體重。用戶鍵入體重後,按下 Enter 鍵以輸入數據。程序將讀取體重,第 1 個 getchar() 讀取 Enter 鍵,第 2 個 getchar() 會致使程序暫停,直至用戶再次按下 Enter 鍵。
 
Microsoft Visual Studio 和 C 標準
    在 Windows 軟件開發中,Microsoft Visual Studio 及其免費版本 Microsoft Visual Studio Express 都久負盛名,它們與 C 標準的關係也很重要。然而, 微軟鼓勵程序員從 C 轉向 C++ 和 C#。雖然 Visual Studio 支持 C89/C90,可是到目前爲止,它只選擇性地支持那些在 C++ 新特性中能找到的 C 標準(如, long long 類型)。並且,自 2012 版本起,Visual Studio 再也不把 C 做爲項目類型的選項,儘管如此,本書中的絕大多數程序仍可用 Visual Studio 來編譯。在新建項目時,選擇 C++ 選項,而後選擇【Win32 控制檯應用程序】,在應用設置中選擇【空項目】。幾乎全部的 C 程序都能與 C++ 程序兼容。因此,本書中的絕大多數 C 程序均可做爲 C++ 程序運行。或者,在選擇 C++ 選項後,將默認的源文件擴展名 .cpp 替換成 .c ,編譯器便會使用 C 語言的規則代替 C++。
 
1.8.7 Windows / Linux
    許多 Linux 發行版均可以安裝在 Windows 系統中,以建立雙系統。一些存儲器會爲 Linux 系統預留空間,以即可以啓動 Windows 或 Linux 。能夠在 Windows 系統中運行 Linux 程序,或在 Linux 系統中運行 Windows 程序。不能經過 Windows 系統訪問 Linux 文件,可是能夠經過 Linux 系統訪問 Window 文檔。
 
1.8.8 Macintosh 中的 C
     目前,蘋果免費提供 Xcode 開發系統下載。它容許用戶選擇不一樣的編程語言,包括 C 語言。
    Xcode 憑藉可處理多種編程語言的能力,可用於多平臺,開發超大型的項目。在 Xcode 4.6 中,經過【File】菜單選擇【New Project】,而後選擇【OS X Application Command Line Tool】,接着輸入產品名並選擇 C 類型。 Xcode 使用 Clang 或 GCC C 編譯器來編譯 C 代碼,它之前默認使用 GCC,可是如今默認使用 Clang。
    UNIX 系統內置 Mac OS X,終端工具打開的窗口是讓用戶在 UNIX 命令行環境中運行程序。蘋果在標準軟件包中不提供命令行編譯器,可是,若是下載了 Xcode ,還能夠下載可選的命令行工具,這樣就可使用 Clang 和 gcc 命令在命令行模式中編譯。
 
............
 
1.11 本章小結
    C 是強大而簡潔的編程語言。它之因此流行,在於自身提供大量的實用編程工具,能很好地控制硬件。並且,與大多數其餘程序相比,C 程序更容易從一個系統移植到另外一個系統。
    C 是編譯型語言。C 編譯器 和 連接器 是把 C 語言源代碼 轉換成 可執行代碼 的程序。
 
 
 

 

  複習題html

    1. 對編程而言,可移植性意味着什麼?git

      完美的可移植程序是,其源代碼無需修改就能在不一樣的計算機系統中成功編譯的程序。程序員

    2. 解釋源代碼文件、目標代碼文件和可執行文件有什麼區別?編程

      源代碼文件包含程序員使用的任何編程語言所寫的代碼。目標代碼文件包含機器語言代碼,它不是完整的程序代碼。windows

    可執行文件包含組成可執行程序的完整機器語言代碼。安全

    3. 編程的7個主要步驟是什麼?編程語言

      (1)定義程序目標;(2)設計程序;(3)編寫程序;(4)編譯程序;(5)運行程序;(6)測試和調試程序;(7)維護和修改程序編輯器

    4. 編譯器的任務是什麼?模塊化

      編譯器吧源代碼(如,用C語言編寫的代碼)翻譯成等價的機器語言代碼(也叫做目標代碼)。函數

    5. 連接器的任務是什麼?

      連接器把編譯器翻譯好的源代碼以及庫代碼和啓動代碼組合起來,生成一個可執行程序。

 

  編程練習

    你剛被MacroMuscle有限公司聘用。該公司準備進入歐洲市場,須要一個把英寸單位轉換爲釐米單位(1英寸=2.54釐米)的程序。

  該程序要提示用戶輸入英寸值。你的任務是定義程序目標和設計程序(編程過程的第1步和第2步)。

 

 1 /*************************************************************
 2 編程練習
 3 1.    你剛被MacroMuscle有限公司聘用。該公司準備進入歐洲市場,
 4 須要一個吧英寸單位轉換爲釐米單位(1英寸 = 2.54釐米)的程序。
 5 該程序要提示用戶輸入英寸值。你的任務是定義程序目標和設計程
 6 序(編程過程的第1步和第2步)。
 7 
 8 1) 定義程序目標
 9 程序的目標 :須要將 英寸 單位轉換爲 釐米 單位
10 程序須要提示用戶輸入英寸的數據、英寸轉換爲釐米的換算公式 顯示換算後的結果
11 2)設計程序
12 程序的界面 直接用 printf() 打印 提示語便可 提示用戶輸入英寸數據
13 1 英寸 = 2.54 釐米 (換算公式)
14 根據換算公式可知 程序中應使用 float 或者 double 的數據類型的數據 以確保相應的精度
15 程序應該當用戶輸入英寸數據後 根據換算公式 將其處理轉換成 釐米爲單位後 經過 printf()函數將結果打印輸出
16 **************************************************************/
17 
18 #include <stdio.h>
19 
20 int  main(void) 
21 {
22     float fInch = 0.0f;        // 英寸
23     float fCm = 0.0f;        // 釐米
24 
25     printf("Please input inch: ");    // 提示用戶輸入英寸值
26     
27     scanf_s("%f", &fInch);        
28     
29     fCm = fInch * 2.54f;        // 根據公式將英寸轉換爲釐米    
30     
31     printf("%.2f inch = %.2f cm\n", fInch, fCm);        // 輸出結果
32 
33     getchar();            // 接收輸入數據後的 Enter 
34     getchar();            // 起暫停做用 等待用戶再次按下 Enter 
35                         // 此程序如在 windows 10 中文環境下運行時,
36                         // 請將輸入法切換爲 英文狀態
37                         // 不然須要按多一次 Enter 鍵
38     return 0;
39 }
40 /**************************************************
41 輸出結果:
42 ---------------------------------------------------
43 Please input inch: 4
44 4.00 inch = 10.16 cm
45 ---------------------------------------------------
46 
47 **************************************************/
相關文章
相關標籤/搜索