【C語言】什麼是 lvalue,什麼是 rvalue?

2021-02-19 魚C工作室

什麼是左值(lvalue)和右值(rvalue)?

隨著學習的深入,你會經常看到 lvalue 這個詞。

一般出現在諸如各種、書籍中,更頻繁遇到的是在你的錯誤提示中:


一般你會看到這個是因為你的代碼這麼寫:

……

        int i;

        5 = i;

……

一些朋友想當然的就覺得 lvalue 指的就是賦值運算符左邊的那個值,而 rvalue 當然就是右邊那個值啦。

所以我們親切的稱呼它們為「左值」和「右值」。

你也是這麼想的,對吧?

事實上這樣理解並不全面,並且常常容易犯思想上的錯誤……

OK,今天小甲魚就嘗試給 lvalue 正名!

首先,我們找到 C 語言的作者問問究竟,他是這麼說的:

《The C Programming Language》

"An object is a manipulatable region of storage; an lvalue is an expression referring to an object.

...

The name 'lvalue' comes from the assignment expression E1 = E2 in which the left operand E1 must be an lvalue expression."

看到這裡,大家就會說了,這不明擺著嗎?人家作者都說了,E1 = E2,這個 E1 就是 lvalue(左值),你還鬧騰個啥?

因為 C 語言是在不斷發展的,畢竟老頭的這本書說的是 C 語言的原型,自 1988 年第二版之後就沒有再出新版了。而 C 的標準則經歷了 K&R C,C89,C90,C99,C11 的迭代……

好吧,我們找來了目前最廣泛使用的 C99 標準:

The name "lvalue" comes originally from the assignment expression E1 = E2, in which the left operand E1 is required to be a (modifiable) lvalue. It is perhaps better considered as representing an object "locator value". What is sometimes called "rvalue" is in this International Standard described as the "value of an expression".

這裡說的很清楚了,lvalue 這個名字最初確實來自於 E1 = E2(E1 就是那個可改變的左值)。但更合理的解釋應該是將 lvalue 理解為 locator value(特定位置的值),rvalue 則應該是 value of an expression(表達式的值)。

所以,單純用左邊(left-value)和右邊(right-value)來理解是不全面的。

請嘗試執行下邊代碼:

#include <stdio.h>

int main()

{

        int a = 5;

        ++(a++);

        return 0;

}

你會得到下邊錯誤提示:


在這裡如果你認為 lvalue 只是賦值運算符左邊那個值,那這個錯誤提示就無法理解了。

但是如果你知道 lvalue 是用於識別或定位存儲位置的標識符,那麼就好解釋了:

(a++) 是先將變量 a 的值(5)做為整個表達式的值返回,再將 a 自增 1(類似於 a = a + 1)。

所以這裡 ++(a++); 相當於 ++(5), a = a + 1; 

那當然要報錯啦,5 是一個常量,當然不能給你 5 = 5 + 1 咯~

好了,差不多是這樣了,謝謝大家花時間聽小甲魚扯淡~

重要的內容要重複強調:C 語言的術語 lvalue 指用於識別或定位一個存儲位置的標識符。(注意:左值同時還必須是可改變的)

噢,對了,說了這麼多,應該說說 rvalue 了吧?

其實 rvalue 的發明完全是為了搭配 lvalue,rvalue 你可以理解為 readable value,即任何可讀取的值都被認為是右值(非左值)。

