第一篇 C++編程常用技術

C++易混淆點

1.關於頭文件的包含

  • #include <> 常用來包含系統提供的頭文件,編譯器會到保存系統標準頭文件的位置查找頭文件
  • #include “” 常用於報貨程序員自己編好的頭文件,用這種格式時,編譯器先查找當期目錄是否有指定的頭文件,然後從標準頭文件中進行查找。

2.函數重載

  • 定義:使用同一個函數名定義多個函數,但這些函數必須參數個數不同類型不同
  • 注意點:在使用函數重載時,同名函數的功能應當相同或相近,不要用同一函數名去實現幾個完全不相干的功能,這樣雖然程序能運行,但是可讀性不好,會讓人覺得莫名其妙。

3.函數模板

  • 格式:template<typename T>
  • 實例:
#include <iostream>
using namespace std;
template<typename T>
T min(T a, T b, T c){
   if(a>b) a=b;
   if(a>c) a=c;
   return a;
}
int main(){
   int a = 1, b = 2, c = 3;
   cout << min(a, b, c)<<endl;
   long long a1 = 100000000, b1=200000000, c1=300000000;
   cout << min(a1, b1, c1) << endl;
   return 0;
}

4.strlen()與 sizeof()的區別

  • strlen()是函數,在運行時才能計算,參數必須是字符型指針(char *),且必須是一’\0’結尾的。當數組名作爲參數傳入時,實際上數組已經退化爲指針了。它的功能是返回字符串的長度。
  • sizeof()是運算符,而不是一個函數,在編譯時就計算好了,用於計算數據空間的字節數。因此sizeof不能用來返回動態分配的內存空間的大小。sizeof常用於返回類型和靜態分配的對象、結構和數組所佔的空間,返回值跟對象、結構、數組所存儲的內容沒有關係。

5.指針

5.1數組與指針

  1. 數組指針,也稱爲行指針
    格式:int (*p)[n]
    分析:()優先級高,說明p是一個指針,且指向一個整型的一維數組。這裏p的步長爲n個整型數據的長度。

  2. 指針數組
    格式:int *p[n]
    分析:[]的優先級高,可以理解爲先與p結合成一個一維數組,再由int *說明這是一個整型指針數組,它有n個指針類型的數組元素。

  3. 區別
    *數組指針是一個指針變量,可以認爲是C語音裏專門用來指向二維數組的,他佔用內存中一個指針的存儲空間;
    *指針數組是多個指針變量,以數組形式存在內存中,佔用多個指針的存儲空間。

  4. 相同點
    同時用來指向二維數組時,其直接引用和用數組名引用都是一樣的。

優先級:()>[]>*

5.2字符串和指針

  1. 字符串指針變量本身是一個變量,用於存放字符串的首地址。可以改變變量使它指向不同的字符串,但不能改變變量所指的字符串常量。(eg: char *p = “hello world!”)因爲定義指針時,編譯器並不爲指針所指向的對象分配內存空間,它只是分配指針本身的空間,所以hello world會被當成常量,並且被放到程序的常量區,不能被修改;
  2. 字符串本身是存放在以該首地址爲首的一塊連續的內存空間中,並以‘\0’作爲字符串的結束標誌;
  3. 字符數組是由若干個數組元素組成,每個元素中存放字符串的一個字符。定義一個字符數組,編譯後就會分配一個內存單元,每個元素都有確定的地址。

5.3函數指針與引用

  1. 函數指針的聲明方法
    返回值類型 (* 指針變量名)([形參列表])
  2. 引用的注意事項
    在聲明一個引用變量時,必須同時使之初始化,即聲明它代表哪個變量。函數執行期間,不可以將其再作爲其他變量的引用。

引用比指針作爲參數時更有效率。
在const int &r=a;這類型的常引用中,用引用變量更改數據,可以使用a變量進行數據的更改。

6.結構體、共用體、枚舉、宏

#include <iostream>
using namespace std;

typedef union{
	long i;
	int k[5];
	char c;
}UDATE;

struct data{
	int cat;
	UDATE cow;
	double dog;
}too;

enum e_weekday{
	sun,
	mou,
	tue,
	wed,
	thu,
	fri,
	sat
};

struct STR{
	char i;
   	int j;
    	short k;
    	double m;
    	int n;

};

int main(){
	cout << "sizeof(short) = " << sizeof(short) << endl;
	cout << "sizeof(STR) = " << sizeof(STR) << endl;
	cout << "sizeof(char) = " << sizeof(char) << endl;
	cout << "sizeof(float) = " << sizeof(float) << endl;
	cout << "sizeof(long long) = " << sizeof(long long) << endl;
	cout << "sizeof(int *) = " << sizeof(int *) << endl;
	cout << "sizeof(e_weekday) = " << sizeof(e_weekday) << endl;
	cout << "sizeof(char *) = " << sizeof(char *) << endl;
	cout << "sizeof(doule) = " << sizeof(double) << endl;
	cout << "sizeof(long) = " << sizeof(long) << endl;
	cout << "sizeof(int) = " << sizeof(int) << endl;
	cout << "sizeof(UDATE) = " << sizeof(UDATE) << endl;
	cout << "sizeof(too) = " << sizeof(too) << endl;
	return 0;
}

在64位機器上的輸出結果,其中long類型在32位機器上只佔4Byte
sizeof(short) = 2
sizeof(STR) = 32
sizeof(char) = 1
sizeof(float) = 4
sizeof(long long) = 8
sizeof(int *) = 8
sizeof(e_weekday) = 4
sizeof(char *) = 8
sizeof(doule) = 8
sizeof(long) = 8
sizeof(int) = 4
sizeof(UDATE) = 24
sizeof(too) = 40

結構體成員是有一種默認的對齊的方式的:在本例中,結構體中的char,int,short爲與double對齊,所以必須要湊夠8個字節,char 與int對齊,各佔4字節湊夠了8字節,char,int佔了8個字節,爲對齊所以short也佔了8字節,下面int和char也湊夠了8字節,所以共佔了32個字節

注意事項:

  • 可以使用union判斷系統是big endian(大端)還是little endial(小端)
    其中大端是指低地址存放最高有效字節,小端則是指低地址存放最低有效字節

  • 幾乎所有的網絡協議都採用big endian的方式來傳輸數據,在兩臺採用不同字節序的主機通信時,在發送數據之前都必須轉換爲網絡字節序(big endian)後再進行傳播。
    將0x1234abcd寫入0x0000開始的內存,結果如下表

地址 big endian little endian
0x0000 0x12 0xcd
0x0001 0x34 0xab
0x0002 0xab 0x34
0x0003 0xcd 0x12
  • 同一枚舉類型中的枚舉子的取值不需要是唯一的,可以相同
  • union中變量公用內存,因以最長的爲準,公用體內變量的默認對齊方式,必須以最長的對齊
  • 宏定義中要遵循先替換後計算的原則,因此帶參數宏定義,要給宏體中的每個參數加上括號,並在整個宏體上再加一個括號
  • 定義宏時建議使用do{…}while()的格式,可以使得宏擴展後,仍然保留初始語義,保證程序的正確性。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章