程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++ Primer 3rd 讀書筆記1/2

C++ Primer 3rd 讀書筆記1/2

編輯:C++入門知識

第一章 開始

1. C++中標准的頭文件是不帶.h後綴的。如下代碼值得注意:

#include

void sayHello()

{

cout<<"Hello World!";

}

void main()

{

sayHello();

}

#include

using namespace std;

void sayHello()

{

cout<<"Hello World!";

}

void main()

{

sayHello();

}

#include

void sayHello()

{

std::cout<<"Hello World!";

}

void main()

{

sayHello();

}

引用帶.h的頭文件時,不需要使用namespace。引用標准的不帶後綴名的頭文件時,需要使用namespace。使用namespace有兩種方式:1.通過using關鍵字調用。2.在具體的函數前通過::調用。例如std::cout。

2. #include稱之為預處理器,有兩種形式:<>表明文件時標准頭文件,查找過程會檢查預定義的目錄,“”引用的表示該文件時用戶提供的頭文件,查找文件從當前目錄開始,當前目錄沒有就查找預定義目錄。通過如下代碼防止重復處理:

#ifndef BOOKSTORE_H

#define BOOKSTORE_H

//content

#endif

使用如下代碼判斷預處理器常量是否已經被定義:

int main()

{

#indef DEBUG

cout<<”Beginning execution of main()”;

#endif

cout<<”Hello”;

}

如果定義了DEBUGE預編譯器常量,那麼會編譯cout<<”Beginning execution of main()”;如果沒有定義DEBUGE,不編譯此句。

3. 基本的輸入輸出流有:cin、cout和cerr。換行輸出為cout<

第二章 浏覽

1. 在C++中,數組不能直接賦值。而在Java中,數組時可以直接賦值的。

2. 在C++中分為靜態(在棧中)和動態(在堆中)分配內存。靜態分配在編譯時分配,效率高但缺乏靈活性;動態分配在執行時刻分配,效率低但靈活性高。靜態對象是有名字的變量,我們直接對其進行操作;動態對象是沒有名字的對象,我們通過指針對其進行操作。靜態對象的分配和釋放由編譯器自動處理;動態對象的分配和釋放由程序員顯式管理,使用的是new和delete。

int *pia = new int(1024);//pia指向單一對象的地址

int *pint = new int[4];//pint指向擁有四個元素數組的第一個元素的地址

delete pia;//刪除單一對象

delete []pint;//刪除數組

3. 調用對象的方法時,點操作符用於類對象調用,->用於對象指針的調用。

4. 訪問函數的開銷比直接訪問內存的開銷大。通過對象的方法訪問對象的變量時(訪問對象的方法是訪問函數,訪問對象的變量直接訪問內存),C++通過inline機制,將調用函數在調用點展開,節省了開銷。

5. 引用是沒有指針語法的指針。

6. 類的構造函數用來初始化對象的數據成員,析構函數負責釋放對象生命周期內申請到的所有資源。

7. 在繼承操作中,基類中需要在子類實現的函數應使用virtual修飾。C++支持多繼承。繼承關系反映的是is-a的關系。組合關系反映的是hava-a的關系。

第三章 C++數據類型

1. 基本數據類型:

char(1bit)、short(2bit)、int(4bit)、long(4bit)、float(4bit)、double(8bit)

其中char、short、int和long為整型,分為有符號和無符號,默認為有符號。文字常量,例如數字1,其值不能改變,並且不可尋址。相比於文字常量,變量是可以尋址的,每個變量有兩個值與其對應,分別是數據值和地址值。

2. Class A;是聲明,聲明不是定義,不引起內存分配。

A a(100);靜態分配

A *a = new A(100);動態分配

3. C++中的關鍵字:

關鍵字explicit可以禁止“單參數構造函數”被用於自動類型轉換

class Stack

{

explicit Stack(int size);

};

沒有explicit的話Stack s = 40;能編譯通過

而有explicit則不能,必需Stack s(40);

關鍵字mutable意為:可變的。用於在const的函數裡面修改一些跟類狀態無關的數據成員

關鍵字volatile被設計用來修飾被不同線程訪問和修改的變量。volatile的作用: 作為指令關鍵字,確保本條指令不會因編譯器的優化而省略,且要求每次直接讀值.

