如何将平面阵列重塑成C中的2d?

时间:2017-08-09 21:59:21

标签: c

我有一个数组,其中x * x元素被定义为指针。

我想做这样的事情:

void func(const unsigned int x, const int *flat_array)
{
    const int (*reshaped)[x] = flat_array;
    ...
}

但是如何?

4 个答案:

答案 0 :(得分:3)

此代码适用于我。请注意,它使用C99(和C11)可变长度数组(VLA)。它不会使用C89 / C90编译器进行编译。

#include <stdio.h>

static void func(const unsigned int x, const int *flat_array)
{
    const int (*reshaped)[x] = (void *)flat_array;
    for (unsigned int i = 0; i < x; i++)
    {
        for (unsigned int j = 0; j < x; j++)
            printf("%3d", reshaped[i][j]);
        putchar('\n');
    }
}

int main(void)
{
    int flat[] =
    {
        /* random -n 25 10 99 | commalist -n 5 -b '        ' */
        73, 34, 76, 48, 17,
        25, 71, 11, 87, 74,
        18, 87, 11, 47, 32,
        33, 62, 41, 55, 90,
        90, 28, 69, 58, 29,
    };

    for (int i = 0; i < 5; i++)
    {
        printf("R[%d]", i);
        for (int j = 0; j < 5; j++)
            printf(" [%d] = %2d", j, flat[i * 5 + j]);
        putchar('\n');
    }

    func(5, flat);
    return 0;
}

在运行macOS Sierra 10.12.6的Mac上使用带编译选项的GCC 7.1.0编译时没有警告:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
      -Wstrict-prototypes rs37.c -o rs37
$

在函数中没有强制转换(到void *),我收到错误:

initialization from incompatible pointer type [-Werror=incompatible-pointer-types]

void *演员表是处理问题的有效方法 - 但它可能很容易被滥用。你也可以写:

    const int (*reshaped)[x] = (int (*)[x])flat_array;

明确地直接转换为正确的类型 - 指向行宽x的整数数组的指针。如果您愿意,可以在演员表中添加const

输出:

R[0] [0] = 73 [1] = 34 [2] = 76 [3] = 48 [4] = 17
R[1] [0] = 25 [1] = 71 [2] = 11 [3] = 87 [4] = 74
R[2] [0] = 18 [1] = 87 [2] = 11 [3] = 47 [4] = 32
R[3] [0] = 33 [1] = 62 [2] = 41 [3] = 55 [4] = 90
R[4] [0] = 90 [1] = 28 [2] = 69 [3] = 58 [4] = 29
 73 34 76 48 17
 25 71 11 87 74
 18 87 11 47 32
 33 62 41 55 90
 90 28 69 58 29

答案 1 :(得分:0)

这应该这样做:

{{1}}

答案 2 :(得分:0)

如果原作是malloced并且我理解重塑意味着什么

#define MIN(x,y) ((x) > (y) ? (y) : (x))

int *reshape(int *src, int srcRows, int srcCols, int newRows, int newColums)
{
    int *newarray = (*src != NULL && newRows > 0 && newColums > 0) ? malloc(newRows * newColums) : NULL;

    if (newarray != NULL)
    {
        for (int row = 0; row < MIN(srcRows, newRows); row++)
            for (int col = 0; col < MIN(srcCols, newColums); col++)
                *(newarray + row * newColums + col) = *(src + row * srcCols + col);
        free(src);
    }
    return newarray;
}

如果新数组较小,则某些数据将丢失。

答案 3 :(得分:0)

假设指针确实指向一个数组,即 - 一大块相同类型的相邻项,那么你可以安全地转换指针类型:

const int (*reshaped)[x] = (const int(*)[x])flat_array;

这保证可行,因为C中的类型别名规则只涉及指向数据的性质,而不涉及所涉及的指针类型。 (参见有效类型的概念,6.5 / 6)。