C 根据循环中的条件应用表达式

C 根据循环中的条件应用表达式,c,r,C,R,我想这个问题肯定被问了好几次,但我什么也没找到 我有一个依赖于参数(caseset)的函数,该参数可以是两种不同的类型。根据其性质,在循环中,我需要执行一个操作,而不是另一个操作。由于对象的性质在开始时是已知的,因此在我看来,每次循环中都有一个if语句是低效和不雅观的。理想情况下,我会每次应用正确的表达式,并在循环顶部选择它。这里有一个代码,让我知道我在追求什么 SEXP doSomething(SEXP anObject, SEXP caseset, SEXP isMat) { /*

我想这个问题肯定被问了好几次,但我什么也没找到

我有一个依赖于参数(
caseset
)的函数,该参数可以是两种不同的类型。根据其性质,在循环中,我需要执行一个操作,而不是另一个操作。由于对象的性质在开始时是已知的,因此在我看来,每次循环中都有一个
if
语句是低效和不雅观的。理想情况下,我会每次应用正确的表达式,并在循环顶部选择它。这里有一个代码,让我知道我在追求什么

SEXP doSomething(SEXP anObject, SEXP caseset, SEXP isMat) {
  /*
  * here anObject is an external pointer to a C structure,
  * caseset is either a character matrix or a data.frame made of character columns.
  */
 int i,j,nrow,ncol;
 int isMatrix = LOGICAL(isMat)[0];
 const char *field;
 /*
  * Determine the number of rows and columns in each case
 */
 if (isMatrix) {
   ncol = length(VECTOR_ELT(getAttrib(caseset,R_DimNamesSymbol),1));
   nrow = length(caseset)/ncol;
 } else {
   ncol = length(caseset);
   nrow = length(VECTOR_ELT(caseset,0));
 }
 for (i=0;i<nrow;i++) {
   for (j=0;j<ncol;j++) {
     if (isMatrix) {
       field = CHAR(STRING_ELT(caseset,j*nrow+i));
     } else {
       field = CHAR(STRING_ELT(VECTOR_ELT(caseset,j),i));
     }
     /*
      * Do stuff involving field and anObject
     */    
   }
 }
 return result;
}
SEXP剂量测量(SEXP对象、SEXP案例集、SEXP isMat){
/*
*这里的对象是指向C结构的外部指针,
*caseset是字符矩阵或由字符列组成的data.frame。
*/
int i,j,nrow,ncol;
int isMatrix=逻辑(isMat)[0];
常量字符*字段;
/*
*确定每种情况下的行数和列数
*/
if(isMatrix){
ncol=长度(向量ELT(getAttrib(caseset,R_dimnessymbol),1);
nrow=长度(案例集)/ncol;
}否则{
ncol=长度(案例集);
nrow=长度(向量_ELT(案例集,0));
}

对于(i=0;i,可以使用函数指针数组。 例如,要编程计算器,而不是:

if (c == '+')
   return (a + b);
elif (c == '-')
   return (a - b);
...
你可以这样做:

char *op = {'+', '-', '/', '*', '%', 'whatever you want', NULL};
for (int i=0, op[i] && op[i] != c, i++};
if (op[i])
   return (my_function_ptr[i](a, b));

它会调用数组中的函数号“i”。

C并不以优雅著称。其他语言可能允许您使用某种迭代器。检查isMatrix两次并不坏。但当然,您可能需要检查更多次,或者可能支持更多类型

考虑使用基于isMat的两个内部函数:

SEXP doSomething(SEXP anObject, SEXP caseset, SEXP isMat) {
/*
 * here anObject is an external pointer to a C structure,
 * caseset is either a character matrix or a data.frame made of character     columns.
 */
  return LOGICAL(isMat)[0] ? doSomethingMatrix(anObject,caseset) : doSomethingFrame(anObject,caseset);
}
static doSomethingMatrix(SEXP anObject, SEXP caseset) {
  int i,j,nrow,ncol;
  const char *field;

  ncol = length(VECTOR_ELT(getAttrib(caseset,R_DimNamesSymbol),1));
  nrow = length(caseset)/ncol;

  for (i=0;i<nrow;i++) {
    for (j=0;j<ncol;j++) {
      field = CHAR(STRING_ELT(caseset,j*nrow+i));

      // Share the long processing code between the two functions
      doStuffField(anObject,field);
    }
  }
  return result;
}
SEXP剂量测量(SEXP对象、SEXP案例集、SEXP isMat){
/*
*这里的对象是指向C结构的外部指针,
*caseset是字符矩阵或由字符列组成的data.frame。
*/
返回逻辑(isMat)[0]?doSomethingMatrix(anObject,caseset):doSomethingFrame(anObject,caseset);
}
静态剂量计矩阵(SEXP对象,SEXP案例集){
int i,j,nrow,ncol;
常量字符*字段;
ncol=长度(向量ELT(getAttrib(caseset,R_dimnessymbol),1);
nrow=长度(案例集)/ncol;

对于(i=0;我个人认为)在你的要点中没有注意到任何一种方法都是错误的。然而,如果你真的关心代码的美观性,为什么不直接使用C++(Rcpp)?你可以写得更优雅吗?@ NrasSurtTX供你评论。我正在包装C库,在C + +/RCPP中迁移的时间太多了,考虑到我知道C比C++ C++好得多。我想共享处理部分可能是最优雅的。(可能使用宏而不是函数)。