程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 你好,C++(3)2.1 一個C++程序的自白,2.1自白

你好,C++(3)2.1 一個C++程序的自白,2.1自白

編輯:C++入門知識

你好,C++(3)2.1 一個C++程序的自白,2.1自白


第2部分 與C++第一次親密接觸

在浏覽了C++“三分天下”的世界版圖之後,便對C++有了基本的了解,算是一只腳跨入了C++世界的大門。那麼,怎樣將我們的另外一只腳也跨入C++世界的大門呢?是該即刻開始編寫C++程序?還是……

正在我們猶豫的時候,便看到前面有一個人被一群滿頭問號的C++初學者圍在當中。我們趕緊擠進去一看,噢,原來是一個C++程序正做自我介紹呢。

2.1  一個C++程序的自白

“大家好,歡迎來到奇妙的C++世界。我是C++世界的迎賓——一個最簡單最普通的C++程序,我的名字叫“HelloWorld.exe”。我雖然簡單而普通,但卻幾乎是這個世界上最著名的C++程序。每個來到C++世界的初學者與C++的第一次親密接觸都是通過我來完成的。大家在聽我介紹之前,一定會覺得C++程序非常神秘,比如,C++程序是如何創建的?一個完整的C++程序由哪幾部分構成?傳說中的源文件到底是什麼文件?C++程序是如何執行的?其實,我們C++程序一點都不神秘,跟大家一樣,我們有自己的老爸老媽,有自己的五官四肢,也有自己的生命過程。什麼?大家覺得不可思議?別著急,下面且聽我一一道來……”

2.1.1  用Visual Studio創建C++程序

大家進入C++世界最感興趣的第一件事,就是親自動手創建一個C++程序。大多數C++程序都是通過一種叫做集成開發環境(Integrated Development Environment,IDE)的軟件創建的,可以說,它是創建C++程序的工廠。雖然可以用於創建C++程序的集成開發環境有很多,但是我們首選的還是由微軟公司開發的Visual Studio。作為一款經過二十多年不斷發展而來的集成開發環境,Visual Studio擁有多種功能各異的版本:有適用於大規模團隊開發的旗艦版,也有適用於個人開發的專業版,還有免費的快速版。如果我們只是想利用Visual Studio進行C++的學習,我們可以使用其中的Visual C++ Express版本。它不僅功能齊備,而且小巧。更重要的是,它是免費的,我們可以從微軟的網站免費下載安裝。Visual Studio是Windows平台上最常用的開發環境,至於其它的開發工具以及Linux平台上的開發工具,請大家參考後文的2.3小節。

現在,請大家在我的引導下,一步一步地使用Visual Studio創建我們的第一個C++程序。第0步,新建項目。從開始菜單找到已經安裝好的Visual Studio並點擊啟動。當第一次啟動Visual Studio時,它會要求我們選擇界面布局設置,這裡我們選擇適用於Visual C++的布局設置,然後經過片刻的等待就可以看到Visual Studio華麗麗的起始頁了。在Visual Studio中,我們所有的開發工作都是在某個項目中進行的,所以我們利用Visual Studio編寫程序的第一步就是創建用於管理程序文件的項目:單擊起始頁左側的“新建項目”,在彈出的“新建項目”對話框中,選中左側樹狀圖中的“Visual C++”節點,然後在右側的項目類型列表中選中“空項目”這個項目模板,接著在對話框下方輸入項目名稱“HelloWorld”並選擇項目存放的位置,最後點擊“確定”按鈕,就完成了新項目的創建。

                       

圖2-1 新建項目

第1步,添加源文件。新項目的創建,只是搭起了一個空的框架,還等著我們向其中添加一些實質的內容。在左側的“解決方案資源管理器”中,找到“HelloWorld”項目下的“源文件”分支,然後右鍵單擊“源文件”分支,在彈出的菜單中依次選擇“添加->新建項”,就可以得到“添加新項”對話框。在“添加新項”對話框中,選中左側樹狀圖中的“Visual C++”分支,然後在右側文件類型列表中選中“C++文件”,接著在對話框下方將文件名稱修改為“HelloWorld.cpp”,最後點擊“確定”按鈕,Visual Studio就會為我們新建一個HelloWorld.cpp源文件並添加到項目中。

 

 

圖2-2 添加源文件

