C 指標和引用的用法

2021-06-13 19:12:29 字數 4775 閱讀 4797

一、基本知識

指標和引用的宣告方式:

宣告指標: char* pc;

宣告引用: char c = 'a'

char& rc = c;

它們的區別:

①從現象上看,指標在執行時可以改變其所指向的值,而引用一旦和某個物件繫結後就不再改變。這句話可以理解為:指標可以被重新賦值以指向另乙個不同的物件。但是引用則總是指向在初始化時被指定的物件,以後不能改變,但是指定的物件其內容可以改變。

②從記憶體分配上看,程式為指標變數分配記憶體區域,而不為引用分配記憶體區域,因為引用宣告時必須初始化,從而指向乙個已經存在的物件。引用不能指向空值。

③從編譯上看,程式在編譯時分別將指標和引用新增到符號表上,符號表上記錄的是變數名及變數所對應位址。指標變數在符號表上對應的位址值為指標變數的位址值,而引用在符號表上對應的位址值為引用物件的位址值。符號表生成後就不會再改,因此指標可以改變指向的物件(指標變數中的值可以改),而引用物件不能改。這是使用指標不安全而使用引用安全的主要原因。從某種意義上來說引用可以被認為是不能改變的指標。

④不存在指向空值的引用這個事實意味著使用引用的**效率比使用指標的要高。因為在使用引用之前不需要測試它的合法性。相反,指標則應該總是被測試,防止其為空。

⑤理論上,對於指標的級數沒有限制,但是引用只能是一級。如下:

int** p1;         // 合法。指向指標的指標

int*& p2;         // 合法。指向指標的引用

int&* p3;         // 非法。指向引用的指標是非法的

int&& p4;         // 非法。指向引用的引用是非法的

注意上述讀法是從左到右。

#include "stdio.h"

int main(void)

二、作為引數傳遞

利用引用的這個特性,可以用它作為函式的傳出引數。如程式3:

#include #include using namespace std;

int newevaluation(string& astr)

int main(void)

當然程式3引用傳遞的方式也可以寫成指標傳遞的方式,如程式5:

#include #include using namespace std;

int newevaluation(string* const astr)

int main(void)

三、函式指標和函式引用

函式指標是c++最大的優點之一。和使用普通指標相比,高階程式設計師只要有可能都更願意使用引用,因為引用更容易處理一些。然而,當處理函式時,函式引用對比函式指標就未必有這個優勢了。現有的**很少使用函式引用。下面將向介紹如何函式指標、如何使用函式引用以及分別在什麼情況下使用它們。

① 函式指標的例子

#include void print(int i)

void multiply(int& ndest, int nby)

void print_something()

int sayhello()

int main()

② 函式引用的例子

#include void print(int i)

void print2(int i)

void multiply(int& ndest, int nby)

void print_something()

int sayhello()

int main()

總結:

函式指標的宣告使用方式:

《想要指向的函式之返回型別》(*函式指標的名稱)《想要指向的函式之引數型別…>

如要想宣告乙個函式指標指向以下函式:

void print(int i)

那麼就可以如下操作: 

void (*pfunction)(int);

然後如下用函式的位址給pfunction賦值:

pfunction = &print;

在然後,pfunction就可以和函式print一樣使用了,比如,

pfunction(1);

等等。函式引用的宣告和使用方式:

《欲引用的函式之返回型別》(&函式引用的名稱)《欲引用的函式之引數型別…>=《欲引用的函式的名稱》,至所以如此,是引用在宣告的時候必須初始化,引用不能指向空值。

如要想宣告乙個函式引用指向以下函式:

void print(int i)

那麼就可以如下操作:

void (&rfunction)(int)=print;

在然後,rfunction就可以和函式print一樣使用了,比如,

rfunction(1);

等等。四、const修飾指標和引用

大致而言,const修飾指標和引用分三種情況,即const修飾指標、const修飾引用和const修飾指標的引用。下面分別討論之。

① const修飾指標

