C 程式設計思想重點筆記(上)

2022-02-03 08:04:07 字數 4468 閱讀 4838

c和c++指標的最重要的區別在於:c++是一種型別要求更強的語言。void *而言,這一點表現得更加突出。c雖然不允許隨便地把乙個型別的指標指派給另乙個型別,但允許通過void *來實現。例如:

bird*b;

rock*r;

void*v;

v =r;

b = v;

c++不允許這樣做,其編譯器將會給出乙個出錯資訊。如果真的想這樣做,必須顯式地使用對映,通知編譯器和讀者。

引數傳遞準則

當給函式傳遞引數時,人們習慣上應該是通過常量引用來傳遞,這種簡單習慣可以大大提高效率:傳值方式需要呼叫建構函式和析構函式,然而如果不想改變引數,則可通過常量引用傳遞,它僅需要將位址壓棧。事實上,只有一種情況不適合用傳遞位址方式,這就是當傳值是唯一安全的途徑,否則將會破壞物件(而不是修改外部物件,這不是呼叫者通常期望的)。

c++訪問許可權控制:public、private、protected

其中protected只有在繼承中才有不同含義,否則與private相同,也就是說兩者只有一點不同:繼承的結構可以訪問protected成員,但不能訪問private成員。

前置宣告注意

struct x;  //

declaration(incomplete type spec)

struct

y ;

這裡f(x*)引用了乙個x物件的位址,這是沒有任何問題的,但如果是void g(x memx);就不行了,編譯器會報錯。這一點很關鍵,因為編譯器知道如何傳遞乙個位址,這一位址大小是一定的,而不用管被傳遞的物件型別大小。如果試圖傳遞整個物件,編譯器就必須知道x的全部定義以確定它的大小以及如何傳遞它,這就使程式設計師無法宣告乙個類似於y :: g(x) 的函式。c++是純的嗎?

如果某個類的乙個函式被宣告為friend,就意味著它不是這個類的成員函式,但卻可以修改類的私有成員, 而且它必須被列在類的定義中,因此我們可以認為它是乙個特權函式。這種類的定義提供了有關許可權的資訊,我們可以知道哪些函式可以改變類的私有部分。 因此,c++不是完全的物件導向語言,它只是乙個混合產品。friend關鍵字就是用來解決部分的突發問題。它也說明了這種語言是不純的。畢竟c + +語言的設計是為了實用,而不是追求理想的抽象。

c++輸入輸出流的操縱運算元(manipulator)有:endl、flush、ws、hex等。

cout/

清空流

cout << hex << "0x"

<< i; //

輸出16進製制

cin>>ws; //

跳過空格

iostream.h還包括以下的操縱運算元:

如何建立我們自己的操縱運算元?

我們可能想建立自己的操縱運算元,這是相當簡單的。乙個像endl這樣的不帶引數的操縱運算元只是乙個函式,這個函式把乙個ostream引用作為它的引數。對endl的宣告是:

ostream& endl(ostream&);

例子:產生乙個換行而不重新整理這個流。人們認為nl比使用endl要好,因為後者總是清空輸出流,這可能引起執行故障。

ostream& nl(ostream&os) 

intmain()

c語言中const與c++中const的區別:

常量引進是在早期的c++版本中,當時標準c規範正在制訂。那時,常量被看作是乙個好的思想而被包含在c中。但是,c中的const意思是「乙個不能被改變的普通變數」,在c中,它總是占用儲存而且它的名字是全域性符。c編譯器不能把const看成乙個編譯期間的常量。在c中, 如果寫:

const bufsize=100

;char buf[bufsize];

儘管看起來好像做了一件合理的事,但這將得到乙個錯誤結果。因為bufsize占用儲存的某個地方,所以c編譯器不知道它在編譯時的值。在c語言中可以選擇這樣書寫:

const bufsize;

這樣寫在c++中是不對的,而c編譯器則把它作為乙個宣告,這個宣告指明在別的地方有儲存分配。因為c預設const是外部連線的,c++預設cosnt是內部連線的,這樣,如果在c++中想完成與c中同樣的事情,必須用extern把連線改成外部連線:

