1. 程式人生 > >從彙編角度看c++引用(reference)

從彙編角度看c++引用(reference)

  每當提到c++中的引用時,我們的腦海中浮現的第一句話可能就是--引用就是一個變數的別名,但是引用的的型別到底是什麼?它和指標有什麼關係?它本身在記憶體中佔用空間麼?我們的編譯器是如何將它實現的呢?帶著這些疑問,我們今天就從彙編的角度來解析c++中的引用到底是什麼東西?

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.從彙編的角度來看引用的實現,首先我們開看看如下程式碼:
#include<stdio.h>
int main(){
	int a=1;
	int &b=a;
	printf("the value of c is: %d\n",b);
}
這是一個很簡單的程式,讓我們來看看g++(系統為ubuntu 16.04)下的幾行關鍵的彙編程式碼:

 movl   $0x1,-0x14(%ebp) 
 ebp暫存器存放的是棧底的地址,這條指令的意思是將1的值存放到距離棧底24位元組的位置,-0x18(%ebp)表示變數a的地址
 lea    -0x14(%ebp),%eax
 將a的地址存放到暫存器eax中
 mov    %eax,-0x10(%ebp)
 將暫存器eax的值存放到變數a的地址的上面(棧的擴充套件方向為從高低至到底地址)
 mov    -0x14(%ebp),%eax
 因為a是函式printf的引數,所以將a的值放到暫存器eax中
 sub    $0x8,%esp
 調整棧頂指標
 push   %eax
 將變數a入棧
 push   $0x8048550
 這裡的0x8048550是.rodata段中the value of c is: %d\n字串常量的地址,將這個字串常量的地址入棧
 call   8048330 <
[email protected]
>  呼叫函式printf,這裡使用的是動態連結中延遲繫結的方法,詳細內容請看《程式設計師的自我修養》動態連結一章
我們將程式碼修改如下:
#include<stdio.h>
int main(){
	int a=1;
	int &b=a;
	printf("the value of c is: %d\n",a);
	printf("the value of c is: %d\n",*(&a-1));
}
程式輸出如下


可見,在彙編的角度來看,引用的實現要藉助指標,但具體的實現方法是編譯器的事,我們不必細究.

相關推薦

彙編角度c++引用(reference)

  每當提到c++中的引用時,我們的腦海中浮現的第一句話可能就是--引用就是一個變數的別名,但是引用的的型別到底是什麼?它和指標有什麼關係?它本身在記憶體中佔用空間麼?我們的編譯器是如何將它實現的呢?帶著這些疑問,我們今天就從彙編的角度來解析c++中的引用到底是什麼東西?

彙編角度C++類的方法訪問類成員的原理

C++編譯後最終也是生成了機器碼,不需要直譯器或虛擬機器來執行。相比C語言,C++的類大大的方便了程式碼結構的組織,使得構建大程式簡便容易了很多。例項化一個類後,類的成員方法就可以訪問這個類的成員了,那麼從彙編角度看,到底是如何實現的呢?其實這個原理也十分簡單,

彙編角度檢視C語言函式呼叫約定【非常有用】

轉自:https://blog.csdn.net/Holmofy/article/details/76094986   為了防止出現不必要的程式碼影響組合語言的檢視,所以程式中不使用任何庫函式,以保持彙編程式碼的簡潔。 這裡所使用的彙編是VC的MASM。 預設函式呼叫方式_

Swift 列舉-彙編角度列舉記憶體結構

一、基本使用 先看列舉的幾種使用(暫不要問,看看是否都能看懂,待會會逐一講解) 1、操作一 簡單使用 //第一種方式 enum Direction { case east case west case south case north func testDi

彙編和底層的角度c和類c語言

從彙編和底層的角度看c和類c語言       寫這篇文章的目的是對近期底層學習的總結,也算是勉勵自己吧,畢竟是光靠興趣苦逼自學不是自己專業的東西要承受很多壓力。 https://blog.csdn.net/jggyyhh/article/details

使用角度 ReentrantLock 和 Condition

阻塞 transient string turn his 介紹 ner await dex java 語言中談到鎖,少不了比較一番 synchronized 和 ReentrantLock 的原理,本文不作分析,只是簡單介紹一下 ReentrantLock 的用法,從使用中

「前端資訊」剛上線的阿里達摩院官網,前端角度圈點之處

寫在前面: 從去年十月份,馬雲成立阿里巴巴達摩院,到今年9月28號一年整,阿里達摩院官網正式上線。作為從事網際網路行業的人,大抵都是會去達摩院官網看看的,本文即我個人從前端角度對達摩院官網,進行的一次簡單粗暴的測評,細數圈點之處,並提取一些作為前端可以值得借鑑和思考的程式碼技巧。第一次寫

