【问题标题】:What does subtracting two arrays do in c++?在 C++ 中减去两个数组有什么作用?
【发布时间】:2022-02-03 03:53:53
【问题描述】:

例如,如果我从大小为 2 的数组中减去大小为 3 的数组,则无论里面是什么,它都会返回 3。这是为什么呢?

例如:

int a[2] = {1,2};
int b[3] = {999,999,999};
cout << a-b;

输出为 3

【问题讨论】:

  • 数组自然衰减为指向其第一个元素的指针。不相关指针的指针算术导致未定义的行为。你到底在做什么?请尝试创建minimal reproducible example 向我们展示。
  • 嗨,对不起,我的问题有点令人困惑。我添加了我的测试示例。我只是对减去 2 个数组的作用感到困惑,我还没有在网上找到任何关于它的内容。
  • 编写无效程序的方法有很多。这是其中之一。您不会发现大多数在线讨论的方式仅仅是因为有很多。
  • 它减去指针。如果它们是指向同一数组的元素的指针,那将是合法的,但由于它们是不同的数组,因此行为是未定义的。
  • 虽然这确实是未定义的行为,但可能发生的情况是编译器将数组彼此相邻放置在内存中。并且指针运算的结果总是以基类型为单位(所以你减去两个指向int的指针,所以结果是以int元素为单位的)。不能依赖此行为始终或无处不在。

标签: c++


【解决方案1】:

这里的第一个问题是,两个数组的减法是什么? 如果您提到减去具有相同索引的元素,则必须确保数组的大小相等。 然后遍历两个数组并使用循环将一个数组减去另一个数组。 您想要实现的事情会导致未定义的行为。 您也可以使用重载的 '-' 运算符来减去两个数组对象,但这有点复杂。

【讨论】:

    【解决方案2】:

    这很容易发生,因为您的示例确实减去了 int 的指针,而不是向量。

    会发生什么:

    &a[0] - &b[0]
    

    我假设您尝试实现向量减法。一种方法是重载运算符-

    看看这里,如何实现运算符重载:What are the basic rules and idioms for operator overloading?

    【讨论】:

    • "一种方法是重载运算符 [原文如此]-" 但是您如何对数组执行此操作?
    • 理想情况下,这应该与将矢量数据和特定操作封装到模板化类/结构中结合起来。对于运算符重载本身,请查看以下示例:stackoverflow.com/questions/19697444/…
    【解决方案3】:

    无论里面是什么,它都会返回 3

    不,它并不总是返回 3。

    这取决于编译器/链接器/库/平台/许多其他因素。

    例如,在我的机器上,g++ 编译器和 MSVC 得到两个不同的结果。 您永远不应该做出任何假设并依赖这种行为。

    #include <iostream>
    
    using namespace std;
    
    int main(int argc, char **argv) {
      {
        int a[2] = {1, 2};
        int b[3] = {999, 999, 999};
        cout << a - b << endl;
    
        cout << static_cast<void *>(a) << ' ' << static_cast<void *>(b) << endl;
      }
    
      {
        int a[2] = {1, 2};
        int middle_array[2] = {1, 2};
        int b[3] = {999, 999, 999};
        cout << a - b << endl;
    
        cout << static_cast<void *>(a) << ' ' << static_cast<void *>(b) << endl;
      }
      return 0;
    }
    

    使用 G++

    $g++ t3.cpp && ./a.exe
    3
    0xffffcc28 0xffffcc1c
    5
    0xffffcc14 0xffffcc00
    

    使用 MSVC

    cl t3.cpp && t3.exe
    -6
    00000012814FFB00 00000012814FFB18
    -8
    00000012814FFB08 00000012814FFB28
    

    附:对于好奇的人。 这些是两台不同机器(g++)的测试结果:

    4
    0x7ffcdaa00640 0x7ffcdaa00630
    8
    0x7ffcdaa00620 0x7ffcdaa00600
    
    -2
    0x7ffd969a2904 0x7ffd969a290c
    -4
    0x7ffd969a28fc 0x7ffd969a290c
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-12
      • 2012-12-06
      • 1970-01-01
      • 1970-01-01
      • 2014-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多