【问题标题】:C++ linear access to 3 dimensional arrayC++线性访问3维数组
【发布时间】:2022-01-09 08:20:40
【问题描述】:

您好,据我了解,当我分配 3 维数组时,我真正获得了线性内存,通过定义步幅仅将其解释为 3 维。

所以我想使用线性索引访问 3 维数组,但是如何使用线性索引获取第一个元素 - 原则上应该可以,例如给定 int32 为了获得第 11 个元素,我应该从 beginin 移动 320 位f 数组取下一个 32 并将这些位解释为 int - 似乎比从线性索引计算 3 d 索引的性能要高得多,因为它需要多次除法......

在下面我尝试了取消引用,但我仍然做错了,因为我在这里得到取消引用到第二个数组的第 0 个元素,而不是我想要的

C++ 代码

int intsss[3][3][3] = {
                     { {1,2, 3}, {4, 5, 6}, {7,8, 9} },
                     { {10,11, 12}, {13, 14, 15}, {16,17, 18} },
                     { {19,20, 21}, {22, 23, 24}, {25,26, 27} }
  };

 std::cout << intsss[0][0][1] << std::endl;
  std::cout << **intsss[1] << std::endl;

输出

2
10

【问题讨论】:

  • intsss[0] 是一个数组,数组衰减为指针。您正在查看地址。
  • 好的,我明白了!那么如何使用线性索引获取第一个元素!
  • 只需取消引用指针*intsss[0]
  • 谢谢,我更新了问题,您究竟如何考虑取消对这个特定 3d 案例的引用?如上所示,我仍然在做错事
  • *intsss[0] + index_1D,但我认为这是丑陋的 AF,如果您遍历最内层数组的大小,从技术上讲是未定义行为 (UB)。您还可以使用union 在与 3D 数组相同的空间中键入(也 UB)一个 1D 数组,或使用 reinterpret_cast 告诉编译器使用 intsss 作为指向 int 的指针(仍然是UB)。我强烈建议对 3D 数组进行一些分析索引,以查看优化器完成代码后是否真的有问题。

标签: c++ arrays indexing


【解决方案1】:

**intsss[1]**(intsss[1]) 相同。如果你想用另一种方式表达intsss[0][0][1],请使用(**intsss)[1](但在我看来,这是没有意义的)。

要以线性方式寻址多维数组,首先获取指向第一个元素的指针:&amp;intsss[0][0][0]。然后像普通指针一样使用它:

int* p = &intsss[0][0][0];
std::cout << p[1];

还有其他一些等效的方法可以获取指向第一个元素的指针:intsss[0][0]**intsss。如果你使用这些,你应该小心并确保你理解指针衰减是如何工作的,并确保你得到一个指向 int 的指针而不是一个指向数组的指针。例如:intsss[0] 是一个二维数组,它衰减为指向 3 个整数数组的指针。对这个指针进行算术运算一次会跳转 3 个整数——可能不是你想要的。

严格来说,如果您越过最内层数组的末尾,这种线性寻址是非法的(未定义的行为)。但在实践中,它确实有效。

【讨论】:

    【解决方案2】:

    使用下面的代码来玩,直到你得到你想要的。

    #include <iostream>
    #include <sstream>
    #include <string>
    
    void PRINT(const std::string &s) { std::cout << s; std::cout.flush(); }
    template<typename...T> void say(T...t) { std::string s{}; std::stringstream ss(""); (ss<<...<<t); s=ss.str(); PRINT(s); }
    
    int main()
    {
        int intsss[3][3][3] = { { {1,2, 3}, {4, 5, 6}, {7,8, 9} },
                                { {10,11, 12}, {13, 14, 15}, {16,17, 18} },
                                { {19,20, 21}, {22, 23, 24}, {25,26, 27} } };
        int a, b, c;
        say("\n-----------\n");
        a=intsss[2][2][0];
        b=intsss[2][2][1];
        c=intsss[2][2][2];
        say("330 -> ", a, "\n331 -> ", b, "\n332 -> ", c, "\n");
        
        say("\n-----------\n");
        a=**intsss[0];
        b=**intsss[1];
        c=**intsss[2];
        say("**0 -> ", a, "\n**1 -> ", b, "\n**2 -> ", c, "\n");
        
        return 0;
    }
    

    【讨论】:

    • 您需要先提供更多详细信息..
    • @tilz0R:“给乞丐一条鱼……或者教乞丐如何钓鱼……”
    猜你喜欢
    • 2019-04-27
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    • 2013-07-27
    • 1970-01-01
    相关资源
    最近更新 更多