1.和常量引用一樣,所謂的指向常量的指針或者引用沒有規定其所指的對象一定要是個常量。所謂指向常量的指針僅僅要求不能通過該指針改變對象的值,但是並沒有規定那個對象的值不可以通過其他的方式改變。
2.常引用可以對數值進行引用,而引用不可以
int i = 10;
int &r = i; //ok
int &r = 0 //no
const in &r = 0; //ok
有關const
int i = -1, &r = 0; // illegal, r must refer to an object.
int *const p2 = &i2; // legal.
const int i = -1, &r = 0; // legal.
const int *const p3 = &i2; // legal.
const int *p1 = &i2; // legal
const int &const r2; // illegal, r2 is a reference that cannot be const.
const int i2 = i, &r = i; // legal.
int i, *const cp; // illegal, cp must initialize.
int *p1, *const p2; // illegal, p2 must initialize.
const int ic, &r = ic; // illegal, ic must initialize.
const int *const p3; // illegal, p3 must initialize.
const int *p; // legal. a pointer to const int.
3.迭代器不能計算兩個加運算
mid = beg+(end-beg)/2; //這樣是合法的
mid = (beg+end)/2 ; //這樣是非法的,因爲迭代器沒喲定義加法運算,減法爲兩個迭代器之間的距離,
可以計算
4.數組的維度必須是一個常量表達式
int cnt = 10;
int ans[cnt]; //不可以,因爲cnt不是一個常量
const int cnt2 = 19;
int ans[cnt]; //可以,因爲cnt2是一個常量表達式
5.確定一個值的引用還是指針
一般來講,簡單的類型從右往左讀,對於複雜的類型,從中間往兩邊閱讀
int *ptrs[10]; //ptrs是一個含有是個整型指針的數組
int (*parray)[10] = &arr; //parray是一個指針,指向的是含有10個整數的數組
int *(&array)[10] = ptrs; //array 是一個數組的引用,該數組含有10個指針
6.全局變量int類型的被初始化爲0,局部變量不會被初始化
7.聲明規定了變量的名字,定義還申請了儲存空間。如果只是聲明一個變量而並非定義它,就只需要在前面添加關鍵字extern
extern int i //聲明一個變量
int j // 定義一個變量
8.引用是另一個對象的別名,而指針本身就是一個對象。
9.引用必須初始化,並且一旦定義了引用就無法再綁定到其他對象。而指針無須在定義時賦初值,也可以重新賦值讓其指向其他對象
10.如果你是想在多個文件之間公用一個常量,const 定義之後的值,
extern const int bufsize = 100;//在.cpp的文件中定義並初始化了一個常量
extern const int bufsize ; //在.h文件中與.cpp中的值是一個值
11.內置的下標運算符所用的索引值不是無符號類型,這一點與vector和string完全不同
int *p = &ia[2]; //p爲指向索引爲2的元素
int j = p[1]; //p[1]等價於*(p+1),也就是ia[3]的那個元素
int k = p[-2]; //p[-2]是ia[0]表示的那個元素
12.
char ca[] = {'c','+','+'}; //不以空字符結束
cout<< strlen(ca)<<endl; //嚴重錯誤,ca沒有以空字符結束
C++繼承C風格的字符串,末尾必須以空字符結束,才能計算字符串的長度。
13.
char *str = s //錯誤,不能用string對象初始化char*
const char *str = s.c_str(); //正確
//c_str函數返回值是一個C風格的字符串,也就是函數返回的結果是一個指針,該指針指向一個空字符結束的字符數組
14.
//begin() 和 end() 獲取數組的頭尾指針
int a[] = {1,2,3,4,5,566,6};
for(int *i = begin(a);i!=end(a);i++)
{
*i = *i+1;
}
15.
當一個對象被用作右值的時候,用的是對象的值(內容);
當一個對象被用作左值的時候,用到是對象的身份(在內存中的位置);
16.一般情況下對於一個不知道大小的整數,用size_t,不用int,他會根據平臺的不同選擇不同的大小的內存
因爲與int固定四個字節不同有所不同,size_t的取值range是目標平臺下最大可能的數組尺寸,一些平臺下size_t的範圍小於int的正數範圍,又或者大於unsigned int. 使用Int既有可能浪費,又有可能範圍不夠大。
17.
靜態局部對象在程序的執行路徑第一次經過的時候對他進行初始化,並且直到程序終止才被銷燬,在此期間即使對象所在的函數結束執行也不會對他有影響。
size_t count_calls()
{
static size_t ctr = 0;
return ++ctr;
}
int main()
{
for(size_t i = 0;i!=10;i++)
cout<<count_calls()<<endl;
return 0;
}
17.通過傳入引用,隱式的返回其中的參數
//通過傳入引用occurs,最後將occurs隱式的返回
string::size_type find_char(const string& s, char c, string::size_type& occurs)
{
auto ret = s.size();
occurs = 0;
for (auto i = 0; i != s.size(); ++i)
{
if (s[i] == c)
{
if (ret == s.size())
ret = i;
++occurs;
}
}
return ret;
}
int main()
{
string s ="asdsfasdf";
int ctr = 0;
auto index = find_char(s,'s',ctr);
cout<<ret<<endl;
}
18.指針或者引用參與const,C++ 允許我們用字面值初始化常量引用
19
如果一個函數的定義爲
string::size_type find_char(string &s,char c,string::size_type &occurs);
這樣只能將find_char 函數作用於string類型的對象,類似於下面這樣的調用將發生錯誤。
find_char("Hello World",'o',ctr)//因爲字面值不能賦值給傳遞給普通引用形參,const的對象也不能傳值
給普通的引用。
20.
不能夠返回局部對象的指針或者引用
const string &manip()
{
string ret;
if(!ret.empty()) //錯誤:返回局部對象的引用!
return ret;
else
return "Empty"; //錯誤:“empty”是一個局部臨時對象
}
可以這樣用
const string &shortstring(const string &s1,const string &s2)
{
return s1.size() <= s2.size()?s1:s2;
}