验证参数为0或1

时间:2015-08-02 10:19:08

标签: c

我有一个num类型的参数int,用户可以在其中为其中一个值01提供。
我可以用明显的方法检查它:

if (num < 0 || num > 1)
    print("The parameter value is incorrect.\n");

但我想知道是否有更好的(更快的?更少的代码?)来做到这一点?

修改
这是一些数据流代码,因此性能至关重要。我正在寻找一种更快的方式来运行此检查。

谢谢

7 个答案:

答案 0 :(得分:8)

我会继续清晰而不是更少的角色:

if (num != 0 && num != 1){
    print("The parameter value is incorrect.\n");
}

当它凌晨2点你正在调试程序时,你想要的最后一件事就是过度考虑范围和按位操作。

答案 1 :(得分:5)

清除代码(天真)微优化

您实际上是在对实际编译器的行为做出错误的假设。在这两种情况下,都是:

if (num < 0 || num > 1) { ...

if (num != 0 && num != 1) { ...

optimizing compiler会将其减少到最短的形式。您可能会看到,两者都生成相同的程序集,可能看起来像(x86平台):

cmp    $0x1,%eax
jbe    1e <foo+0x1e> # jump if below or equal

这已经足够快,因为所有主要架构的cmp指令都有 latency of one cycle

最重要的是选择任何代码,使你的意图,未来的维护者清楚,让编译器完成它的工作。只需确保您使用适当的优化级别(例如-O2或更高级别)设置它。

援助分支预测

但是,如果性能在这里非常重要(并且您对其进行了分析,不是吗?),那么您可以考虑另一种优化,即branch prediction级别(假设你的CPU支持它)。 GCC具有__builtin_expect内在的,允许提示编译器,在大多数情况下,分支将被采用。

  

您可以使用__builtin_expect为编译器提供分支   预测信息。一般来说,您应该更喜欢使用实际   正如程序员所做的那样(-fprofile-arcs)的配置文件反馈   众所周知,在预测他们的计划实际执行情况方面表现不佳。   但是,有些应用程序很难收集这些数据。

例如,如果您有信心,该函数在大约99%的案例中需要01,那么您可以将其写为:

#define unlikely(x) __builtin_expect((x), 0)

if (unlikely(num != 0 && num != 1)) { ...

答案 2 :(得分:3)

public datatype foo(String[] ids){

Cursor cursor = dataBase.rawQuery("SELECT * FROM tbl_product" + " WHERE productId" + "=?", ids);

}

!!将其他值更改为0或1,因此如果您尝试传递5:

if (!!num == num)
{
   /* value is either a zero or 1 */
}

答案 3 :(得分:2)

你可以使用移位运算符

if(num>>1) print("The parameter value is incorrect.\n");

答案 4 :(得分:0)

由于唯一可以点亮的位是第一位,因此检查其余位是关闭的。

另外,由于它只是1,因此它的负面(c语法):~1

所以:

if (num & ~1)
    print("The parameter value is incorrect.\n");

答案 5 :(得分:0)

有很多方法可以做到这一点。 我认为短路并不总是正确的。 认为有时您可能需要告知用户他的输入,而不仅仅是说&#34;参数值不正确&#34;。 我,我有自己的功能,试试这个:

#include<stdio.h>

int checkInput(int min, int max);

int main(void){
    int number = checkInput(0,1);

    printf("\nYour number is\t%d\n",number);

    return 0;
}

int checkInput(int min, int max){
    int option,check;
    char c;

    do{
        printf("Please type a number beetwen %d and %d:\t",min,max);

        if(scanf("%d%c",&option,&c) == 0 || c != '\n'){
            while((check = getchar()) != EOF && check != '\n');
            printf("\tI sayed a Number please\n\n");
        }else if(option < min || option > max){
            printf("\tThe number has to be beetwen %d and %d\n\n",min,max);
        }else{
            break;
        }
    }while(1);

    return option;
}

输出:

Please type a number beetwen 0 and 1: 0k
    I sayed a Number please
Please type a number beetwen 0 and 1:   1j
    I sayed a Number please

Please type a number beetwen 0 and 1:   8
    The number has to be beetwen 0 and 1

Please type a number beetwen 0 and 1:   1

Your number is  1

答案 6 :(得分:0)

同意if (num < 0 || num > 1) { ...是要走的路

我以为我会添加类似高尔夫的代码

if (num > 1u) { ...

在与int num比较之前,这会将unsigned转换为1u

此方法的一个弱点是num是否比unsigned更宽泛的签名类型。在这种情况下,代码可能会“徘徊”#34;让我们更加默默无闻

if (num > 1ull) { ...

最后,使用(num < 0 || num > 1)

  1. 生成最快的代码

  2. 生成糟糕的代码,OP真的应该考虑一个比这么小的代码优化更好的整体性能改进编译器。