const修飾指標又分為三種情況,即const修飾指標本身、const修飾指標所指的變數(或物件)以及const修飾指標本身和指標所指的變數(或物件)。

a. const修飾指標本身

在這種情況下,指標本身是常量,不能改變,任何修改指標本身的行為都是非法的,例如:    

double pi = 3.1416;            

double* const pi = π

double alpha = 3.14;

pi = α // 錯誤。因為指標pi是常量,不能再被改變。

*pi = alpha; // ok。雖然指標pi不能被改變,但指標所指的變數或者物件可變。

b. const修飾指標指向的變數(或物件)

在這種情況下,指標本身可以改變,但const所修飾的指標所指向的物件不能被改變,例如:

double pi = 3.1416;

const double* pi = π

double alpha = 3.14;

*pi = alpha; // 錯誤。因為pi所指向的內容是常量,因此*pi不能被改變。

pi = α // ok。雖然指標所指的內容不能被改變,但指標pi本身可改變。從而通過這種方式改變*pi。

c. const修飾指標本身和指標所指向的變數(或物件)

在這種情況下,指標本身和指標指向的變數(或物件)均不能被改變,例如:

double pi = 3.146;

const double* const pi = π

//double const* const pi = π

cout << "pi = " << pi << endl;

cout << "*pi = " << *pi << endl;

double alpha = 3.14;

//*pi = alpha; // 錯誤。因為pi所指向的內容是常量,因此*pi不能被改變。

//pi = α // 錯誤。因為指標pi是常量,不能再被改變。

② const修飾引用

const修飾引用沒有指標修飾指標那麼複雜,只有一種形式。引用本身不能被改變,但所指向的物件是可以被改變的,見上面「一、基本知識」。

double pi = 3.1416;

//const double& pi = pi;

double const& pi = pi; //和上面一句是等價的

//double& const pi = pi; //有問題。很多編譯器會產生warning

cout << pi << endl;

③ const修飾指標引用

我們用例子來說明。

double pi = 3.14;

const double* ppi = π

//const double*& rpi = π //錯誤。不能將double* 轉換成const double *&

const double*& rpi = ppi; //ok。宣告指標引用的正確方法

說明:const double*& rpi = π 為什麼會出現錯誤呢?我們知道,引用是被引用物件的別名,正因為如此,由於rpi是ppi的別名,因此rpi和ppi的型別必須完全一致。從上面的**段我們可以看到,rpi的型別是const double*,而&pi的型別是double*,因此這句程式是錯誤的。

下面這段**和 ① 中的b中的情形對應(即內容不可變,指標可變):

double pi = 3.1416;

double api = 3.14;

const double* ppi = π

const double* papi = &api;

const double*& rpi = ppi;

const double*& rapi = ppi;

*rapi = api; // 錯誤。指標所指向的值不能被直接改變

rapi = papi; // ok。指標本身可以被改變

指標引用的用法還有其它的情形,由於罕用,故此不談及。

本文**:

C 常量指標 指標常量 引用和常引用的用法解析

今天學習c 的常量型別和引用,其中常量指標 指標常量 引用和常引用幾個概念較為接近,特地整理一下。1.常量指標 pointer to const 常量指標,顧名思義,是指向常量的指標,其定義的一般形式為 const t pointer name t為資料型別,target為t類資料。常量指標本身是可...

指標引用的用法

指標引用就是乙個指標的引用,看下面例1 int a 10 int b 20 void swap int lhs,int rhs swap a,b 上面的程式可以成功交換兩個int值,但是如果形參傳的是int而非其引用的話則不會交換2個int值,因為形參非引用的情況下,編譯器會複製a,b然後把a,b的...

指標引用的用法

指標引用就是乙個指標的引用,看下面例1 int a 10 int b 20 void swap int lhs,int rhs swap a,b 上面的程式可以成功交換兩個int值,但是如果形參傳的是int而非其引用的話則不會交換2個int值,因為形參非引用的情況下,編譯器會複製a,b然後把a,b的...