4. 基本數據類型變量的初始化:如果該基本類型的變量是在全局域定義的,系統初始化其值為0,如果是局部域或者通過new定義的,系統不對其初始化

5. 對象的初始化支持兩種方式。1.int a=100;2.inta(100);

6. 空指針(void*)可以接受任何指針類型的地址值賦值,它表明該值是個地址值,但是該地址值的對象類型不知道,不能知道該指針覆蓋的內存區域。

7. C++提供兩種風格的字符串類型,一種是老式的C風格字符串,另一種是標准的C++引入的字符串string。使用老式的C風格字符串需要#include,常使用一個char *類型的指針指向。例如char *s=”Hello”;當char *s=0;或者char *s=””;時,其長度為0。老式的字符串使用strlen測定器長度,不包括\0。使用標准C++的字符串string,需要包含頭文件#include,使用size()方法獲取其長度。通過size()= =0或者empty()方法判斷字符串是否為空。string提供對老式C語言中字符串的支持,可以與其運算,可以將老式C語言風格的字符串轉換為string類型,反之則不行,需要通過constchar *s = s1.c_str()轉換。

8. 對於字符串的賦值。s2=s3;過程如下:首先將s2關聯的字符存儲區釋放掉,然後分配足夠存儲與s3相關聯的字符的存儲區,最後將與s3相關聯的字符拷貝到該存儲區中。注意這裡與Java的區別。

9. const定義變量為常量,使得變量的值不能被修改常量必須初始化非const對象的指針不能指向const對象。const指針可以指向非const變量,此時也不能通過指針修改其值。

A.const int*p=0;//(自右向左)p是一個指向int類型的,被定義為const對象的指針。稱之為:指向const的指針指向const的指針可以指向其他,但是不能改變指向的值。const int *p 等價於 int const *p。(const關鍵字位於第一、第二位置都是指向const的指針)

const double minWage = 0;

p=&minWage;

*p=100;//×指向const的指針可以指向其他,但是不能改變指向的值

double dval=3.14;

p=&dval;

*p=100;//×指向const指針可以指向其他,但是不能改變指向的值

指向const的指針常用在函數的參數中,例如int strcmp(const char *str)用於保證被傳遞到函數中的實際對象在函數中不被修改。

B.interr=0;int *const cur=&err;//cur是指向int類型的const指針。稱之為:const指針const指針不能指向其他的地址值,但是可以修改其值。

C.const double pi=3.14;const double *constpi_ptr=&pi;指向const類型的const指針。

const int aa = 100;

int bb = 200;

int cc = 300;

//指向const的指針

const int *p = &aa;

//*p=100;錯誤

p=&bb;

//*p=100;錯誤

//const指針

//int *const pp = &aa;錯誤,非const類型的指針不能指向const常量

int *const pp = &bb;

//pp=&cc;錯誤

*pp = 100;

int const * ppp = &aa;

ppp = &cc;

10. 引用是沒有指針語法的指針,常用語函數的形參,將類對象傳遞給函數。引用必須初始化。引用一旦定義,不能指向其他對象。指針所有的操作都被應用在它所指向的對象上。

int a = 100; int&p = a;(指向int型的引用)

int *pi = &a;int *&ppi = pi;(指向指針的引用,&和*作用抵消)

指向const的引用可以使用文字常量初始化,例如:const int &p = 3.14;其內部實現是通過為文字常量定義一個變量,然後引用指向該變量進行實現的。int *pi=0;內部其實為:int tmp=0; const int &ri=tmp;而對於非指向const的引用,由於文字常量不能尋址,因此不能這樣初始化(int &p=1;×)。

對於const intival = 1024;定義指向ival指針的引用如下:

const int *const&p = &ival;(第一個const說明指向的是常量,第二個const說明是const指針,只能指向1024的地址,因為文字常量的地址是固定的)

引用與指針的區別;

1. 引用必須總是指向一個對象,必須初始化。指針可以為空。

2. 引用之間相互賦值時,改變的是被引用的對象而不是引用本身。

int &ri = ival, &ri2=ival2;ri=ri2;改變的是ival,而不是引用本身。賦值之後兩個引用依然指向原來的對象。

11. 枚舉:用於指定一個對象含有指定的幾個值。Enum Forms{a=2,b,c}.c=4.

