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

C++ 字符數組、字符指針與字符串字面量的深層區別

     編輯:關於C語言

現象

char *Sp = "Example One";
char Sa[] = "Two";
cout << Sp << &Sa[0]; // 輸出字符串內容,而非地址

為什麼 cout 輸出的是字符串而不是地址?

本質解析

1. 字符串字面量存儲

  • "Example One" 存放在**只讀數據段**(.rodata),編譯器分配匿名字符數組,以 \0 結尾。
  • 字面量值為**首字符地址**(類型 const char*,C++ 允許隱式轉 char* 但已棄用)。
  • Sp 指向這塊只讀內存,**修改行為未定義**。

2. 字符數組 Sa[]

  • 在棧上分配 4 字節('T','w','o','\0'),**可修改**。
  • Sa 是數組標識符,大多數語境下退化為 char*(首元素地址)。
  • &Sa[0] 顯式取首元素地址,類型 char*。

3. cout 的重載決議

  • operator<<(ostream&, const char*) 被定義為**輸出以指針為起始的 C 字符串**(直到 \0)。
  • 因此 cout << Sp、cout << &Sa[0] 觸發此重載,**打印字符串內容**。
  • 若要打印地址,需強制轉型:cout << (void*)Sp 或 cout << (const void*)Sp。

對比總結表

特性char *p = "lit"char a[] = "lit"std::string s = "lit"
存儲區域只讀數據段 (.rodata)棧 (局部) / 數據段 (全局/靜態)堆 (動態分配)
可修改性**不可修改** (UB)可修改可修改
大小指針大小 (4/8)字符串長度+1 (含\0)動態 (含容量)
sizeof指針大小數組總字節數對象大小 (非字符串長度)
賦值/拷貝淺拷貝 (只複製指針)不可整體賦值 (需 strcpy)深拷貝 (複製內容)
生命週期程序全程作用域結束銷毀RAII 自動管理

最佳實踐

  1. 只讀字符串用 const char* 或 string_view (C++17)。
  2. 需修改/擁有所有權用 std::string。
  3. 嵌入式/無 STL 環境用字符數組 + 長度參數,嚴禁指向字面量的非 const 指針。
  4. 打印地址統一用 (void*) 強轉**,避免誤觸發字符串重載。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved