最近仔細看了C++ primer,總結了一下C++中的一些值得注意的地方,與大家分享。也可以幫助一些從C過渡到C++的同學,更順利地完成過渡。一共總結了88個小點,裏面大都是我認爲C++中比較重要的特性,還有一些易錯點,還有一些在C的時候就沒有弄明白的語法。
1.對於extern關鍵字,只有在函數外部時,纔可以含有初始化式。
比如:
int main()
{
extern int a = 0;
return 0;
}
這樣對a的定義是錯誤的。extern是聲明某個變量或者某個函數可以在別的目標文件中找到定義,同時,extern聲明的某個變量,編譯器在尋找這個變量時只會在其他文件的非static全局變量區尋找定義。所以將a變量定義在main()中是不能被編譯器發現的,但是可以在函數中聲明變量。這部分聽起來比較拗口,我們從具體下面一個實例中體會一下:
在test1.cpp中編寫主函數,調用test2.cpp中的變量及函數:
test1.cpp:
#include <iostream>
using namespace std;
extern int number1;
extern void print();
void sum(int number2)
{
extern int number3;
cout << "the sum of number1~3 is " << number1 + number2 + number3 << endl;
return;
}
int main()
{
extern int number2;
cout << "number1 is " << number1 << endl;
cout << "number2 is " << number2 << endl;
print();
sum(number2);
return 0;
}
test2.cpp
#include <iostream>
int number1 = 10;
int number2 = 20;
int number3 = 30;
void print()
{
std::cout << "use print() successfully!" << std::endl;
return;
}
由於想盡快包含多的extern聲明情況,所以聲明瞭函數,在子程序中聲明瞭變量,在全局聲明瞭變量。
這樣編譯test1.cpp是完全沒有問題的。
執行結果:
如果有朋友對頭文件的作用,和程序編譯過程還有靜態和動態鏈接庫有疑問,推薦看一下我寫的:
靜態鏈接庫與動態鏈接庫----C/C++
2.在C++中不能定義引用類型的引用,比如int &&a。
什麼叫定義引用類型的引用,我們可以和理解指向指針的指針一樣去看待它。比如:
int a = 0;
int &rb = a;
int &rc = rb;
這樣是完全可以的。rc,rb都引用同一個對象。
3.在scanf()中,double型的輸入只能入%lf,float型用%f,而輸出double和float型都用%f。
有朋友會說我在printf()的時候一直都是用的%lf,這個確實可能正確輸出,但是有許多系統沒有定義它,爲了保留可移植性,我推薦用%f輸出double和float。其實printf中%f是輸出double型的,但是由於輸出float型類型時,自動提升爲double型,所以%f即可以輸出double也可以輸出float型。
4. typedef 和define定義變量名時的語法區別
typedef 類型 名字
define 名字 類型名
對於typedef int *int_pointer;
int_pointer ptra;
這樣就定義了一個ptra的整型指針。一個比較好理解的方式是將ptra替換typedef定義式中的int_pointer。可以很明顯的看出ptra的整性指針定義。實際上,編譯器也是這麼幹的。
上面這個例子沒有很好的體現出typedef的便利性,下面我們定義一個函數指針:
typedef bool (*cmpFcn)(const string &, const string &);
bool lengthCompare(const string &, const string &);
cmpFcn pf1 = 0;
cmpFcn pf2 = lengthCompare; //等效於cmpFcn pf2 = &lengthCompare;
這樣就可以很明顯的看出typedef的便利性了。同樣的,只要將pf1替換typedef中的cmpFcn就可以看清楚的看出定義。
在primer 112頁有個typedef的事例,這個事例特別容易搞錯,typedef凡是涉及定義const類型時都需要特別注意,這個問題我們以後再說。
5.迭代器相減後的類型爲vector等容器內定義的difference_type類型,而指針相減則爲標準庫中的ptrdiff_t。
ptrdiff_t其實就可以看成signed long int, 而標準庫另一種類型size_t則爲unsigned long int。long型在linux中爲一個字長,64位的機子是8個字節。
總結:difference_type與size_type爲STL所有,這些類型與具體機器無關,可移植性好
size_t與ptrdiff_t爲標準庫所有。