相關焦點

  • 【R函數學習】R語言時間序列函數整理
    ( m2=arima(prop, order = c(1,0,0),method="ML", include.mean = F) ) #用AR(1)模型擬合,不含截距項。運行Box.test(r,type="Ljung-Box",lag=6,fitdf=1)後,顯示的結果:Box.test(r,type="Ljung-Box",lag=6,fitdf=1) Box-Ljung testdata: r X-squared = 5.8661, df = 5, p-value = 0.3195「df = 5」
  • R語言時間序列函數大全(收藏!)
    tsdiag(m1) #對估計進行診斷,判斷殘差是否為白噪聲summary(m1)r=m1$residuals #用r來保存殘差Box.test(r,type=」Ljung-Box」,lag=6, fitdf=1)#對殘差進行純隨機性檢驗,fitdf表示殘差減少的自由度AutocorTest(m1$resid) #加載FinTS包
  • C語言太簡單?這14道C語言謎題,你能答對幾個?
    通過這些迷題,希望你能更了解C語言。如果你不看答案,不知道是否有把握回答各個謎題?讓我們來試試。下面的程序並不見得會輸出"hello-std-out",你知道為什麼嗎?要知道為什麼,你需要知道printf的返回值是什麼。printf返回值是輸出的字符個數。下面的程序會輸出什麼?
  • C語言中的奇技淫巧
    前言學習C語言的過程中,總會遇到很多令人眼前一亮的代碼,尤其是你寫了幾十行的代碼,別人只用了簡單幾行的遞歸就實現的功能
  • 我的R語言學習方法
    通過運營R語言公眾號,認識了各行各業在學習和使用R語言的朋友們。經常會遇到這些問題:我是R新手,要怎樣學習R語言?我要學習R語言,需要學習那些內容?王老師,R語言學習,有什麼書籍或者視頻推薦和分享嗎?等等。
  • C語言 | 求圓周長 面積 表面積 體積
    「要成為絕世高手,並非一朝一夕,除非是天生武學奇才,但是這種人…萬中無一」這道理放在C語言學習上也一併受用
  • 學習c語言筆記——C庫函數printf()
    c語言中的printf是什麼來的?」。我答:「它是一個函數,主要用來輸出運算結果。」 ,下面就給大家介紹C庫函數printf()使用方法。下面我們通過一個調用c庫函數的c語言案例來說明printf()函數的使用方法,如c語言1。
  • C語言 | 大寫字母A轉換為小寫a
    在編程方面有著天賦異稟的人畢竟是少數,我們大多數人想要從C語言小白進階到高手,需要經歷的是日積月累的學習。那麼如何學習呢?當然是每天都練習一道C語言題目!!作者閆小林白天搬磚,晚上做夢。我有故事,你有酒麼?解題思路:字符數據以ASCII碼存儲在內存的,形式與整數的存儲形式相同,所以字符型數據和其他算術型數據之間可以互相賦值和運算。
  • 教您用R語言畫直方圖!| 繽紛燦爛R語言 | 醫學方R語言高階課程
    泰坦尼克是當時的一艘巨輪,輪船上的乘客的年齡分布十分廣泛,生存率各有不同,我們現在想看看,隨著年齡的變化,生存率有什麼變化。此處我們把年齡作為連續型變量。>xmax = max(X)xmin = min(X)#這三步是為了找到x軸的取值範圍plot(h1, ylim=c(hmin, hmax), col="green", xlim=c(xmin, xmax))
  • 自學C語言的最大難題是什麼?
    萬事開頭難,自學C語言最大的困難在於遇到問題不知道如何解決,還有不知道學到什麼程度才能找到工作,這是自學程式語言最大的障礙,學到中間不知道什麼時候是個頭
  • R語言學習 - 熱圖美化
    "ID"))head(data_m)  ID variable      value1  a    Grp_1   5.9580732  b    Grp_1  19.6305823  c    Grp_1 100.3512994  d    Grp_1 600.0000005  a    Grp_2   5.8436526  b    Grp_2  20.376791
  • 【必讀乾貨】5個讓人驚呼「臥槽」的C語言例子,你一定不能錯過
    = c; f[b++] = a/5);    for(; d=0,g=c*2,c>5000; c--,printf("%.4d",e+d/a),e=d%a)    for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);     } 執行結果:
  • C語言 | 選擇1或2調用max或min
    「要成為絕世高手,並非一朝一夕,除非是天生武學奇才,但是這種人…萬中無一」這道理放在C語言學習上也一併受用
  • 《R語言實戰》菜雞筆記(八):回歸
    = women[-c(13, 15),])opar <- par(no.readonly=TRUE)par(mfrow = c(2, 2))plot(fit_7)par(opar)fit_4 <- lm(Murder ~ Population + Illiteracy + Income + Frost, data=data_1)opar <- par(no.readonly
  • C語言 | 三目運算實現判斷大寫
    在編程方面有著天賦異稟的人畢竟是少數,我們大多數人想要從C語言小白進階到高手,需要經歷的是日積月累的學習。那麼如何學習呢?當然是每天都練習一道C語言題目!!作者閆小林白天搬磚,晚上做夢。我有故事,你有酒麼?例7:輸入一個字符,判別它是否為大寫字母,如果是,將它轉換成小寫,如果不是,不轉換。然後輸出最後得到的字符,要求使用三目運算符。
  • p-value到底是什麼?
    對於大部分小夥伴來說,在日常數據分析中,經常會使用p-value的大小來判斷不同處理或兩個樣本之間是否存在顯著性差異。我們先來看幾個概念。
  • 看了這幾個C語言例子,你一定和我一樣連說5個臥槽...
    z(p,q):q;n=p;for(i=41;i<79;i++y o[i++]='\r';o[i++]=0;v o);(void)fflush(stdout);sleep(1);}main(a,c)char**c;{char*u,*malloc(),*m="Usage: black [string]\n\0No more memory\n\0Unusable memory
  • 如果是初學C語言請看完,如何學好C語言絕對精品
    當然,如果讓你們帶著現在的知識回到他們的那個時代,那麼就沒有什麼圖靈獎了。    C語言程序設計是我們的專業基礎課,但是C語言本身卻是一個非常強大的工具,它是到目前為止最為廣泛使用的工具,並且在可以預見的將來,它仍然是皈依為程式設計師的人們心中的神器。這個工具作什麼的呢?它在人和機器之間建立了一個交流的平臺。
  • R語言繪製堆疊柱形圖示例
    barplot 查看該命令詳情png('barplot_plot.png', width = 1000, height = 700)par(xpd = TRUE, mar = par()$mar + c(1, 3, 1, 16)) barplot(as.matrix(100 * phylum_top10), col = c('#8DD3C7', '#FFFFB3',
  • 怎樣學習C語言(獻給迷茫的C愛好者)!
    當然,假設讓你們帶著如今的知識回到他們的那個時代,那麼就沒有什麼圖靈獎了。C語言程序設計是我們的專業基礎課,可是C語言本身卻是一個非常強大的工具,它是到眼下為止最為廣泛使用的工具,並且在能夠預見的將來,它仍然是皈依為程序猿的人們心中的神器。這個工具作什麼的呢?它在人和機器之間建立了一個交流的平臺。