Reputation: 11
I have an array [16] that has values, I want to make it [4][4]
with the same values.
These value are not fixed, but I always will get array as this.
u8 pt[16] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
So, I want to change it to 4*4 array
I tried to change it, but I couldn't do it.
This is what I did, but I used 4 for loops. I want to make it less than that.
for (int i=0; i < 1; i++) {
for (int j=0; j < 4; j++) {
a[i][j]= pt[j];
}
}
for (int i=0; i < 1; i++) {
for (int j=0; j < 4; j++) {
a[i+1][j]= pt[j+4];
}
}
for (int i=0; i < 1; i++) {
for (int j=0; j < 4; j++) {
a[i+2][j]= pt[j+8];
}
}
for (int i=0; i < 1; i++) {
for (int j=0; j < 4; j++) {
a[i+3][j]= pt[j+12];
}
}
So, can any one help me? .
Upvotes: 0
Views: 671
Reputation: 263177
Contrary to your original description, you're not changing the dimensions of an array, you're merely copying the elements of a 1-dimensional 16-element array into a 2-dimensional 4-by-4 array.
Your sequence of 4 nested for
loops is far too complicated (apart from not working). For example, each of your outer loops:
for (int i=0; i < 1; i++) {
is fairly useless; it iterates exactly once, setting i
to 0
.
You start with:
u8 pt[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
(I presume u8
is an 8-bit unsigned type, though you don't show us its definition. It's probably better to use the standard uint8_t
, defined in <stdint.h>
.
And you want to copy the elements into this 2D array:
u8 a[4][4];
There are (at least) two ways to do this. You can iterate over the elements of pt
, computing for each one which element of a
you want to assign to:
for (int i = 0; i < 16; i ++) {
a[i/4][i%4] = pt[i];
}
Or you can iterate over the elements of a
, computing for each one which element of pt
you want to assign from:
for (int i = 0; i < 4; i ++) {
for (int j = 0; j < 4; j ++) {
a[i][j] = pt[i * 4 + j];
}
}
In either case, you just need a single (possibly nested) loop, not 4 separate loops.
Or you could just copy the entire array at once:
memcpy(&a, &pt, sizeof a);
That works because the C language makes certain guarantees about how arrays are stored in memory. The elements are stored contiguously and in the specified order, and a 2-dimensional array is simply an array of arrays (in the case of a
, it's a 4-element array where each element is itself a 4-element array of u8
s). It also depends on the fact that the order in which you want to copy the elements happens to match the way they're stored in memory.
(There are also some aliasing tricks you can play using pointer conversions, but I don't think I want to get into that. Such tricks are likely to work, but they can result in undefined behavior.)
A few observations on your code: It's full of magic numbers, as are the snippets I've provided here. That's fine for a small example, but in the context of real-world code, magic numbers are dangerous. If I wanted to change the problem to use a 5-by-5 array, I'd have to change multiple occurrences of the number 4
to 5
and change 16
to 25
. It's even worse if I want to use a 4-by-5 array.
Instead, you might want to declare your arrays as:
#define LEN 4
uint8_t pt[LEN*LEN] = { /* ... */ };
uint8_t a[LEN][LEN];
and then replace all occurrences of 4
by LEN
, and 16
by LEN*LEN
. Then you can change the size of the array just by changing the definition of LEN
and recompiling.
Well, almost; you'll also have to change the initialization. Possibly you'd want to use a loop to initialize pt
:
for (int i = 0; i < LEN*LEN; i ++) {
pt[i] = i;
}
And you should consider whether you need to do any of this in the first place. I don't know the context of your code, but it's quite possible that you don't need both pt
and a
. If declaring only one array serves your purpose, then don't waste time declaring a second array and copying into it. Of course if that's what you need you should do it -- but we can't tell from your question just what you're trying to accomplish beyond copying elements from one array to another.
Upvotes: 0
Reputation: 2837
In your example you don't change the size of array. You just change its signature.
You can access to array without [][]
. Just get values by pointer: *(myArray + i*16 + j)
so you can assign indexes i
,j
as you want.
Upvotes: 1
Reputation: 62777
Solution is to use a 1-dimensional buffer, and do the dimensions manually:
int width = 1;
int height = 16;
int *array = malloc(width * height * sizeof int);
int x1 = 0; // valid values go from 0..0
int y1 = 8; // valid values go from 0..15
int value1 = array[x + y * width]; // get column x on row y
// change array dimensions
int width = 4;
int height = 4;
array = realloc(array, width * height * sizeof int ); // no-op in this case as size does not change
int x2 = 3; // now valid values go from 0..3
int y2 = 3; // now valid values go from 0..3
int value2 = array[x + y * width]; // get column x on row y
Notes:
malloc
and realloc
should be checked (and with realloc
, by using an extra temp variable for return value, so original value is not lost if it fails)free(array)
to release allocated memoryfree
the old array, but I assume here you just want to keep the original data and just change the dimensions for accessing it.Upvotes: 1
Reputation: 44288
you can't resize them, you can make newer bigger ones and copy the old one into it.
However in your case, if you are just wanting to treat your 1*16 as a 4*4, you can cast it.
Upvotes: 0
Reputation: 145829
You can only change the size of an array object that has been allocated dynamically using malloc
. Use realloc
function to change its size. In your case, the array would have the same size sizeof (int [1][16]) == sizeof (int [4][4])
so realloc
would not even be needed.
Upvotes: 0