複習c++,有必要對一些東西做一下筆記,方便以後學習,如有問題,歡迎提出。
首先,最常用兩種復合型別應該是引用和指標。
所謂復合型別,是在基本型別基礎(如:int)上定義的型別。
引用是c++的乙個復合型別,首先,它和指標不同的是它並不是乙個物件,僅僅只是另乙個物件的別名。而且,引用繫結的東西必須是乙個物件,引用不是物件,所以定義引用的引用是不合法的。
也不能定義字面量的引用。同時,普通引用的繫結物件與引用定義型別必須相同。
如:
int &a=10;//錯誤的,不能定義字面量
double b = 1.22
;int &c = b;//
錯誤,必須是同一種型別。
雖然,普通的引用不能這麼定義。
關於const引用:
但是const引用卻可以,這意味著,像下面這樣的**是合理的:
實際上,這種形式正式下面要講的頂層const,約定指向物件時const,它是可以直接用常數為引用賦值,注意對比上面的。
這也正是為什麼可以為頂層const的函式引數傳遞常數的原因。
const int &a=10;double b = 1.22
;const int &c=b;
const int &d = 2*b;
為什麼const可以呢?這樣**在編譯過程中是這樣的
例如第三個:
int tem =b;const
int &c=tem;
系統生成了臨時物件。在c++primer中,作者給了這樣乙個解釋,const的引用時不允許對const所修飾的物件進行改變,這意味著,無法改變const引用所繫結的物件,自然也
無法改變tem,但是普通的引用,我們肯定是希望改變引用所繫結的物件的,不然為什麼要用引用,既然如此,如果這個規則在普通引用也試用,那改變的將是臨時物件,這肯定是矛盾的。
指標是另外一種符合型別。
指標是物件,這個和引用是不同的,它繫結的是另外乙個物件的位址。對未知位址的操作可能造成意想不到的效果。所以在指標並不知道指向**是,可以先指向null,或者c++新標準的nullptr。null是預處理變數,不屬於std空間,可以直接用。
指標陣列和陣列指標:
看這兩種指標定義:int *p[3]和int (*p)[3],有什麼不同呢。
int *p[3],強調了p[3]儲存的是int *,也就是這是乙個儲存指標的陣列,記憶體是三個int單元。
const是乙個限定符,表示常量。
指向常量的指標和指標常量:
被const限定的指標和引用,相當於簽訂了協議,表示這個指標或引用所對應的值將不會改變,然而所對應的值是否是常量並不要求,就好像我只約束我自己,你那邊怎麼樣我不管。
這意味著普通的指標或者引用不能繫結常量位址,而指向的常量指標或引用這可以繫結普通位址。
還有一種是 常量指標:int *const a;指約束自己,指標本身是常量。
頂層const和底層const:
top-level const(頂層const):本身是const
low-leve const(底層const):指向物件是const
之所以這樣分類是,因為,底層const約束自己不改變指向的值,所以在執行拷貝或拷出的時候,它要嚴格約定雙方都是底層,不允許對方改變指向物件的值。
而頂層const則約束的是自己,也就是指標或者別的基本資料型別本身不被改變,這意味著,在拷入和拷出並不需要都是頂層const,因為這樣的操作不會改變他自己。
關於頂層const的拷貝,舉例子:
int i = 0;const
int c = 2
;i = c;
c是乙個頂層const,因為它本身就是不可改變的物件,這種值拷貝並不在乎c是否為const。
關於底層const的拷貝,也舉個例子:
constint *b = 2
;int *p = b; //
錯誤的
這種情況下是錯誤的,底層const的拷出是嚴格的,b已經約定了它指向的物件是不會被改變的,而p變數本身沒有這種約定,b是不放心的。也就是說底層const在拷出的時候是嚴格的,雙方都應該是底層const。但是對於底層const,拷入確實可以的:
int i = 0;const *p = &i;
這是可以的,普通的int *可以轉換成const int*。
const形參和實參:
實際上,頂層const作為形參是會被編譯器忽略掉的,什麼意思,我們看個例子:
void fun(constinta);
void fun(int a);
看這兩種函式宣告,我們以為很開心的過載了,但是最後確報錯了,實際上,忽略了頂層const,這兩種宣告是完全一樣的。
我們可以對比這一種情況,如果還分不清底層或者頂層const的話:
void fun(constint&
a);void fun(int &a);
盡量使用常量引用:
實際上,在前面已經提到過:
int a = 1;int &b =a;
//我們可以這麼用
/但不可以這麼用
int &c = 1
; //不可以
//但可以這麼用
const
int &d = 1;
要是是這樣乙個函式:
void fun(int &a);
如果這麼呼叫:
fun(2);
會報錯。
但是如果是這樣的宣告:
void fun(constint &a);
就不會報錯了。
C 學習 C 復合型別
1.引用 引用是為某乙個變數起了另乙個名字,定義方式為type rval val 引用型別必須與引用的變數型別完全一致,引用後,rval和val將會被視為乙個變數,只不過有兩種呼叫方式,改變rval的值,val的值會隨之改變,改變val的值,對rval進行呼叫時值也發生了改變。將乙個值繫結後,將無法...
C 復合型別和函式總結
c 復合型別和函式總結 指標 型別 指標變數 int pi ival型別 宣告符,為解引用符 為取址符 constexpr 型別 常量表示式 decltype 返回運算元的型別 堆 heap 自由儲存區,動態儲存區 new 運算子在堆上動態分配空間 new 型別或new 型別 初始值 delete ...
C 復合型別
陣列 陣列是一種資料格式,能夠儲存多個同型別的資料。宣告陣列的通用格式 typename arrayname arraysize arraysize指定了元素的個數,它必須是整型常量 20或者const值 也可以是表示式,但是其中的所有值在編譯時必須是已知的,所以說arraysize不是變數,變數的...