第2步,編輯代碼。有了空白的源文件,就相當於畫家支好了畫板,作家擺好了稿紙,就等著我們開始編寫代碼了。在已經被打開的HelloWorld.cpp文件中,我們編輯如下的代碼(這裡值的特別提醒的是,其中的標點都應該是英文的):

#include <iostream>

using namespace std;

 int main()
{
    // 在屏幕輸出“Hello World!”字符串
    cout<<"Hello World!"<<endl;

    return 0;
}

圖2-3 編輯代碼

第3步,編譯執行程序。代碼編輯完成之後,我們就可以編譯並執行這個程序向C++世界打個招呼了。這一步可以通過菜單命令“調試->開始執行(不調試)”來完成,但更多時候,我們通過Ctrl+F5快捷鍵來完成。當我們按下快捷鍵之後,Visual Studio會編譯項目當中的源文件,如果源文件中沒有錯誤,它就會生成相應的HelloWorld.exe可執行文件,隨後會啟動執行這個程序,從而在DOS窗口打印出一個“Hello World!”字符串向C++世界打招呼。

 

圖2-4 Hello World!

最佳實踐:等一下,等一下,我還沒看清輸出結果呢!

當我們在Visual Studio中執行某個程序時,如果這個程序在執行過程中不需要與用戶進行交互,那麼它執行時打開的DOS窗口會在其執行完畢後立即關閉。如果這個程序有結果輸出,我們甚至來不及看清程序的輸出結果。一個程序執行完了,連輸出結果都來不及看清這怎麼行呢?

為了解決這個問題,我們可以在程序的主函數返回之前加上一條“system("pause");”語句。例如:

int main()
{

    // …

    // 讓程序在結束之前暫停
   system("pause");

    return 0;
}

加上這條語句後,程序會在執行完畢之前暫停,這樣,我們就有足夠的時間看清程序的輸出結果了。自然,這條語句也還可以用在程序執行過程中那些需要暫停的地方,以此來提高程序的可交互性。

另外一種查看程序輸出結果的方法,就是先啟動DOS窗口,然後DOS窗口中手動地執行我們的應用程序。在這種方式下,DOS窗口並不會在程序執行完畢後關閉,所以我們也有時間查看程序的輸出結果。

經過這樣四個簡單的步驟,我們就輕松編寫了我們的第一個C++程序,完成了與C++的第一次親密接觸。除了借助Visual Studio創建C++程序之外,我們甚至還可以采取純粹手工的方式創建C++程序。但無論何種方式,它們的基本流程都是一樣的。如果使用Visual Studio方式,因為有開發工具的幫助,上手容易開發效率也會比較高。而如果是使用手工方方式,則可以對整個開發過程進行靈活定制,從而滿足我們一些個性化的需求。對於初學者而言,手工方式稍顯復雜。最佳的學習路線應該是,先以Visual Studio方式入門,等到有了一定的基礎,需要對程序的編寫過程有更精細控制的時候,再改用手工方式。這樣才不至於在入門階段就被復雜的手工方式困住了腳步,而在進階後又受到開發工具的限制。

2.1.2  C++程序=預編譯指令+程序代碼+注釋

麻雀雖小,五髒俱全。大家別看我個頭小,只有短短的幾行代碼,實現的功能也很簡單,但是我同樣擁有C++程序的“五官和四肢”:預編譯指令、程序代碼和注釋,如圖2-5所示。大多數情況下,這三個基本組成部分都被放在一個擴展名為“cpp”的文本文件中,這個文件被稱為C++ 源文件。源文件記錄了我的“五官和四肢”,規劃了我的人生。源文件的編寫者就是我的設計師了。通過修改源文件,可以改變我的面貌、我的人生軌跡,讓我完成各種任務,實現各種功能。

 

圖2-5 C++程序=預編譯指令+程序代碼+注釋

下面,大家一起來看看我的源文件,從中認識我的“五官和四肢”。

1. 預編譯指令

在源文件中,以“#”開始的內容就是預編譯指令。它的作用是告訴編譯器,讓它在真正進行編譯之前對源文件進行一些插入文件、替換字符串等預處理,以得到最終參與編譯的源文件。例如,在我的源文件HelloWorld.cpp中,第一行就是一個插入文件的預編譯指令:

#include <iostream>

