1. 程式人生 > >C Primer Plus (第6版) 讀書筆記_Chapter 1

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

抽象 ner 競爭 crete 個數字 面向 ref 編程 bsd

第 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 鍵,窗口才消失。要實現這種效果,可以在程序的最後(retruan 這行代碼之前) 添加下面一行代碼:
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 語言源代碼轉換成可執行代碼的程序。

  復習題

    1. 對編程而言,可移植性意味著什麽?

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

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

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

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

    3. 編程的7個主要步驟是什麽?

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

    4. 編譯器的任務是什麽?

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

    5. 鏈接器的任務是什麽?

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

  編程練習

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

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

  

/**********************************************************
編程練習		
1.	你剛被MacroMuscle有限公司聘用。該公司準備進入歐洲市場,
	需要一個吧英寸單位轉換為厘米單位(1英寸 = 2.54厘米)的程序。
	該程序要提示用戶輸入英寸值。你的任務是定義程序目標和設計程
	序(編程過程的第1步和第2步)。
************************************************************/

#include <stdio.h>
int main(void)
{
	float fInch = 0.0f, fCm = 0.0f;		// fInch 英寸 	fCm 厘米
	
	printf("Please input inch: ");
	scanf_s("%f", &fInch);
	
	fCm = fInch * 2.54;
	printf("%.2f inch = %.2f cm\n", fInch, fCm);
	

	return 0;
}

/*****************************************************
輸出結果:
------------------------------------------------------
Please input inch: 2
2.00 inch = 5.08 cm
------------------------------------------------------

******************************************************/

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