View previous topic :: View next topic |
Author |
Message |
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
C syntax question |
Posted: Thu Feb 07, 2008 7:25 pm |
|
|
Dear members,
I have a question about the loop FOR method.
I understand it but there's something i need to know...
Consider the following loop
Code: |
for(i=50;i>0;i--){
dostuff();
}
|
The loop stop when I = 0 but never execute the rest of the loop
so logically if i do this:
Code: |
for(i=50;i>0;i--){
printf("I=%d",i);
}
|
the code will start from 50,49....and print 1 .. but 0 is skipped.
I have tried using this for(i=50;i>=0;i--)
but I've got a warning : Condition always TRUE for this line.
So this might be the problem and cause the pic to hang because the
uINT8 I will reach -1 thus causing an error.
i need to reach the 0...but how?
EDIT: i have thinked of this but i really doubt this is the optimal thing to do..
have I to be a signed integer, then
for(i=50;i>-1;i--) ?
Best Regards,
Laurent |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Feb 07, 2008 7:43 pm |
|
|
Quote: | I have tried using this for(i=50;i>=0;i--)
but I've got a warning : Condition always TRUE for this line.
So this might be the problem and cause the pic to hang because the
uINT8 I will reach -1 thus causing an error. | After reaching zero the variable will wrap to 255, not to -1 because it is declared as unsigned. 255 is always greater than 0, that's why the compiler warned you and the PIC hangs.
Quote: | i need to reach the 0...but how? |
Solution 1, make i a signed variable. Disadvantage is that i can be no larger than 127 (unless you change it to an int16): Code: | signed int8 i;
for(i=50;i>=0;i--){
printf("I=%d",i);
} |
Solution 2, start counting at 51 and subtract 1 whenever you use i in the loop: Code: | int8 i;
for(i=51;i>0;i--){
printf("I=%u",i-1); // note the %u for unsigned integers.
} |
Solution 3, using do-while instead of for-next: Code: | int8 i;
i = 51;
do{
i--;
printf("I=%u",i); // note the %u for unsigned integers.
} while (i > 0); |
Solution 1 is my favourite.
Edit 8-feb: Changed signed into to unsigned in Solution 2.
Last edited by ckielstra on Fri Feb 08, 2008 7:28 am; edited 1 time in total |
|
|
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Thu Feb 07, 2008 7:56 pm |
|
|
Thanks ckielstra !
Is there a performance issue when using do while,, which method is faster ?
I mean which take less cpu cycle to execute ?
oh btw, i was always wondering how you could calculate how much cpu cycle my function takes ... from another post you replied me you said that the code X from Y was 70 cycles more efficient than another code... how do you see that ?
Best Regards,
Laurent |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
Re: C syntax question |
Posted: Thu Feb 07, 2008 8:30 pm |
|
|
ELCouz wrote: |
Code: |
for(i=50;i>0;i--){
printf("I=%d",i);
}
|
|
I like this for readability.
Code: |
i=51;
while(--i)
{ j=!j;
}
.................... i=51;
0165C: MOVLW 33
0165E: MOVWF 3D
.................... while(--i)
.................... { j=!j;
01660: DECF 3D,F
01662: BZ 1668
01664: BTG 3E.0
.................... }
01666: BRA 1660
|
Look at the list file. Each instruction takes a defined number of instruction cycles. |
|
|
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Thu Feb 07, 2008 11:43 pm |
|
|
Thanks for your help & clarification!
I love this forum, every time is visit it , i learn something
Best Regards,
Laurent |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
Re: C syntax question |
Posted: Fri Feb 08, 2008 8:20 am |
|
|
Quote: | oh btw, i was always wondering how you could calculate how much cpu cycle my function takes ... from another post you replied me you said that the code X from Y was 70 cycles more efficient than another code... how do you see that ? Smile | MPLAB has a Stopwatch window under the Debugger menu. Select the simulator or ICD as your debugging target . Use 'Set PC at cursor' and 'Run to Cursor' to meassure the number of clock cycles.
Neutone wrote: | I like this for readability.
Code: |
i=51;
while(--i)
{ j=!j;
}
.................... i=51;
0165C: MOVLW 33
0165E: MOVWF 3D
.................... while(--i)
.................... { j=!j;
01660: DECF 3D,F
01662: BZ 1668
01664: BTG 3E.0
.................... }
01666: BRA 1660
|
| This version will loop 50 times, not 51 times!
With the printf from the other example inside it would print the range 50 to 1, when required 50 to 0.
An easy fix would be to change the '--i' to 'i--' but this introduces two instructions extra overhead. Inspired by Neutone I came up with another variant which I named Solution4. Below are some test results Code: | // Solution 1: 312 cycles. (requires variable i to be signed)
for(i=50;i>=0;i--)
{ j++;
}
// Neutone: 256 cycles but executes the loop with i==50 to 1, instead of 50 to 0.
i=51;
while(--i)
{ j++;
}
// Modified Neutone, looping correct 50 to 0: 365 cycles
i=51;
while(i--)
{ j++;
}
// Solution 4: A modified version of solution3, inspired by Neutone.
// 308 cycles
// Executes the loop with i = 50 - 0
i=50;
do
{ j++;
} while (i--);
// Solution 5: A modified version of Solution4 using '--i' instead of 'i--'
// 202 cycles
// Oops! Executes the loop with i == 50 to 1, that's 1 too short.
i=50;
do
{ j++;
} while (--i);
// Solution 3: 257 cycles.
i=51;
do
{
i--;
j++;
} while (i>0);
| In my opinion solution 1 is still the best readable but the use of the signed integer poses a maximum of 127 on the allowed range. Solution 4 is a good second and does not have the limitation of the signed loop variable. Solution 3 is the fastest. |
|
|
|