【C++】---指針和引用的區別

兩者本質

引用是別名,指針是地址、實體

兩者區別

不同點 分析
1.初始化要求不同 引用在創建的同時必須初始化,即引用到一個有效的對象,而指針在定義的時候不必初始化,可以在定義後面的任何地方重新賦值。
2.可修改性性不同 引用一旦被初始化爲指向一個對象,它就不能被改變爲另一個對象的引用;而指針在任何地方都可以改變爲指向另一個對象。給引用賦值並不是改變它和原始對象的綁定關係。
3.不存在NULL引用 引用不能使用指向空值的引用,它必須總是指向某個對象;而指針則可以是NULL,而不需要總是指向某些對象,可以把指針指向任意的對象,所以指針更加靈活,但是也更容易出錯
4.測試需要的區別 由於引用不會指向空值,這意味着使用引用前不需要測試它的合法性,而指針則需要經常進行測試。因此使用引用的代碼效率比使用指針的效率要高。
5.應用的區別 如果是指一旦指向一個對象後就不會改變指向,那麼應該使用引用。如果有存在指向NULL(不指向任何對象)或在不同的時刻指向不同的對象這些可能性,應該使用指針更爲穩妥一些。
6.運算符的區別 指針和引用的自增(++)運算意義不同,引用自加即引用的實體增加1,指針自加即指針向後偏移一個類型的大小
7.計算對象大象大小 "sizeof 引用"得到的是所指向的變量(對象)的大小,而"sizeof 指針"得到的是指針本身的大小。
8.多級的區別 有多級指針,但是不存在多級引用,只能有一級引用。
9.訪問時的區別 引用訪問的是一個變量,是直接訪問的,而指針則是訪問一個變量則是在間接訪問的。
10.const的區別 引用沒有const,指針有const,const指針不可變。

兩者的相同點

指針指向一塊內存,它的內容是所知內存的的地址;引用則是某塊內存的別名。

int main()
{
 int aa = 10;
 int& wa = a;
 
 cout<<"&aa = "<<&aa<<endl;
 cout<<"&wa = "<<&wa<<endl;
 return 0; 
}

總的來說,引用即具有指針的效率,又具有變量使用的方便性和直觀性。

爲什麼傳引用比傳指針更安全

答:由於不存在空指針,並且引用一旦被初始化爲指向一個對象,它就不能改變爲另一個對象的引用,因此引用更爲安全。
對於指針來說,它可以隨時指向別的對象,並且可以不被初始化,或爲NULL,所以不安全,const指針任然存在空指針,並且有可能產生野指針。

指針:對於一個類型T,T就是指向T的指針類型,也就是一個T類型的變量能夠保存一個對象的地址,而類型T是可以加一些限定詞,如const等等。

char a='A';
char* p=&a;

![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20191221192801875.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0wxOTAwMlM=,size_16,color_FFFFFF,t_70
引用:引用是一個對象別名,主要用於函數參數和返回值類型,符號X&標識X類型的引用。

int i=1;
int &r=1;
int x=r;
r=2;

int* p=&r;

在這裏插入圖片描述
做參數

void Swap(int& left, int& right) 
{
 int temp = left;
 left = right;
 right = temp;
}

做返回值

int& Test(int& a)
 {
 a += 10;
 return a; 
 }

兩者做參數效率的比較

#include <time.h>
struct A {
 int a[10000];
};
void Test1(A a)
{}
void Test2(A& a)
{}
void Test3()
{
 A a;
 // 以指針作爲函數參數
 size_t begin1 = clock();
 for (size_t i = 0; i < 10000; ++i)
 Test1(a);
 size_t end1 = clock();
 
 // 以引用作爲函數參數
 size_t begin2 = clock();
 for (size_t i = 0; i < 10000; ++i)
 Test2(a);
 size_t end2 = clock();
 // 分別計算兩個函數運行結束後的時間
 cout << "Test1(int*)-time:" << end1 - begin1 << endl;
 cout << "Test2(int&)-time:" << end2 - begin2 << endl; }
// 運行多次,檢測指針和引用在傳參方面的效率區別
int main()
{
    for (int i = 0; i < 10; ++i)
    {
      Test3();
    }
 return 0; 
 }

在這裏插入圖片描述

兩者做返回值效率的比較

#include <time.h>
struct A {
	int a[10000];
};
A a; A Test1()
{
	return a;
}

A& Test2()
{
	return a;
}
void Test3()
{
	// 以指針作爲函數的返回值類型
	size_t begin1 = clock();
	for (size_t i = 0; i < 100000; ++i)
		Test1();
	size_t end1 = clock();
	// 以引用作爲函數的返回值類型
	size_t begin2 = clock();
	for (size_t i = 0; i < 100000; ++i)
		Test2();
	size_t end2 = clock();
	// 計算兩個函數運算完成之後的時間
	cout << "Test1 time:" << end1 - begin1 << endl;
	cout << "Test2 time:" << end2 - begin2 << endl;
}
// 測試運行10次,指針和引用作爲返回值效率方面的區別
int main()
{
	for (int i = 0; i < 10; ++i)
	Test3();
	system("pause");
	return 0;
}

在這裏插入圖片描述
由效率測試可以看出,在效率方面,無論是引用做參數還是返回值,時間花費的相對更少。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章