Total code size with the algorithms presented so far (GCC 4.3.2 optimization level 0s):-
My algo #1,
for (count = 0; count < 8; count++)
{
DATA = (bits >> count);// shift right * count
PORTC = DATA;
}
104 bytes
My algo #2,
for (count = 0; count < 8; count++)
{
PORTC = DATA; // output current contents of DATA
DATA = (DATA >> 1); // shift DATA right * 1 (will be output next time through the loop)
}
94 bytes
rstofer,
for (count = 0; count < 8; count++) {
switch(count) {
case 0 : PORTC = 0x01;
break;
case 2 : PORTC = 0x02;
break;
case 3 : PORTC = 0x04;
break;
case 4 : PORTC = 0x08;
break;
case 5 : PORTC = 0x10;
break;
case 6 : PORTC = 0x40;
break;
case 7 : PORTC = 0x80;
break;
default : break;
}
}
174 bytes
phil from seattle #1,
uint8_t bitmap[8] = { 0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80};
for(count=0;count<8;count++){
PORTC = bitmap[count];
}
156 bytes
phil from seattle #2,
for(count=0;count<8;count++){
PORTC = 1<<count;
}
104 bytes
However, neither rstofer's nor phil from seattle's code does what is required, which is shifting an arbitrary bit pattern (eg. 1100100 or 11000000111001) progressively right. The case statements or array contents could be adjusted to suit a particular bit pattern, but modifying all those 'magic numbers' would be time-consuming and easy to mess up.
Burying a shift operation in case statements or array elements are examples of 'tricky' coding that should be avoided. Unless you desperately need the fastest possible execution and/or smallest footprint, programs should be written for readability and understanding first, then optimized only if necessary. If shifting right is what you want to do, use the >> operator. Don't be afraid to use intermediate variables, spread statements over several lines, or break complex code up into simpler functions which make your intention clearer and the code easier to expand or modify. Avoid 'magic' numbers. Let the compiler take care of optimizing your code.