C语言字符串处理疑惑:指针和数组定义字符串的地址输出差异
问题核心原因:
char* 指针变量和 char[] 数组的内存模型本质不同 1. 第一段代码的运行逻辑
对应代码:
char *name = "asd"; printf("%p\n%p", (void *)&name, (void *)&name[0]);
- 这里的
name是独立的指针变量,如果是局部变量就存储在栈内存中,本身占用4/8字节(取决于系统位数) - 字符串字面量
"asd"存储在进程的只读常量区,name中存储的正是这个常量区首字符'a'的地址 - 两个取地址操作的含义完全不同:
&name:取的是指针变量自身的栈内存地址&name[0]:等价于name存储的值,也就是常量区'a'的地址
两个地址属于完全不同的内存区域,因此输出必然不一致。
2. 第二段代码的运行逻辑
对应代码:
char name[] = "asd"; printf("%p\n%p", (void *)&name, (void *)&name[0]);
- 这里的
name是数组名,程序会直接在当前栈上分配4字节的连续空间(存储'a'、's'、'd'、'\0'),并将字符串字面量的内容拷贝到这片栈空间中 - 数组名本身是地址常量,代表数组首元素的起始地址,不存在单独的内存空间存储这个地址值
- 两个取地址操作的地址值是重合的:
&name[0]:取数组第一个元素'a'的地址,就是数组的起始位置&name:取整个数组的地址,类型是char (*)[4](数组指针),虽然类型和首元素指针不同,但地址的数值和数组首元素地址完全一致
因此两个输出的地址值相同。
认知修正
你之前的认知混淆了「字符串字面量的隐式转换规则」和「变量类型的本质」:C语言没有内置的字符串类型,我们常说的「字符串」本质是以\0结尾的连续char内存块。当字符串字面量被赋值给指针时,确实会自动转换为首个字符的指针,但数组和指针是完全不同的语法实体,不能直接等价。
内容的提问来源于stack exchange,提问作者user13991697
相关产品推荐
相关产品推荐

