如何在C中使用联合实现伪多态性

问题描述 投票:0回答:1

考虑一个数据结构来描述 C 中的矩阵块:

// Matrix block
typedef struct {
    union {
        int    i;
        double d;
    } *a;       // pointer to first element in matrix block
    int  k;     // block index
    int  p;     // no. of block rows
    int  q;     // no. of block columns
    int  m;     // no. of matrix rows
    int  n;     // no. of matrix columns
    int  r;     // MPI rank of block owner
} mtrx_blk;

我想使用联合作为指向矩阵块第一个元素的指针。我想对不同的矩阵类型使用相同的

mtrx_blk
结构。就我而言,矩阵可以是
double
int
类型。例如,如果我创建两个带有
NBLK = 2;
的矩阵块和一个类型为
A
的矩阵
double

// for each block
for (int k = 0; k < NBLK; k++) {

    blk[k] = (mtrx_blk) { .a = &A[k*P*Q], .k = k, .p = P, .q = Q, .m = M, .n = N, .r = k };
    }

矩阵 A 的大小为 M x N 个元素,矩阵块的大小为 P x Q 元素。

上面给指针赋值的方式

.a
会导致错误:

gcc -std=c11 -pedantic-errors struct-union.c -o struct-union
struct-union.c: In function 'main':
struct-union.c:52:36: error: initialization of 'union <anonymous> *' from incompatible pointer type 'double *' [-Wincompatible-pointer-types]
   52 |         blk[k] = (mtrx_blk) { .a = &A[k*P*Q], .k = k, .p = P, .q = Q, .m = M, .n = N, .r = k };
      |                                    ^
struct-union.c:52:36: note: (near initialization for '(anonymous).a')

我尝试将其表述为:

// for each block
for (int k = 0; k < NBLK; k++) {

    blk[k] = (mtrx_blk) { .a.d = &A[k*P*Q], .k = k, .p = P, .q = Q, .m = M, .n = N, .r = k };
    }

但这也无法编译

gcc -std=c11 -pedantic-errors struct-union.c -o struct-union
struct-union.c: In function 'main':
struct-union.c:52:31: error: field name not in record or union initializer
   52 |         blk[k] = (mtrx_blk) { .a.d = &A[k*P*Q], .k = k, .p = P, .q = Q, .m = M, .n = N, .r = k };
      |                               ^
struct-union.c:52:31: note: (near initialization for '(anonymous)')
struct-union.c:52:38: error: initialization of 'union <anonymous> *' from incompatible pointer type 'double *' [-Wincompatible-pointer-types]
   52 |         blk[k] = (mtrx_blk) { .a.d = &A[k*P*Q], .k = k, .p = P, .q = Q, .m = M, .n = N, .r = k };
      |                                      ^
struct-union.c:52:38: note: (near initialization for '(anonymous).a')

我的问题是:

  1. 我该如何正确做?
  2. 我的逻辑是否正确?我可以对整数数据类型的矩阵
    .a.i = &B[k*P*Q]
    使用类似的语法
    B
    吗?

请在下面找到完整的源代码:

#include <stdlib.h>

// Matrix block
typedef struct {
    union {
        int    i;
        double d;
    } *a;       // pointer to first element in matrix block
    int  k;     // block index
    int  p;     // no. of block rows
    int  q;     // no. of block columns
    int  m;     // no. of matrix rows
    int  n;     // no. of matrix columns
    int  r;     // MPI rank of block owner
} mtrx_blk;

int main(int argc, char *argv[]) {

    // no. of matrix rows
    int const M = 10;

    // no. of matrix columns
    int const N = 10;

    // no. of blocks
    int const NBLK = 2;

    // no. of block rows
    int const P = M/NBLK;

    // no. of block columns
    int const Q = N;

    // allocate memory for matrix
    double *A = (double*) malloc(M*N*sizeof(double));

    // allocate array of blocks
    mtrx_blk *blk = (mtrx_blk*) malloc(NBLK*sizeof(mtrx_blk));

    // for each block
    for (int k = 0; k < NBLK; k++) {

        blk[k] = (mtrx_blk) { .a.d = &A[k*P*Q], .k = k, .p = P, .q = Q, .m = M, .n = N, .r = k };
    }

    // free memory of array of blocks
    free(blk);

    // free memory of matrix
    free(A);

    return 0;
}
c struct union
1个回答
0
投票

使用指针的并集,而不是指向并集的指针。

typedef struct {
    union {
        int    *i;
        double *d;
    } a;        // pointer to first element in matrix block
    int  k;     // block index
    int  p;     // no. of block rows
    int  q;     // no. of block columns
    int  m;     // no. of matrix rows
    int  n;     // no. of matrix columns
    int  r;     // MPI rank of block owner
} mtrx_blk;
© www.soinside.com 2019 - 2024. All rights reserved.