標籤:

C語言怎麼理解書上寫&取址操作符不能用於常量、表達式和register類型變數?

int *a,b=12; //b常量

a=b;

我自己試的可以,但是書上說不可以這麼寫,所以我就不理解為什麼。


標準的說法應該是:(C語言中)操作符的操作數不能為非左值表達式(右值表達式),或者指定了位域或存儲類型為 register 的對象的左值表達式。

C11 6.5.3.2 Address and indirection operators

對於題主所說的:

  • 常量:應該是指 integer constant 等,例如你不能夠寫 12,X。不過這樣就和下面一條重複了。
  • 表達式:確切地說是非左值表達式,例如你不能夠寫 (a + b)。
  • register:這一點沒什麼問題。


b 是左值,在棧中分配了空間,因此可以拿到這塊空間的起始地址。

常量、立即數通常只包含在 TEXT 段,作為一條彙編指令的一部分,所以拿不到其地址。

(數值)表達式結果的計算過程只會修改寄存器,最後的結果也存放於寄存器中,所以取不到其地址。


樓上說的是標準答案,我補充下:

你寫的a=b,b是變數,不是常量。

所謂常量是指一個確定的數或者字元。

至於register,這是寄存器變數,因為寄存器並不在內存上,所以無法獲取寄存器在內存上的地址…這個修飾符是早期由於內存太小導致有些經常用到的變數可以直接去寄存器上獲取值,但現在基本上已經不用了…

所以你在用獲取寄存器變數的地址值時,編譯器不報錯,但會自動忽略這個register這個關鍵詞

簡單來說,書上的意思是

你不能寫

a=1

a=(1+1)或者a=(a+b)

理論上不能寫a=有register修飾過的變數


我覺得你可能不理解什麼是常量,題目中12是常量,而b是變數,你這樣賦值沒毛病啊。表達式和常量是一個值,沒有強轉成指針當然不好給指針賦值咯。還有就是,對於寄存器,怕是沒有地址這個說法吧,畢竟內存中的地址都可以用寄存器表達。


這麼理解,考慮下常量,表達式還有寄存器變數,在程序實際運行中都是存放在哪兒?然後搜點相關的編譯過程的帖子看看。。。


只有內存才有地址的概念。這有什麼不好理解的。


b不是常量,是變數


簡單就是:

int *p, a =12;

p = a; //這是正確的,a是變數是有地址的,通過取地址符把a變數的地址給指針p,是正確的。

p = 12; //12是一個常量,所以12是沒有地址的,所以12是錯誤的。

寄存器是不包含在內存中的存儲空間。

C語言30天核心突破


推薦閱讀:

第90集:使用快速選擇工具『Photoshop CC 2017 one-on-one基礎篇』
PS教程:創建一個James White風格懷舊海報
C語言入門級書刊推薦?
自然飽和度「大師們」真沒懂!
在modern c++中,模板元編程有哪些更方便的寫法?

TAG:CC |