C++数组中的等于运算符

4
const char ca[]="test";
const char cb[]="test";

const char *pca="test"; //(*)
const char *pcb="test";

cout<<(ca==cb)<<endl; //0
cout<<(pca==pcb)<<endl; //1

我对这个结果感到很困惑。
当处理 ca==cb 时,cacb 是不同的对象,它比较第一个元素的地址,因此 &ca[0]!=&cb[0]
但我不理解 pcapcb 的行为。
(*) 是否等效于
const char temp[]="test";
const char *pca = temp;

"test" 是一个对象吗?而且 pcapcb 都指向这个对象的第一个元素吗?


3
编译器可以但不是必须为相同的字符串字面量合并存储。 为什么(只有)某些编译器对相同的字符串字面量使用相同的地址? - songyuanyao
1个回答

1
const char ca[]="test";
const char cb[]="test";

这将创建名为cacb变量,它们足够大以容纳初始值(而不是赋值)中给定的字符串文字中的字符和终止符号,然后将文字字符串的内容复制到每个变量中。
const char *pca="test"; //(*)
const char *pcb="test";

这只是将字符指针设置为指向给定的字符串文字。实现可以自由地使用相同的内存来表示这些文字,从而为多个目的而重命名内存。它可以这样做,因为尝试修改字符串文字本身就是未定义行为。
关于你最后提到的指针等同于的观点:
const char temp[]="test";
const char *pca = temp;

那不是事实。现在pca变量指向的内存是可以通过temppca进行修改的。
请注意,这种字符串字面量别名可能比第一次想象的更加微妙。 代码段:
cout << a << "is " << "invalid\n";
cout << b << "is " << "valid\n";

可能只会在内存中存储两个字符串字面值:

Addr:
  0   1     2      3   4   5   6   7   8   9  10   11   12
+---+---+-------+----+---+---+---+---+---+---+---+----+----+
| i | s | <spc> | \0 | i | n | v | a | l | i | d | \n | \0 |
+---+---+-------+----+---+---+---+---+---+---+---+----+----+

使用:

  • is<spc> 被转换为地址 0;
  • invalid\n 被转换为地址 4;以及
  • valid\n 被转换为地址 6。

如果其他代码需要 id\n,则可以直接使用地址 9。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接