我对指针的理解不足。
const char* p = "Some text";
const char* q = "Some text";
if (p == q)
cout << "\nSAME ADDRESS!";
cout << "\np = " << p;
cout << "\nq = " << q; //same outputs "Some text"
在Visual Studio 2015中,语法if (p == q)
不会比较地址,它会比较值......我认为它应该是if (*p == *q)
。
那么如何比较地址呢?我认为使用if (&p == &q)
,但是it's been said它将是指针的地址,而不是它们所指向的地址。
答案 0 :(得分:4)
在Visual Studio 2015中,语法
if (p == q)
没有比较地址,它会比较值......
它会比较地址。具有完全相同内容的字符串(或其他)文字将被优化为仅实例化一次(在同一地址)。
要检查实际地址,请使用
之类的语句cout << (void*)p << ' ' << (void*)q << endl;
答案 1 :(得分:4)
我认为你正在混淆两个不同的概念。如果你有两个任何类型的p
和q
指针,那么p == q
总是比较存储在指针中的地址而不是指向的对象。结果,声明
if (p == q)
测试p
和q
是否真正指向同一个对象。至于你为什么要回到相同的对象 - 许多编译器作为优化,将所有相同值的字符串文字汇集到一个字符串文字中,并设置所有指针以共享它。此优化可节省二进制文件中的空间。这也是写入字符串文字的未定义行为的原因 - 如果您可以写入字符串文字,那么您可能会意外地污染初始化为该字面值的其他字符串。
独立地,流库是专门编程的,因此如果您尝试打印出const char *
,它会将const char*
视为指向以空字符结尾的字符串开头的指针,然后打印出该字符串中的所有字符。
如果您想打印地址,可以先将指针转换为void*
:
cout << static_cast<const void*>(p) << endl;
cout << static_cast<const void*>(q) << endl;
这样做的原因是流库被设计成如果你试图打印出一个不是字符指针的指针,它就会显示地址。类型转换基本上告诉编译器&#34;请忘记这实际上是char*
,而是将其视为通用指针。&#34;
同样,如果您想比较字符串本身,请使用strcmp
:
if (strcmp(p, q) == 0) {
// Equal!
}
也就是说,在C ++中,您应该考虑使用std::string
而不是const char*
,因为它更安全,更易于使用。
答案 2 :(得分:3)
通常它依赖于编译器选项(实现定义),编译器是否将相同的字符串文字存储为一个字符串文字或分开。
因此,对于此代码段
const char* p = "Some text";
const char* q = "Some text";
if (p == q)
if语句中的条件可以评估为true或false。
来自C ++标准(2.14.5字符串文字)
12是否所有字符串文字都是不同的(即存储在 非重叠对象)是实现定义的。的效果 尝试修改字符串文字是未定义的。
因此在本声明中
if (p == q)
确实比较了指针,但比较的结果是实现定义的,并且通常可以由程序员通过设置编译器选项来控制。