我想声明一个指向指针的指针,其中一些指针将被const
,而另一些将是非常量指针。
下面是一个玩具示例。我有一套columns
.每列都是指向int
或double
类型的数据的指针。到目前为止,这工作正常。我也想使用const
指针。
#include<stdlib.h>
#include<stdio.h>
#define TYPE_INT 0
#define TYPE_DOUBLE 1
int main(void) {
int ncol = 2;
int nrow = 3;
void **columns = malloc(ncol*sizeof(void*));
int *types = malloc(ncol*sizeof(int));
columns[0] = malloc(nrow*sizeof(int));
types[0] = TYPE_INT;
columns[1] = malloc(nrow*sizeof(double));
types[1] = TYPE_DOUBLE;
for (int i=0; i<ncol; ++i) {
for (int j=0; j<nrow; ++j) {
printf("value of column %d and row %d is: ", i+1, j+1);
types[i]==TYPE_INT ?
printf("%d", ((int*)columns[i])[j]) :
printf("%.3f", ((double*)columns[i])[j]);
printf("n");
}
}
return 0;
}
value of column 1 and row 1 is: 0
value of column 1 and row 2 is: 0
value of column 1 and row 3 is: 0
value of column 2 and row 1 is: 0.000
value of column 2 and row 2 is: 0.000
value of column 2 and row 3 is: 0.000
如果我尝试将double *
更改为const double*
int main(void) {
int ncol = 2;
int nrow = 3;
void **columns = malloc(ncol*sizeof(void*));
int *types = malloc(ncol*sizeof(int));
columns[0] = malloc(nrow*sizeof(int));
types[0] = TYPE_INT;
columns[1] = (const double*)malloc(nrow*sizeof(double));
types[1] = TYPE_DOUBLE;
for (int i=0; i<ncol; ++i) {
for (int j=0; j<nrow; ++j) {
printf("value of column %d and row %d is: ", i+1, j+1);
types[i]==TYPE_INT ?
printf("%d", ((int*)columns[i])[j]) :
printf("%.3f", ((const double*)columns[i])[j]);
printf("n");
}
}
return 0;
}
然后gcc
警告
ptrs.c: In function ‘main’:
ptrs.c:13:14: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
columns[1] = (const double*)malloc(nrow*sizeof(double));
如何将列指针保持在一起,无论它们是const
还是正常?
根据你的数组(columns
和types
(被同一个[列]索引索引,我推断给定的行一定是相同的类型?
你[基本上]有一个动态的2D"稀疏"数组。
而不是使用双星指针(例如void **
(,我会创建一些结构进行扩展。
这可能有点过度设计,但这是我的看法:
#include <stdlib.h>
#include <stdio.h>
typedef enum {
TYPE_INT,
TYPE_DOUBLE,
TYPE_CONST_INT,
TYPE_CONST_DOUBLE,
} type_t;
typedef union {
void *vp;
const void *vpc;
int *ip;
const int *ipc;
double *dp;
const double *dpc;
} rowptr_t;
typedef struct {
int type;
rowptr_t *rowptr;
} column_t;
typedef struct {
int mat_ncol;
int mat_nrow;
column_t *mat_base;
} matrix_t;
size_t
typesize(type_t type)
{
size_t siz;
siz = 0;
switch (type) {
case TYPE_INT:
case TYPE_CONST_INT:
siz = 4;
break;
case TYPE_DOUBLE:
case TYPE_CONST_DOUBLE:
siz = 8;
break;
}
return siz;
}
const char *
typefmt(type_t type)
{
const char *fmt;
fmt = NULL;
switch (type) {
case TYPE_INT:
case TYPE_CONST_INT:
fmt = "%d";
break;
case TYPE_DOUBLE:
case TYPE_CONST_DOUBLE:
fmt = "%Lf";
break;
}
return fmt;
}
void
typeprt(matrix_t *mat,int colidx,int rowidx)
{
column_t *col;
rowptr_t *row;
const void *vpc;
col = &mat->mat_base[colidx];
row = &col->rowptr[rowidx];
vpc = row->vpc;
switch (col->type) {
case TYPE_INT:
case TYPE_CONST_INT:
printf("%d",*(const int *) vpc);
break;
case TYPE_DOUBLE:
case TYPE_CONST_DOUBLE:
printf("%.3f",*(const double *) vpc);
break;
}
}
void
matinit(matrix_t *mat,int ncol,int nrow)
{
mat->mat_nrow = nrow;
mat->mat_ncol = ncol;
mat->mat_base = calloc(ncol,sizeof(*mat->mat_base));
}
void
allocrow(matrix_t *mat,int colidx,type_t type)
{
column_t *col;
size_t siz;
siz = typesize(type);
col = &mat->mat_base[colidx];
col->rowptr = malloc(mat->mat_nrow * siz);
col->type = type;
}
int
main(void)
{
matrix_t mat;
matinit(&mat,2,3);
allocrow(&mat,0,TYPE_INT);
allocrow(&mat,1,TYPE_DOUBLE);
for (int i = 0; i < mat.mat_ncol; ++i) {
for (int j = 0; j < mat.mat_nrow; ++j) {
printf("value of column %d and row %d is: ", i + 1, j + 1);
typeprt(&mat,i,j);
printf("n");
}
}
return 0;
}
你可以这样做,但在赋值期间,你需要显式地将const
指针强制转换为非常量指针。还要为const
类型添加其他#define
,以便您知道特定列中存储的内容:
#define TYPE_CONST_DOUBLE 2;
//...
//a const pointer storing an address of some buffer
const double *ptr = (const double*)malloc(nrow*sizeof(double));
//now we cast the const pointer to a non-const one and put it into the columns array
columns[1] = (void*)ptr;
types[1] = TYPE_CONST_DOUBLE;
当你从columns[n]
中读取值时,如果类型是TYPE_CONST_DOUBLE
,只需转换回const double *
。