1. 程式人生 > >淺談C++中指標和引用的區別

淺談C++中指標和引用的區別

指標和引用在C++中很常用,但是對於它們之間的區別很多初學者都不是太熟悉,下面來談談他們2者之間的區別和用法。

1.指標和引用的定義和性質區別:

(1)指標:指標是一個變數,只不過這個變數儲存的是一個地址,指向記憶體的一個儲存單元;而引用跟原來的變數實質上是同一個東西,只不過是原變數的一個別名而已。如:

int a=1;int *p=&a;

int a=1;int &b=a;

上面定義了一個整形變數和一個指標變數p,該指標變數指向a的儲存單元,即p的值是a儲存單元的地址。

而下面2句定義了一個整形變數a和這個整形a的引用b,事實上a和b是同一個東西,在記憶體佔有同一個儲存單元。

(2)可以有const指標,但是沒有const引用;

(3)指標可以有多級,但是引用只能是一級(int **p;合法 而 int &&a是不合法的)

(4)指標的值可以為空,但是引用的值不能為NULL,並且引用在定義的時候必須初始化;

(5)指標的值在初始化後可以改變,即指向其它的儲存單元,而引用在進行初始化後就不會再改變了。

(6)"sizeof引用"得到的是所指向的變數(物件)的大小,而"sizeof指標"得到的是指標本身的大小;

(7)指標和引用的自增(++)運算意義不一樣;

2.指標和引用作為函式引數進行傳遞時的區別。

(1)指標作為引數進行傳遞:

複製程式碼
#include<iostream>
using namespace std;

void swap(int *a,int *b) {   int temp=*a;   *a=*b;   *b=temp; } int main(void) {   int a=1,b=2;   swap(&a,&b);   cout<<a<<" "<<b<<endl;   system("pause");   return 0; }
複製程式碼

結果為2 1;

用指標傳遞引數,可以實現對實參進行改變的目的,是因為傳遞過來的是實參的地址,因此使用*a實際上是取儲存實參的記憶體單元裡的資料,即是對實參進行改變,因此可以達到目的。

再看一個程式;

複製程式碼
#include<iostream>
using
namespace std; void test(int *p) {   int a=1;   p=&a;   cout<<p<<" "<<*p<<endl; } int main(void) { int *p=NULL; test(p); if(p==NULL) cout<<"指標p為NULL"<<endl; system("pause"); return 0; }
複製程式碼

執行結果為:

0x22ff44 1

指標p為NULL

大家可能會感到奇怪,怎麼回事,不是傳遞的是地址麼,怎麼p回事NULL?事實上,在main函式中聲明瞭一個指標p,並賦值為NULL,當呼叫test函式時,事實上傳遞的也是地址,只不過傳遞的是指地址。也就是說將指標作為引數進行傳遞時,事實上也是值傳遞,只不過傳遞的是地址。當把指標作為引數進行傳遞時,也是將實參的一個拷貝傳遞給形參,即上面程式main函式中的p何test函式中使用的p不是同一個變數,儲存2個變數p的單元也不相同(只是2個p指向同一個儲存單元),那麼在test函式中對p進行修改,並不會影響到main函式中的p的值。

如果要想達到也同時修改的目的的話,就得使用引用了。

2.將引用作為函式的引數進行傳遞。

在講引用作為函式引數進行傳遞時,實質上傳遞的是實參本身,即傳遞進來的不是實參的一個拷貝,因此對形參的修改其實是對實參的修改,所以在用引用進行引數傳遞時,不僅節約時間,而且可以節約空間。

看下面這個程式:

複製程式碼
#include<iostream>
using namespace std;

void test(int &a)
{
  cout<<&a<<" "<<a<<endl;
}

int main(void)
{
    int a=1;
    cout<<&a<<" "<<a<<endl;
    test(a);
    system("pause");
    return 0;
}
複製程式碼

輸出結果為: 0x22ff44 1

          0x22ff44 1

再看下這個程式:

這足以說明用引用進行引數傳遞時,事實上傳遞的是實參本身,而不是拷貝。

所以在上述要達到同時修改指標的目的的話,就得使用引用了。

複製程式碼
#include<iostream>
using namespace std;

void test(int *&p)
{
  int a=1;
  p=&a;
  cout<<p<<" "<<*p<<endl;
}

int main(void)
{
    int *p=NULL;
    test(p);
    if(p!=NULL)
    cout<<"指標p不為NULL"<<endl;
    system("pause");
    return 0;
}
複製程式碼

輸出結果為:0x22ff44 1

         指標p不為NULL

相關推薦

C++指標引用區別

指標和引用在C++中很常用,但是對於它們之間的區別很多初學者都不是太熟悉,下面來談談他們2者之間的區別和用法。1.指標和引用的定義和性質區別:(1)指標:指標是一個變數,只不過這個變數儲存的是一個地址,指向記憶體的一個儲存單元;而引用跟原來的變數實質上是同一個東西,只不過是原變數的一個別名而已。如:int a

初夏小C++指標引用“”的區別

