Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

do we need to compare each element of a array in C?

Tags:

arrays

c

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?

like image 300
user2131316 Avatar asked Jul 05 '13 12:07

user2131316


3 Answers

Yes, you must do it element by element.

If your array consists of just pure integer types (i.e. not an array of structs) 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 chars. 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 structs 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.

like image 146
unwind Avatar answered Oct 21 '22 23:10

unwind


For primitive data types (not structs), if you know the size of the array and what you are trying to compare against: memcmpwill 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:

  • I'm not making a generic claim, just showing that in my environment the memcmp solution beats the other ones by a large margin.
  • the loop unrolling I have is not the greatest implementation. It's just a crude attempt to have some number for loop unrolling in place.

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 );
}
like image 33
Christian Garbin Avatar answered Oct 21 '22 22:10

Christian Garbin


You have to compare the array elements one by one.

like image 34
Yu Hao Avatar answered Oct 21 '22 21:10

Yu Hao