c 學習總結 復合型別,const。

2022-05-17 15:03:18 字數 2999 閱讀 7580

複習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的拷貝,也舉個例子:

const

int *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(const

inta);

void fun(int a);

看這兩種函式宣告,我們以為很開心的過載了,但是最後確報錯了,實際上,忽略了頂層const,這兩種宣告是完全一樣的。

我們可以對比這一種情況,如果還分不清底層或者頂層const的話:

void fun(const

int&

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(const

int &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不是變數,變數的...