C 程式設計思想部分精華提取

2021-12-29 20:48:11 字數 2566 閱讀 6715

1、宣告與定義:

首先,必須知道「宣告」和「定義」之間的區別,因為這兩個術語在全書中會被確切地使用。「宣告」向計算機介紹名字,它說,「這個名字是什麼意思」。而「定義」為這個名字分配

儲存空間。無論涉及到變數時還是函式時含義都一樣。無論在哪種情況下,編譯器都在「定義」處分配儲存空間。對於變數,編譯器確定這個變數佔多少儲存單元,並在記憶體中產生存放它們的空間。對於函式,編譯器產生**,並為之分配儲存空間。函式的儲存空間中有乙個由使用不帶參數列或帶位址操作符的函式名產生的指標。定義也可以是宣告。如果該編譯器還沒有看到過名字a,程式設計師定義int a,則編譯器馬上為這個名字分配儲存位址。宣告常常使用於e x t e r n關鍵字。如果我們只是宣告變數而不是定義它,則要求使用e x t e r n。對於函式宣告, e x t e r n是可選的,不帶函式體的函式名連同參數列或返回值,自動地作為乙個宣告。函式原型包括關於引數型別和返回值的全部資訊。int f(float,char);是乙個函式原型,因為它不僅介紹f這個函式的名字,而且告訴編譯器這個函式有什麼樣的引數和返回值,使得編譯器能對引數和返回值做適當的處理。c + +要求必須寫出函式原型,因為它增加了乙個重要的安全層。

extern int i;//宣告

extern float f(float);//宣告

float b;//宣告+定義

float f(float a)

int i;//定義

int h(int x)

main()

在函式宣告時,引數名可給出也可不給出。而在定義時,它們是必需的。這在c語言中確實如此,但在c + +中並不一定。

2、控制代碼類:

c + +中的訪問控制允許將實現與介面部分分開,但實現的隱藏是不完全的。編譯器必須知道乙個物件的所有部分的宣告,以便建立和管理它。我們可以想象一種只需宣告乙個物件的公共介面部分的程式語言,而將私有的實現部分隱藏起來。但c + +在編譯期間要盡可能多地做靜態型別檢查。這意味著盡早捕獲錯誤,也意味著程式具有更高的效率。然而這對私有的實現部分來說帶來兩個影響:一是即使程式設計師不能輕易地訪問實現部分,但他可以看到它;二是造成一些不必要的重複編譯。

可見的實現部分:

有些專案不可讓終端使用者看到其實現部分。例如可能在乙個庫的標頭檔案中顯示一些策略資訊,但公司不想讓這些資訊被競爭對手獲得。比如從事乙個安全性很重要的系統(如加密演算法),我們不想在檔案中暴露任何線索,以防有人破譯我們的**。或許我們把庫放在了乙個「有敵意」的環境中,在那裡程式設計師會不顧一切地用指標和型別轉換訪問我們的私有成員。在所有這些情況下,就有必要把乙個編譯好的實際結構放在實現檔案中,而不是讓其暴露在標頭檔案中。

減少重複編譯:

在我們的程式設計環境中,當乙個檔案被修改,或它所依賴的檔案包含的標頭檔案被修改時,專案負責人需要重複編譯這些檔案。這意味著無論何時程式設計師修改了乙個類,無論是修改公共的介面部分,還是私有的實現部分,他都得再次編譯包含標頭檔案的所有檔案。對於乙個大的專案而言,在開發初期這可能非常難以處理,因為實現部分可能需要經常改動;如果這個專案非常大,用於編譯的時間過多就可能妨礙專案的完成。解決這個問題的技術有時叫控制代碼類( handle classes)或叫「cheshire cat」[ 1 ]。有關實現的任何東西都消失了,只剩乙個單一的指標「 s m i l e」。該指標指向乙個結構,該結構的定義與其所有的成員函式的定義一樣出現在實現檔案中。這樣,只要介面部分不改變,標頭檔案就不需變

動。而實現部分可以按需要任意更動,完成後只要對實現檔案進行重新編譯,然後再連線到專案中。這裡有個說明這一技術的簡單例子。標頭檔案中只包含公共的介面和乙個簡單的沒有完全指定的類指標。這是所有客戶程式設計師都能看到的。這行

struct cheshire;

是乙個沒有完全指定的型別說明或類宣告(乙個類的定義包含類的主體)。它告訴編譯器,cheshire 是乙個結構的名字,但沒有提供有關該結構的任何東西。這對產生乙個指向結構的指標來說已經足夠了。但我們在提供乙個結構的主體部分之前不能建立乙個物件。在這種技術裡,包含具體實現的結構主體被隱藏在實現檔案中。

#ifndef handle_h

#define handle_h

class handle;

#endif

這是所有客戶程式設計師都能看到的。這行

struct cheshire;

是乙個沒有完全指定的型別說明或類宣告(乙個類的定義包含類的主體)。它告訴編譯器,cheshire 是乙個結構的名字,但沒有提供有關該結構的任何東西。這對產生乙個指向結構的指標來說已經足夠了。但我們在提供乙個結構的主體部分之前不能建立乙個物件。在這種技術裡,包含具體實現的結構主體被隱藏在實現檔案中。

#include "handle.h"

struct handle::cheshire;

void handle::initialize()

void handle::cheanup()

int handle::read()

void handle::change(int x)

cheshire 是乙個巢狀結構,所以它必須用範圍分解符定義

struct handle::cheshire

客戶程式設計師唯一能訪問的就是公共的介面部分,因此,只是修改了在實現中的部分,這些檔案就不須重新編譯。雖然這並不是完美的資訊隱藏,但畢竟是一大進步

作者:fengzhishang2019

c 程式設計思想

c和c 指標的最重要的區別在於 c 是一種型別要求更強的語言。就void 而言,這一點表現得更加突出。c雖然不允許隨便地把乙個型別的指標指派給另乙個型別,但允許通過void 來實現。例如 bird b rock r void v v r b v c 不允許這樣做,其編譯器將會給出乙個出錯資訊。如果真...

《程式設計師面試寶典》精華 程式語言部分

7.1int p p 0 是錯誤的,指標p並未指向某個實際的位址 7.2char a a 陣列存放中棧中,函式返回即消失,char a a 陣列存放於全域性唯讀資料段 7.2 若類b繼承類a,兩者皆有成員變數,a中有f方法,則b b b.f 呼叫的是a中的f,f使用的變數也為a中的變數 7.3 指向...

java程式設計思想筆記 多型部分四

1.在子類中的方法如果覆蓋了父類的方法,它的返回值可以是父類的返回方法的返回型別的子類。例如 package test class r class t extends r class father public class p164 extends father 2.向下轉型 父類的子類可以自由的進...