C在结构中初始化数组

时间:2009-10-13 03:08:25

标签: c struct

我想在结构中包含一个可变长度数组,但是无法正确初始化它。

struct Grid {
  int rows;
  int cols;
  int grid[];
}

int main() {
  struct Grid testgrid = {1, 3, {4, 5, 6}};
}

我尝试的所有内容都会给我一个'错误:灵活数组成员的非静态初始化'错误。

5 个答案:

答案 0 :(得分:27)

这是我的版本:

#include <stdio.h> 

struct matrix {
  int rows;
  int cols;
  int **val;
} a = {        .rows=3,  .cols=1,
        .val = (int*[3]){ (int[1]){1},
                          (int[1]){2},
                          (int[1]){3} } },

  b = {        .rows=3,  .cols=4,
        .val = (int*[3]){ (int[4]){1, 2, 3, 4},
                          (int[4]){5, 6, 7, 8},
                          (int[4]){9,10,11,12} } };

void print_matrix( char *name, struct matrix *m ){
  for( int row=0;row<m->rows;row++ )
    for( int col=0;col<m->cols;col++ )
      printf( "%s[%i][%i]: %i\n", name, row, col, m->val[row][col] );
  puts("");
}

int main(){
  print_matrix( "a", &a );
  print_matrix( "b", &b );
}

答案 1 :(得分:12)

你可以通过使结构static或全局结构在gcc中工作,但事实证明初始化灵活的数组成员是不符合的,因此除了使用gcc之外它可能不起作用。这是一种只使用符合C99标准的功能的方法......

#include <stdlib.h>
#include <stdarg.h>

typedef struct Grid {
  int rows;
  int cols;
  int grid[];
} *Grid;

Grid newGrid(int, int, ...);

Grid newGrid(int rows, int cols, ...)
{
Grid g;
va_list ap;
int i, n = rows * cols;

  if((g = malloc(sizeof(struct Grid) + rows * cols * sizeof(int))) == NULL)
    return NULL;
  g->rows = rows;
  g->cols = cols;
  va_start(ap, cols);
  for(i = 0; i < n; ++i)
    g->grid[i] = va_arg(ap, int);
  va_end(ap);
  return g;
}
.
.
.
Grid g1, g2, g3;
g1 = newGrid(1, 1, 123);
g2 = newGrid(2, 3, 1, 1, 1,
                   2, 2, 2);
g3 = newGrid(4, 5, 1,  2,  3,  4,  5,
                   6,  7,  8,  9, 10,
                  11, 12, 13, 14, 15,
                  16, 17, 18, 19, 20);

答案 2 :(得分:3)

在你的结构中有一个可变长度数组(VLA)。您在结构中拥有的内容称为灵活数组成员。灵活的阵列成员与VLA完全无关。 C中的灵活数组成员存在合法化和支持古老的“struct hack”习惯用法,它基于动态分配具有不同大小的尾随数组的struct对象的内存。

无法使用聚合初始化程序初始化灵活的数组成员,这是您在代码中尝试的内容。你想在这里做什么根本不可能。 C中没有这样的功能。

同时,编译器生成的错误消息的文本似乎表明它支持这样的扩展名。这可能是真的,但请记住,这绝不是标准的C功能。

答案 3 :(得分:1)

我不相信这是可能的或支持的。正如DigitalRoss指出的那样,您可以在static数组的情况下从文字初始化...虽然我仍然不确定它是否包含在标准中或只是一个公共扩展名。我似乎无法在标准中找到支持灵活数组的文字初始化的子句,尽管我可以看到gcc explicitly supports it

答案 4 :(得分:0)

使用malloc的版本:

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

typedef struct Grid {
  int rows;
  int cols;
  int *grid;
} Grid;

/* Should validate params */
Grid
buildGrid(int rows, int cols, int vec[]) {

    Grid grid;
    grid.rows = rows;
    grid.cols = cols;
    int i;

    if ( (grid.grid = malloc(sizeof(vec))) == NULL ) {
        /* do something.*/
    }

    for(i = 0; i < sizeof(vec) ; i++ ) {
        grid.grid[i] = vec[i];
    }

    return grid;
}