12. 數組維數值必須是常量表達式,必須能在編譯期間計算出其值。顯式初始化的時候可以不寫維數值。字符串也是一個數組,但是其包含了額外的“\0”。數組不能被另一個數組初始化,也不能賦值給另一個數組。C++不提供編譯器對數組的邊界檢查。

13. 數組與指針:數組標示符代表數組中第一個元素的地址,它的類型是數組元素類型的指針。

14. vector可以被另一個vector初始化,可以賦值給另一個vector。

15. typedef的一道易錯題

Typedef char *cstirng;

Extern const cstring cstr;

問cstr是什麼?

不是指向const字符的指針const char *cstr,而是指向char的const指針char * const cstr。

16. volatile修飾符的作用是告訴編譯器,該對象的值可能在編譯器未監測到的情況下被改變。因此編譯器不能武斷地對引用這些對象的代碼進行優化處理。

17. pair提供key-value形式的存儲結構,使用需包含

第四章 表達式

1. %取模運算符號只能應用於整型操作數上,例如char、short、int和long。

2. 關系和邏輯運算符如果應用在整數值的上下文環境中,會自動提升為1或者0.

3. 不能使用諸如a[index--]

4. 利用i++和++i實現Stack。

Push:stack[top++] = value;

Pop:value = stack[--top];

5. sizeof操作符的作用是返回一個對象或類型名的長度。當使用sizeof計算數組時,返回的是數組的整個類型長度,而不是第一元素的長度。Sizeof計算指針時,sizeof(p)=4;siziof(*p)=p指向內存元素的類型大小。Sizeof計算引用時,返回的是引用的類型大小。sizeof a和sizeof(a)兩種方式都正確。

size_t st;

st = sizeof st;

std::cout<<"st="<

double *sp = new double[3];

int as[] = {1,2,3,4};

std::cout<<"sizeof(sp)="<

std::cout<<"sizeof(*sp)="<

std::cout<<"sizeof(as)="<

std::cout<<"sizeof(double *)"<

std::cout<<"sizeof(double &)"<

輸出結果為:4、8、16、4、8

此外:sizeof(‘c’)=1;sizeof(“c”)=2;【包含\0】sizeof(std::string)=16;string str =”s”;sizeof(str)=16;

6. 系統為程序分配內存的區域稱之為空閒存儲區或者堆。使用new執行分配內存的操作。所有從堆中分配的對象都是未命名的,new表達式返回的不是對象本身,而是對象的地址,對象所有的操作都是通過地址值間接完成的。使用delete來刪除我們從堆中申請的對象。刪除單個元素:delete p;刪除數組:delete[] p;

7. inta = 3;int b = a + 1.24;首先將a提升為double,然後a+1.24得到double的結果,然後將結果轉換為int(編譯器會報錯)。發生隱形轉換的情況如下:

1. 混合運算:int a= 3; double d = 3.243; double dd = a + d;

2. 用一種類型的表達式賦值給另一種類型的對象。 a = d;或者 int *p =0;

3. 把一個表達式傳遞給一個函數調用,表達式類型與參數類型不同。Extern double sqrt(double); cout<

4. 從一個函數返回一個表達式,表達式與返回類型不同。Double dif(int a,int b){return a – b;}

8. 算數運算中:

1. 類型總是被提升為較寬的類型。Int->float->double->long double

2. 小於整形的有序類型的算數表達式都轉換成整形。例如char、signed char short等。此外還有enum中的值,boo值也被提升為整形int。

9. 顯式類型轉換常用命令:static_cast(靜態轉換,一般的轉換)、dynamic_cast(運行時刻識別由指針或引用指向的類對象)、const_cast(const常量轉換)和reinterpret_cast。顯示類型轉換的語法為:castname(expression);

舊式強制轉換語法:

1. C++強制轉換符號:type(expr)

2. C語言強制轉換符號:(type)expr;

10. 任何非const數據類型的指針都可以被賦值為void*。

第五章 語句

1. string*p, p1;定義p為指針,p1為字符串。string *p,*p1;定義p,p1為指針。

2. switch如果不加break,則會從入口點一直執行。

3. break:跳出循環體;continue:跳出本次循環,轉而進行洗一次循環。

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