原始碼角度Spring生命週期(官方最全)

Spring在beanfactory中給出了spring的生命週期的list列表 一、bean初始化前的處理 Bean factory implementations should support the standard bean lifecycle interfaces as

推廣角度:企業如何進行整合營銷

各種公司都在進行整合營銷,各個企業推廣負責人都在談論整合營銷的好處,到底什麼是整合營銷?企業如何進行整個營銷? 一、整合營銷的定義 其核心思想是將與企業進行市場營銷有關的一切傳播活動——例如一般廣告、直銷、銷售促進、公共關係以及CI、包裝和人員促銷——通過天衣無

「前端諮詢」剛上線的阿里達摩院官網,前端角度圈點之處

寫在前面: 從去年十月份,馬雲成立阿里巴巴達摩院,到今年9月28號一年整,阿里達摩院官網正式上線。作為從事網際網路行業的人,大抵都是會去達摩院官網看看的,本文即我個人從前端角度對達摩院官網,進行的一次簡單粗暴的測評,細數圈點之處,並提取一些作為前端可以值得借鑑和

網際網路+角度雲端計算的現狀與未來(1)

此文已由作者劉超授權網易雲社群釋出。歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。網際網路這個詞目前已經普遍化,這大概也歸功於羅振宇的羅輯思維對於網際網路概念的極力宣揚,似乎不加上網際網路三個字,企業宣傳都張不開嘴。於是網際網路+這個名詞就隨處可見了。支撐網際網路化的一個重要的力量就是雲端計算。但現在的雲

資料角度人臉識別中Feature Normalization,Weight Normalization以及Triplet的作用 資料角度人臉識別中Feature Normalization,Weight Normalization以及Triplet的作用

轉 從資料角度看人臉識別中Feature Normalization,Weight Normalization以及Triplet的作用 2018年10月19日 16:42:52

彙編視角函式呼叫

C語言函式如下 int bar(int c, int d) { int e = c + d; return e; } int foo(int a, int b) { return bar(a, b); } int main(void

原始碼角度for迴圈和foreach的區別

for迴圈和foreach的區別 關於for迴圈和foreach的區別,你真的知道,用了那麼多年使用起來已經很熟悉了,可突然問我講講這兩的區別,一下還真把我給卡住了一下,下面從原始碼的角度簡單分析一

jvm角度java多執行緒

最近在學習jvm,發現隨著對虛擬機器底層的瞭解,對java的多執行緒也有了全新的認識,原來一個小小的synchronized關鍵字裡別有洞天。決定把自己關於java多執行緒的所學整理成一篇文章,從最基礎的為什麼使用多執行緒,一直深入講解到jvm底層的鎖實現。 多執行緒的目的 為什麼要使用多執

【Android體驗】使用者角度,Android手機/應用應該要這樣:

  入手HTC HERO已經半年,雖然自己也是計算機專業的,但是對這個手機,我還是儘量的希望能夠以一個普通的使用者角度來體驗的,所以一直都沒有去了解android開發方面的知識。不過,在使用的過程中,還是免不了麻煩不得不瞭解了很多本來就不應該是一個普通手機使用者要了解的知識。本文是Google 暑期大學生部

原始碼角度php自增和自減】

自增和自減基礎 學過程式語言的同學應該都可以隨口說出 ++a 和 a++ 的區別,具體的區別如下: Example Name Effect ++$a Pre-increment Increments abyone,then

網際網路+角度雲端計算的現狀與未來(2)

此文已由作者劉超授權網易雲社群釋出。歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。六、業務架構趨勢一:網際網路衝擊已成必然,快速變更成為核心競爭力,DevOps重構組織架構,流程,文化是必然選擇在業務架構方面,我這裡強調的是服務化。是解決如何避免開發和運維的黑天鵝問題。所

記憶體角度解釋C語言變數屬性

1.儲存類 描述C語言變數儲存在記憶體中的地方。 記憶體有多種管理方法:棧,堆,資料段,bss段,.text段(程式碼段) (1)區域性變數分配在棧上。 (2)顯示初始化為非0的全域性變數,分配在資料段 (3)沒有初始化(預設為0)的全域性變數分配在b

【Android】原始碼角度Handler機制

在Android開發規範中,規定了主執行緒的任務的響應時間不能超過5s,否則會出現ANR,即程式無響應。為了避免這個問題的出現,常用的一個解決方案就是開闢新執行緒,在開闢出來的子執行緒中去處理耗時的業務,然後回到UI執行緒(主執行緒)來重新整理UI,這個過程中“