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
}
精彩评论