簡體   English   中英

C 指向 const 和非 const 類型指針的指針

[英]C pointer to a const and non-const types pointers

我想聲明一個指向指針的指針,其中一些指針將是const ,而其他指針將是非常量指針。

下面是一個玩具示例。 我有一組columns 每列都是指向intdouble類型數據的指針。 到目前為止,這工作正常。 我也想使用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還是正常的?

根據您的 arrays ( columnstypes )被相同的 [column] 索引索引,我推斷給定的行必須是相同的類型?

你[本質上]有一個動態的二維“稀疏”數組。

我不會使用雙星指針(例如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指針。 還為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 *

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM