書籍中提到:
public struct ValPoint {
public int x;
public ValPoint(int x) { this.x = x; }
}
ValPoint vPoint1; // 書上說這裡並未入棧
vPoint1.x = 1; // 這一步才入棧
Console.WriteLine(vPoint1.x); // 這一步出棧
疑問:聲明時結構體到底放在哪裡?
ValPoint vPoint1; 在編譯階段就在當前棧框預留 sizeof(ValPoint) 位元組(此處 4 字節)。此時 記憶體已分配,但內容未初始化(或為零,視語境而定)。
C# 編譯器強制要求:讀取變量前必須明確賦值。vPoint1.x = 1 滿足此規則,後續 Console.WriteLine(vPoint1.x) 才合法。若嘗試在賦值前讀取,編譯報錯 CS0165。
棧框 (Stack Frame)
+------------------+
| 返回地址 |
| 舊 EBP |
| 局部變量區 | ← vPoint1 佔用 4 字節,固定偏移量
| ... |
+------------------+
方法進入時一次性分配,方法退出時一次性釋放。
| 特性 | 結構體 | 類 |
|---|---|---|
| 分配位置 | 棧(局部變量)或內嵌在物件內 | 堆 |
| 聲明時行為 | 分配空間,需確定性賦值 | 分配引用,初始為 null |
| 賦值語義 | 值複製 | 引用複製 |
聲明結構體變量時,棧空間立即預留;「入棧」實為首次賦值滿足確定性賦值規則。理解這一機制有助於避免「使用未賦值變量」錯誤,並正確把握值類型的性能特徵。