簡體   English   中英

如何在C中更改數組的大小?

[英]How to change the size of an array in C?

我有一個數組[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 (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];
    }
}

那么,任何人都可以幫助我嗎?

在您的示例中,您不會更改數組的大小。 你只需改變它的簽名。

您可以在沒有[][]情況下訪問數組。 只需通過指針獲取值: *(myArray + i*16 + j)這樣您就可以根據需要分配索引ij

解決方案是使用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 ,通過使用額外的temp變量作為返回值,因此如果失敗則原始值不會丟失)
  • 上面的代碼使分配的緩沖區未初始化,具有“隨機”值
  • 記得free(array)釋放分配的內存
  • 如果你想進行更高級的轉換,你需要在內存中移動值,然后分配一個新緩沖區並將舊值復制到正確的新位置,然后free舊數組,但我想在這里你只想保留原始數據並只是更改訪問它的尺寸。

您只能更改使用malloc動態分配的數組對象的大小。 使用realloc函數更改其大小。 在您的情況下,數組將具有相同的sizeof (int [1][16]) == sizeof (int [4][4])因此甚至不需要realloc

你不能調整它們的大小,你可以制作更大的那些並將舊的復制到其中。

但是在你的情況下,如果你只是想將你的1 * 16視為4 * 4,你可以施展它。

與原始描述相反,您不是要更改數組的尺寸,而只是 1維16元素數組的元素復制到2維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位無符號類型,雖然你沒有告訴我們它的定義。使用<stdint.h>定義的標准uint8_t可能更好。

並且您希望將元素復制到此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語言對數組如何存儲在內存中提供了一定的保證。 元素被連續並按照指定的順序存儲的,和一個2維陣列是簡單地數組的數組(在的情況下a ,這是一個4元件陣列,其中每個元素是本身的4元件陣列u8 S) 。 它還取決於您要復制元素的順序恰好與它們存儲在內存中的方式相匹配的事實。

(你也可以使用指針轉換來玩一些別名技巧,但我認為我不想進入。這些技巧很可能會奏效,但它們可能導致未定義的行為。)

關於你的代碼的一些觀察:它充滿了神奇的數字 ,就像我在這里提供的片段一樣。 這對於一個小例子來說很好,但在現實世界的代碼中,魔術數字很危險。 如果我想改變該問題為使用5×5陣列,我不得不改變數目的多次出現45 改變1625 如果我想使用4乘5陣列,情況會更糟。

相反,您可能希望將數組聲明為:

#define LEN 4
uint8_t pt[LEN*LEN] = { /* ... */ };
uint8_t a[LEN][LEN];

然后用LEN替換所有出現的4 ,用LEN*LEN替換16 然后,您只需更改LEN的定義並重新編譯即可更改數組的大小。

好吧,差不多; 你還必須改變初始化。 可能你想用一個循環來初始化pt

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

你應該首先考慮是否需要做這些事情。 我不知道你的代碼的上下文,但你很可能不需要pta 如果只聲明一個數組用於您的目的,那么不要浪費時間聲明第二個數組並將其復制到其中。 當然,如果這就是你所需要的,你應該這樣做 - 但是我們無法從你的問題中分辨出除了將元素從一個數組復制到另一個數組之外你想要完成什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM