左值 右值 從int a 3 談起

2021-05-27 21:24:55 字數 3446 閱讀 3526

今天,我們來講

c語言最常見,最微不足道的一行**:

int a = 3;

千萬別小看了這一行**,它幾乎囊括了

c語言裡的全部內容。

1.int a = 3;

宣告了乙個變數,而且是乙個

int型的變數。

2.int a = 3;

在宣告變數的同時,給

a這個變數賦了乙個初值。

要徹底搞清楚這行**,就應該搞清楚這樣幾個問題:

1.什麼是宣告?

2.什麼是變數?

3.什麼是賦值?

好,我們就來乙個乙個的討論:

1.什麼是宣告呢,舉乙個例子吧!「排排坐,分果果」是大家再熟悉不過的了。在這裡:我們設想有一群小孩坐成一排,有乙個老師給他們分水果。我們告訴老師說有乙個蘋果,老師就會把這個蘋果分給某個小孩。

在這個例子中,「老師」就相當於編譯器(

compiler

),「小孩」就相當於一塊一塊的記憶體空間,「我們告訴老師說有乙個蘋果」就相當於「宣告」。因此,所謂宣告(這裡只考慮變數宣告),就是通知編譯器一件事。

具體通知編譯器什麼呢?這就要看我們是宣告什麼?比如,我們宣告乙個變數,我們就跟編譯器說:我要乙個變數,而且是乙個整形變數。這就好比我們告訴老師說:我有乙個水果,而且是乙個蘋果。水果就是乙個變數,而蘋果就是變數型別。

好,為什麼要宣告呢?大家都知道,計算機只看得懂位址,而要我們去記住每乙個位址,那是相當不現實的,就好比我把

int a = 3;

寫成int 0x000000h=3

;一樣,乙個變數還好說,變數一多恐怕就沒人知道那些

0x000000h, 0xfecadfh

……是什麼意思了,所以為了我們程式設計師的方便,我們給位址啟乙個名字,這樣我們就能很快的記住它們了。這樣是方便了我們,可是問題出來了,我們都知道

a是乙個整形的變數,可是電腦它不知道啊,怎麼辦呢?就通過編譯器,通過編譯器對我們的語言翻譯,譯成電腦看得懂的語言。所以,編譯器就是乙個「翻譯員」,把我們說的「人語」翻譯成電腦的「機器語」。這樣一來,我們的工作就簡化了,我們宣告乙個

a,編譯器就會為我們找乙個記憶體來放這個

a。至於放在**,我們就不知道了,也不必知道,我們只要能用

a就可以了。回到我們上面的例子,我們只要告訴老師說我要分乙個蘋果,至於老師把蘋果分給哪個小朋友我們就不知道了。

下面,我們接著說變數。可以毫不誇張的說沒有變數就沒有程式。變數的重要性可見一斑。

那到底什麼是變數呢?

變數的定義:變數是乙個數學抽象,一種數學模型。沒有很好的定義,就給出乙個描述吧:變數有乙個名字,有乙個存放的位置,有乙個存放的值,存放的值有乙個型別。所以,名字叫變數名,存放的位置叫位址,存放的值叫變數的值,值的型別叫變數型別。就像乙個編號的盒子裡放在乙個雞蛋。這個整體就是乙個變數。在計算機裡就是一塊存著資料的記憶體。 a 

與位址0x00000h

都是乙個意思,或者說存在一一對應的關係。只是

a 屬於我們(人)的方案,

0x000000h 

屬於電腦的方案。兩者的實質是一樣的。

變數的值:我覺得說值不是很好,說資料(

data

)更好一些。變數的值就是記憶體塊裡存放的資料。也就是那個放在盒子裡的雞蛋。

說完了變數,我們就來詳細的說一下賦值,這個問題同樣也是

c 語言的很有魅力的乙個地方。再把

int a = 3; 

這個**拿出來說。這一行**其實是兩行:

int a; a = 3; int a;

就是宣告,這裡就不再討論了。

a = 3; 

就是賦值。在講賦值之前,我們先引入兩個非常重要的概念:左值,右值。

顧名思義,左值就是放在「=」左邊的值;右值就是放在「=」右邊的值。(「=」讀作賦值號,不是等號)這不是廢話嗎?這還要說!先別急,等等你就能體會到這兩句豐富的意義了。