其中,“#include”指令用於將指定的文件插入該指令所在的位置,作為整個源文件的一部分。因為這樣的文件總是在一個源文件的頭部被插入,所以我們通常將這樣的文件稱為頭文件(header file)。在這裡,我們插入了“iostream”這個頭文件,這是因為我們在程序中需要用到其中定義的cout和endl來完成輸出(關於C++的輸入輸出,可以參考後文2.2小節的介紹)。需要注意的是,“#include”指令後的文件名有兩種表示方式:如果使用雙引號""來包圍一個文件名,則預處理器在處理這個指令的時候,將首先在當前目錄(也就是這個源文件所在的目錄)下搜索這個文件,如果不存在,則繼續在項目的包含目錄(包括項目的默認頭文件目錄,也就是Visual Studio安裝目錄下的“\VC\include”文件夾,以及在項目屬性中設置的項目附加頭文件目錄)下搜索這個文件;而如果使用尖括號<>來包圍一個文件名,預處理器則會直接在項目的包含目錄下搜索這個文件。所以,通常我們使用""來插入當前項目目錄下的頭文件(比如我們自己創建的頭文件),而使用<>來插入各種項目包含目錄下的庫頭文件(比如這裡的iostream)。這裡值得再次提醒的是,代碼中使用的所有標點符號(這裡使用的尖括號,也包括後面代碼中用到的雙引號、逗號、分號等)必須是英文的。某些中英文符號非常相似,很容易被初學者搞混淆而引起編譯錯誤,這一點尤其值得初學者注意。

2. 程序代碼

程序代碼主體由若干C++語句(通常以分號結束的一行代碼就是一條語句)構成,可以說語句是構成程序的基本單位。在我的源文件中,第一條C++語句是:

using namespace std;

這條語句表示我所使用的名字空間是std。所謂名字空間,就是程序中各種標識符(比如這裡的cout和endl,我們通過這些符號來訪問程序中的各種元素,實際上也可以說是這些元素的名字,所以這些符號也被稱為標識符)所在的范圍,更具體的可以參考7.3.2小節關於名字空間的介紹。在C++中,任何標識符都被定義在某個名字空間中,而同一個標識符也可以在多個名字空間中同時定義。這就像張家村有一個人叫陳良喬,而李家村也有一個人叫陳良喬一樣,大家在稱呼“陳良喬”這個人的時候,為了表達清楚,我們必須在名字前加上一個前綴,稱之為“張家村的陳良喬”或是“李家村的陳良喬”。C++中的名字空間就相當於這裡的“張家村”、“李家村”。在這裡,我們在後面代碼中使用的cout、endl都是來自std這個村的,所以我們用這條語句告訴編譯器,如果遇到沒有加前綴的標識符(比如,這裡的cout),可以到std村去找找看,如果能找到,那就是它了(結果,在std村裡找到了std::cout)。C++的大多數內容都定義在std這個名字空間中,所以,很多時候我們都需要在代碼中使用這條語句引入std名字空間。當然,如果不使用這條語句,我們也可以在標識符的前面直接加上名字空間的前綴,明確地表示這是來自於某個名字空間的標識符(在代碼中,使用 std::cout代替 cout,用std::endl代替endl)。

接下來的一條語句是:

int main()

這條語句連同它後面大括號內的內容,共同構成了main()函數,也稱為主函數。所謂函數,是C++程序中最基本的一個組織單元,它把若干條語句組織到一起共同實現某個功能。如果說一條語句相當於人體的一個細胞的話,那麼函數就相當於由若干細胞構成的擁有一定功能的器官。而這裡的主函數就是一個程序中最重要的“器官”。一個C++程序必須有一個主函數,且只能有一個主函數。當C++程序開始執行的時候,將首先進入主函數,然後逐條地執行其中的語句,直到其中的語句執行完畢退出主函數,程序執行也就宣告結束。可以說,主函數定義了一個C++程序的一生。

知道更多:為什麼一個C++程序必須有且只能有一個main函數?

當我們雙擊執行程序後,執行程序的進程會首先創建主線程,主線程然後調用約定啟動運行時庫,由啟動運行時庫調用約定好的main函數,自此開始執行用戶的代碼。main函數是主線程的執行入口,所以一個C++程序必須有一個main函數。

同時,一個線程不可能擁有多個執行入口。而且在C++中,全局符號(變量、函數) 只能有一個定義。main函數作為一個全局函數,自然也就只能有一個。

接下來的就是主函數中的一條語句:

cout<<"Hello World!"<<endl;

