【问题标题】:Passing by reference 3-Dim Fixed length array通过引用传递 3-Dim 固定长度数组
【发布时间】:2011-05-16 23:27:41
【问题描述】:

任何人都可以提示如何通过引用传递此类数组

int array[2][3][4];

以便我可以保存他的指针以便使用和修改数组? 比如,如果我说的是一个整数:

// Scope 1
int a = 3;
increment(&a);
// End Scope 1

// Scope 2
int *pa;
void increment(int *tpa) { 
  pa = tpa; *pa++; 
}
// End Scope 2

非常感谢和最好的问候。

【问题讨论】:

  • 我不确定你的意思。您说您想要对数组的引用,但您提供的示例函数increment 只需要对数组中单个元素的引用(或指针)。例如如果你调用了increment( &a[0][1][2] )pa 将被设置为指向该元素的指针。
  • 再次感谢。我会尝试更好地解释自己:我在一个类中定义了我的 int a[2][3][4]。我需要将它的指针传递给另一个类,以便第二个类可以使用和修改“a”。怎么做? IE。如何定义函数,如何在第二个类中声明指针,如何从第一个类传递数组?

标签: c++ c function multidimensional-array pass-by-reference


【解决方案1】:

如果你真的想通过引用传递数组,你可以这样做:

void f(int (&a)[2][3][4]) { }

在没有引用的 C 中,您可以通过指针传递数组(当然,这也适用于 C++):

void f(int (*a)[2][3][4]) { }

【讨论】:

  • 你们回复的速度真是太棒了。谢谢。
  • @JoeSlav:欢迎来到 StackOverflow :) 你应该学会接受对你帮助最大的答案
  • 感谢詹姆斯的回答,我在自己的回答中进行了扩展。也感谢 Armen 的欢迎!
【解决方案2】:

C++:

void f(int (&array)[2][3][4])
{
}

C: C 中没有引用

请注意,无论您如何传递数组,无论是否通过引用,数组都不会被复制,因此您将获得原始指针。你也可以像这样传递这个数组:

void f(int array[][3][4])
{
}

【讨论】:

    【解决方案3】:

    编辑:我在下面保留我的原始答案,因为我相信人们有必要了解数组实际上是如何传递给函数的以及它们是如何在内存中布局的,但经过进一步思考,我认为有一个简单的和正确的方法来完成你想做的事情。

    将数组封装在结构中,例如

    typedef struct ArrayHolderStruct{
        int array[2][3][4];
    } ArrayHolder
    
    //...
    //scope 1
    ArrayHolder thingy;
    thingy.array[0] = something;
    //other initialization.
    F( &thingy );
    //...
    
    //scope 2
    ArrayHolder *pa;
    void F ( ArrayHolder *p ){
        pa = p;
        p->array[0][1][2] = 42;
    }
    
    //Call F first to set pa.
    void G(){
        pa->array[0][1][2] = 6 * 9; // if pa = &thingy, thingy will be modified.
    }
    

    该结构将允许您维护有关封装数组的布局信息,并且您不必担心讨厌的索引算法。

    -----旧答案----- 传递对数组的引用是没有用的,除非您想更改数组的大小或布局(无论如何您都不能使用静态大小的数组)。即使您通过“值”传递数组,您也会获得对数组元素的引用(或指针)。也就是说,如果你声明你的函数:

    void f ( int a[2][3][4] ){
        a[0][1][2] = 42;
    }
    

    f 退出时,像f( array ) 一样调用它,array[0][2][2] 将被设置为 42,即使您没有将“引用”到 array 传递到函数中。

    如果您想保存指向数组的指针以供以后在库函数等中使用,您可以执行以下操作:

    //scope 2
    int * pa;
    void f ( int a[2][3][4] ){
        pa = &a[0][0][0];
    }
    

    在这一点上变得很棘手 - 你必须知道 pa 在内存中是如何放置(放置?)的。我认为 C 已经对“行主要顺序”进行了标准化,所以数组应该像这样在内存中布局:

    a[0][0][0] a[0][0][1] a[0][0][2] a[0][0][3] a[0][1][0] ... a[0][2][3] a[1][0][0] a[1][0][1]... a[1][2][3]
    

    因此,要获取索引 [n][j][k] 处的元素,您必须执行以下操作:

    pa[n * 12 + j * 4 + k] = something;
    

    基本上,将每个索引乘以该顺序索引可以引用的元素数,例如给定固定的jn 索引,每个k 索引恰好指向一个元素,给定一个固定的n 索引,每个j 索引可以指向4 个元素,每个n 索引可以指向一个12 个(因为 12 = 3 * 4)个元素。

    就像我说的,这很棘手。请参阅 Array Data StructuresRow-major order 上的维基百科文章,以更好地了解这些内容的布局。

    【讨论】:

    • 我会在这里添加评论,即使是一般评论。您能否指定,如何在第二个范围内声明数组指针以及如何在函数中传递数组本身?例如 (C++): // 1 int a[2][3][4];乐趣(一); // 结束 1 // 2 int (*b)[2][3][4];无效乐趣(int (&a)[2][3][4]){ b = a; } // 结束 2 谢谢
    • @JoeSlav - 查看我的新答案,我相信它可以完成您想做的事情(保持对固定长度多维数组的恒定引用),而无需担心索引算法。
    【解决方案4】:

    感谢所有参与此活动的人! sskuce 利用“容器”提供了一个非常好的解决方案。我曾考虑过这一点,但并不真正喜欢额外的东西。 有点混乱后,我意识到詹姆斯麦克内利斯一直都给出了答案。所以...这是我更喜欢的解决方案,没有容器和索引算术(注意括号):

    void Scope1() 
    {
        int array[2][3][4];
        Scope2(&array);
    }
    
    int (*pArray)[2][3][4];
    
    void Scope2(int (*tpArray)[2][3][4])) 
    {
        pArray = tpArray;
        (*pArray)[0][0][0] = 3;
    }
    

    再次感谢大家。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-09
      • 1970-01-01
      • 2020-07-30
      • 2012-04-17
      • 2014-08-06
      • 2020-03-09
      • 2019-06-29
      相关资源
      最近更新 更多