首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C 語言指針左值右值深度解析:*cp 賦值 ch2 與 &ch2 的本質區別

     編輯:程式設計疑難解答

代碼片段回顧

char ch = 'a';
char ch2 = 'b';
char *cp = &ch;   // cp 指向 ch
*cp = ch2;        // 第 3 行:通過
*cp = &ch2;       // 第 4 行:編譯錯誤

核心概念:左值、右值、指針解引用

逐行語義分析

第 3 行:`*cp = ch2;`

  • ch2 是右值:字符變量的值 'b'(ASCII 98)。
  • *cp 是左值:cp 指向的內存地址(即 &ch)。
  • 語義:**將字符 'b' 寫入 cp 指向的內存**(即修改 ch 為 'b')。
  • 類型匹配:左邊 `char`(目標內存類型),右邊 `char`(源值類型)✅。

第 4 行:`*cp = &ch2;`

  • &ch2 是右值:ch2 的**地址**(類型 `char *`)。
  • *cp 是左值:目標內存地址(類型 `char`)。
  • 語義嘗試:**將地址值寫入字符內存單元**。
  • 類型不匹配:左邊期望 `char`(1 字節),右邊提供 `char *`(4/8 字節指針)❌。
  • 編譯器報錯:`assignment to 'char' from 'char *' makes integer from pointer without a cast`。

為什麼書上說「*cp 作為左值代表指向內容的地址」?

這句話**精確描述了左值的本質**:「左值表達式求值結果是一個內存地址」。

  • *cp 作為左值時,其「值」是 **cp 指向的那個內存單元的地址**(即 &ch)。
  • 賦值操作 `<左值> = <右值>` 的機制:**取右值的位模式,寫入左值代表的地址處**。
  • 所以 `*cp = ch2` 實際做的是:取 `ch2` 的位模式(字符編碼),寫入 `&ch` 處。
  • 同理 `*cp = &ch2` 試圖做:取 `&ch2` 的位模式(指針地址),寫入 `&ch` 處 —— **寬度不匹配,類型不兼容**。

關鍵認知修正

「*cp 無論作為左值還是右值,代表的都是指向的內容」 —— **錯誤**

概念定義例子
左值表達式標識一個內存位置(有地址),可出現在賦值號左邊變量 `ch`、`*cp`、`arr[i]`
右值表達式表示一個數值,無固定內存位置,只能出現在賦值號右邊字面量 `'b'`、表達式 `ch2`、`&ch2`、函數返回值
*cp (解引用)訪問 cp 指向的內存單元,**本質是左值**(代表那個內存位置)`*cp = x` 向該位置寫入 x

**左值/右值是表達式在上下文中的屬性,不是表達式本身固有的**。同一個 `*cp`,放在 `=` 左邊是左值(地址),放在右邊是右值(內容)。

類比理解

  • cp 是「某房間的鑰匙」(地址)。
  • *cp 是「打開門進入房間」(解引用操作)。
  • 房間裡放著一個盒子(內存單元),盒子裡裝著字符 'a'。
  • *cp = ch2:進房間,把盒子裡的東西換成 'b'。
  • *cp = &ch2:進房間,試圖把「另一個房間的鑰匙」塞進只能裝字符的盒子 —— **塞不進去**(類型/大小不符)。

總結

  1. *cp 作為左值時,**代表 cp 指向的內存地址**(即「目標位置」),不代表內容。
  2. 賦值右邊必須是**目標類型兼容的值**(此處為 `char`),而非地址(`char *`)。
  3. 第 3 行通過:字符值 → 字符內存。第 4 行失敗:指針地址 → 字符內存(類型錯誤)。
  4. 書中「左值代表地址」論述**始終成立**;關鍵在於理解賦值是「將右值位模式寫入左值地址」,類型必須匹配。

掌握「左值=地址、右值=值、賦值=寫入地址、類型必須匹配」這條主線,指針賦值問題自然迎刃而解。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
上下文表達式求值結果含義
左值上下文(賦值目標)*cp內存地址 &ch「這裡有個坑,往這裡填數據」
右值上下文(取值使用)*cp內存中存儲的值 'b'「從這個坑裡取出數據」