Related
I am writing a callback function in C. It is intended to initialise an I2C sensor, and it called at the conclusion of each (split-phase) configuration step; after the 9th call, the device is almost ready to use.
The basic idea of the function is this:
void callback(void)
{
static uint8_t calls = 0;
if (++calls == 9) {
// Finalise device setup (literally a single line of code)
}
}
My problem is that the above if statement is never being entered, despite the function being called 9 times.
The (dis)assembly code for my function seems sane (with the exception of the subi . 0xFF trick for an increment, despite the inclusion of an inc instruction):
00000a4c <callback>:
a4c: 80 91 9e 02 lds r24, 0x029E
a50: 8f 5f subi r24, 0xFF ; 255
a52: 80 93 9e 02 sts 0x029E, r24
a56: 89 30 cpi r24, 0x09 ; 9
a58: 09 f0 breq .+2 ; 0xa5c <callback+0x10>
a5a: 08 95 ret
a5c: 2e e1 ldi r18, 0x1E ; 30
a5e: 35 e0 ldi r19, 0x05 ; 5
a60: 41 e0 ldi r20, 0x01 ; 1
a62: 60 e0 ldi r22, 0x00 ; 0
a64: 84 e7 ldi r24, 0x74 ; 116
a66: 0c 94 c7 02 jmp 0x58e ; 0x58e <twi_set_register>
I am writing the code for an Atmel AVR chip, and thus compiling with avr-gcc. I have no meaningful code debugging capabilities (I don't have access to a JTAG programmer, and the function is asynchronous/split-phase in any case; USART printing is too slow).
However, I have access to a logic analyser, and have been able to determine a number of things by placing while (1) ; statements inside the code:
the function is called - if I place an infinite loop at the start of the function, the microcontroller hangs
the function should be called 9 times - the trigger for the function is an I2C communication, and in the previous step it hangs immediately after the first communication; I can observe 9 complete and valid I2C communications
calls is incremented within the function - if I add if (calls == 0) { while (1) ; } after the increment, it does not hang
calls is never non-zero at the start of the function - if I add if (calls) { while(1) ; } before the increment, it does not hang
I'm completely at a loss for ideas.
Does anyone have any suggestions as to what could cause this, or even for new debugging steps I could take?
I ended up finding the cause of the error; another subsystem was breaking as a side-effect of the first call to the callback function, meaning that no other calls succeeded.
This explains the behaviours I saw:
it hung the first time because it was actually being called
it didn't hang the second time (or any future time) because it was only being called once
the I2C transactions I was observing were occurring, but their callback mechanism was not operating correctly, due to the other subsystem (tasks) breaking
I was able to work this out by using a few GPIO pins as debugging toggles, and thus tracking how the call was progressing through the TWI interface.
Thanks for the help guys. This isn't really an answer to the original question as posed, but it is solved, so that's something :)
For what you say I can only think of 3 possibilities: 1) your assumption that the function is being called on every I2C communication is incorrect, 2) your program has a bug (maybe a memory leak) in some unrelated function which causes the variable calls to become corrupted. or 3) two or more threads are calling your function simultaneously and calls is being incremented in a different way than you expect, use > instead of ==, if this solves the problem, then you are running in a milti-threaded environment and you didn't konw.
You need an accurate method to know the exact value of calls, if you don't have a debugger and don't have the means to output text either, the only thing you have left to play is time. I don't know you compiler, but I am sure it contains some useful timing functions, so what I would do would be to loop before increment for 10+calls seconds, and after increment again 10+calls seconds, for example:
sleep(1000*(10+calls));
++calls;
sleep(1000*(10+calls));
if(calls>8){
// your actual code
}
I would (chronometer in hand) expect a delay of (10+0 plus 10+1) = 21 seconds on the first call, 23 seconds on the second call, 25 in the third and so on. That way I could be sure the value of calls started with 0 and then it was progressively increased until 9.
Also, you must test for what you expect not for what you don't expect, so instead of doing this:
++calls;
if (calls==0) while (1);
do this:
++calls;
if (calls==1) while (1);
that way if your program hangs you can be sure the value of calls is exactly 1, and not whatever different from zero. If you count one valid I2C communication and your program hangs then the transition from 0 to 1 was done correctly, so change the hang statement accordingly:
++calls;
if (calls==2) while (1);
Again, if you count 2 valid I2C communications before your program hangs that means that the transition from 1 to 2 was correct, and so on.
Another suggestion, try this:
uint8_t Times(void){
static uint8_t calls = 0;
return ++calls;
}
void callback(void){
if (Times()>8) {
// Your actual code
}
}
And this:
void callback(void){
static uint8_t calls = 0;
if (calls++>7) {
// some code.
}
}
Hope this helps.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why use a for loop instead of a while loop?
I am currently using embedded c. Software that i am using is keil uvision.
So i have a question regarding on which loop will u use?
Both loop does the exact same thing. As long as signal = 0, 'i' will increase by 1.
Firstly,
for(;signal==0;)
{
i++;
}
The next program:
while(signal==0)
{
i++;
}
So which loop would you use and Why? What is the difference between both of them?
Does it have any difference in terms of time taken to execute? Or it is purely based on your preference?
Generally speaking, for loops are preferred when the number of iterations is known (i.e. for each element in an array), and while loops are better for more general conditions when you don't know how many times you'll run the loop. However, a for loop can do anything a while loop can, and vice versa; it all depends on which one makes your code more readable
In this case, a while loop would be preferable, since you're waiting for signal == 0 to become false, and you don't know when that will occur.
Any for loop can be written with a while loop and vice versa. Which you do is mixture of preference, convention, and readability.
Normally, for loops are used for counting and while loops are sort of waiting for a certain condition to be met (like the end of a file). There is no performance difference.
Boilerplate for and while loops:
for(int i = 0; i < someArraysLength; i++)
{
// Modify contents of array
}
while(lineLeftInFile)
{
// Read and parse the line
}
Whichever is easiest to read and understand.
Keep in mind that someone (other than you) might at some point try to read your code.
My opinion: while
Execution time is irrelevant. Any compiler that's worth a damn will generate the exact same code.
Now, as for semantics and such...computationally,
for (init; test; increment) { /* do stuff */ }
is exactly equivalent to
init;
while (test) {
/* do stuff */
increment;
}
And without init and increment, becomes just
while (test) {
/* do stuff */
}
So computationally, the two are identical. Semantically, though, a for loop is for when you have a setup and/or increment stage (particularly if they make for a predictable number of iterations). Since you don't, stick with while.
I agree with mariusnn, whichever is easiest to read and the while would seem to be easier to read to me as well.
Looking at the assembler produced by Visual Studio 2005 when doing a Debug build, the assembler instructions look to be the same for both of these loops. And actually if you do the same loop using an if statement and a label with the true statement being to increment i and then goto the if statement again, it looks like that also generates the same assembler.
for (; signal == 0; ) {
0041139C cmp dword ptr [signal],0
004113A0 jne wmain+3Dh (4113ADh)
i++;
004113A2 mov eax,dword ptr [i]
004113A5 add eax,1
004113A8 mov dword ptr [i],eax
}
004113AB jmp wmain+2Ch (41139Ch)
while (signal == 0) {
004113AD cmp dword ptr [signal],0
004113B1 jne loop (4113BEh)
i++;
004113B3 mov eax,dword ptr [i]
004113B6 add eax,1
004113B9 mov dword ptr [i],eax
}
004113BC jmp wmain+3Dh (4113ADh)
loop: if (signal == 0) {
004113BE cmp dword ptr [signal],0
004113C2 jne loop+11h (4113CFh)
i++;
004113C4 mov eax,dword ptr [i]
004113C7 add eax,1
004113CA mov dword ptr [i],eax
goto loop;
004113CD jmp loop (4113BEh)
}
So which loop would you use and Why?
If I had to choose between the two, I would probably use the while loop, its simpler and cleaner, and it clearly conveys to other developers that the following block of code will be continuously executed until signal is updated.
then again one could do this: for(; signal == 0; i++); it seems to be the more concise, though thats assuming if indeed this will be production code.
Still all this methods seem well a bit dangerous because of overflow, even on embedded devices most clocks are still quite fast and will probably reach the upper bounds of the underlying data type quite soon, then again I don't know if this will be production code nor do I know if that is an acceptable outcome.
What is the difference between both of them?
Like you said both achieve the same goal though Im sure there other ways as I've shown or as others mentioned, the biggest difference between for and while is that one is usually use when we know the number iterations while the other we don't, though for better or worse I've seen some very unique uses of a for its quite flexible.
Does it have any difference in terms of time taken to execute? Or it is purely based on your preference?
As for performance, fundamentally its up to your compiler to decide how to interpret it, it may or may not produce the same binaries, and hence execution time, you could ask it to produce the assemblies or do some profiling.
It seems that uvision 4 IDE http://www.keil.com/product/brochures/uv4.pdf indeed does support disassembly, as noted at page 94, and profiling as noted at page 103, if that indeed is the version you are using.
Though if the difference is small enough please don't sacrifice readability just to squeeze a couple extra nano-secs, this is just my opinion, Im sure there others that would disagree.
The best advice I could give you is this, try as best as you can, to write clear code, meaning most can see what it conveys without much effort, thats efficient and maintainable.
In my lecture of Design and Analysis of
Algorithms the instructor said the for loop will take less time then while loop for the following sample algo.
1. for(int i=0;i<5;i++)
{
2. print(i);
}
1. int i=0;
2. while(i<5)
{
3. print(i);
4. i++;
}
He said that the compiler will read the 1. of for while 5 times line 2. 4 times thus total time 5+4=9
But in the case of while loop. The compiler will read the 1. for 1 time,2. for 5 time, 3 for 4time and 4. for 4 time. Thus total time 1+5+4+4 = 14time
Please tell me is this right. Is for loop is faster than while loop?
Thanks.
At least with MSVC 16 (VS 2010) the code is pretty much the same in both cases:
for
; Line 5
xor esi, esi
$LL3#main:
; Line 6
push esi
push OFFSET ??_C#_03PMGGPEJJ#?$CFd?6?$AA#
call _printf
inc esi
add esp, 8
cmp esi, 5
jl SHORT $LL3#main
while
; Line 4
xor esi, esi
$LL2#main:
; Line 6
push esi
push OFFSET ??_C#_03PMGGPEJJ#?$CFd?6?$AA#
call _printf
; Line 7
inc esi
add esp, 8
cmp esi, 5
jl SHORT $LL2#main
Code in my Subversion repository.
In all the modern compilers loop analysis is done on a lower level intermediate representation (i.e., when all the high level loop constructs are expanded into labels and jumps). For a compiler both loops are absolutely equivalent.
I'll pass on performance (hint: no difference, check the generated IR or assembly for proof) however there are two important differences in syntax and maintenance.
Syntax
The scope of the i variable is different. In the for case, the i is only accessible within the for header and body, while in the while case it is available after the loop. As a general rule, it's better to have tighter scopes, less variables in-flight mean less context to worry about when coding.
Maintenance
The for loop has the neat advantage of grouping all the iterations operations close together, so they can be inspected in one shot and so checked.
Also, there is one important difference when introducing continue statements:
for(int i = 0; i != 10; ++i) {
if (array[i] == nullptr) { continue; }
// act on it
}
int i = 0;
while (i != 10) {
if (array[i] == nullptr) { continue; }
// act on it
++i;
}
In the while case, the introduction of continue has created a bug: an infinite loop, as the counter is no longer implemented.
Impact
for loops are more readable and all-around better for regular iteration patterns. Even better, in C++11 the range-for statement:
for (Item const& item : collection) {
}
where iteration is entirely taken care of by the compiler, so you are sure not to mess up! (it makes the for_each algorithm somewhat moot... and we can wish the older for form starts retreating)
By corrolary: while loops should be reserved to irregular iteration patterns, this way they will attract special care during code review and from future maintainer by highlighting the irregularity of the case.
I'm trying to execute a very simple buffer overflow attack. I'm pretty much a newbie to this. So, if this question is stupid, please excuse me :-)
The code:
#include<stdio.h>
#include<stdlib.h>
int i, n;
void confused(int i)
{
printf("**Who called me? Why am I here?? *** %x\n ", i);
}
void shell_call(char *c)
{
printf(" ***Now calling \"%s\" shell command *** \n", c);
system(c);
}
void victim_func()
{
int a[4];
printf("Enter n: "); scanf("%d",&n);
printf("~~~~~~~~~~~~~ values and address of n locations ~~~~~~~~~~");
for (i = 0;i <n ;i++)
printf ("\n a[%d] = %x, address = %x", i, a[i], &a[i]);
printf("\nEnter %d HEX Values \n", n);
// Buffer Overflow vulnerability HERE!
for (i=0;i<n;i++) scanf("%x",&a[i]);
printf("Done reading junk numbers\n");
}
int main()
{
victim_func();
printf(“\n done”);
return 0;
}
When I use objdump to get the function addresses, I have the following:
main(): 0x804854d
Address of main() where printf() is called: 0x8048563
victim_func(): 0x8048455
confused(): 0x8048414
Now, what I want is to jump to the function 'confused()' from victim_func() by overflowing the buffer there, and overwriting the return address to the address of confused(). And I want to return back from confused() to the printf() statement in main, and exit normally. So, I provide the following input
Enter n: 7
Enter 7 HEX values:
1
2
3
4
5
8048414 (This is to jump to confused)
8048563 (this is to jump to printf() in main)
Although, the program prints "Done" from that printf statement, it is jumping back to victim_func() and prints "Enter n:"
What am I doing wrong? Any help would be greatly appreciated!
PS: I'm not sure if I have put the question right. Please let me know, if any more information is needed.
A buffer overflow attack is a lot more complex than this. First of all you need to understand assembler in order to perform this. After you disassemble the program and function you want to target you need to determine the stack layout when it's executing that function.
Here's a sample of a buffer overflow it's using visual studio but principle is the same.
#include "stdafx.h"
#include <math.h>
volatile double test;
double function3()
{
test++;
return exp(test);
}
double function2()
{
return log(test);
}
double function1()
{
int a[5] = {0};
a[7] = (int)&function3;
return exp(function2());
}
int _tmain(int argc, _TCHAR* argv[])
{
double a = function1();
test = a;
return a;
}
Thanks to disassembly we know that a in function1 is allocated before where the function saved the stack frame pointer. The value after that one is the return address where function1 should go to if it is finished.
00401090 55 push ebp <- we save the stack pointer
00401091 8B EC mov ebp,esp
00401093 83 EC 1C sub esp,1Ch <- save space to allocate a[5]
00401096 B8 CC CC CC CC mov eax,0CCCCCCCCh
0040109B 89 45 E4 mov dword ptr [ebp-1Ch],eax <- crt debug init a[5]
0040109E 89 45 E8 mov dword ptr [ebp-18h],eax
004010A1 89 45 EC mov dword ptr [ebp-14h],eax
004010A4 89 45 F0 mov dword ptr [ebp-10h],eax
004010A7 89 45 F4 mov dword ptr [ebp-0Ch],eax
004010AA 89 45 F8 mov dword ptr [ebp-8],eax
004010AD 89 45 FC mov dword ptr [ebp-4],eax
From this we can conclude if we overwrite a[7] with a different address, the function will return not to main but with whatever address we wrote in a[7].
Hope this helps.
Now, what I want is to jump to the function 'confused()' from victim_func() by overflowing the buffer there, and overwriting the return address to the address of confused()...
On modern Linux platforms, you will also need to ensure two security features are turned off for testing. First in NX-stacks, and second is Stack Protectors.
To turn off NX-Stacks, use -Wl,z,execstack (as opposed to -Wl,z,noexecstack). To turn off Stack Protectors, use -fno-stack-protector (as opposed to -fstack-protector or -fstack-protector-all).
There's a third protection you might need to turn off. That protection is FORTIFY_SOURCE. FORTIFY_SOURCE uses "safer" variants of high risk functions like memcpy and strcpy. The compiler uses the safer variants when it can deduce the destination buffer size. If the copy would exceed the destination buffer size, then the program calls abort(). To disable FORTIFY_SOURCE, compile the program with -U_FORTIFY_SOURCE or -D_FORTIFY_SOURCE=0.
The security features are turned on by default because there's been so many problems in the past. In general, its a good thing because it stops many problems (like the one you are experimenting with).
First of all it seems to me that you shouldn't enter the number 5 in your sample input. Your array is declared a[4] thus has elements indexed 0-3 - so your attack input seems wrong to me.
It also seems to me that your program assumes several thing about the architecture:
sizof(int)==sizeof(memory address)
The direction of growth and mechanism of the environments stack implementation
If one of these assumptions is untrue it's never going to work.
This seems like a very hard work work assignment.
There are easier examples of buffer overflow attacks than changing the control flow of the code. For example you might be able to overwrite another piece of data which is supposed to be protected from the user (such as a security setting)
You didn't show us the output of the program with the addresses of a[i]. I suspect that the compiler is doing something like aligning the data on the stack to 16. It could be much further to the return address than you expect.
There are three loops in C: for, while, and do-while. What's the difference between them?
For example, it seems nearly all while statements can be replaced by for statements, right? Then, what's the advantage using while?
A while loop will always evaluate the condition first.
while (condition) {
//gets executed after condition is checked
}
A do/while loop will always execute
the code in the do{} block first
and then evaluate the condition.
do {
//gets executed at least once
} while (condition);
A for loop allows you to initiate a counter variable, a check condition, and a way to increment your counter all in one line.
for (int x = 0; x < 100; x++) {
//executed until x >= 100
}
At the end of the day, they are all still loops, but they offer some flexibility as to how they are executed.
Here is a great explanation of the reasoning behind the use of each different type of loop that may help clear things up. Thanks clyfe
The main difference between the for's
and the while's is a matter of
pragmatics: we usually use for when
there is a known number of iterations,
and use while constructs when the
number of iterations in not known in
advance. The while vs do ... while
issue is also of pragmatics, the
second executes the instructions once
at start, and afterwards it behaves
just like the simple while.
For loops are especially nice because they are concise. In order for this for loop:
for (int x = 0; x < 100; x++) {
//executed until x >= 100
}
to be written as a while loop, you'd have to do the following:
int count = 0;
while (count < 100) {
//do stuff
count++;
}
In this case, there's just more stuff to keep up with and the count++; could get lost in the logic. This could end up being troublesome depending on where count gets incremented, and whether or not it should get incremented before or after the loop's logic. With a for loop, your counter variable is always incremented before the next iteration of the loop, which adds some uniformity to your code.
For the sake of completeness, it's probably meaningful to talk about break and continue statements here which come in handy when doing loop processing.
break will instantly terminate the current loop and no more iterations will be executed.
//will only run "do stuff" twice
for (int x = 0; x < 100; x++) {
if (x == 2) {
break;
}
//do stuff
}
continue will terminate the current iteration and move on to the next one.
//will run "do stuff" until x >= 100 except for when x = 2
for (int x = 0; x < 100; x++) {
if (x == 2) {
continue;
}
//do stuff
}
Note that in a for loop, continue evaluates the part3 expression of for (part1; part2; part3); in contrast, in a while loop, it just jumps to re-evaluate the loop condition.
If there is a strong concern about speed and performance, the best approach is to verify the code produced by the compiler at the assembly level.
For instance, the following code shows that the "do-while" is a bit faster. This because the "jmp" instruction is not used by the "do-while" loop.
BTW, in this specific example, the worst case is given by the "for" loop. :))
int main(int argc, char* argv[])
{
int i;
char x[100];
// "FOR" LOOP:
for (i=0; i<100; i++ )
{
x[i] = 0;
}
// "WHILE" LOOP:
i = 0;
while (i<100 )
{
x[i++] = 0;
}
// "DO-WHILE" LOOP:
i = 0;
do
{
x[i++] = 0;
}
while (i<100);
return 0;
}
// "FOR" LOOP:
010013C8 mov dword ptr [ebp-0Ch],0
010013CF jmp wmain+3Ah (10013DAh)
for (i=0; i<100; i++ )
{
x[i] = 0;
010013D1 mov eax,dword ptr [ebp-0Ch] <<< UPDATE i
010013D4 add eax,1
010013D7 mov dword ptr [ebp-0Ch],eax
010013DA cmp dword ptr [ebp-0Ch],64h <<< TEST
010013DE jge wmain+4Ah (10013EAh) <<< COND JUMP
010013E0 mov eax,dword ptr [ebp-0Ch] <<< DO THE JOB..
010013E3 mov byte ptr [ebp+eax-78h],0
010013E8 jmp wmain+31h (10013D1h) <<< UNCOND JUMP
}
// "WHILE" LOOP:
i = 0;
010013EA mov dword ptr [ebp-0Ch],0
while (i<100 )
{
x[i++] = 0;
010013F1 cmp dword ptr [ebp-0Ch],64h <<< TEST
010013F5 jge wmain+6Ah (100140Ah) <<< COND JUMP
010013F7 mov eax,dword ptr [ebp-0Ch] <<< DO THE JOB..
010013FA mov byte ptr [ebp+eax-78h],0
010013FF mov ecx,dword ptr [ebp-0Ch] <<< UPDATE i
01001402 add ecx,1
01001405 mov dword ptr [ebp-0Ch],ecx
01001408 jmp wmain+51h (10013F1h) <<< UNCOND JUMP
}
// "DO-WHILE" LOOP:
i = 0;
. 0100140A mov dword ptr [ebp-0Ch],0
do
{
x[i++] = 0;
01001411 mov eax,dword ptr [ebp-0Ch] <<< DO THE JOB..
01001414 mov byte ptr [ebp+eax-78h],0
01001419 mov ecx,dword ptr [ebp-0Ch] <<< UPDATE i
0100141C add ecx,1
0100141F mov dword ptr [ebp-0Ch],ecx
01001422 cmp dword ptr [ebp-0Ch],64h <<< TEST
01001426 jl wmain+71h (1001411h) <<< COND JUMP
}
while (i<100);
For the sake of readability
They're all interchangeable; you could pick one type and use nothing but that forever, but usually one is more convenient for a given task. It's like saying "why have switch, you can just use a bunch of if statements" -- true, but if it's a common pattern to check a variable for a set of values, it's convenient and much easier to read if there's a language feature to do that
If you want a loop to execute while a condition is true, and not for a certain number of iterations, it is much easier for someone else to understand:
while (cond_true)
than something like this:
for (; cond_true ; )
Remember, a for loop is essentially a fancy while loop. They're the same thing.
while <some condition is true> {
// do some stuff
// possibly do something to change the condition
}
for ( some var, <some condition is true>; increment var ) {
}
The advantage of a for loop is that it's harder to accidentally do an infinite loop. Or rather, it's more obvious when you do one because you generally put the loop var in the initial statement.
A while loop is more clear when you're not doing a standard incrementing pattern. For example:
int x = 1;
while( x != 10 ) {
if ( some condition )
x = 10;
else
x += 5;
}
You should use such a loop, that most fully conforms to your needs.
For example:
for(int i = 0; i < 10; i++)
{
print(i);
}
//or
int i = 0;
while(i < 10)
{
print(i);
i++;
}
Obviously, in such situation, "for" looks better, than "while".
And "do while" shoud be used when some operations must be done already before the moment when condition of your loop will be checked.
Sorry for my bad english).
One common misunderstanding withwhile/for loops I've seen is that their efficiency differs. While loops and for loops are equally efficient. I remember my computer teacher from highschool told me that for loops are more efficient for iteration when you have to increment a number. That is not the case.
For loops are simply syntactically sugared while loops, and make iteration code faster to write.
When the compiler takes your code and compiles it, it is translating it into a form that is easier for the computer to understand and execute on a lower level (assembly). During this translation, the subtle differences between the while and for syntaxes are lost, and they become exactly the same.
A for suggest a fixed iteration using an index or variants on this scheme.
A while and do... while are constructions you use when there is a condition that must be checked each time (apart from some index-alike construction, see above). They differ in when the first execution of the condition check is performed.
You can use either construct, but they have their advantages and disadvantages depending on your use case.
I noticed some time ago that a For loop typically generates several more machine instructions than a while loop. However, if you look closely at the examples, which mirror my observations, the difference is two or three machine instructions, hardly worth much consideration.
Note, too, that the initializer for a WHILE loop can be eliminated by baking it into the code, e. g.:
static int intStartWith = 100;
The static modifier bakes the initial value into the code, saving (drum roll) one MOV instruction. Of greater significance, marking a variable as static moves it outside the stack frame. Variable alignment permitting, it may also produce slightly smaller code, too, since the MOV instruction and its operands take more room than, for example an integer, Boolean, or character value (either ANSI or Unicode).
However, if variables are aligned on 8 byte boundaries, a common default setting, an int, bool, or TCHAR baked into code costs the same number of bytes as a MOV instruction.
They are all the same in the work they do. You can do the same things using any of them. But for readability, usability, convenience etc., they differ.
A difference between while and do-while is that while checks the loop condition and if this is true, the body is executed and the condition checked again. The do-while checks the condition after execution of the body, so with do-while the body is executed at least one time.
Of course you can write a while loop as a do-while and vv, but this usually requires some code duplication.
One peculiarity of the do while is that you need a semi-colon after the while to complete. It is often used in macro definitions to execute several statements only once while constraining the impact of the macro. If macros where defined as blocks, some parsing errors may occur.
One explanation among others
For loops (at least considering C99) are superior to while loops because they limit the scope of the incremented variable(s).
Do while loops are useful when the condition is dependant on some inputs. They are the most seldom used of the three loop types.
Between for and while: while does not need initialization nor update statement, so it may look better, more elegant; for can have statements missing, one two or all, so it is the most flexible and obvious if you need initialization, looping condition and "update" before looping. If you need only loop condition (tested at the beginning of the loop) then while is more elegant.
Between for/while and do-while: in do-while the condition is evaluated at the end of the loop. More confortable if the loop must be executed at least once.
WHILE is more flexible. FOR is more concise in those instances in which it applies.
FOR is great for loops which have a counter of some kind, like
for (int n=0; n<max; ++n)
You can accomplish the same thing with a WHILE, of course, as others have pointed out, but now the initialization, test, and increment are broken across three lines. Possibly three widely-separated lines if the body of the loop is large. This makes it harder for the reader to see what you're doing. After all, while "++n" is a very common third piece of the FOR, it's certainly not the only possibility. I've written many loops where I write "n+=increment" or some more complex expression.
FOR can also work nicely with things other than a counter, of course. Like
for (int n=getFirstElementFromList(); listHasMoreElements(); n=getNextElementFromList())
Etc.
But FOR breaks down when the "next time through the loop" logic gets more complicated. Consider:
initializeList();
while (listHasMoreElements())
{
n=getCurrentElement();
int status=processElement(n);
if (status>0)
{
skipElements(status);
advanceElementPointer();
}
else
{
n=-status;
findElement(n);
}
}
That is, if the process of advancing may be different depending on conditions encountered while processing, a FOR statement is impractical. Yes, sometimes you could make it work with a complicated enough expressions, use of the ternary ?: operator, etc, but that usually makes the code less readable rather than more readable.
In practice, most of my loops are either stepping through an array or structure of some kind, in which case I use a FOR loop; or are reading a file or a result set from a database, in which case I use a WHILE loop ("while (!eof())" or something of that sort).
They are pretty much same except for do-while loop. The for loop is good when you have a counter kind of variable. It makes it obvious. while loop makes sense in cases where a flag is being checked as show below :
while (!done) {
if (some condtion)
done = true;
}
while and for statements can both be used for looping in programming. It will depend on the programmer as to whether the while loop or for loop is used. Some are comfortable using while loop and some are with for loop.
Use any loop you like. However, the do...while loop can be somewhat tricky in C programming.
/*
while loop
5 bucks
1 chocolate = 1 bucks
while my money is greater than 1 bucks
select chocolate
pay 1 bucks to the shopkeeper
money = money - 1
end
come to home and cant go to while shop because my money = 0 bucks
*/
#include<stdio.h>
int main(){
int money = 5;
while( money >= 1){
printf("inside the shopk and selecting chocolate\n");
printf("after selecting chocolate paying 1 bucks\n");
money = money - 1 ;
printf("my remaining moeny = %d\n", money);
printf("\n\n");
}
printf("dont have money cant go inside the shop, money = %d", money);
return 0;
}
infinite money
while( codition ){ // condition will always true ....infinite loop
statement(s)
}
please visit this video for better understanding
https://www.youtube.com/watch?v=eqDv2wxDMJ8&t=25s
/*
for loop
5 bucks
for my money is greater than equal to 1 bucks 0 money >= 1
select chocolate
pay 1 bucks to the shopkeeper
money = money - 1 1-1 => 0
end
*/
#include<stdio.h>
int main(){
int money = 5;
for( ; money >= 1; ){ 0>=1 false
printf("select chocolate \n");
printf("paying 1 bucks to the shopkeeper\n");
money = money - 1; 1-1 = 0
printf(" remaining money =%d\n", money);
printf("\n\n");
}
return 0;
}
For better understanding please visit https://www.youtube.com/watch?v=_vdvyzzp-R4&t=25s