簡體   English   中英

在C中傳遞2D數組

[英]Passing 2D arrays in C

我從C中斷了一次,只是又重新回到了C。

如果我想創建一個2D的雙精度數組,我可以通過兩種方式做到這一點:

double** m_array = (double**) malloc(2*sizeof(double*));
double*  m_array = (double*)  malloc(2*sizeof(double));

要么

double array[2][2];

但是,當我希望傳遞malloc數組而不是傳遞另一個數組時,似乎有兩個約定:

//allowed for passing in malloc'd array, but not for other array
func_m(m_array) //allowed
func_m(array) //disallowed
func_m(double** m_array)

//allowed for passing in either array; required for passing in non-malloc'd array
func(m_array) //allowed
func(array) //allowed
func(double array[][2])

首先,我不需要任何信息,它是指向指針數組的指針。 但是它只能是一個malloc數組。

在第二個中,我需要傳遞double *數組所指向的每個數組的長度。 這似乎很愚蠢。

我想念什么嗎? 提前致謝。

第一個根本不創建二維數組。 它創建一個指針數組,該指針顯然沒有指向。 如果確實將每個指針初始化為一個數組,則該指針仍將是數組的數組,而不是二維數組。

為什么不創建二維數組呢?

double* dynamicArray = malloc(rows * columns * sizeof (double));

要么

double autoArray[rows][columns];

然后您可以使用以下任一功能:

void func(double* array, size_t rows, size_t columns);

為了澄清起見,假設您聲明:

int my_static_array[row][col];

在pmg的答案中,my_static_array與malloc'd數組(稱為my_malloc數組)的類型是什么? my_static_array是內存中連續的row * col * sizeof(int)個字節,並帶有指向其開頭的int *指針。 在計算my_static_array [x] [y]時,編譯器會知道這樣做(因為它們以行優先順序存儲):

*(addr(my_static_array) + [sizeof(int)*col*x] + [sizeof(int)*y])

這就是為什么我需要傳遞C的col值的原因:

(1) func(int my_static_array[][col])
(2) func(int my_static_array[][])

在(1)中,編譯器知道如何為靜態數組正確計算地址。 在(2)中,編譯器沒有足夠的信息。 這就是為什么(1)編譯而(2)不會編譯的原因。

如果是malloc數組,則可以通過:

func(int** my_malloc_array)

由於它是指向一維數組的連續數組的指針,因此編譯器不需要幫助。 my_malloc_array [x] [y]很簡單:

*(*(addr(my_malloc_array)+x)+y)

編譯器不需要其他有關其維數的信息即可進行計算。

那么,這是什么教訓? 二維陣列是一樣的指針數組至1D陣列。 前者的類型為int(* my_static_array)[row * col]-指向行* col元素數組的指針,后者的類型為int **-指向指針數組的指針。

您對2D陣列的分配是錯誤的。 通常的2D方法是

double **m_array = malloc(NROWS * sizeof *m_array);
for (i = 0; i < NROWS; i++) {
  m_array[i] = malloc(NCOLS * sizeof *m_array[i]);
}

將數組或指針(任何維)傳遞給函數時,必須讓函數知道維:它們未在數組或指針本身內編碼。

一方面,您具有指向某些對象的指針(指向指針(至指針(...))),另一方面,您具有某種類型的數組(數組(屬於數組(...)))。

當您將指針傳遞給函數時,就是這樣。 當您“傳遞數組”時,發生的事情是該數組衰減為指向其第一個元素的指針。 所以

foo(array); // is the same as foo(&(array[0]));

array是多維數組時,衰減指針的類型是pointer to array[size] of SOMETHING (但您不能使用該大小!)。

最簡單的方法是使用簡單的指針編寫函數並傳遞所有維的乘法

double array[3][4][5];
foo(&(array[0][0][0]), 3*4*5);

假設計算機存儲器是一個充滿按順序編號的框的倉庫。 當你做

int matrix[10][3];

您保留30個用於保存矩陣值的框(例如,框131至160)。

現在,假設您要對函數中矩陣中的所有值求和:

int matrix_sum(int matrix[10][3]) { /* ... */ }

但是接收到的所有函數(由標准規定)都是指向矩陣第一個元素的指針:指向3個int數組的指針。 因此,該函數知道框131、132和133屬於矩陣,但它不知道矩陣實際有多長時間。

使用簡單的typedef:

typedef double Twodouble_t[2];

void func(Twodouble_t *ptr)
{
  size_t i, numelements = sizeof*ptr/sizeof**ptr;
  puts("first array");
  for( i=0; i<numelements; ++i )
    printf("\n%f",ptr[0][i]);
}
...
Twodouble_t array[]={ {1., 1.},{2., 2.},{3.,3.} };
func(array);
...

暫無
暫無

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

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