-2

I came upon a competitive question asking the output of the following (please overlook the software engineering issues of the problem, if any, as this is an academic example, however if it is relevant to the problem, please elaborate it):

#include <stdarg.h>
#include <stdio.h>
int ripple(int, ...);
int main()
{
    int num;
    num = ripple(3,5,7); // Shouldn't he pass 3 args after `3`, if arg count is 3?
    printf("%d", num);
    return 0;
}
int ripple(int n, ...)
{
    int i, j=1, k=0;
    va_list p;
    va_start(p, n);
    for(; j<n; ++j)
    {
        i = va_arg(p, int);
        for(;i;i&=i-1)// Didn't understand the usage
            ++k;
    }
    return k;
}

I really didn't get how this code works or what it does (perhaps because of my near to nil experience with stdarg.h). Any help is most welcome. Thanks.

Jishan
  • 1,654
  • 4
  • 28
  • 62

1 Answers1

1

j runs from 1 to n-1 in ripple(), so that the first argument to that function is actually one plus the number of the remaining arguments, and calling ripple(3, 5, 7) is fine.

for(;i;i&=i-1)// Didn't understand the usage
    ++k;

adds to k the number of bits set in the binary representation of i, compare "Counting bits set, Brian Kernighan's way" in "Bit Twiddling Hacks", or this answer: https://stackoverflow.com/a/109036/1187415.

In your case 5 = 101b and 7 = 111b have in total 2+3=5 bits set, therefore ripple(3, 5, 7) = 5.

Community
  • 1
  • 1
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Still confused with the bit-setting part though. – Jishan Aug 31 '14 at 10:51
  • 1
    @Debojyoti: You have asked two different questions (which should be avoided generally). I have tried to answer the first question which is referenced in the title. – I have also given some information and links about the second question. Actually the best way to figure out how this works is to do the calculation by hand on a piece of paper for some numbers. I am sure that you will see it quickly! – Martin R Aug 31 '14 at 10:57