3

I got this question in interview, it seems simple one but I want to confirm my understanding about its functioning.

f (char *p, char *q, int n)
{
    int i1 = n >> 2;
    int i2 = n & 3;

    switch (i2) 
    {
        do {
            *q++ = *p++;
            case 3:  *q++ = *p++;
            case 2:  *q++ = *p++;
            case 1:  *q++ = *p++;
            case 0:  ;
        } while (i1--);
    }
}

I was asked below questions in interview:

  1. What this function does?
  2. Why would somebody write such convoluted code?
  3. Is there any way to write it differently (simpler, faster)?

Answers given:

  1. This function copies the number of elements from the memory where *P is pointing to the memory where *q is pointing.

  2. if you will write it with for loop as below (writing only loop)

    for(i=0;i<n;i++)
       *q++ = *p++;
    

    then the compiler taking more MIPS/time in condition checking. In this it will first subtract i from n and then checks is I non zero ? In the given code while loop maintain condition only 1 condition if i1 is non-zero ? So in while loop there is less condition checking.

  3. We can write as:

    f (char *p, char *q, int n)
    {
      for(i=n;i--;)
        *q++ = *p++;
    }
    

    It seems simple and faster to me.

Please give me your opinion.

Mat
  • 202,337
  • 40
  • 393
  • 406
Manish Kumar
  • 1,419
  • 3
  • 17
  • 36
  • 3
    A good advice - before you post here code, write it in a text editor on your computer, then copy it to your question. This way you can notice some typeos, and get the indention right. – elyashiv Dec 08 '13 at 17:41
  • It looks like someone is wrongly edited your code? it should be do{switch(){..};}while(); – dragon135 Dec 21 '13 at 03:14

1 Answers1

1

First in your answer you don't seem to take into account that n>>2 integer-divides n by 4 before looping. Then, you don't check the second condition, which is that if n % 4 == 0, to not copy the value.

  • copies 7 bytes and ignores the 8th byte for n/4 bytes from p to q;
  • it's very efficient at doing what it does. Using &3 instead of %4 is most likely much faster, and using >> 2 instead of /4 might be faster; only might because it is possible that either the compiler or the c language is designed to automatically make that optimization for you;
  • I would give something like that

    f (char *p, char *q, int n)
    {
    int i1 = n >> 2; //i1 = n / 3;
    int i2 = n & 3;  //i2 = n & 0b111 = n % 4;
    
    for(; i1 + 1 ; --i) {
        *q++ = *p++;
        if (i2) *q++ = *p++;            
        } 
    }
    
  • mentionning that the for loop is easier to understand and just as efficient,

  • and that changing the switch statement for a single if statement is cleaner and most likely of similar performance.

  • I would then conclude by noting that I added comments on the bitwise operations to make their function clearer.

Jules G.M.
  • 3,624
  • 1
  • 21
  • 35