Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 检查给定的整数组是否包含0值_C++_C - Fatal编程技术网

C++ 检查给定的整数组是否包含0值

C++ 检查给定的整数组是否包含0值,c++,c,C++,C,假设我有一堆整数(10~20),需要检查其中是否有等于0的。最有效的方法是什么?我不想对巨型if(a=0 | | | b=0 | | c=0 | |……)语句进行求值。我想到了if(abc…=0),但如果我没记错的话,乘法不是一个很快的过程。还有其他的技巧吗,比如按位操作?我正在尝试尽可能低的层次来实现这一点。我非常确定,最快、最清晰的方法是通过明确的测试: int has_zero = !a || !b || !c || !d || !e ...; 因为|和&&是C中的短路运算符,所以一旦知

假设我有一堆整数(10~20),需要检查其中是否有等于0的。最有效的方法是什么?我不想对巨型if(a=0 | | | b=0 | | c=0 | |……)语句进行求值。我想到了if(abc…=0),但如果我没记错的话,乘法不是一个很快的过程。还有其他的技巧吗,比如按位操作?我正在尝试尽可能低的层次来实现这一点。我非常确定,最快、最清晰的方法是通过明确的测试:

int has_zero = !a || !b || !c || !d || !e ...;
因为
|
&&
是C中的短路运算符,所以一旦知道最终结果,计算就会停止,因此如果(例如)
b
变量为零,则满足表达式为true并停止计算其余变量

@AbhayAravinda建议
!(a&&b&&c&&d…
可能更有效,但我不这么认为;因为这不是一个显式的not操作,而是一个针对零的低级别测试,所以对于几乎任何体系结构来说,这都是一个非常简单的测试,可以可靠地完成。我快速查看了这两个版本的优化汇编程序,并没有明显的性能赢家,但我认为第一个版本更清晰

如果每个周期都很重要,那么在您的平台上检查两个版本,但在我的64位Intel系统上,gcc和clang实际上会为两个版本生成相同的程序集(启用优化)

简单测试代码:

int a, b, c, d, e, f;

int test_or()
{
    return !a || !b || !c || !d || !e || !f;
}

int test_and()
{
    return ! (a && b && c && d && e && f);
}


int main()
{
    return test_or() | test_and();
}

用gcc-S-O testfile.c编译这个文件,并查看生成的
.S
文件。

依次测试每个文件。利用
| |
的短路特性;将变量按概率为零的降序排列:

if (!a/*most likely to be zero*/ || !b || ...){
    // one of them is zero
}

大多数人给出的答案如下:

!a || !b || ...
(其中,
a
最有可能为零)

其思想是,如果
a
为零,则不计算序列的其余部分(因为没有必要),这是一种由编译器执行的优化

这将问题转化为:编译器是否执行此优化(在“可能是”的情况下,执行此优化的参数是什么)


你能告诉我们你正在使用哪个编译器(版本)吗?这可能使我们能够验证这一点。

您可以查看汇编程序的输出

!a | | |!b | |!c | | |!d | | |!e | | |!f
将为您提供一组
cmp
je
语句。每个变量对应一对。由于布尔快捷计算,它可能运行得非常快。或者不是

更好的确定性解决方案可能是使用按位and运算符。如果一个操作数为0,则结果将为0。比如说:

if (a & b & c & d & e & f & g & h & i & j & k)
将为每个变量生成一个
mov
,然后是
语句


因此,如果变量0位于if语句的后半部分,则bitweise和将更快。

这些整数是如何存储的?单个变量?如果它们是单独的变量,那么
int有0=!a | | |!b | |!c | | |!d | |…
等可能是最快的方法。这会使第一个零短路,并停止评估其余的。@AbhayAravinda对零的测试在大多数体系结构中是一个非常基本的操作,如果它有任何不同,我会感到惊讶。“还有其他技巧,比如按位操作可以工作吗?”-->“如果(a=0 | | | b=0 | | c=0 | | |……)编译器不会使用任何其他技巧,例如位操作……"? 本质上,您要求做得比编译器更好。如果可以的话,那么您使用的是一个不符合标准的编译器。对于一个大的long
a==0 | |……
语句,您到底反对什么?可读代码,还是效率?因为有很多单独的变量,你可能会被一个长期的不可读的语句所困扰。实际上,C语言的定义(C++也继承)的一部分是这个“优化”会发生:任何C或C++编译器都会这样做。我建议用数字数组来说明如何做这个。只是一个小提示。您可以使用编译器资源管理器进行检查。那么,按位AND肯定会更短,在很多情况下更快。这里是如何涉及到按位AND的?