左值的更確切定義:標識存放資料的乙個空間。是乙個標誌。

右值的更確切定義:乙個資料。

請務必記住這個檢證定理:左值只能是乙個位址,它表示乙個可以存資料的地方。右值只能是乙個具體的資料。

再來看這個例子:

a = 3

;很顯然,

a 在「=」的左邊,是左值;

3 在「=」的右邊,是右值。這個式子合法嗎?

我們來證明一下,左值

a 是乙個可以存資料的地方嗎?

a 在計算機裡不就是

0x00000h

嗎?是的,

a 是乙個位址的別名,是乙個可以存資料的地方。

右值3 是乙個具體的資料嗎?毫無疑問是的。因此

3 是乙個合法的右值。

左值,右值都合法,所以

a = 3

合法。證畢。

反過來看這個例子:

3 = a;

證明:1)3 

在「=」的左邊,所以

3 是左值,但是它並不是乙個可以存放資料的地方。所以它不是乙個合法的左值。

2)a 

在「=」的右邊,所以

a 是右值,它能表示乙個具體的資料嗎?可以,因為在這個變數裡存放有資料。這個資料就是乙個具體的值。所以,它是乙個合法的右值。

3)由於左值不合法,所以3 =

a 不合法。證畢。

總結:變數

a 既可以作左值,又可以作右值,作左值的時候,標識乙個位址;作右值的時候,作乙個具體的資料。好,現在我們就知道什麼叫賦值了:賦值就是把乙個具體的資料(右值)放到乙個可以存資料的地方(用左值標識出來)。

再來看乙個麻煩一點的例子:

inta,b = 2

;a = b + 3

;….(2)

請問什麼是左值?什麼是右值?

a 是左值,

b 是右值。這麼簡單。那就錯了。請好好想想左、右值的定義。右值:放在「=」右邊的值。是這樣的(a)

=(b +3) 

右值應該是

b+3的值。怎麼這麼奇怪。

b+3是什麼東西呢?

b + 3

叫做表示式。再講這個例子之前,我們先來說一下表示式。

什麼是表示式?和變數一樣,表示式也只有描述性定義:表示式由三部分組成:有乙個操作符,有一組運算元,有乙個結果。結果是乙個很重要的東西,但是經常被我們忽略。

就說b + 3

(注意,後果沒有;)就是乙個表示式。「+」是操作符,「b」和

「3」是運算元。它的結果是什麼呢?變數

b 裡放著的值是

2 , 

所以結果就是

2+3 = 5。

這樣我們就來證明

a = b + 3

是否合法。

證明:1)a 

是乙個合法的左值,變數可以作左值。

2)b+3 

的值是5 ,

是乙個具體的資料,可以作右值。

因此,a = b + 3 

是合法的。

反過來呢

b+3 = a

是否合法?不合法(證明從略)

由此可以得出乙個不完整的結論:一般情況下,表示式不能作左值。

從 談左值右值

看如下 int idata 0 idata idata 兩個問題 1.上面的 能通過編譯嗎?2.如果能,結果是什麼 如果不能,為什麼?相信對c c 語法熟悉的人來說,第乙個問題並不難,idata 是非法的。有點難度的是解釋為什麼不能通過編譯。要簡單回答這個問題,就涉及到了左值和右值的概念。簡單理解,...

左值 右值 左值引用 右值引用

2015 06 01 15 07 404人閱讀收藏 舉報 c 11 5 一 c 中的左值和右值 誤區 左值位於等號左邊,右值位於等號右邊。c 11中的定義 左值表示式表示的是乙個物件的身份 在記憶體中的位置 而右值表示式表示的是物件的值 內容 左值和右值都是針對表示式而言的,左值是持久的,右值是短暫...

左值 左值引用 右值 右值引用

1 左值和右值的概念 左值是可以放在賦值號左邊可以被賦值的值 左值必須要在記憶體中有實體 右值當在賦值號右邊取出值賦給其他變數的值 右值可以在記憶體也可以在cpu暫存器。乙個物件被用作右值時,使用的是它的內容 值 被當作左值時,使用的是它的位址。2 引用 引用是c 語法做的優化,引用的本質還是靠指標...