开发者

Passing by reference 3-Dim Fixed length array

Can anyone hint on how to pass开发者_开发技巧 by reference an array of the kind

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

so that I may save his pointer in order to use and modify the array? Like, if I were speaking about a single integer:

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

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

Thanks a lot and best regards.


If you really want to pass the array by reference, you can do so:

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

In C, which doesn't have references, you can pass the array by pointer (this works in C++ too, of course):

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


C++:

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

C: There are no references in C

Note that no matter how you pass the array, via reference or not, the array is not going to be copied, so you'll get the original pointer. You can pass this array also like this:

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


Thanks to everyone who participated in this! sskuce provided a very good solution, taking advantage of a "container". I had thought about this but didn't really like the extra stuff. I realized after a little jumbling that James McNellis had given the answer all along. So... here's the solution I prefer with no containers and no indexes arithmetic (mind the parenthesis):

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;
}

Thanks again to everyone.


Edit: I'm keeping my original answer below, as I believe it's necessary for folks to understand how arrays are actually passed to functions and how they're layed out in memory, but on further reflection I think there is a simple and correct way to get what you want done.

Encapsulate the array within a struct, e.g.

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.
}

The struct will allow you to maintain layout information about the encapsulated array, and you don't have to worry about nasty index arithmetic.

-----OLD ANSWER----- Passing a reference to an array is not useful, unless you want to change the size or layout of the array (which you can't do with statically sized arrays anyway). You'll get a reference (or pointer) to the elements of the array even if you pass the array by "value". That is to say, if you declare your function:

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

and call it like f( array ) when f exits, array[0][2][2] will have been set to 42, even though you didn't pass a "reference" to array into the function.

If you want to save a pointer to the array for later use in a library function, etc, you could do something like:

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

It gets tricky at this point - you have to know how pa is layed (laid?) out in memory. I think C has standardized on 'row major order', so the array should be layed out in memory like:

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]

So, to get at an element at index [n][j][k], you have to do something like:

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

Basically, multiply each index by the number of elements that can be referenced by an index of that order, e.g. each k index points to exactly one element given a fixed j and n index, each j index can point to 4 elements given a fixed n index, and each n index can point to one of 12 (because 12 = 3 * 4) elements.

Like I said, it's tricky. See the wikipedia articles on Array Data Structures and Row-major order to get a better understanding of how these things are layed out.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