You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中char*指针输出为字符串而非地址的底层原理疑问

测试代码与运行结果回顾

#include <iostream>
using namespace std;
int main()
{
    const char* b="str";
    cout << b << endl;
    cout << *b << endl;
    cout << &b << endl;
    cout << *(&b) << endl;
    
    return 0;
}

运行输出:

str
s
0x7ffdf39c27f0
str

输出逐行解释

核心前提:C++标准库的std::cout对char*/const char*类型做了<<运算符的特殊重载,默认将其视为C风格字符串的首地址,会从该地址开始逐字节读取内存直到遇到'\0'终止符后输出所有读取到的字符,而非直接输出指针存储的地址值。

  • cout << b << endl;:b存储的是字符串常量"str"的首字符地址,cout识别到char*类型后按C风格字符串规则输出,最终打印str。
  • cout << *b << endl;:对指针b解引用,取到首地址处存储的第一个字符's',最终打印s。
  • cout << &b << endl;:&b是取指针变量b本身的内存地址,指针变量本身存储在栈内存中,所以直接输出该地址的十六进制值0x7ffdf39c27f0。
  • cout << *(&b) << endl;:&b是b的内存地址,对该地址解引用得到的就是b本身,也就是指向"str"首地址的char*,逻辑和第一行完全一致,最终打印str。

常见疑问解答

为什么char*直接输出不是地址

这是C++标准库为了兼容C风格字符串的使用习惯做的设计,std::ostream的<<运算符针对字符指针类型做了专属重载,优先按字符串输出。如果需要输出char*存储的地址值,只需要将其强制转换为void*类型即可,示例:cout << static_cast<void*>(b) << endl;,此时就会打印"str"字符串本身的首地址。

为什么b和("str")结果一致

字符串字面量"str"本身的类型是const char[4](包含末尾的隐式'\0'),在大多数使用场景下会隐式转换为指向首元素的const char*指针,对该指针解引用就是取首字符's',和*b的逻辑完全相同,所以结果一致。

替换为char b[]为什么输出一致

当你将代码修改为char b[] = "str"时,b是栈上分配的字符数组,本身存储了s/t/r/'\0'四个字符。数组名在传入cout时会隐式转换为指向数组首元素的char*指针,后续的解引用、取地址操作的表现和指针版本完全一致,所以输出结果相同。

内存结构说明

以64位系统为例,对应内存布局如下:

内存区域存储内容地址示例
只读数据段's' 、't'、'r'、'\0'(字符串常量"str")0x00005555abcd0000 ~ 0x00005555abcd0003
栈区指针变量b,存储的值为字符串常量首地址0x00005555abcd00000x7ffdf39c27f0(即你输出的&b的结果)

学习资料推荐

  • 书籍:《C++ Primer》第5版,重点阅读第三章(字符串、数组和指针)、第十四章(运算符重载)相关章节,能系统理解C++指针、数组、重载规则的底层逻辑。
  • 内容方向:可自行搜索C++隐式类型转换、C风格字符串实现原理、std::ostream运算符重载规则相关的技术内容深入学习。

内容的提问来源于stack exchange,提问作者tequila

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 09:48:03