声明一个未知大小的二维数组,C

我有一个数组声明为C中的结构的成员。该数组声明为:

char mValue[MAXROWS][MAXCOLUMNS]; 

其中MAXROWSMAXROWS是300.有更好的方法吗? 我的意思是,我应该将它们声明为指针吗?

谢谢!

如前面的海报所示,一个好方法是创建一个线性数组,然后“将其转换为2D”。 很多时候,缓存2D指针大大提高了使用这个数组的程序的速度,如下所示:

 mystruct *p = (mystruct*)calloc(ROWS * COLUMNS, sizeof(mystruct)); mystruct **p2 = (mystruct**)calloc(ROWS, sizeof(mystruct*)); for (int i = 0; i < ROWS; i++) p2[i] = p + i*COLUMNS; 

然后,您可以使用以下命令访问2D元素:

 p2[row][column] = foo; 

如果所有行的大小相同,则应使用一维数组,其中行按顺序存储:

 ABCDE FGHIJ ---> ABCDEFGHIJKLMNO KLMNO 

i行,第j列的元素将位于1D数组中的索引i * ROW_LENGTH + j

您可以使用malloc(ROW_LENGTH * NUM_ROWS)分配数组。

另一种技术是创建一个线性数组,然后将其转换为2d:

 char *p = malloc(ROWS * COLUMNS); // To access x, y // This is in row-major ordr *(p + (x * COLUMNS) + y); 

我发现,对于这种代码,最好创建辅助函数来访问元素。 根据您的分析数据,将这些转换为宏可能是有意义的,但要格外小心。

 #include  /* For printf */ /* This is the bit that would go in a header, like char2darray.h */ #include  /* For calloc */ #include  /* For assert */ struct Char2DArray { int rows; int columns; char *values; }; /* This is the bit that would go in a source file, like char2darray.c */ void C2DA_initialize(struct Char2DArray *array, int rows, int columns) { assert(array != 0); array->values = calloc(rows * columns, sizeof(char)); array->rows = rows; array->columns = columns; } void C2DA_set(struct Char2DArray *array, int row, int column, int value) { assert(array != 0); assert(array->values != 0); assert(row < array->rows); assert(row >= 0); assert(column < array->columns); assert(column >= 0); array->values[(row * array->rows) + column] = value; } char C2DA_get(struct Char2DArray *array, int row, int column) { assert(array != 0); assert(array->values != 0); assert(row < array->rows); assert(row >= 0); assert(column < array->columns); assert(column >= 0); return array->values[(row * array->rows) + column]; } void C2DA_free(struct Char2DArray *array) { free(array->values); array->values = 0; } /* Here's a main.c to use it */ int main() { struct Char2DArray a; C2DA_initialize(&a, 16, 16); unsigned char c = 0; int x, y; for (x=0; x<16; x++) { for (y=0; y<16; y++) { C2DA_set(&a, x, y, (char)c); c++; } } printf("Character with hex value 0x55 is %c\n", C2DA_get(&a, 5, 5)); C2DA_free(&a); return 0; } 

如果数组需要具有动态大小,那么您需要使其成为指针或使数组成为结构的最后一个成员并在分配结构大小时玩游戏。

相关comp.lang.c常见问题条目:

  • 我遇到了一些声明这样结构的代码……
  • 如何动态分配多维数组?

我发现在面对类似的问题时,改变我的方法非常有用。

向量向量填充相同的任务,避免了内存分配障碍,并保持相同的熟悉的速记。 可能还有其他陷阱,但我还没有遇到过它们。

 //Declaration of mValues, undefined size: std::vector< std::vector > mValues; //Filling of mValues: int max_x = 100 ; int max_y = 100 ; char char_foo = 'a'; for ( int x = 0; x <= max_x; ++x ) { vector temp; for ( int y = 0; y <= max_y; ++y ) { temp.push_back( char_foo ); } mValues.push_back( temp ); } // Referencing with familiar index notation: mValues[a][b]; //The a-th row's b-th element 

如果您正在努力使用数组,但强烈希望使用熟悉的索引语言,我发现这是一个很好的选择。

请注意,在调用此数据时,索引顺序A和B对于内存使用至关重要。 如果性能问题,未能以A,B顺序调用信息将会成为严重问题。