【问题标题】:Need explanation of the output需要解释输出
【发布时间】:2020-07-20 10:27:27
【问题描述】:
#include <stdio.h>
    int main(){
    int a[4]={1,2,3,4};
    int b[4]={1,2,3,4};
    int n =&b[3]-&a[2];
    printf("%d\n", n);
}

请大家解释一下为什么输出显示为 5。

【问题讨论】:

  • 您有未定义的行为,因此可以输出任何内容。指针算法仅对 same 数组的元素有效。
  • 不相关:选择一种语言。你是用 C 还是 C++ 编程?
  • 您可以添加您期望的输出。

标签: c c++14


【解决方案1】:

就是undefined behaviour。

不相关的对象之间没有定义指针运算。

您观察到的是,在您的实现中,数组 a 和 b 是连续布局的,这解释了差异 5。但这绝不是一种保证行为,并且指针算术本身是未定义的。

【讨论】:

    【解决方案2】:

    由于指针运算仅对前面指出的相同数组的元素有效,让我们从使程序有效开始。您可以通过将指针转换为能够保存指针值的整数来做到这一点,例如 std::uintptr_t:

    #include <cstdint>
    #include <iostream>
    
    int main(){
        int a[4]={1,2,3,4};
        int b[4]={1,2,3,4};
        auto diff = reinterpret_cast<std::uintptr_t>(&b[3]) -
                    reinterpret_cast<std::uintptr_t>(&a[2]);
        std::cout
            << diff << '\n'
            << diff / sizeof(int) << '\n'
        ;
    }
    

    可能的输出:

    20
    5
    

    这意味着b[3] 和a[2] 之间的地址差为20,并且该地址空间中有5 个ints 的空间。

    【讨论】:

    • 你应该提到这个程序仍然是未定义的行为。
    • @Jabberwocky 你的意思是&amp;b[3] 可能小于&amp;a[2]?结果是实现定义的,但我没有看到 UB。
    • 不相关对象UB之间的指针运算不是吗?
    • @Jabberwocky 在reinterpret_cast 之后,它们只是整数,因此程序中根本没有进行指针运算。
    • @Jabberwocky 是的,你会得到两个整数之间的差异,这基本上可以是我猜的任何东西。
    猜你喜欢
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多