考虑一个数据结构来描述 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')
我的问题是:
.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;
}
使用指针的并集,而不是指向并集的指针。
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;