如何在C中更改数组的大小?

时间:2013-12-06 00:21:10

标签: c arrays

我有一个数组[16],它有值,我想用[4][4]作相同的值。

这些值并不固定,但我总是会得到数组。

u8 pt[16] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
             0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};

所以,我想把它改成4 * 4数组

我试图改变它,但我做不到。

这就是我所做的,但我使用了4个for循环。我想减少它。

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

那么,任何人都可以帮助我吗?

5 个答案:

答案 0 :(得分:1)

在您的示例中,您不会更改数组的大小。你只需改变它的签名。

您可以在不使用[][]的情况下访问数组。只需通过指针获取值:*(myArray + i*16 + j),这样您就可以根据需要分配索引ij

答案 1 :(得分:1)

解决方案是使用1维缓冲区,并手动执行尺寸:

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

注意:

  • 应检查mallocrealloc的返回值(并使用realloc,使用额外的临时变量作为返回值,因此如果原始值失败则原始值不会丢失)< / LI>
  • 上面的代码使得分配的缓冲区未初始化,使用&#34; random&#34;值
  • 记得free(array)释放已分配的内存
  • 如果你想进行更高级的转换,你需要在内存中移动值,然后分配一个新缓冲区并将旧值复制到正确的新位置,然后free旧数组,但我在这里假设你只想保留原始数据,只需更改访问它的尺寸。

答案 2 :(得分:0)

您只能更改使用malloc动态分配的数组对象的大小。使用realloc功能更改其大小。在您的情况下,数组将具有相同的大小sizeof (int [1][16]) == sizeof (int [4][4]),因此甚至不需要realloc

答案 3 :(得分:0)

你不能调整它们的大小,你可以制作更大的那些,并将旧版本复制到其中。

但是在你的情况下,如果你只是想将你的1 * 16视为4 * 4,你可以施展它。

答案 4 :(得分:0)

与原始描述相反,您不是更改数组的维度,您只是复制一维16元素数组的元素成为一个二维的4乘4阵列。

4个嵌套for循环的序列太复杂了(除了不工作)。例如,每个外部循环:

for (int i=0; i < 1; i++) {

相当无用;它只迭代一次,将i设置为0

您从:

开始
u8 pt[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
              0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };

(我认为u8是一个8位无符号类型,但你没有告诉我们它的定义。使用uint8_t中定义的标准<stdint.h>可能更好。

并且您希望将元素复制到此2D数组中:

u8 a[4][4];

有(至少)两种方法可以做到这一点。您可以迭代pt的元素,为每个要为分配a元素计算

for (int i = 0; i < 16; i ++) {
    a[i/4][i%4] = pt[i];
}

或者您可以迭代a的元素,为中要分配pt元素计算每个元素:

for (int i = 0; i < 4; i ++) {
    for (int j = 0; j < 4; j ++) {
        a[i][j] = pt[i * 4 + j];
    }
}

在任何一种情况下,你只需要一个(可能是嵌套的)循环,而不是4个单独的循环。

或者你可以一次只复制整个数组:

memcpy(&a, &pt, sizeof a);

这是有效的,因为C语言对数组如何存储在内存中提供了一定的保证。元素以指定顺序连续存储,而二维数组只是一个数组数组(在a的情况下,它是一个4元素数组,其中每个元素本身就是一个4元素数组u8 s)。它还取决于您要复制元素的顺序恰好与它们存储在内存中的方式相匹配。

(还有一些使用指针转换可以玩的别名技巧,但我认为我不想进入。这些技巧可能会起作用,但它们可能会导致未定义的行为。)

对您的代码进行了一些观察:它充满了magic numbers,我在这里提供的代码片段也是如此。这对于一个小例子来说很好,但在现实世界的代码中,魔术数字很危险。如果我想将问题更改为使用5 x 5数组,我必须将数字4的多次出现更改为5 更改{{ 1}}到16。如果我想使用一个4乘5的阵列,那就更糟了。

相反,您可能希望将数组声明为:

25

然后将所有#define LEN 4 uint8_t pt[LEN*LEN] = { /* ... */ }; uint8_t a[LEN][LEN]; 替换为4,将LEN替换为16。然后,您只需更改LEN*LEN的定义并重新编译即可更改数组的大小。

好吧,差不多;你还必须改变初始化。可能你想使用循环来初始化LEN

pt

你应该首先考虑是否需要任何。我不知道您的代码的上下文,但您很可能不需要for (int i = 0; i < LEN*LEN; i ++) { pt[i] = i; } pt。如果只声明一个数组用于您的目的,那么不要浪费时间声明第二个数组并将其复制到其中。当然,如果这就是你需要的,那么你应该这样做 - 但是我们无法从你的问题中看出你在将元素从一个数组复制到另一个数组时所要完成的事情。