I have the following code:
int isUsed[6] = {1,1,1,1,1,1};
How to compare if all of the elements in this array are equal to 1? or other value? I know we can loop the array and compare it one by one, but do we have other ways to do it?
Yes, you must do it element by element.
If your array consists of just pure integer types (i.e. not an array of struct
s) and you just want to check for equality, you can use memcmp()
.
This of course loops internally, but it's a pre-made standard function so it aids readability. It might hurt performance though, since it compares char
s. On the other hand (after comments) it might gain performance due to being a well-known library function which might be optimized.
Also, for completeness', the reason I had the caveat about no struct
s above is that structures often contain pad bytes, which will be "seen" by memcmp()
and can cause an incorrect result.
For instance:
struct {
int x;
char y;
int z;
} a = { 1, 2, 3 }, b = { 1, 2, 3 };
On many systems, the above struct
will have padding between y
and z
, which might cause an incorrect result from memcmp()
since the padding bytes have undefined values.
For primitive data types (not structs), if you know the size of the array and what you are trying to compare against: memcmp
will do the job:
#include <stdio.h>
#include <string.h>
static int allOnes[6] = {1,1,1,1,1,1};
int main(int argc, const char* argv[]) {
int isUsed[6] = {1,1,1,1,1,1};
if( memcmp( isUsed, allOnes, sizeof allOnes ) == 0 )
printf( "Array has only 1's\n" );
else
printf( "At least one element is not 1\n" );
}
EDIT: about performance...
Some comments mention the performance of memcmp
and loops, including unrolled loops.
Below is a simple test program to measure performance. In my machine (Mac OS X, LLVM compiler), this is what I get:
memcmp: 0.036031 seconds result=1
loop: 0.097180 seconds result=1
unrolled loop: 0.075623 seconds result=1
Before making specific comments about the numbers above, please note that:
memcmp
solution beats the other ones by a large margin.Feel free to rework the code and post other numbers.
#include <stdio.h>
#include <string.h>
#include <time.h>
static int allOnes[6] = {1,1,1,1,1,1};
bool compareWithMemcmp()
{
int isUsed[6] = {1,1,1,1,1,1};
return memcmp( isUsed, allOnes, sizeof allOnes ) == 0;
}
bool compareWithLoop()
{
int isUsed[6] = {1,1,1,1,1,1};
for( int i = 0; i < sizeof allOnes / sizeof allOnes[0]; i++)
if( isUsed[i] != 1 )
return false;
return true;
}
bool compareWithUnrolledLoop()
{
int isUsed[6] = {1,1,1,1,1,1};
// IMPORTANT: doesn't account for odd-length array
for( int i = 0; i < sizeof allOnes / sizeof allOnes[0]; i += 2)
if( (isUsed[i] != 1) || (isUsed[i+1] != 1) )
return false;
return true;
}
int main(int argc, const char* argv[]) {
bool result;
clock_t begin = clock();
for( int i = 0; i < 10000000; i++ )
result = compareWithMemcmp();
printf( "memcmp: %f seconds result=%d\n",
(double)(clock() - begin) / CLOCKS_PER_SEC, result );
begin = clock();
for( int i = 0; i < 10000000; i++ )
result = compareWithLoop();
printf( "loop: %f seconds result=%d\n",
(double)(clock() - begin) / CLOCKS_PER_SEC, result );
begin = clock();
for( int i = 0; i < 10000000; i++ )
result = compareWithUnrolledLoop();
printf( "unrolled loop: %f seconds result=%d\n",
(double)(clock() - begin) / CLOCKS_PER_SEC, result );
}
You have to compare the array elements one by one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With