1.引用只能繫結一個實體,而指標可以指向不同實體2.使用指標時要判空,而引用不需要因此更安全3.引用在定義時必須初始化,指標不做要求4.在sizeof中:引用結果是引用型別的大小,但指標始終是地址空間所佔位元組個數 void Size() { long long x =

C++指標引用區別、以及引用取地址符&的區別

一. 指標和引用的區別 對於指標來說,它是一個地址,這個地址是一個數值,那麼就意味這個數值可以為0(空指標),也可以為其他,即指標可以不指向任何東西。 而對於引用來說,他是一個外號,外號一定是“某個存在物體”的外號,所以引用不能為空,即不能存在空引用。例如我們給小明起了個外號:明明,那我們說

C++指標引用區別

下面用通俗易懂的話來概述一下: 指標-對於一個型別T,T*就是指向T的指標型別,也即一個T*型別的變數能夠儲存一個T物件的地址,而型別T是可以加一些限定詞的,如const、volatile等等。見下圖,所示指標的含義: 引用-引用是一個物件的別名,主要用於函式引

Mybatis的 ${ } #{ }的區別

mybatis sql註入 語句 nbsp 之前 com pre 預編譯 sql 語句 一、舉例說明 1 select * from user where name = "dato"; 2 3 select * from user where name = #

C++指標引用還有*&的關係

*是取值,&是取地址。 在函式定義宣告的時候按照谷歌規範,輸入是const &型別的,輸出是指標型別的。 在使用過程中如果輸入是上一個函式的輸出,在使用的時候需要使用&或者星號×指標進行處理。 在函式宣告過程中使用&表示引用,函式內對引數進行了修改外部也會發生

關於C++指標引用的速度

想寫這篇博文的起因是某天突然有人問我,你知道C++中指標和引用有什麼差別嗎,我就按照我所以知道的嘰裡呱啦的講了一堆(其實也就是隨便拿本C++書都有說的那些),我講完後對方得意地說你沒講到重點,重點是引用要比指標快得多。我一聽傻了,說實話我從來沒想過這個問題,既然有人說了,那就

C#的值類型引用類型

title log 創建 編譯 設計 編寫 通過 發布 構造 在C#中,值類型和引用類型是相當重要的兩個概念,必須在設計類型的時候就決定類型實例的行為。如果在編寫代碼時不能理解引用類型和值類型的區別,那麽將會給代碼帶來不必要的異常。很多人就是因為沒有弄清楚這兩個概念從而在編

【.Net】C#的值類型引用類型

rem 理解 amp div net 親情 實例 函數 大小 在C#中,值類型和引用類型是相當重要的兩個概念,必須在設計類型的時候就決定類型實例的行為。如果在編寫代碼時不能理解引用類型和值類型的區別,那麽將會給代碼帶來不必要的異常。很多人就是因為沒有弄清楚這兩個概念從而在編

c++結構體共用體的區別

ont 基本類型 erl list 變量名 ext 使用結構體 oot 數據格式 在c++中,結構體(struct)和共用體(union)是兩種很相似的復合數據類型,都可以用來存儲多種數據類型,但是兩者還有很大的區別。 結構體(struct) 結構是用戶自定

【分析】C#Control的Invoke與BeginInvoke在主副線程的執行順序區別(SamWang)

info start result 初步 總結 inter blank rap 傳遞   今天無意中看到有關Invoke和BeginInvoke的一些資料,不太清楚它們之間的區別。所以花了點時間研究了下。   據msdn中介紹,它們最大的區別就是BeginInvoke屬於

C的mallocfree (指標與空間 堆與棧)

淺談C中的malloc和free 在C語言的學習中,對記憶體管理這部分的知識掌握尤其重要!之前對C中的malloc()和free()兩個函式的瞭解甚少,只知道大概該怎麼用——就是malloc然後free就一切OK了。當然現在對這兩個函式的體會也不見得多,不過對於本文章第三

Mysqlwherehaving的區別

where和having的區別一、誤區:不要錯誤的認為having和group by 必須配合使用.二、where和having用法解析:1、 where和having都可以使用的場景: select goods_price,goods_name from goods where goods_price &g

[轉載]c#的delegateevent了

作者講的很好,風趣幽默,娓娓道來https://www.cnblogs.com/chunhui212/p/5887579.html delegate delagete可以實現將方法作為引數傳遞,理解為函式指標,它允許傳遞一個類A的方法m給另一個類B的物件,使得類B的物件能夠呼叫這個方法m。其

C的mallocfree

一、malloc()和free()的基本概念以及基本用法: 1、函式原型及說明: void *malloc(long NumBytes):該函式在堆上分配了NumBytes個位元組的空間,並返回了指向這塊記憶體的指標。如果分配失敗,則返回一個空指標(NULL)。 關於分

C++ 的 new/delete new[]/delete[]

在 C++ 中,你也許經常使用 new 和 delete 來動態申請和釋放記憶體,但你可曾想過以下問題呢? new 和 delete 是函式嗎? new [] 和 delete [] 又是什麼?什麼時候用它們? 你知道 operator new 和 operator delete 嗎? 為什麼

【面試常見問題】【C++】指標引用區別,有哪些不同點,細細道1

首先咱們弄清楚複合型別(Compound type)這個概念,因為指標和引用是Compound type中的兩種! 引用(reference): 何謂“引用”,這麼說吧,相信每個人都有個乳名,後來等到你升學入職啥的發現乳名B格很Low ! 這時候需要為自己起另外一個名字

C的wprintf寬字元顯示

 今天在CSDN的Blog首頁看到一篇文章“也談計算機字元編碼 ”,由於前一陣業餘翻譯了“UTF-8 and Unicode FAQ for Unix/Linux”一文,自己對字符集、編碼和Unicode等內容一直保著者很強的興趣,自然不會放過這樣的文章。作者的文章寫得很明白

AndroidSerializableParcelable使用區別

Android中序列化有兩種方式:Serializable以及Parcelable。其中Serializable是Java自帶的,而Parcelable是安卓專有的。 一、Serializable序列化 serializable使用比較簡單,只需要對某個類實現Serializable 介面即可。 Ser

javaSEsetlist的區別

一、關於集合類 set和list首先是java中的集合類,那麼可以簡單介紹下集合類。 現在有個簡單問題。 把一個公司每個員工作為一個物件,那麼這個公司就有了很多這樣的員工物件,該如何儲存這些物件? 如果使用原始的陣列方式,且不說員工物件的個數不確定,即使現在確定下來,每天都