【问题标题】:Relational operators关系运算符
【发布时间】:2021-12-28 17:51:13
【问题描述】:

我对@9​​87654322@ 函数的结果感到困惑,在下面的情况下为-1

#include <stdio.h>
int test(const void*, const void*);
int main()
{
    int a = 10, b = 5;
    int result = test(&a, &b);
    printf("Result: %d", result);
    return 0;
}

int test(const void* a, const void* b) {
    const double* da = (const double*)a;
    const double* db = (const double*)b;
    return (*da > * db) - (*da < *db);
}

0x0135fb00 现在是我的 da 值和地址
0x0135faf4 现在是我的 db 值和 b 地址

据我所知,关系运算符在 True 时返回 1,在 False 时返回 0,所以在这种情况下我们应该有:

*da &gt; *db --&gt; 1
因为da(a 的地址)的值大于db(b 的地址)的值。
*da &lt; *db --&gt; 0
因为da(a 的地址)的值不小于db(b 的地址)的值。
所以1-0就是1。
只是为了说明,我通过调试器比较 da 的值和 db 的值得出了这个结论(我使用的是带有默认 C 编译器的 Visual Studio)。我错过了什么?
PS:我在官方GNU web site上遇到过这段代码。

【问题讨论】:

  • 什么是sizeof(int)sizeof(double)?我怀疑你没有阅读你认为你正在阅读的内容......
  • 您为什么决定将指向int 的指针重新解释为指向double 的指针?那部分绝对不是来自您问题中的链接
  • @bersi 仅仅因为编译的代码并不意味着它是正确的。在您的情况下,您将指针转换为不兼容的类型(从int*double*),从而调用未定义行为。在 C 中,确保代码不违反此类规则始终是程序员的责任
  • int 转换为double 调用显式转换。从int* 转换为double* 并取消引用会导致未定义的行为。当您将int 的地址转换为double 的地址时,您不会更改该地址的数据。
  • @bersi 简单。您的 int 有 4 个字节(不是位)。当您将其转换为double 时,它会占用内存中的 4 个相邻字节,这些字节通常包含垃圾或其他变量(或者,甚至是返回地址,因此这是一个安全问题)

标签: c relational-operators


【解决方案1】:

在你的问题中,你说:

*da &gt; *db --&gt; 1

因为 da 的值(a 的地址)大于 db 的值(b 的地址)。

但是,当您取消引用指针时(使用 * 运算符),上述语句改为测试 da 指向 的任何内容是否大于 db 指向的任何内容到

如果您真的想比较地址,请忽略*,即:

(da > db) - (da < db)

如果您的最终目标是比较地址,则无需转换 void 指针,因此您可以重写 test 如下:

int test(const void *a, const void *b) {
    return (a > b) - (a < b);
}

【讨论】:

  • 这样的比较指针只为指向同一数组对象的指针定义。哪个 OP 没有,所以这些比较也是 undefined behavior
  • 如果我错了,请纠正我。我尝试将ab 的类型从int 更改为double,然后一切正常。似乎通过指针将 int 转换为 double 可能会导致未定义的值,因为 double 比 int 大 4 个字节的垃圾。这是正确的吗?
  • 将指针与&lt;&gt; 进行比较的行为不是由C 标准针对不指向同一聚合(数组、结构等)中的对象的指针定义的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-05
  • 2018-05-30
  • 1970-01-01
  • 2017-09-27
  • 2016-08-02
  • 1970-01-01
相关资源
最近更新 更多