2014-10-09 81 views
0

我想重塑一個長度爲L的數組到MxN中的一個,但不是通過在for循環中複製元素來創建新內存我想做一些指針投射以允許我訪問帶有雙下標的數組(數組[X] [Y])。C重塑1d到2d

我已經搜索了很長時間,找不到任何有用的東西。

任何幫助真的不勝感激。

編輯:感興趣的數組是在堆不堆棧上。

+0

您必須複製或受到未定義b。 – 2501 2014-10-09 09:21:58

回答

4

指針鑄造在這裏似乎不是一個好主意。但是如果列數在運行時間之前是已知的,我經常遇到的一個選擇是簡單地定義一個例如

#define arrayName(i,j) arrayName[((i)*N) + (j)] 

或者

#define ELEMENT(arrayName, i,j) (arrayName)[((i)*N) + (j)] 

,如果你希望它是更靈活。

+0

這是正確的解決方案。保持相同的類型(!),只是索引它不同。 – 2501 2014-10-09 09:30:28

0

typedef s爲您的朋友:

#include <stdio.h> 
#include <stdlib.h> 

#define M 5 
#define N 4 

typedef int Array1D[M * N]; 
typedef int Array2D[M][N]; 

int main() 
{ 
    Array1D *a1 = malloc(sizeof(*a1)); 
    Array2D *a2 = (Array2D *)a1; 
    int i, j; 

    for (i = 0; i < M * N; ++i) 
    { 
     (*a1)[i] = i; 
    } 

    for (i = 0; i < M; ++i) 
    { 
     for (j = 0; j < N; ++j) 
     { 
      printf("%8d", (*a2)[i][j]); 
     } 
     printf("\n"); 
    } 

    free(a1); 

    return 0; 
} 

注:上面的代碼現在已經更新爲使用堆分配,以免破壞強重疊規則。

+0

這將違反嚴格的別名並導致ub,特別是因爲您正在使用堆棧內存。 – 2501 2014-10-09 09:22:47

+0

好吧我的記憶在這堆,如果我只是保持鑄造而不是typedefs,這仍然是一個很好的解決方案? – chris 2014-10-09 09:24:36

+0

@chris如果你使用堆並且不用舊指針引用數組,你可以避開它。但我仍然不會這樣做,除非你知道你在做什麼和/或寫一個內存分配器。 – 2501 2014-10-09 09:26:10

2

union s爲您的朋友:

#include <stdio.h> 

#define M 5 
#define N 4 

typedef union { 
    int a1[M * N]; 
    int a2[M][N]; 
} U; 

int main() 
{ 
    U u; 
    int i, j; 

    for (i = 0; i < M * N; ++i) 
    { 
     u.a1[i] = i; 
    } 

    for (i = 0; i < M; ++i) 
    { 
     for (j = 0; j < N; ++j) 
     { 
      printf("%8d", u.a2[i][j]); 
     } 
     printf("\n"); 
    } 

    return 0; 
} 
+0

我可以通過對內存的兩個引用安全地修改數據嗎? – chris 2014-10-09 10:18:27

+0

是的,這在C99/C11中是明確允許的。 – 2014-10-09 10:22:13

0

順便說一句,如果你想它的超級動態(如無大小在編譯時就知道),你可以通過不復制所有的值,但通過這樣做創建第二個維度的索引,如下所示:

#include <stdio.h> 
#include <stdlib.h> 

const int FULL = 100; 
const int X = 10; 
const int Y = 10; 

int *dim1; 
int **nested; 

int main(void) { 
    dim1 = malloc(sizeof(int)*FULL); 
    nested = malloc(sizeof(int*)*X); 
    for(int i=0; i<X;i++) 
    { 
     nested[i] = &dim1[Y*i]; 
    } 
    dim1[15] = 42; 
    printf("nested[1][5]: %d",nested[1][5]); 

    free(nested); 
    free(dim1); 
    return 0; 
} 
+0

好主意,但我認爲你有X和Y錯誤的方式嗎? – 2014-10-09 11:34:57

+0

@RaulR取決於你如何訂購它,這是專欄內存。 – PeterT 2014-10-09 11:37:53

+0

當然 - 但除非你與FORTRAN或其他列專業的接口,然後行專業會更可取,我會想? – 2014-10-09 11:58:45