通过C中的指针传递可变大小的多维数组

时间:2010-12-23 11:54:49

标签: c multidimensional-array

我正在尝试将可变大小的2D数组传递给函数来打印它。我知道当一个固定大小的数组时它是如何完成的。但是如何使用可变大小的数组做到这一点?这里有一些代码可以让你知道我想要做什么:

void print_grid(char (*g)[9], int size) // the array subscript (9 here) be variable
{
   int i, j;
   for (i=0; i<size; i++)
   {
      for (j=0; j<size; j++)            
         printf("%c ", g[i][j]);
      printf("\n");
   }
}

我将使用以下代码调用此函数:

char a[3][3], b[9][9];
// assign a, b
print_grid(a, 3);
print_grid(b, 9);

如果没有在print_grid()中分配任何动态内存,有没有办法做到这一点?

4 个答案:

答案 0 :(得分:5)

void print_grid(int rows, int cols, char g[][cols]) { ... }

答案 1 :(得分:1)

void print_grid(char *g, int size) 
{
   int i, j;

   for( i = 0; i < size; i++)
      for( j = 0; j < size; j++)
      {
         printf("%c ", *(g + i*size + j));
         printf("\n");
      }
}

print_grid(a, 3);

答案 2 :(得分:1)

在C中传递数组时,它总是通过引用传递,即通过指针传递。此指针的类型不是指向数组的指针,而是指向第一个元素的指针。例如,代码生成器将处理void f(char[][10]),就像void f(char*)一样。数组尺寸丢失。但是,如果解析器看到f两次声明,那么解析器会抱怨。

C背后的动机是拥有一个功能强大且可移植的汇编程序,而不是一种新的编程语言。多维数组是机器中不存在的逻辑结构。数组是一种思考方式。

将数组的维度传递给函数C程序员传统上使用struct s:

typedef struct array_tag {
    int count;
    char data[1]; /* actually data[count] */
} ARRAY;

typedef struct grid_tag {
    int rows, columns;
    char grid[1][1]; /* actually grid[rows][columns] */
} GRID;

void f(ARRAY* x)
{
    int i;
    for (i = 0; i < x->count; ++i) {
        char c = x->data[i];
    }
}

void g(GRID* x)
{
    int i, j;
    for (i = 0; i < x->rows; ++i)
        for (j = 0; j < x->columns; ++j) {
            char c = x->grid[i][j];
        }
}

void h()
{
    {
        const int len = 100;
        ARRAY* x = (ARRAY*) malloc(sizeof(ARRAY) + len * sizeof(char));
        x->count = len;
        f(x);
    }

    {
        const int rows = 2, cols = 3;
        GRID* x = (GRID*) malloc(sizeof(GRID) + rows * cols * sizeof(char));
        x->rows = rows;
        x->columns = cols;
        g(x);
    }
}

是的,此示例中的malloc表达式分配的字节数太多。因此GNU编译器支持arrays of zero length for a long time,这在C90中是不允许的。

C99在灵活阵列方面又向前迈进了一步。来自ISO / IEC 9899:1999,第6.7.2.1节,第16段:“作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型;这称为灵活数组成员。“在C99中,ARRAYGRID类型可以声明为:

typedef struct array_tag {
    int count;
    char data[]; /* actually data[count] */
} ARRAY;

typedef struct grid_tag {
    int rows, columns;
    char grid[][1]; /* actually grid[rows][columns] */
} GRID;

你可以

assert(1*sizeof(int) == sizeof(ARRAY));
assert(2*sizeof(int) == sizeof(GRID));

许多人认为C阵列很古怪。但它们也是一个优雅的解决方案,允许声明无限复杂的数组。它被称为“K&amp; R阵列方程”。一个很好的解释can be found here

希望这会有所帮助。

答案 3 :(得分:0)

这一个does it,假设一个平方网格:

void print_grid(void* g, int size)
{
  char* my = (char*) g;
  int i, j;
  for (i=0; i<size; i++)
  {
    for (j=0; j<size; j++)            
       printf("%c ", my[i+j]);
    printf("\n");
  }
}

如果您想使用非平方网格,请将size替换为rowscolumns参数并调整计数:i<rowsj<columns。< / p>