双引号的特性及char指针初始化时字符串字面量的地址疑问
嘿,这个问题问到点子上了!我来给你把细节掰扯清楚~
双引号的核心特性
- 用双引号包裹的内容叫做字符串字面量,它本质是一个自动以
\0(空字符)结尾的char数组。比如"hello"在内存里实际是{'h','e','l','l','o','\0'},总长度是6(别忘算上空字符哦)。 - 字符串字面量是只读的!编译器通常会把它们放到程序的只读数据段(比如
.rodata),要是你脑子一热想通过指针修改它的内容,大概率会触发未定义行为(比如程序直接崩溃)。 - 编译器有个贴心优化:会自动合并重复的字符串字面量。比如你代码里两次用到
"hello",编译器基本只会在内存里存一份,这也是为啥两次打印都是同一个内容的关键原因。
char*初始化时的表现:你的猜测完全正确!
当你写char* ptr = "hello";的时候,"hello"确实会被解析成数组首元素(也就是那个'h')的内存地址,然后赋值给ptr。不过这里有几个容易踩坑的点得提一下:
- 更规范的写法是
const char* ptr = "hello";——因为字面量是只读的,不加const的话,编译器多半会给你个警告,提醒你别瞎改这块内存。 - 这里其实发生了数组到指针的隐式转换:
"hello"本身是char[6]类型的数组,在赋值给指针变量时,数组名会自动转换成指向首元素的指针,这是C/C++里的默认规则。
再补几个原理细节
- 存储位置:程序编译阶段,所有字符串字面量都会被打包到只读数据区,等程序运行时,这块内存会被加载到内存的只读段,所以绝对不能修改。
- 重复字面量的复用:刚才说的编译器优化,专业点叫“字符串池”——相同的字面量只会存一次,所以不管你在代码里用多少次
"hello",它们的内存地址都是一样的,打印出来自然都是同一个内容。 - 别搞混两种初始化方式:
char* ptr = "hello"是让指针指向只读的字面量;而char arr[] = "hello"是把字面量的内容复制到栈上的数组arr里,这个arr是可以随便修改的,两者完全不一样!
内容的提问来源于stack exchange,提问作者glint
相关产品推荐
相关产品推荐

