C - 检查变量是否为*none*的最简洁方法?

Eri*_*pke 4 c comparison if-statement

背景:

通常,我们开发人员必须检查单个变量是否是众多选项中的至少一个.例如,

if ( (data == 125) || (data == 500) || (data == 750) )
{
    /* ... do stuff ...*/
}
Run Code Online (Sandbox Code Playgroud)

这里的建议(尽管用C#编写)提供了一个优雅的解决方案来使用这样的switch语句,

switch ( data )
{
    case 125:
    case 500:
    case 750:
        /* ... do stuff ...*/
        break;

    default:
        /* ... do nothing ... */
        break;
}
Run Code Online (Sandbox Code Playgroud)

这适用于"或"条件,但对于否定的"或"条件如下所述是丑陋的,

if ( !( (data == 125) || (data == 500) || (data == 750) ) )
{
    /* ... do stuff ...*/
}
Run Code Online (Sandbox Code Playgroud)

这可以写成

switch ( data )
{
    case 125:
    case 500:
    case 750:
        /* ... do nothing ... */
        break;

    default:
        /* ... do stuff ...*/
        break;

}
Run Code Online (Sandbox Code Playgroud)

而且似乎有点hackish.

题:

有没有更简洁的方法来检查单个变量是否不是很多选项,如上面的否定"或"条件?

参考文献:

unw*_*ind 8

我认为后者很好.

但是,您可以更好地将其正式化:

static bool in_sprawling_set(int data)
{
  switch ( data )
  {
    case 125:
    case 500:
    case 750:
        return true;
  }
  return false;
}
Run Code Online (Sandbox Code Playgroud)

然后你想做的工作:

if(!in_sprawling_set(data))
{
  /* do the work, not in set */
}
Run Code Online (Sandbox Code Playgroud)

这将"in set"逻辑置于其自身的功能中,使其温和地自我记录,并且实际的使用位置更加清晰,因为它!变得更加突出并且最终if是非常可读的("如果不在庞大的集合中") .

注意:如果值的数量非常大,我可能会使用预先排序的数组和二进制搜索,而不是一个巨大的switch.我意识到一个足够聪明的编译器可以自己进行转换,但是巨大的可读性switch会相当低(特别是如果你想case每行只放一个).有bsearch()搜索:

static int cmp_int(const void *ap, const void *bp)
{
  const int a = *(const int *) ap, b = *(const int *) bp;
  return a < b ? -1 : a > b;
}

static bool in_sprawling_set(int data)
{
  static const int values[] = { 125, 500, 750 };
  return bsearch(&data, values, sizeof values / sizeof *values, sizeof *values, cmp_int) != 0;
}
Run Code Online (Sandbox Code Playgroud)

有相当多的样板文件正在进行中,但是您可以看到列出实际值的部分(随着更多值的添加而增长的唯一内容)更加紧凑.