在c語言當中,我們經常會遇見一些平時感覺怎麼用都不會出錯的小知識點,但是再將它的難度提高一點點的時候,或者將它改變一點點,我們就不再將它用起來那麼的得心應手。左值和右值正是乙個這樣的十足十的例子。在學習了指標知識之後,高度理解左值與右值便不再顯得那麼的無聊。
這個解釋看起來有點傻,但是不得不說:
左值就是那些能夠出現在賦值符號左邊的東西,右值就是那些能夠出現在賦值符號右邊的東西。
例如:a=b+25;
這裡,a是左值,它標識了乙個可以儲存結果值的點,也就是說,他有乙個可以自己掌控的固定的空間,b+25是右值,因為他指定了乙個值。
那麼他們可以互換嗎?
例如:b+25=a;
答案當然是不可以;
注意,當計算機計算b+25時它的結果必然儲存在機器的某個地方。但是程式設計師並沒有辦法**該結果會儲存在什麼地方,也無法保證下一次這個表示式的值仍然會存在原來的那個地放。其結果就是b+25不能當左值。因為他沒有固定的標識乙個點。
但是a可以作為乙個右值,因為每個位置都包括了乙個值。
所以總結了來看:
左值:我們主要用他的空間 ;
右值:我們主要用他的值。
字面值常量都不能為左值。
為了鞏固上面的所學理論,也為了讓我們更加的了解怎麼回事,我們現在開始將下面的例子深入討論:
當有**:
char ch=『a』;
char *cp=&ch;
那我們來看看下面的**是什麼意思?能否做左值?能否做右值?
&ch;
//&ch是位址常量,只能做左值,不能做右值;
cp;//cp是乙個變數,既有儲存空間,又有值,所以左值和右值都可以做;
&cp;
//&cp是位址常量,只能做右值,不能做左值。
*cp+1;
//它的運算順序是,現將cp解引用,再將cp的值加1,所以是乙個常量(在本題中,他表示給a+1,也就是字元b),只能做右值,不能左值;
*(cp+1);
//這裡的運算表示ch之後的一塊空間(讀取cp下乙個空間的內容),既可以做左值,又可以做右值;
++cp;
//這裡表示給ch的位址加1,也就是給位址常量加1,可以做右值,不可以做左值;
cp++;
//理由與++cp的理由相同;
*++cp;
//先自加,在解引用,表示了ch的下乙個空間(讀取下乙個空間的內容),既可以做左值,又可以做右值;
*cp++;
//理由同上;
(*cp)++;
//表示將ch的位址加1,是乙個常量,不可以做左值,但是可以做右值;
++*++cp;
++*cp++;
// 表示對ch的空間位址先前置++,在後置++,是乙個常量,不能做左值,但是可以做右值。
好了,先到這裡吧
關於右值引用的一些理解
右值引用之前看過不少次了,但過一段時間就忘了,這裡簡單整理一下我的理解 右值引用主要用來實現 移動語義 和 完美 1.移動語義 使用上可以用std move 把引數強制轉換成右值 我理解就是和淺拷貝很像,不過淺拷貝是多個指標指向堆上的空間,可能會重複釋放從而出錯,而移動語義是只有乙個指標占有堆上的空...
右值引用的一些測試
編譯 g std c 11 g fno elide constructors o0 test.cc o test fno elide constructors 用來關閉編譯器優化 include class a a 拷貝建構函式 a const a a value a.value 移動建構函式 a ...
關於C 的右值引用的一些看法
關於c 中的右值引用的詳細可以看這一批博文 從4行 看右值引用 那一篇博文詳細結合四行簡單的 詳細介紹了右值引用的使用方法和一些場景,非常實用。而本篇博文主要介紹一下我在學習右值引用的一些心得。因為在學習右值引用的時候,有一些地方非常難理解。所以寫下這一篇博文,防止遺忘,由於對於c 涉獵不多,所以有...