【问题标题】:Determine the type of an array which stores the pointer to other arrays of different dimensions确定存储指向其他不同维度数组的指针的数组的类型
【发布时间】:2020-04-20 05:14:37
【问题描述】:

对于许多 LEN,我在 [0,LEN) 中有许多整数的所有可能排列的常量二维数组:

static const char permu2[][2] = {{0, 1}, {1, 0}};
static const char permu3[][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2},
                                {1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
static const char permu4[][4] = {
    {0, 1, 2, 3}, {0, 1, 3, 2}, {0, 2, 1, 3}, {0, 2, 3, 1}, {0, 3, 1, 2},
    {0, 3, 2, 1}, {1, 0, 2, 3}, {1, 0, 3, 2}, {1, 2, 0, 3}, {1, 2, 3, 0},
    {1, 3, 0, 2}, {1, 3, 2, 0}, {2, 0, 1, 3}, {2, 0, 3, 1}, {2, 1, 0, 3},
    {2, 1, 3, 0}, {2, 3, 0, 1}, {2, 3, 1, 0}, {3, 0, 1, 2}, {3, 0, 2, 1},
    {3, 1, 0, 2}, {3, 1, 2, 0}, {3, 2, 0, 1}, {3, 2, 1, 0}};
static const char permu5[][5] = {{0, 1, 2, 3, 4}, {0, 1, 2, 4, 3}, {0, 1, 3, 2, 4}, /*... */}
// and many more as you can imagine...

我想将指向这些数组的指针存储在另一个数组中:

static const char *permu[] = {0,      0,      permu2, permu3, permu4,
                             permu5, permu6, permu7, permu8};
static const int fac_seq[] = {1,   1,    2,     6,      24,      120,
                              720, 5040, 40320, 362880, 3628800, 39916800};

因此对于给定的 LEN=n,我可以通过这种方式访问​​这些常量:

const int n = 8;
for ( size_t i = 0; i < fac_seq[n]; i++ ) {
    for ( size_t j = 0; j < n; j++ ) {
        printf( "%2d", *( permu[n] + n*i  + j ) );
    }
    putchar( '\n' );
}

虽然这将编译并正常工作,但编译器 (gcc) 抱怨如下:

30.c:1966:47: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
 static const char *permu[] = {0,      0,      permu2, permu3, permu4,
                                               ^~~~~~
30.c:1966:47: note: (near initialization for ‘permu[2]’)
30.c:1966:55: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
 static const char *permu[] = {0,      0,      permu2, permu3, permu4,
                                                       ^~~~~~
30.c:1966:55: note: (near initialization for ‘permu[3]’)

permu 数组的正确类型应该是什么?我试过const char **permu[] 仍然收到同样的警告。

【问题讨论】:

  • 你可以试试static const void *permu[]?然后,您必须在访问时强制转换它。或者,您可以将每个数组设为一维并自己计算索引。
  • @WeatherVane 是的,这行得通,谢谢!只要让它成为一个答案,我会接受它:)

标签: c arrays pointers types


【解决方案1】:

你可以试试

static const void *permu[] = { };

然后你必须在访问时强制转换它。

或者,您可以将每个数组设为一维并自己计算索引。

【讨论】:

    【解决方案2】:

    正确的声明是

    static const char (*permu[9])[] = {0,      0,      permu2, permu3, permu4,
                                       permu5, permu6, permu7, permu8};
    

    permu 是一个包含 9 个指针的数组,这些指针指向未知数量的 const chars 数组。写9 是可选的;它可以从初始化程序中推断出来。您可以改为将其设为指向void 的指针数组,就像在另一个答案中一样,但最好保留尽可能多的信息。你可以这样使用它:

    const int n = 4;
    const char (*perms)[n] = permu[n];
    for (size_t i = 0; i < fac_seq[n]; i++) {
        for (size_t j = 0; j < n; j++) {
            printf("%2d", perms[i][j]);
        }
        putchar('\n');
    }
    

    请注意,我执行了分配给perms 的演员表。我将一个指向未知大小数组的指针转换为数组大小实际上为n 的指针。这就是稍后允许使用双 [] 语法的原因:const char[n] 类型具有定义的大小 (sizeof(char)*n),因此我们知道对于 perms[i] 需要跳过多远。

    Godbolt

    【讨论】:

    • 我对 C 语言的 VLA 有点不情愿。你认为它会减慢程序的速度吗? (因为阶乘序列爆炸得非常快)
    • 等等,这不是 VLA 对吧?这只是一个类型转换,并没有在堆栈上完成真正的分配......我是对的吗?
    • 它是一个 VLA 类型,因为它是一个指向数组的指针,其中大小是一个变量。不,它并不慢,因为没有堆栈分配。
    猜你喜欢
    • 2014-01-26
    • 2014-08-25
    • 1970-01-01
    • 2013-09-22
    • 2012-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    相关资源
    最近更新 更多