传递一个恒定的二维数组,以作为C中的结构

时间:2018-04-03 14:37:21

标签: c arrays struct

我是C的新手,我需要一个结构来传递常量二维数组作为一个参数。我想做这个

const int a_size_x = 20;
const int a_size_y = 30;
const int a_output_array[size_x][size_y] = {{..., ...}, ..., {..., ...}};

const int b_size_x = 20;
const int b_size_y = 30;
const int b_output_array[size_x][size_y] = {{..., ...}, ..., {..., ...}};

void function(const int array[], int arr_size_x, int arr_size_y){
    for (int i = 0; i < arr_size_x; i++) 
    {
        for (int j = 0; j < arr_size_y; j++)
        {
            printf("%i ", array[i][j];
        }
        printf("\n");
    }

function(a_output_array, a_size_x, a_size_y);
function(b_output_array, b_size_x, b_size_y);

更容易调用 function(a),如下所示:

const struct OUTPUT
{
    const int size_x;
    const int size_y;
    const int array[size_x][size_y];
};

struct OUTPUT a = {.size_x = 20, .size_y = 30, .array = {{...}, ..., {...}};
....
struct OUTPUT z = {.size_x = 30, .size_y = 20, .array = {{...}, ..., {...}};


function(const struct OUTPUT out){
    for (int i = 0; i < out.size_x; i++) 
    {
        for (int j = 0; j < out.size_y; j++)
        {
            printf("%i ", out.array[i][j];
        }
        printf("\n");
    }

function(a);
function(b);

但当然编译器说结构声明中size_x和size_y未声明 我已经读过灵活的数组成员,但是需要动态内存分配,而在AVR哈佛架构中,malloc不能在程序存储器中工作,我把所有这些数据都放在了程序存储器中。

有没有办法在C中做到这一点?可能是,用C ++?

更新对我有用的答案 - 创建一个长度 2 +宽度*高度的一维数组,其中前两个成员的宽度和高度都是真的,并使用指针与此合作。这是打印出这个数组的示例函数:

char arr [11] = 
{
   3 // width
   3 // height
   1, 2, 3,
   4, 5, 6,
   7, 8, 9
}

void print_array(char *ptr)
{
   char width = *ptr++;
   char height= *ptr++;
   for (int i = 0; i < height; i++)
   {
      for (int j = 0; j < width; j++)
      {
         print("%c\t", *ptr++);
      }
      print("\n");
   }
}

print_array(arr);

3 个答案:

答案 0 :(得分:2)

使用初始化程序声明数组时,数组的边界必须是常量。具有const限定符的变量不符合常量。但是,您可以使用执行文本替换的宏:

#define A_SIZE_X 2
#define A_SIZE_Y 3
const int a_output_array[A_SIZE_X][A_SIZE_Y] = {{3,4,5},{6,7,8}};

#define B_SIZE_X 2
#define B_SIZE_Y 3
const int b_output_array[B_SIZE_X][B_SIZE_Y] = {{1,2,3},{4,5,6}};

将2D数组传递给函数时,定义必须说它需要2D数组。您希望const int array[]是一维数组。

如果在定义中首先指定了边界,则可以使用具有不同边界的函数接受数组:

void function(int arr_size_x, int arr_size_y, const int array[arr_size_x][arr_size_y]) {

然后你可以这样称呼它:

function(A_SIZE_X, A_SIZE_Y, a_output_array);
function(B_SIZE_X, B_SIZE_Y, b_output_array);

答案 1 :(得分:2)

对于大多数编译器,2D数组可以称为1D: 矩阵[3] [3] = [1,2,3               4,5,6               7,8,9] 1D中的索引由行大小*行号计算。例如:matrix [5] = 6。

这意味着您只能传递1个参数,行长度,而calculating the length of the whole vector可以推导出第2个参数(行数)。

您可以将行长度参数添加到数组的末尾,这样只传递数组,如果有帮助的话。

答案 2 :(得分:1)

请注意,第一个代码段的签名错误,编译器应该警告您:

void function(const int array[], int arr_size_x, int arr_size_y){

这里,array指向int 的指针(在函数签名中,数组自动调整为指针),但是为了传递2d数组,你需要一个< em>指向int 数组的指针。你测试过这段话了吗?我认为它没有做你想做的事。

使用C99及以上版本(假设编译器支持VLA,可变长度数组),这样的东西是正确的:

void function( int arr_size_x, int arr_size_y, const int (*array)[arr_size_y]){

至于你对结构的想法,你只能在保持第二个维度时才能这样做。 C数组在内存中是连续的,因此为了正确地进行索引,编译器必须在编译时知道除第一个维之外的所有维。 VLA是该规则的一个例外,但您无法静态声明VLA。

可以做的是使用平面阵列并自己进行2d索引,就像在这个小例子中一样:

struct outputdata
{
    size_t rows;
    size_t cols;
    int *data;
};

const int a_data[] = {1, 2, 3, 4, 5, 6};
const struct outputdata a = {
    .rows = 2,
    .cols = 3,
    .data = a_data
};

// [...]

void function(const struct outputdata x)
{
    for (size_t r = 0; r < x.rows; ++r)
    {
        for (size_t c = 0; c < x.cols; ++c)
        {
            printf("%d ", x.data[r*x.cols + c]);
        }
    }
}