简体   繁体   中英

How to change the size of an array in C?

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

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.

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:

  • return values of 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)
  • above code leaves the allocated buffer uninitialized, with "random" values
  • remember to free(array) to release allocated memory
  • if you want to do a fancier transformation, where you need to move values in memory, then allocate a new buffer and copy old values to right new places, then free the old array, but I assume here you just want to keep the original data and just change the dimensions for accessing it.

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM