首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 與 C++ char 型別本質差異:Unicode 與 ANSI 的跨語言陷阱

     編輯:關於C#

核心差異一覽

特性C# charC/C++ charC/C++ wchar_t
大小2 位元組 (16 bits)1 位元組 (8 bits)2 位元組 (Windows) / 4 位元組 (Linux)
編碼UTF-16 代碼單元ANSI/ASCII (視編譯器/地區設定)UTF-16 (Windows) / UTF-32 (Linux)
字元範圍U+0000 ~ U+FFFF (基本多文種平面)0 ~ 255 (擴展 ASCII)完整 Unicode 碼位
字串型別string (不可變 UTF-16 序列)char* / std::string (位元組序列)wchar_t* / std::wstring
字面值語法'A', '中', '\u4E2D''A', '中' (需原始碼編碼一致)L'A', L'中', u'A' (C++11 char16_t)

C# char 為何是 2 位元組?


Console.WriteLine(sizeof(char)); // 輸出 2
Console.WriteLine("A".Length);   // 輸出 1
Console.WriteLine("中".Length);  // 輸出 1 (單一 UTF-16 代碼單元)
Console.WriteLine("😀".Length);  // 輸出 2 (代碼對 surrogate pair)
  • char 代表單一 UTF-16 代碼單元,非完整 Unicode 字元 (Grapheme Cluster)。
  • 補充平面字元 (Emoji、罕用漢字) 需 2 個 char (Surrogate Pair) 表示。
  • .NET string 內部為 UTF-16 編碼,Length 回傳代碼單元數,非字元數。

C/C++ char 陷阱


// C++ 
#include 
int main() {
    std::cout << sizeof(char) << std::endl;      // 1
    std::cout << sizeof(wchar_t) << std::endl;   // 2 (Windows/MSVC) 或 4 (Linux/GCC)
    
    char c = '中'; // 警告:截斷!僅保留低位元組
    wchar_t wc = L'中'; // 正確
    std::cout << c << " " << wc << std::endl;
}
  • char 歷史包袱:早期為 ASCII,後擴展為各地區代碼頁 (CP936/CP950/CP1252 等),非可攜式。
  • 現代 C++ (C++11+) 建議使用 char16_t (UTF-16)、char32_t (UTF-32)、std::u16string/std::u32string。
  • Windows API 使用 WCHAR (即 wchar_t) 系列函數 (MessageBoxW 等) 支援 Unicode。

跨語言互操作 (P/Invoke) 關鍵對應

C# 型別C/C++ 型別MarshalAs適用場景
string (In)const wchar_t* (LPCWSTR)[MarshalAs(UnmanagedType.LPWStr)]預設字串封送 (Unicode)
string (In)const char* (LPCSTR)[MarshalAs(UnmanagedType.LPStr)]ANSI 介面 (舊版 API)
StringBuilder (Out)wchar_t* (LPWSTR)[MarshalAs(UnmanagedType.LPWStr)]接收 Unicode 字串
charwchar_t / WCHAR自動單字元傳遞
byte / sbytechar / signed char自動ANSI 字元/位元組

SQL Server 對應關係

SQL Server 型別儲存內容.NET 讀取型別
char(n)定長非 Unicode (代碼頁)string (自動轉 UTF-16)
nchar(n)定長 Unicode (UCS-2/UTF-16)string
varchar(n)變長非 Unicodestring
nvarchar(n)變長 Unicodestring (推薦預設)
現代應用一律使用 nvarchar,避免代碼頁轉換錯誤與資料遺失。

常見錯誤與避坑

  1. 假設 char = 1 byte:C# 中 sizeof(char)==2,寫入二進位檔案時用 BinaryWriter.Write(char) 寫 2 位元組。
  2. 字串長度 ≠ 字元數:"😀".Length == 2,計算顯示寬度請用 StringInfo 或 System.Globalization。
  3. P/Invoke 忘記 MarshalAs:預設封送字串為 LPWStr (Unicode),呼叫 ANSI API 必須加 [MarshalAs(UnmanagedType.LPStr)]。
  4. C++ 字串字面值編碼:原始碼儲存編碼 (UTF-8/GB2312) 決定 "中" 在記憶體位元組,建議原始碼統一 UTF-8 並加 u8 前綴 (C++20)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved