首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >指针值不同,但它们比较起来是相等的。为什么?

指针值不同,但它们比较起来是相等的。为什么?
EN

Stack Overflow用户
提问于 2013-08-16 20:03:50
回答 6查看 9.9K关注 0票数 71

一个简短的例子会输出一个奇怪的结果!

代码语言:javascript
复制
#include <iostream>

using namespace std;

struct A { int a; };    
struct B { int b; };
struct C : A, B
{
    int c;
};

int main()
{
    C* c = new C;
    B* b = c;

    cout << "The address of b is 0x" << hex << b << endl;
    cout << "The address of c is 0x" << hex << c << endl;

    if (b == c)
    {
        cout << "b is equal to c" << endl;
    }
    else
    {
        cout << "b is not equal to c" << endl;
    }
}

输出结果如下:,这让我非常惊讶。

代码语言:javascript
复制
The address of b is 0x003E9A9C
The address of c is 0x003E9A98
b is equal to c

让我好奇的是:

0x003E9A9C不等于0x003E9A98,但输出为"b is equal to c"

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-08-16 20:12:08

C对象包含两个子对象,类型分别为AB。显然,它们必须有不同的地址,因为两个不同的对象不能有相同的地址;所以它们中最多有一个可以与C对象有相同的地址。这就是为什么打印指针会产生不同的值。

比较指针并不是简单地比较它们的数值。只能比较相同类型的指针,因此必须转换第一个指针以匹配另一个指针。在本例中,c被转换为B*。这与最初用于初始化b的转换完全相同:它调整指针值,使其指向B子对象而不是C对象,并且两个指针现在比较相等。

票数 87
EN

Stack Overflow用户

发布于 2013-08-16 20:21:13

类型为C的对象的内存布局如下所示:

代码语言:javascript
复制
|   <---- C ---->   |
|-A: a-|-B: b-|- c -|
0      4      8     12

我以字节为单位添加了与对象地址的偏移量(在类似您的平台中,sizeof(int) = 4)。

在main中,您有两个指针,为清楚起见,我将它们重命名为pbpcpc指向整个C对象的开始,而pb指向B子对象的开始:

代码语言:javascript
复制
   |   <---- C ---->   |
   |-A: a-|-B: b-|- c -|
   0      4      8     12
pc-^   pb-^

这就是为什么他们的价值观不同的原因。3E9A98+4是3E9A9C,十六进制。

如果现在比较这两个指针,编译器将看到B*C*之间的比较,这是不同类型的指针。因此,如果有隐式转换,它必须应用隐式转换。pb不能转换为C*,但反过来也是可能的-它将pc转换为B*。该转换将给出一个指针,该指针指向pc所指向的任何位置的B子对象-这与定义B* pb = pc;时使用的隐式转换相同。显然,结果等于pb

代码语言:javascript
复制
   |   <---- C ---->   |
   |-A: a-|-B: b-|- c -|
   0      4      8     12
pc-^   pb-^
   (B*)pc-^

因此,当比较这两个指针时,编译器实际上会比较转换后的指针,它们是相等的。

票数 76
EN

Stack Overflow用户

发布于 2013-08-16 20:22:49

我知道答案是有的,但也许这会更直接,并有一个例子来支持。

在此处的if (b == c)中,c操作数上存在从C*B*的隐式转换

如果你使用下面的代码:

代码语言:javascript
复制
#include <iostream>

using namespace std;

struct A { int a; };    
struct B { int b; };
struct C : A, B
{
    int c;
};

int main()
{
    C* c = new C;
    B* b = c;

    cout << "The address of b is 0x" << hex << b << endl;
    cout << "The address of c is 0x" << hex << c << endl;
    cout << "The address of (B*)c is 0x" << hex << (B*)c << endl;

    if (b == c)
    {
        cout << "b is equal to c" << endl;
    }
    else
    {
        cout << "b is not equal to c" << endl;
    }
}

你会得到:

代码语言:javascript
复制
The address of b is 0x0x88f900c
The address of c is 0x0x88f9008
The address of (B*)c is 0x0x88f900c
b is equal to c

因此,转换为B*类型的c具有与b相同的地址。不出所料。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18272909

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档