1、初始化:初始化指創建變量並給它賦值初值,賦值則是擦除對象當前值並用新的值代替。
2、內置類型變量的初始化:在函數外定義的變量都初始化爲0,在函數體裏定義的內置類型變量不進行自動初始化。
3、建議每個內置類型的對象都要初始化。雖然不是必須的,但是會更加容易和安全。
4、類類型變量的初始化:類通過定義一個或多個構造函數來控制類對象的的初始化。
5、聲明和定義:變量的定義用於爲變量分配存儲空間,還可以爲變量指定初始值。聲明用於向程序表明變量的類型和名字。定義也是聲明:當定義變量時我們聲明瞭他的類型和名字。
6、變量在使用前必須先聲明或定義。
7、在全局作用域聲明的const變量是定義該對象的文件的局部變量。此變量只存在於那個文件中,不能被其他文件訪問。const對象必須初始化,且其值不能被修改。
8、引用就是對象的另一個名字。在實際程序中主要用作函數的形式參數。作用在引用上的所有操作事實上都是作用在該引用綁定的對象上。
9、const引用是指向const對象的引用。非const引用只能綁定到與該引用相同類型的對象。
10、typedef 名字:typedef 通常被用於以下三種目的
①爲了隱藏特定類型的實現,強調使用類型的目的
②簡化複雜的類型定義,使其容易理解
③允許一種類型用於多個目的,同時使得每次使用該類型的目的明確
11、class和struct關鍵字定義類的唯一差別在於默認訪問級別:默認情況下,struct的成員爲public,而class的成員爲private。
12、頭文件中應該只定義確定必要的東西。
13、兩個字符串字面值相加是非法的。
14、cctype定義的函數:
15、vector對象的初始化方式:
①vector<T> v1; //vector保存類型爲T的對象。默認構造函數,v1爲空
②vector<T> v2(v1); //v2爲v1的一個副本
③vector<T> v3(n,i); //v3含有n個值爲i的元素
④vector<T> v4(n); //v4含有值初始化的元素的n個副本
16、vector必須是已存在的元素才能用下標操作符進行索引。通過下標操作進行賦值時,不會添加任何元素。
17、每種容器都定義了一對命名爲begin和end的函數,用於返回迭代器。
18、解引用操作符(*操作符):解引用操作符返回當前指向的元素。
19、標準庫bitset類型:初始化bitset方法如下:
①bitset<n> b; //b有n位,每位都是0
②bitset<n> b(u); //b是unsigned long型u的一個副本
③bitset<n> b(s); //b是string對象中含有的位串的副本
④bitset<n> b(s,pos,n); //b是s中從位置pos開始的n個位的副本
20、當用unsigned long值作爲bitset對象的初始值時,該值將轉化爲二進制的位模式。當用string對象初始化bitset對象時,string對象直接表示爲位模式。從string對象讀入位集的順序是從右到左:
string val("1100");bitset<32> bitval(val); //第二三位是1,其餘位都是0
21、除了程序員自己注意細節,並徹底測試自己的程序之外,沒有別的方式可防止數組越界。
22、儘量避免使用指針和數組。vector和迭代器一般取代了數組和指針,string取代了C風格的字符串。
23、由於指針的類型用於確定指針所指對象的類型,因此初始化或賦值時必須保證類型匹配。
24、void* 可以保存任何類型對象的地址。
25、指針賦值和通過指針進行賦值兩種操作的區分方法:如果如果對左操作數進行解引用,則修改的是指針所指向的對象的值;如果沒有使用解引用操作,則修改的是指針本身的值。
string s1("some value");
string *sp1 = &s1;
string s2("another");
string *sp2 = &s2;
*sp1 = "a new value"; //*sp1 = "a new value"
sp1 = sp2; //*sp1 = "another"
26、兩個指針減法操作結果是標準庫類型ptrdiff_t的數據。
27、C++允許計算數組或對象的超出末端的地址,但不允許對地址進行解引用操作。而計算數組超出末端位置之後或數組首地址之前的地址都是不合法的。
28、定義const對象必須初始化。
29、C語言風格字符串是以空字符null結束的字符數組。在處理C風格字符串的標準庫函數時,牢記字符串必須以結束符null結束。
char cal1[]={'C','+','+'}; //not null
char cal2[]={'C','+','+','\0'}; //null 是C語言風格
char cal3[]="C++"; //null 是C語言風格
const char *cp="C++"; //null 是C語言風格
30、C風格字符串的標準庫函數,頭文件#include<cstring>
一般有如下函數:strlen(s)返回字符串的長度,不包括結束符、strcmp(s1,s2) 字符串相等返回0、strcat(s1,s2)將s2連接到s1、
strcpy(s1,s2)將s2複製給s1、strncat(s1,s2,n)將s2的前n個字符連接到s1、strncpy(s1,s2,n)將s2的前n個字符複製到s1
31、混合使用C風格和string風格字符串:
string str = "C++";
const char *str1 = str.c_str();
cout << str1 << endl; //輸出 C++
32、數組初始化vector:
const int array_size = 5;
int int_arr[array_size] = {1,2,3,4,5};
vector<int> ivec(int_arr, int_arr + array_size);
33、將第27位置1, bitset_quiz.set(27); int_quiz |= 1UL << 27;
將第27位置0, bitset_quiz.reset(27); int_quiz &= ~(1UL << 27);
查看第27位狀態, bool status; status = bitset_quiz[27]; int_quiz&(1UL<<27);
34、在賦值操作上加圓括號是必需的,因爲賦值操作符的優先級低於不等操作符。
35、值初始化的()語法必須置於類型名後面,而不是變量後。
int *pi = new int(); //*pi=0
int x(); //沒有起到初始化作用,程序報錯
36、動態內存的管理容易出錯
(1)刪除指向動態內存的的指針失敗,造成“內存泄漏”。一般很難發現,只有消耗盡內存,內存泄漏纔會真正顯露出來。
(2)讀寫已刪除的對象。如果刪除指針所指向的對象之後,將指針置爲0值,則比較容易檢測出這類錯誤。
(3)對一個內容空間使用兩次delete表達式。
37、靜態全局變量與全局變量的唯一區別就是作用域不同。
全局變量
- 作用域:全局作用域(全局變量只需在一個源文件中定義,就可以作用於所有的源文件。)
- 生命週期:程序運行期一直存在
- 引用方法:其他文件中要使用必須用extern 關鍵字聲明要引用的全局變量。
- 內存分佈:全局數據區
- 注意:如果在兩個文件中都定義了相同名字的全局變量,連接出錯:變量重定義
全局靜態變量
- 作用域:文件作用域(只在被定義的文件中可見。)
- 生命週期:程序運行期一直存在
- 內存分佈:全局數據區
- 定義方法:static關鍵字,const 關鍵字
- 注意:只要文件不互相包含,在兩個不同的文件中是可以定義完全相同的兩個靜態變量的,它們是兩個完全不同的變量
靜態局部變量
- 作用域:局部作用域(只在局部作用域中可見)
- 生命週期:程序運行期一直存在
- 內存分佈:全局數據區
- 定義方法:局部作用域用中用static定義
- 注意:只被初始化一次,多線程中需加鎖保護
局部變量
- 作用域:局部作用域(只在局部作用域中可見)
- 生命週期:程序運行出局部作用域即被銷燬
- 內存分佈:棧區
- 注意:auto指示符標示
Tips:
- 若全局變量僅在單個C文件中訪問,則可以將這個變量修改爲靜態全局變量,以降低模塊間的耦合度;
- 若全局變量僅由單個函數訪問,則可以將這個變量改爲該函數的靜態局部變量,以降低模塊間的耦合度;
- 設計和使用訪問動態全局變量、靜態全局變量、靜態局部變量的函數時,需要考慮重入問題,因爲他們都放在靜態數據存儲區,全局可見;
- 如果我們需要一個可重入的函數,那麼,我們一定要避免函數中使用static變量(這樣的函數被稱爲:帶“內部存儲器”功能的的函數)
- 函數中必須要使用static變量情況:比如當某函數的返回值爲指針類型時,則必須是static的局部變量的地址作爲返回值,若爲auto類型,則返回爲錯指針。