Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Putting a composite statement in the condition of a for loop

Tags:

c

for-loop

I have a contrived example to demonstrate the request for a specific functionality - I wonder if anyone has a clever trick to do this.

The following is a problem one encounters quite frequently:

"Print a series of numbers; print a space between them, and a carriage return (but no space) at the end.

The obvious solution is to make the last (or first) statement a special case. I was pondering ways to make this more efficient/compact.

brute force:

for(ii=0; ii<4; ii++) {
  printf("%d", ii);
  if(ii<3) printf(" "); else printf("\n");
}

Note that this involves two evaluations of a condition.

unrolling:

for(ii=0; ii<3; ii++) {
  printf("%d ", ii):
}
printf("%d\n", ii);

Leverages the fact that ii will be incremented one last time as we leave the loop.

functionality I would like

ii = 0;
while(1) {
  printf("%d", ii);
  ii++;
  if(ii<3) printf(" "); 
  else {printf("\n"); break;}
}

And I was wondering if it's possible to make this work inside the for statement. I tinkered a bit, and found that the following works (somewhat to my surprise... it did need the parentheses, and it quite unreadable between the ?: and the , operators - see http://codepad.org/wFa2YwCg):

for(ii=0; (ii<3)?(printf("%d ",ii),1):(printf("%d\n",ii),0);ii++);

I am essentially turning the evaluate this condition part of the for loop into a execute this statement for most of the loop, and this other one for the last pass statement.

I was wondering if there is a better way to do this - both efficient, and readable?

like image 828
Floris Avatar asked Dec 06 '13 15:12

Floris


2 Answers

[In many ways this question should be closed as it's opinion based.]

This problem crops up often. I always opt for a solution that minimises the instructions in the iterative part.

{ /*don't pollute the outer scope with ii*/
    int ii;
    for (ii = 0; ii < 3; ++ii/*I've always preferred this to ii++*/) {
        printf("%d ", ii);
    }
    printf("%d\n", ii);
}

Ternaries, if statements etc. just obfuscate things. In my opinion.

like image 73
Bathsheba Avatar answered Sep 29 '22 09:09

Bathsheba


I have used the following type of construct for this situation. It is not more efficient (still has a condition at each iteration), but I like it because it results in a single printf:

char *sep = " ";
for(ii=0; ii<4; ii++) {
  if ( ii == 3 )
    sep = "\n";
  printf( "%d%s", ii, sep );
}
like image 24
Mark Wilkins Avatar answered Sep 29 '22 08:09

Mark Wilkins