引用和指標的那些事

2022-09-02 12:45:10 字數 3532 閱讀 2265

2.3.1 引用

引用並非物件,相反的,它只是為乙個已存在物件所起的另外乙個名字。

示例:int ival = 1024;

int &refval = ival;

tips:

1.除2種情況外,引用的型別要和與之繫結的物件嚴格匹配

2.引用必須被初始化,且一旦初始化後,它和初始值物件一直繫結在一起,不能更改繫結的物件

3.引用本身不是乙個物件,所以不能定義引用的引用

2.3.2 指標

取位址符(操作符&), 解引用符(操作符*)

示例:int ival = 42;

int *p = &ival;

指標的4種狀態:

a. 指向乙個物件

b.指向相鄰物件所佔空間的下乙個位置

c. 空指標,指標沒有指向任何物件

d. 無效指標,就是上述情況外的其他值

如果指標指向了乙個物件,則允許使用解引用符*來訪問該物件(解引用,僅用於有指定物件的有效指標):

如上例操作物件,直接用 *p。

空指標的3種生成方式:

a. int *p1 = nullptr; (c++11新引入,推薦使用)

b. int *p2 = 0;

c. int *p3 = null;

tips:

1.除2種情況外,指標的型別要和它指定的物件嚴格匹配。

2.建議初始化所有指標。

3.賦值操作時,永遠改變的是等號左側的物件。

int *pi = 0;

pi = &ival; //pi的值被改變,現在pi指向了ival

*pi = 0; //ivald的值發生改變

4.將指標作為if語句的判斷條件時,指標值為0,則為false;指標值非0,則為true。

5.void*指標可用於存放任意物件的位址,其記憶體空間僅僅是記憶體空間,沒法訪問記憶體空間所存的物件,

所以void* 指標能做的事比較有限: 拿它和別的指標比較;作為函式的輸入或輸出,或者賦值給另外乙個void*指標

補充(理解復合型別的宣告:):

1.int* p1,p2; //p1是指向int的指標,p2是int型整數

int *p1,*p2; //p1和p2都是指向int的指標

2.指向指標的指標:

通過*的個數可以區分指標的級別,如**表示指向指標的指標。***表示指向指標的指標的指標。,如:

int ival = 1024;

int *pi = &ival; //pi指向乙個int型的數(ival)

int **pi = π //ppi指向乙個int型指標(pi)

3.面對比較複雜的指標或者引用的宣告語句時,從右向左閱讀有助於弄清它的真實含義。如:

int i =42;

int *p; //p是乙個int型的指標

int *&r = p; //r是乙個對指標p的引用

r = &i;

*r=0;

第三行,要理解r的型別到底是什麼,從右到左閱讀r的定義。離變數名r最近的符號(此例是&r符號的&)對變數的型別最直接的影響,

因此r是乙個引用,宣告符的其他部分用來確定r引用的型別是什麼(此例中的符號*,說明r引用是乙個指標)

2.4 const限定符

1. const物件一旦建立後其值就不能再改變,所以const物件必須初始化。

2. 預設情況下,const物件僅在檔案內有效。若想在多個檔案中宣告並使用它,需要新增關鍵字extern:

//file_1.cc

extern const int bufsize = fcn();

//file_1.hh標頭檔案,與cc中定義的bufsize是同乙個

extern const int bufsize;

3.1-const的引用(常量引用):

const int ci =1024;

const int &r1 = ci; //正確,引用及其對應的物件都是常量

tips:

a. 允許為乙個常量引用繫結乙個非常量的物件、字面值,甚至是個一般表示式:

int i = 42;

int &r1 = i;

const int &r2 = i; //正確,允許將const int&繫結到乙個普通的int 型別

const int &r3 = 42; //正確

r1 = 0; //正確

r2 = 0; //錯誤,r2是乙個常量引用

補充: 常量引用對於引用的物件本身是不是常量未作限定,僅對引用可參與的操作做出了限定

b. 乙個常量引用被繫結到另外一種型別上:

double dval = 3.14;

const int &r1 = dval; //r1會繫結到由dval臨時生成的int型臨時量(物件)

3.2-指標和const:

與引用一樣,想要存放常量物件的位址,只能使用指向常量的指標

const double pi = 3.14;

const double *cptr = π //cptr可以指向乙個雙精度常量

const指標:

常量指標必須初始化。而且一旦初始化則它的值就不能再改變了。

把*放在const關鍵字之前用以說明是乙個常量,也意味著不變的是指標本身的值而非指向的那個值。(從右向左讀)

int errnumb = 0;

int *const currerr = &errnumb; //currerr將一直指向errnumb

const double pi = 3.14;

const double *const pip = π //pip是乙個指向常量物件的常量指標

3.3-頂層const:

指標:頂層const:表示指標本身是乙個常量

底層const:表示指標所指的物件是乙個常量

int i =0;

int *const p1 = &i; //頂層const

const int ci = 42; //頂層const,不能改變ci的值

const int *p2 = &ci; //底層const

const int *const p3 = p2; //右邊的是頂層const,左邊的是底層const

const int &r = ci; //用於宣告的const都是底層const

執行物件的拷貝操作時,頂層const不受什麼影響。但是,拷入和拷出的物件必須具有相同的底層const資格。

或者兩個物件的資料型別必須能相互轉換,一般來說,非常量可以轉換為常量,反之則不行。

int *p = p3; //錯誤:p3包含底層const的定義,而p沒有

p2 = p3; //正確:p2和p3都是底層const

p2 = &i; //正確:int*能轉換成const int*(指的是i)

int &r = ci; //錯誤:普通的int& 不能繫結到int常量上

const int &r2 = i; //正確:const int& 可以繫結到乙個普通int上

3.4 constexpr和常量表示式

後續補充

二、處理型別

指標和引用那些事

指標和引用的概念 引用 乙個已定義變數別名 指標和引用區別 1 指標是乙個位址,指向記憶體中一塊儲存單元,它的值可以發生變化,可以指向其他儲存單元 引用是乙個變數別名,和原來變數是同乙個東西,即在記憶體中占有同一儲存單元,被編譯器實現為const指標,並且不可被多次初始化 重定義 話不多說,看下面例...

指標的那些事

關於指標,大家都不陌生,無論學習c,c 亦或者其它程式語言,它都是不可或缺的。但是指標的定義 指標的用法 等等各種問題。我們都必須弄清楚,不能讓他阻礙我們前進的步伐 先說int p 這裡有必要說明一下 int 表示的定義乙個指向int 型別的指標變數 該變數記憶體裡是所指物件的位址,用 指標運算子 ...

C C 和指標 printf 的那些事

一,printf 1 作用 產生格式化輸出的函式 定義在 stdio.h 中 2 用法 int printf const char format,argument format 引數輸出的格式,定義格式為 flags width perc f n h l type 規定資料輸出方式,具體如下 1.t...