GCC编译器中char*与char[]在&运算符下的差异解析请求
为何
char*与char[]使用&运算符时地址对比结果不同? 当通过&运算符获取变量地址时,编译器对char * var和char var[]这两种类型的处理方式不同。以下是一段用于演示的代码片段:
#include <stdio.h> #include <stdint.h> #include <string.h> int main(int argc, char ** argv) { const char * str1 = "This is string 1"; char str2[32]; snprintf(str2, sizeof(str2), "This is string 2"); if ((uint32_t)str1 == (uint32_t)&str1) { printf("str1 == &str1\n"); } else { printf("str1 != &str1\n"); } if ((uint32_t)str2 == (uint32_t)&str2) { printf("str2 == &str2\n"); } else { printf("str2 != &str2\n"); } return 0; }
程序输出:
iuser@MyXPS MINGW64 ~/Documents/pointers $ ./run.sh str1 != &str1 str2 == &str2
差异解释
这两种写法本质是完全不同的变量类型,&运算符的作用对象和行为自然存在差异:
1. const char *str1的逻辑
str1是一个指针变量,它本身在栈上占用一块内存(通常4/8字节,取决于系统位数),存储的是字符串常量"This is string 1"在只读数据段的首地址。str1的值:是字符串常量的起始地址。&str1:是指针变量str1自身在栈上的存储地址。- 这两个地址指向完全不同的内存区域:一个是只读数据段的字符串,一个是栈上的指针变量,因此它们的值必然不相等,对应输出
str1 != &str1。
2. char str2[32]的逻辑
str2是一个数组变量,它代表栈上一块连续的32字节内存空间,用于存储字符串。- 在C语言中,数组名在多数语境下会被隐式转换为指向数组第一个元素的指针(即
str2等价于&str2[0]);但当&运算符作用于数组名时,数组名不会被转换,而是直接返回整个数组的地址。 - 数组的起始地址(
str2转换后的指针值)和整个数组的地址(&str2)指向同一个内存位置——因为数组的起始位置就是第一个元素的位置,所以强制转换为uint32_t后值完全相等,对应输出str2 == &str2。 - 补充:二者类型不同,
str2转换后为char*,&str2为char(*)[32](指向32个char的数组的指针),只是数值一致。
内容的提问来源于stack exchange,提问作者gilfoyle
相关产品推荐
相关产品推荐