cout是定義在頭文件“iostream”中的一個輸出流對象,它是C++標准庫預定義的對象,通常用於將文字或數字輸出到屏幕。前面使用“#include”預編譯指令包含“iostream”頭文件就是為了在代碼中使用這個對象。關於輸入/輸出流,會在以後的章節中做更詳細的介紹,這裡只要知道這條語句可以將“Hello World!”這串文字輸出到屏幕上即可。值得再次提醒的是,這裡的雙引號也必須是英文的。

我的最後一條語句是:

return 0;

它表示程序成功執行完畢並返回(return)。通常,我們返回一個0值表示程序成功執行(如果在程序的執行過程中出現錯誤,也可以返回表示錯誤信息的其他數值。程序的執行者可以接受這個返回值以判斷程序是否成功執行)。到這裡,主函數中的語句執行完畢,而我的一生也到此終結。

3. 注釋

注釋是源代碼的編寫者為了幫助代碼的閱讀者(代碼後期維護人員,也包括編寫者自己)更好地理解代碼,而在代碼中寫下的關於某一行或某一段代碼的一些解釋性文字。雖然源代碼中的注釋並不會參與最終的編譯,不會對程序的功能產生影響,但它會提高代碼的可讀性,為後期的維護帶來極大的便利。例如這裡的:

// 在屏幕輸出“Hello World!”字符串

就是一條注釋,它解釋了接下來的一條語句的作用,從而可以讓我們對代碼有更好的理解。

在形式上,C++中的注釋可以分為單行注釋和塊注釋兩種。“//”是單行注釋符,“//”之後直到換行的所有內容都屬於注釋。因為內容只有一行,所以它常常用來對代碼作簡短的解釋。例如上面的注釋就是一個典型的單行注釋。

C++中的塊注釋我們用一對“/*”和“*/”表示,凡是出現在這對符號之間的所有內容都屬於注釋。因為它可以包含多行內容,當我們需要對代碼做詳細解釋的時候,可以使用塊注釋。例如:

/*
    這是一段注釋
*/

在功能上,注釋一般分為序言性注釋和解釋性注釋。序言性注釋多位於程序源文件的開始,用來說明程序的文件名、用途、編寫時間、維護歷史等。在上面的例子中,我們可以在源文件的第一行加上一個序言性注釋來解釋這個源文件的功能:

// HelloWorld.cpp:在屏幕輸出“Hello World!”字符串

序言性注釋被廣泛用於大型的項目中。通常,每個項目都有自己定義的序言性注釋格式,用來向代碼的閱讀者說明一些必要的信息。下面是從一個實際的項目中摘錄的一段序言性注釋,它說明了源文件的名字、作用、文件的修改歷史等信息,幫助閱讀者更好地理解代碼。大家可以以此為模板,編寫適合於自己的序言性注釋。

///////////////////////////////////////////////////////////////////////
// AppDataView.cpp : implementation file
//
//CAppDataView
//  This view is designed to display the App Data
//
// Version: 2.1
// Date: September 2001
// Author: Chen Liangqiao
// Email: [email protected]
// Copyright (c) 2002. All Rights Reserved.
//
//   History:
/*
27.09.2001       Chen Liangqiao   
                     Added OnCreate(), OnUpdate():
                        Added usage of mesh tracer layers
                        Added bugfix for Graphics zoom error
30.10.2001       Chen Liangqiao   
                     Changed order of MPR View only in _TORCHTONAV
08.11.2001       Zeng Me   
                        Added EUpdateReason, used for UpdateAllView(),
                        Added voxel trafo
                        Changed the control panel due to new CTestCtrl
*/

///////////////////////////////////////////////////////////////////////

與序言性注釋多位於源文件開始部分不同,解釋性注釋多分散於源代碼的各個部分,用來向代碼閱讀者解釋代碼的含義,說明一些必要的問題等。例如,上面例子中的注釋:

//在屏幕上輸出“Hello World!”字符串
cout<<"Hello World!"<<endl;

這句解釋性注釋就是用來向代碼閱讀者說明其下代碼的功能是輸出字符串“Hello World!”。

最佳實踐:什麼是好的注釋

雖然程序的注釋並不影響程序功能的實現,編譯器也不會去閱讀我們的注釋,但是好的注釋卻可以增加程序代碼的可讀性,使程序更易於維護。誰都不願意維護一份沒有注釋的代碼,那無異於閱讀天書。那麼,什麼樣的注釋才算是好注釋呢?

首先,該注釋的地方一定要注釋。

