试图避免切换

Trying to avoid a switch

我正在使用一个函数 (mxGetData()) returns 一个指针 void*,并且根据变量 i_type 我需要将返回的数组视为整数、浮点数、双精度数等的数组。现在我有一个很大的开关来处理每种类型,但是有什么办法可以避免这种开关吗?请注意,指针 uchr_dtint_dtflt_dt 等是不同的类型。

switch(i_type){
case mxUINT8_CLASS:
  uchr_dt = (unsigned char*)mxGetData(var);
  break;
case mxINT32_CLASS:
  int_dt = (int*)mxGetData(var);
  break;
case mxUINT32_CLASS:
  uint_dt = (unsigned int*)mxGetData(var);
  break;
case mxSINGLE_CLASS:
  flt_dt = (float*)mxGetData(var);
  break;
case mxDOUBLE_CLASS:
  dbl_dt = (double*)mxGetData(var);
  break;
default:
  Fatal_Error("Input type not supported.\n");
}

---更新---

之后我只需要遍历返回的数组。 我喜欢用一个 void *p 来避免上面的开关的想法,但是我如何才能确保当我遍历 p 时,指针移动了正确的量?如果编译器将 p 视为 double*,但它实际上是 'char*'(例如),它将超出范围。

double myCopy[nData];
for(i=0; i<nData; i++)
  myCopy[i] = (double) p[i];

使用工会怎么样?

union {
  void* void_dr;
  unsigned char* uchr_dt;
  int* int_dt;
  // ...
} u;

u.void_dt = mxGetData(var);

根据类型,您可以访问 u.uchr_dt

我看到两个平庸的解决方案。在我继续之前,我认为 switch 语句是最好的选择,因为程序段可能不会 always 仅限于一个赋值。也就是说...

选项 #1: 一个变量

实际上,这可能是明智的。只需使用 void * 变量来获取指针,并且仅 运行 您需要的代码,确保将其转换为该部分。

换句话说,跳过 switch/case 概念 这里 而是将它移动到使用该值的地方,假设你不是坚持旧价值观。

选项 #2: 利用 C 的算法

uchr_dt = (i_type == mxUINT8_CLASS) ? (unsigned char*)mxGetData(var) : NULL;
int_dt = (i_type == mxUINT16_CLASS) ? (int*)mxGetData(var) : NULL;
uint_dt = (i_type == mxUINT32_CLASS) ? (unsigned int*)mxGetData(var) : NULL;
flt_dt = (i_type == mxSINGLE_CLASS) ? (float*)mxGetData(var) : NULL;
dbl_dt = (i_type == mxDOUBLE_CLASS) ? (double*)mxGetData(var) : NULL;

有点恶心,但是序列中的所有语句除了(最多)一个会分配 NULL 而另一个会进行分配。

如果您需要保留旧值,您也可以将 NULL 替换为 (type*)xxx_dt 或其他内容。

不过就像我说的那样,即使其中一个可行,switch 声明也将是总体方案中的最佳方法。

使用char*,设置i_type也设置i_size,然后使用memcpy:

char *p = (char*) mxGetData(var);

...

double myCopy[nData];

for(i = 0; i < nData; i++)
  memcpy(myCopy + i, p + i * i_size, i_size);