日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

理解C++ lvalue与rvalue

發(fā)布時(shí)間:2025/3/20 c/c++ 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 理解C++ lvalue与rvalue 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一個(gè)眾所周知的危險(xiǎn)錯(cuò)誤是,函數(shù)返回了一個(gè)局部變量的指針或引用。一旦函數(shù)棧被銷毀,這個(gè)指針就成為了野指針,導(dǎo)致未定義行為。而左值(lvalue)和右值(rvalue)的概念,本質(zhì)上,是理解“程序員可以放心使用的變量”。

?

空泛的討論先到這里,先看一段會(huì)報(bào)錯(cuò)的代碼:

#include <iostream>using std::cout; using std::endl;int foo(int &a) {return a; }int main() {int a = 1;cout << &a << endl;int *p = &foo(a); }

這里,對(duì)foo(a)取地址會(huì)引起錯(cuò)誤: "lvalue required as left operand of assignment".字面理解是,&取地址運(yùn)算符只能獲取左值的地址。

毫無疑問的是,foo(a)的值是存在的,是數(shù)值1。之所以報(bào)錯(cuò),是因?yàn)榫幾g器認(rèn)為它不是左值,不允許程序員獲取它存放的地址。

?

我對(duì)這點(diǎn)標(biāo)準(zhǔn)的理解是:

獲取一個(gè)臨時(shí)空間的地址通常意味著要對(duì)這塊內(nèi)存賦值。在C++程序中,臨時(shí)空間的銷毀時(shí)機(jī)是不確定(undefined)的,它隨時(shí)被用于其他臨時(shí)空間的存儲(chǔ)。于是程序員不允許使用這塊空間。聯(lián)系之前總結(jié)的堆棧概念,可以對(duì)C++中的變量存儲(chǔ)有更深的理解。

https://www.cnblogs.com/kinsang/p/6855579.html

?

在堆棧概念一文,我小結(jié)了C++程序中數(shù)據(jù)可以存在三個(gè)地方:

1. 函數(shù)棧,在函數(shù)體內(nèi)的定義的變量

2. 堆,特別指使用new,malloc獲取的內(nèi)存空間

3. 靜態(tài)數(shù)據(jù)區(qū),即.data 和.bss

?

對(duì)于lvalue的通俗描述,是“具有確定地址的非臨時(shí)對(duì)象”,而不滿足lvalue定義的值均被認(rèn)為是rvalue。換句話說,C++程序里面出現(xiàn)的值,非左即右。下面我們分析一下這三個(gè)存放數(shù)據(jù)的區(qū)域里面可以被使用的值的情況:

堆的空間上的變量完全由程序員申請(qǐng)和管理的,所以它們都有明確的地址,是可以放心使用的左值。

靜態(tài)數(shù)據(jù)區(qū)

對(duì)于靜態(tài)數(shù)據(jù)區(qū),盡管存放的位置是固定的,但里面的數(shù)據(jù)并不能認(rèn)為都是左值。主要是因?yàn)槔锩嬗小白置嬷怠?#xff0c;包括const所實(shí)現(xiàn)的常量,即靜態(tài)存儲(chǔ)而不能被修改的值。

函數(shù)棧

當(dāng)函數(shù)調(diào)用發(fā)生的時(shí)候,系統(tǒng)會(huì)創(chuàng)建函數(shù)棧,保留上下文,函數(shù)調(diào)用結(jié)束的時(shí)候,函數(shù)棧內(nèi)的變量會(huì)被銷毀。函數(shù)體里面定義的變量是左值,而臨時(shí)變量是右值。

?

拓展

C++ 11標(biāo)準(zhǔn),為了更好地利用臨時(shí)變量,提出Rvalue Reference,對(duì)應(yīng)的的實(shí)現(xiàn)是move semantics (轉(zhuǎn)移語意)和Perfect Forwarding(完美轉(zhuǎn)發(fā))。對(duì)這些新特性還不了解,暫時(shí)不寫。

?

參考:

http://www.cnblogs.com/dejavu/archive/2012/09/02/2667640.html

http://stackoverflow.com/questions/230584/where-are-variables-in-c-stored

http://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c

lvalue和rvalue

在計(jì)算機(jī)的遠(yuǎn)古時(shí)代,變量的lvalue和rvalue是指:
lvalue:變量在內(nèi)存中的位置。通過它能夠找到內(nèi)存中存放的變量(location value);
rvalue:存放在lvalue對(duì)應(yīng)的內(nèi)存中的東西(register value);
C++中的每個(gè)表達(dá)式要么是lvalue要么是rvalue。lvalue表示一個(gè)內(nèi)存位置,而rvalue表示計(jì)算表達(dá)式的結(jié)果。
rvalue引用是對(duì)有名稱變量的引用,并允許變量表示的內(nèi)存通過lvalue引用來訪問。
rvalue引用是對(duì)包含表達(dá)式結(jié)果的內(nèi)存位置的引用。

lvalue引用:

使用lvalue引用形參,可以編寫直接訪問調(diào)用者實(shí)參的函數(shù),避免了按值傳遞中的隱式復(fù)制。若不修改實(shí)參,只需要給lvalue引用類型使用const修飾符,以避免意外修改參數(shù)。無論是按值傳遞、按址傳遞參數(shù)或引用都是編譯器的規(guī)則,我們需要熟悉參數(shù)在不同情況下的傳遞,好的理解方式就是輸出地址來觀察。

lvalue引用:

使用lvalue引用形參,可以編寫直接訪問調(diào)用者實(shí)參的函數(shù),避免了按值傳遞中的隱式復(fù)制。若不修改實(shí)參,只需要給lvalue引用類型使用const修飾符,以避免意外修改參數(shù)。無論是按值傳遞、按址傳遞參數(shù)或引用都是編譯器的規(guī)則,我們需要熟悉參數(shù)在不同情況下的傳遞,好的理解方式就是輸出地址來觀察。

?

?

[cpp]?view plain?copy
  • #include?<iostream>??????
  • using?namespace?std;??
  • ??
  • void?add_1(int?&?num)??
  • {??
  • ????num?+=?1;??
  • }??
  • ??
  • int?main()??
  • {??
  • ????int?v?=?6;??
  • ????add_1(v);??
  • ????cout?<<"v="<<?v?<<?endl;??
  • ????return?0;??
  • }??
  • 輸出結(jié)果:v=7.

    rvalue引用:

    首先,舉一個(gè)報(bào)錯(cuò)的例子: [cpp]?view plain?copy
  • #include?<iostream>??????
  • using?namespace?std;??
  • ??
  • void?add_1(int?&&?num)??
  • {??
  • ????num?+=?1;??
  • }??
  • int?main()??
  • {??
  • ????int?v?=?6;??
  • ????add_1(v);??
  • ????cout?<<?"v="<<v?<<?endl;??
  • ????return?0;??
  • }??
  • 編譯會(huì)報(bào)錯(cuò):?無法將左值綁定到右值引用。 因?yàn)?#xff1a;lvalue不能通過rvalue引用,有rvalue引用形參的函數(shù)只能通過rvalue實(shí)參來調(diào)用,后面列舉正確編譯的例子: [cpp]?view plain?copy
  • #include?<iostream>??????
  • using?namespace?std;??
  • ??
  • void?add_1(int?&&?num)??
  • {??
  • ????num?+=?1;??
  • ????cout?<<?"num="?<<?num?<<?endl;??
  • }??
  • int?main()??
  • {??
  • ????int?v?=?6;??
  • ????int?s?=?4;??
  • ????add_1(v+s);??
  • ????cout?<<?"v="<<v?<<?endl;??
  • ????return?0;??
  • }??
  • 運(yùn)行結(jié)果:num=11,v=6.

    參考:

    ?

    ?

    http://blog.chinaunix.net/uid-7471615-id-83794.html

    http://blog.csdn.net/rogerhe/article/details/6410993?

    http://www.cnblogs.com/yunqie/p/5892252.html?

    轉(zhuǎn)載于:https://www.cnblogs.com/pityhero233/p/8601319.html

    總結(jié)

    以上是生活随笔為你收集整理的理解C++ lvalue与rvalue的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。