注釋是對代碼的“提示和說明”,是為了幫助代碼的閱讀者更好地理解代碼而存在的。當我們認為代碼不能被“一眼看穿”而需要加以解釋,或者是代碼需要特別說明的時候,就應該添加注釋,加以額外的解釋和說明,幫助閱讀者理解代碼。例如:

// 判斷某個浮點數是否近似整數
bool is_int(double d)
{
    // 用浮點數d減去其整數部分(int)d,獲得其小數部分
    double s = d - (int)d;

   // 判斷小數部分是否在誤差范圍內
    if(s > 0.000001)
        return false;
    else
        return true;
}

這裡的注釋,恰當地對比較難以理解的代碼進行了解釋(如果沒有注釋,很難一下子就理解“double s = d - (int)d;”這行代碼的含義到底是什麼),提高了代碼的可讀性。

其次,不該注釋的地方最好不要注釋。

注釋僅僅是對代碼的“提示和說明”而已,如果代碼本身已經能夠很好地做到“望文生義”,也就沒有必要“畫蛇添足”地加以注釋了。另外需要注意的是,注釋只是簡短的說明性文字,不是詳盡的文檔。程序的注釋不可喧賓奪主,注釋過多會讓人眼花缭亂,反而降低了代碼的可讀性。例如,下面代碼中的注釋就不太合適:

// 判斷某個浮點數是否近似整數

// 其參數是表示輸入的浮點數d

// 其返回值是一個表示是否近似的bool值

bool is_int(double d)
{
    // 用浮點數減去其整數部分,獲得其小數部分
    // 其中,d表示浮點數,(int)d表示浮點數的整數部分
    double s = d - (int)d;

    // 判斷小數部分是否在誤差范圍內
    if(s > 0.000001)
         return false; // 小數部分大於誤差范圍,則表示浮點數不近似整數,返回false
    else
         return true; // 小數部分小於誤差范圍,則表示浮點數近似整數,返回true
}

這段代碼中的注釋,對一些含義非常淺顯易懂的代碼也進行了詳盡的解釋,注釋的內容遠超過了代碼的內容,這樣不但沒有增加代碼的可讀性,反倒是讓代碼淹沒在了復雜的注釋中,反而降低了代碼的可讀性。這樣的注釋實屬“畫蛇添足”多此一舉。

另外,應該養成良好的代碼注釋習慣。編寫代碼時添加必要的注釋,修改代碼時修改相應的注釋,刪除無用的注釋,保證注釋與代碼的一致性。

注釋應當准確、易懂,避免二義性。錯誤的注釋不但無益反而有害。

注釋的位置應與被描述的代碼相鄰,可以放在代碼的上方或右方,不可放在下方。例如:

// 在屏幕輸出“Hello World!”字符串
// 對下方的代碼進行注釋
cout<<"Hello World!"<<endl;


int n = 1024; // 循環次數,對左側代碼進行注釋

如果代碼比較長,特別是有多重嵌套時,應當在某些段落的結束處加以注釋,以便於查看嵌套結構的起始和結束位置。例如,一個多重循環的代碼及其注釋如下:

for ( int i = 0; i < 100; ++i )
{
    for ( int j = 0; j < 100; ++j )
    {
        // 算法處理...
    } // j循環結束
} // i循環結束

程序代碼不僅僅是寫給編譯器看的,它更是寫給程序員自己或者他人看的。對於編譯器來說,代碼中有沒有注釋無所謂,然而對於閱讀代碼的程序員來說,合適的注釋可以很大程度上提高代碼的可讀性,讓代碼更易於維護。因而,注釋是C++程序代碼中必不可少的一部分,而程序代碼中是否包含合適的注釋,也成為衡量一個程序員是否優秀的標准。

預編譯指令、程序代碼與注釋共同構成了我的“五官與四肢”,但這時候我還只是一個後綴為cpp的文本文件,而要得到最後的可執行的exe文件,還得靠我的父親母親:編譯器和鏈接器。


你好,我是一名C初學者,助一個《C程序設計題解與上機指導》第三版的DPF版本,

建議看國外的書
 

你好 可以給我一個 USB\VID_13D3&PID_5094&MI_00\6&302321C3&0&0000 這個ID的 攝像頭驅動 k50i 的xp的

尊敬的華碩用戶,您好。
建議您下載以下驅動程序:support.asus.com.cn/...09.zip
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved