试图避免开关

时间:2015-03-26 23:42:25

标签: c switch-statement mex

我使用返回指针mxGetData()的函数(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];

3 个答案:

答案 0 :(得分:2)

使用联盟怎么样?

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

u.void_dt = mxGetData(var);

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

答案 1 :(得分:0)

我看到两个平庸的解决方案。在我继续之前,我认为switch语句是最佳选择,因为程序段可能始终仅限于一项赋值。那说......

选项#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陈述将成为宏观计划中最好的方法。

答案 2 :(得分:0)

使用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);