extern

const bufsize;//

declaration only

這種方法也可用在c語言中。

注意:在c語言中使用限定符const不是很有用,即使是在常數表示式裡(必須在編譯期間被求出);想使用乙個已命名的值,使用const也不是很有用的。c迫使程式設計師在預處理器裡使用#define。

類裡的const和enum

下面的寫法有什麼問題嗎?:

class

bob

結果當然是編譯不通過。why?因為const在類物件裡進行了儲存空間分配,編譯器不能知道const的內容是什麼,所以不能把它用作編譯期間的常量。這意味著對於類裡的常數表示式來說,const就像它在c中一樣沒有作用。在類裡的const意思是「在這個特定物件的壽命期內,而不是對於整個類來說,這個值是不變的」。那麼怎樣建立乙個可以用在常數表示式裡的類常量呢?

乙個普通的辦法是使用乙個不帶例項的無標記的enum。列舉的所有值必須在編譯時建立,它對類來說是區域性的,但常數表示式能得到它的值,這樣,我們一般會看到:

class

bob ; //

legal

int array[size]; //

legal

}

使用enum是不會占用物件中的儲存空間的,列舉常量在編譯時被全部求值。我們也可以明確地建立列舉常量的值:enum ;類裡面的const成員函式

class

x

這裡f()是const成員函式,表示只能const類物件呼叫這個函式(const物件不能呼叫非const成員函式),如果我們改變物件中的任何乙個成員或呼叫乙個非const成員函式,編譯器將發出乙個出錯資訊。

關鍵字const必須用同樣的方式重複出現在定義裡,否則編譯器把它看成乙個不同的函式:

int x::f() const
任何不修改成員資料的函式應該宣告為const函式,這樣它可以由const物件使用。

注意:建構函式和析構函式都不是const成員函式,因為它們在初始化和清理時,總是對物件作些修改。

如果我們想要建立乙個const成員函式,但仍然想在物件裡改變某些資料,這時該怎麼辦呢?這關係到按位const和按成員const的區別。按位const意思是物件中的每個位是固定的,所以物件的每個位映像從不改變。按成員const意思是,雖然整個物件從概念上講是不變的,但是某個成員可能有變化。當編譯器被告知乙個物件是const物件時,它將保護這個物件。

這裡我們要介紹在const成員函式裡改變資料成員的兩種方法。

volatile關鍵字

volatile的語法與const是一樣的,但是volatile的意思是「在編譯器認識的範圍外,這個資料可以被改變」。不知何故,環境正在改變資料(可能通過多工處理),所以,volatile告訴編譯器不要擅自做出有關資料的任何假定—在優化期間這是特別重要的。如果編譯器說:「我已經把資料讀進暫存器,而且再沒有與暫存器接觸」。一般情況下,它不需要再讀這個資料。但是,如果資料是volatile修飾的,編譯器不能作出這樣的假定,因為可能被其他程序改變了, 它必須重讀這個資料而不是優化這個**。

注意:

C 程式設計思想筆記 0110 。。。

1.乙個類裡,c o n s t恢復它在c中的一部分意思。它在每個類物件裡分配儲存並代表乙個值,這個值一旦被初始化以後就不能改變。在乙個類裡使用c o n s t的意思是 在這個物件壽命期內,這是乙個常量 然而,對這個常量來講,每個不同的物件可以含乙個不同的值。這樣,在乙個類裡建立乙個c o n s...

C 程式設計思想筆記 隱藏實現

友元 如果程式設計師想允許不屬於當前結構的乙個成員函式訪問結構中的資料,可以在類中宣告這個函式為友元。友元必須子啊乙個類中宣告,巢狀友元 乙個巢狀的struct並不能自動地獲得訪問私有成員的許可權,要取得訪問私有成員的許可權,要先宣告乙個巢狀的struct,然後宣告它是全域性範圍使用的乙個友元。友元...

c 程式設計思想

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