核心区别在于内存存储位置不同。
核心原因
| 变量 | 存储位置 | 比较的是什么 | 结果 |
|---|---|---|---|
str1[]、str2[] |
栈区 | 数组的地址(不同位置) | 不相等 |
str3、str4 |
常量区 | 指向同一个常量字符串的地址 | 相等 |
详细解释
1️⃣ char str1[] = "hello bit.";
c
char str1[] = "hello bit."; // 在栈上开辟数组,把字符串"拷贝"进去
char str2[] = "hello bit."; // 在栈上开辟另一个数组,再拷贝一份
内存布局:
text
栈区:
str1 → [h][e][l][l][o][ ][b][i][t][.][\0] (地址:0x100)
str2 → [h][e][l][l][o][ ][b][i][t][.][\0] (地址:0x200)
-
str1和str2是两个不同的数组 -
虽然内容相同,但地址不同
-
str1 == str2比较的是地址 → 不相等
2️⃣ const char* str3 = "hello bit.";
c
const char* str3 = "hello bit."; // 指向常量区的字符串
const char* str4 = "hello bit."; // 指向同一个常量字符串
内存布局:
text
常量区(只读):
0x5000: [h][e][l][l][o][ ][b][i][t][.][\0]
↑ ↑
str3 str4
(存的是 0x5000) (存的也是 0x5000)
-
字符串字面量
"hello bit."存储在常量区(只读) -
编译器会优化:相同内容的字符串字面量只存一份
-
str3和str4都指向同一个地址 -
str3 == str4比较的是地址 → 相等
图解对比
text
┌─────────────────────────────────────────┐
│ 栈区 │
│ ┌──────┐ ┌─────────────────────┐ │
│ │ str1 │────→│ h e l l o b i t . \0 │ │
│ └──────┘ └─────────────────────┘ │
│ ┌──────┐ ┌─────────────────────┐ │
│ │ str2 │────→│ h e l l o b i t . \0 │ │
│ └──────┘ └─────────────────────┘ │
│ (两块不同的内存,内容相同) │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ 常量区 │
│ ┌────────────────────────────────────┐ │
│ │ h e l l o b i t . \0 │ │
│ └────────────────────────────────────┘ │
│ ↑ ↑ │
│ str3 str4 │
│ (指向同一块内存) │
└─────────────────────────────────────────┘
如何比较字符串内容?
如果要比较字符串内容 是否相同,要用 strcmp():
c
#include <string.h>
if (strcmp(str1, str2) == 0)
printf("内容相同\n"); // 这个会执行
总结
| 写法 | 存储位置 | 比较结果 |
|---|---|---|
char arr[] = "..." |
栈区(每次拷贝) | 地址不同 → 不相等 |
char* p = "..." |
常量区(共享) | 指向同一地址 → 相等 |
一句话 :str1 和 str2 是两份拷贝,str3 和 str4 指向同一份常量字符串。