开发者

Is there a way to have one array that holds other arrays in c?

I have 4 int arrays. They all have the same number of elements. Something like this:

int  ar1[] = {1,2,3,4};
int  ar2[] = {10,12,13,14};
int  ar3[] = {8,9,15,16};
int  ar4[] = {17,18,19,20};
int  big[][] ={ar1,ar2,ar3,ar4};  // I know this is messed up but here is where the question lies

Is there a way so that when I run a for loop:

int i;
for(i =0; i<4; i++){
    int x;
    for(x = 0; x<4; x++){
       printf(big[i][x]); // something like this   
    }
}

So that when this is executed, it prints out:

Array 1 : 1 2 3 4 Array 2 : 10 12 13 14 etc.....

开发者_StackOverflow中文版

Thanks.


Check this out: Multidimensional arrays in C and this Wikipedia page for the general information on multidimensional arrays in C.

Your code should work with this:

int* big[] = {ar1, ar2, ar3, ar4};


A C 2-dimensional array is nothing more or less than an array of arrays. Such a 2-d array cannot be "ragged", i.e., each row must have the same number of elements. For your particular case, you could declare it as:

int big[4][4] =
    { { 1, 2, 3, 4 },
      { 10, 12, 13, 14 },
      { 8, 9, 15, 16 },
      { 17, 18, 19, 20 } };

You can omit the first dimension: int big[][4] = ... and the length will be determined by the initializer, but you can't omit the second one.

One advantage of this approach is that it's a single object, and you can use sizeof to determine how many elements it has:

sizeof big == 16 * sizeof (int)
sizeof big[0] == sizeof *big == 4 * sizeof (int)
sizeof big[0][0] == sizeof (int)

But the disadvantage is that the dimensions are fixed.

Another approach is to use an array of pointers, where each pointer points to the first element of an array:

int row0[] = { 1, 2, 3, 4 };
int row1[] = { 10, 12, 13, 14 };
int row2[] = { 8, 9, 15, 16 };
int row3[] = { 17, 18, 19, 20 };

int *big[4] = { row0, row1, row2, row3 };

(In the initializer, row0 is an array name, but it decays to a pointer to the first element; likewise for row1, row2, and row3). This is more flexible, but you have to keep track of the number of elements in each row; sizeof big[0] will give you the size of a pointer, not of the row itself.

Yet another approach is make big a pointer-to-pointer:

int row0[] = { 1, 2, 3, 4 };
int row1[] = { 10, 12, 13, 14 };
int row2[] = { 8, 9, 15, 16 };
int row3[] = { 17, 18, 19, 20 };

int *rows[] = { row0, row1, row2, row3 };

int **big = rows;

This is even more flexible (and in practice you'd probably allocate everything with malloc().

A fourth approach, probably not terribly useful, would be to make big an array of pointers to arrays; I won't go into the details of that.

Due to the array-to-pointer decay rules, even though big is of 4 different types in the 4 different cases, you can use the same syntax to refer to the int elements: big[x][y].

Recommended reading, as always: section 6 of the comp.lang.c FAQ.


Sure, and you're pretty close to having it. In C, what you do is construct (always) a bunch of adresses, and either you or the compiler does the necessary arithmetic to treat is as however many dimensions you want.

So, let's say we make a one-dimensional array, a vector:

int vec[] = {0, 1, 2, 3 };

In memory, that becomes a location with a name vec

vec:
     DS  0
     DS  1
     DS  2
     DS  3

where DS is just saying "define storage and initialize with".

When you write a for loop to iterate through it:

int ix;
for(ix=0; ix < 4; ix++){
   printf("%d\n", vec[ix]);
}

it becomes a loop somewhat like

ix:    DS 0
loop:  CMP ix, 4
       JGE end     ; jump if comparison is >=
       PUSH vec+ix ; address arithmetic
       JSR PRINTF  ; call the printf routing using value on the stack
       INC ix      ; ix := ix+1
       JUMP loop   ; goto top
end:  

(That's in no particular assembler, just a pseudocode.)

Now, let's make a 2d array

int ary2[][] = {{0,1,2,3},{4,5,6,7});
int ix, jx;
for(ix=0; ix<4;ix++){
   for(jx=0; jx<4; jx++){
      printf("%d\n", ary2[ix][jx]);
   }
}

In memory, that just becomes

ary2:
     DS 0
     DS 1
     DS 2
     DS 3
     DS 4
     DS 5
     DS 6
     DS 7

in other words, just another blob of memory. Our loop becomes

ix:   DS  0
jx:   DS  0
;; Now, the compiler helps us a little bit: it "remembers" that
;; the inner array is 4 long.  We'll keep that around as 'len'
len:  DS  4
ofst: DS  0   ; and we'll keep a convenient variable for the "offset"
;; here's out loop
loop1:
      CMP ix, 4
      JGE end1
loop2:
      CMP  jx, 4
      JGE  end2
;; I'm going to cheat here.  ASSUME I've got a little
;; routine that multiplies ix*len and puts it in offset
      MLTOFFSET  ix,len
      ADD  jx, ofst
;; so what this all did was make ofst == (ix*len)+jx
      PUSH ary2+ofst
      INC  jx
      JUMP loop2
end2:
      INC ix
      JUMP loop1
end1:

If you walk through that, what you find is that ary2[ix][jx] turns into ary2+0,ary2+1,ary2+2,...ary2+6,ary2+7 -- and those are exactly the values you need to make that one piece of memory act like a 2 dimensional array.

The same trick, of course, can be carried on for as many dimensions as you want; the compiler just has to "remember" how big the steps will be.


since you know the elements in each of the array(i.e 4),you can easily construct the bigger array having 16 elements.... arr1,arr2,arr3,arr4 and arr5(all the 4 arrays will be stored in it) you can traverse the bigger array,and fill in the contents for smaller arrays

arr5-->[4 elements]arr1----------[4 elements]arr2--------[4 elements]arr3-------[4 elements]arr4==========[16 elements]

for(i=0;i<16;i++)//traversing the bigger array) {

//for first array ,fill up the contents and increment the i,this would fill up the bigger array for(j=0;j<4;j++,i++) arr5[i]=arr1[j]; similarly for other arrays as well

}

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