Related
I'm currently making my own programming language for fun using Ruby and wondering why having a "while" and "for" loop is something so universal. Why is it be bad to just have a single "loop" keyword?
ex)
loop (True) # acts as a while loop with a condition
loop var in 1..20 # acts as a for loop
loop var in list # acts as a for each loop
Would this somehow be disadvantageous or is the "while" and "for" loop simply just for semantic and readability?
In fact, there are even more loop-variants. For example do-while.
To answer your question:
Yes, all of them can be used to do the same thing. However, depending on the loop-variant you use, you implicitly say what this loop does.
For example, you only use a for-loop if you know how often you want to loop (e.g. for each item in a list (i know, there is also a foreach in many languages)). It is considered bad habit to modify the loop variable inside a for-loop.
So if you are not sure how often you will loop, you should most likely use something else than a for-loop... for example a while-loop.
Here are some simple code examples:
for(i = 0; i < someList.Length; i++) {
// do some stuff x times
}
while(someValue < someOtherValue) {
someValue = someValue * someValue;
}
For me it is clear, that i should not use a for-loop for the 2nd loop.
To sum up: Yes, you only need one loop construct. However, I personally (!) like to have the advantage to actually say something just by the choice which loop i take.
Would this somehow be disadvantageous or is the "while" and "for" loop simply just for semantic and readability?
I think that your idea would not be disadvantageous and, yes, while and for are chosen for semantics/readability (or even historical reasons). Then, there are slightly different meanings in every language. Often, the for loop implies that you have a control variable. From the classic basic
for i=1 to 10 ... (next i)
to pascal, and even in more advanced constructs (iterators) from python, this idea is respected. Moreover, in some languages (pascal, for example) a for implies that the low-high limits are pre-calculated. This pascal code for example:
B := 5;
for i := 1 to B do begin
B := 25
end;
can give warnings or errors, or can lead to 5 iterations even if in the body of the loop the upper limit is modified. The C language, which also has for, is totally different, even if the general idea of "control variable" is respected in 99% of the cases. The C for does not pre-compute limits (by design), can have more than one control variable, or even none at all:
for ( ; ; ) ...
is a valid for loop which does not have a control variable (and no meaning to break the loop!).
On the other hand, while, repeat, do ... while and so on are semantically clear (you can "talk" the code with your voice, and everything is self explaining), and do not imply variables (they imply nothing).
The above loops all have a common problem: they have a test which is performed at the beginning (or the end) of every iteration. Suppose you want to read characters from standard input, do something with them, and stop when this character is EOF. The C way is:
while ( ( ch=getchar() ) != EOF) ... ; // do something with ch
The C language can do this because an assignment is also an expression. If it was not so, one had to write:
ch=getchar();
while (ch != EOF) {
.... ; // do something with ch
ch = getchar();
}
// I must use two times the statement "ch = getchar();"
// or...
do {
ch = getchar();
if (ch == EOF) break;
... ; // do something with ch
} while (true)
// I use getchar() only once, but I end up with an awful "while (true)"
In your new language, you could invent a different cycle which goes like this:
cycle
// statements always executed at least once
when (condition)
// statement executed if the condition is true
// and, if true, the cycle restarts
end
With this syntax, the example about getchar() would become:
cycle ch=getchar(); when (ch != EOF) ... ; // do something bla bla bla...
The normal while, while (true) and do-while loops would become:
cycle when (condition); BODY // while
cycle BODY; // while (true)
cycle BODY; when (condition) // do-while
Think about it... :-)
Most languages have for and while for historical reasons and familiarity. Familiarity is important: if you reuse the same concepts and keywords as other languages, your language is easier to learn. Many languages use "!" for the negation for this reason (many other languages use "not"). Look at this page comparing syntax across languages, you'll see lots of similarities: http://rigaux.org/language-study/syntax-across-languages.html
Now, to answer your question. Although most languages have the while keyword, you really don't need it.
Best example I can think of is Go:
// C-like for
for i := 0; i < 10; i++ {
sum += i
}
// while
for sum < 1000 {
sum += sum
}
// infinite loop
for {
}
// do .. while
for ok := true; ok; ok = condition {
...
}
// range-for
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
So, as you can see, it's perfectly possible to use a single keyword for all loops.
Main reason for having both for and while is familiarity and readability. But you can easily do without.
What are typical uses of null statement
;
in C ?
I know that it is basically used to skip expression where it is expected by the compiler, but here I'm interested only in real-world examples of such use cases.
It's typically the side-effect of a code block that was stripped by the preprocessor, like
#if DEBUG
#define ASSERT(_x) Assert(_x)
#else
#define ASSERT(_x)
#endif
ASSERT(test); // Results in null statement in non-debug builds
That, or in loops where your condition already contains whatever needs to be done in each iteration.
while (*(dst++) = *(src++))
;
After a label at the end of a function (or more precisely, at the end of any block), e.g.
void foo(void)
{
// ...
exit:
;
}
while (somethingWithSideEffects()) ;
I have used it, albeit rarely, in a possibly unusual situation (and one that some/many people would find wrong). I have had to sometimes write a very complex if condition without an else clause where the if condition has to be negated. Obviously it can be something like this:
if ( !( overly complex condition ) )
{
do stuff
}
It sometimes makes more sense (to me at least) to think of it in terms of positive logic. In other words, if the overly complex condition holds true, I don't want the code to run. So I have instead written it as:
if ( overly complex condition )
; // do nothing
else
{
do stuff
}
Example:
while (!kbhit())
;
Should be self-explanatory.
Unit tests for a compliant compiler.
I can think of scanf validation. scanf gets stuck when user didn't give the correct input. So, to prevent scanf from being stuck, characters until end of line must be removed.
if( scanf("%d",&integer) == 0 )
{
while( getchar() != '\n' ) ;
// ....
}
A somewhat unusual use -- but for which I really appreciate the existence of the null statement -- is when I have two conditions and two actions which I find I can most naturally express like this:
if(condition1)
/* do nothing */ ;
else if(condition2)
do_something;
else do_something_else;
Often condition1 tests that everything is okay, but if it's not, condition2 distinguishes between two different exception actions do_something and do_something_else.
This isn't the only way to express such a thing, of course. It would be possible to repeat condition1:
if(!condition1 && condition2)
do_something;
else if(!condition1)
do_something_else;
But that seems inferior, because it repeats condition1. Or it would be possible to use nested if statements:
if(!condition1) {
if(condition2)
do_something;
else do_something_else;
}
But of course nested if statements are notoriously prone to overcomplication and obfuscation, too. So I often prefer the first version, with the null statement.
The only uses I can think of are:
1- At the end of a loop, where the operations are already encoded within the loop statements. e.g. while(a[i--]);
2- At the end of a label, where no operation is needed to be done. e.g. Label: ;
i was wondering how to write a null expression into the inline if and came up with this. it compiles and works.
condition ? x = 1 : "do nothing";
fun stuff.
It's more of a null expression rather than a null statement, but it's often found in for loops.
for (;;) // Loop "forever"
for (int i=10; i--; ) // 9..0
etc
The only place I use null statements is when a case begins with a declaration:
switch(x) {
case 5: ;
int y = makeValue(z);
...
break;
...
}
This will not compile if you remove the null statement that the case begins with. The reason is that a label cannot precede a declaration.
Can we put semicolon like while(condition); in a C Programming?
If while(condition); is valid, what does it mean?
while (condition);
is the same as
while (condition)
{
}
It can be used for waiting loops, e.g.:
while (!isLightGreen()); // waits until isLightGreen() returns true
go();
It means the body of the loop is empty. Typically this pattern is used when the condition itself does some work.
For example, this loop can copy bytes within the condition:
while ( '\0' != (*pt++ = *ps++))
;
If you're using a semicolon, it's a good idea to put it on a separate line so that it looks less like a mistake. I personally tend to use empty braces -- {}, and sometimes a comment that the empty block is intentional.
Edit:
In the second comment, Tom Anderson notes an improvement over a lone semicolon. Google's C++ style guide recommends either this or {}.
while ( '\0' != (*pt++ = *ps++))
continue;
Yes, you can. It just means that the while loop will keep looping until condition is false. For example:
#include<stdio.h>
int x = 10;
int func()
{
printf("%d\n", x);
return --x;
}
int main()
{
while(func());
return 0;
}
But generally people don't do this, as it would make more sense to put the logic in the body of the loop.
Edit:
There are some examples of this in use, for example, copying a null-terminated string:
char dest[256];
char *src = "abcdefghijklmnopqrstuvwxyz";
while(*(dest++) = *(src++));
Because the condition may actually have side effects, such a construct is allowed. Consider the following:
while (*p && *p++ != ' ');
This would advance the p pointer to the first character that is a space.
You may even use the comma operator to have ordinary statements inside the condition:
while (do_something(), do_something_else(), i < n);
Because statements connected with the comma operator evaluate to the rightmost statement, in that case i < n, the above is identical to:
do {
do_something();
do_something_else();
} while (i < n);
It will keep evaluating condition until it's false. It is a loop without a body.
Programmers often add a space before the semicolon, i.e.
while(condition) ;
or empty braces:
while(condition) {}
to show the empty body is intentional and not just a typo. If you are reading some existing source code and wondering why there is an empty loop there you should read the next few lines as well to see if the semicolon should really be there or not (i.e. do the next few lines look like the body of a loop or not?).
Yes, it's correct. It will loop the condition until it's false.
while ( condition() );
I always write this as:
while (condition())
continue;
So that it's obvious that it wasn't a mistake. As others have said, it only makes sense when condition() has side effects.
while() is a loop. You're probably looking to do a "do-while" loop. Do-while loops run in this format:
do
{
// Your process
// When something goes wrong or you wish to terminate the loop, set condition to 0 or false
} while(condition);
The one you have listed above, however, is an empty loop.
while() loops work nearly the same; there is simply no "do" portion.
Good luck!
It means that keep checking condition until it evaluate to false
The key to understanding this is that the syntax of the while loop in "C" is as follows:
while (condition) statement
Where statement can be any valid "C" statement. Following are all valid "C" statements:
{ statements } // a block statement that can group other statements
statement; // a single statement terminated by a ;
; // a null statement terminated by a ;
So, by the rules of the while loop, the statement part (null statement in your example) will execute (do nothing) as long as condition is true. This is useful because it amounts to a busy wait till the condition turns false. Not a good way to wait, but useful nevertheless. You could use this construct, for example, if you want to wait for another thread (or a signal handler) to set a variable to some value before proceeding forward.
The code while(condition); is perfectly valid code, though its uses are few. I presume condition is a variable, not a function — others here discuss functional condition.
One use of while(condition); may be to block while waiting for a signal e.g. SIGHUP, where the signal handler changes the variable condition. However, this is usually not the best way to wait for a signal. One would typically use a sleep in the loop i.e. while(condition) { sleep(1); }.
The absence of any sleep means that the loop will be continually processing in the interim, and likely wasting processing cycles. Unless the process has its resources managed (and even there...), I think this is only suitable where the loop needs to be broken in an interval less than the granularity of the available sleep command (i.e. sleep is granulated by the second, but you need the code after the look executed with sub-second response time). That being said, a blocking pipe or socket may be preferable to signals, performance wise – though I don't have any emperical data to back that up offhand, and I suspect performance may vary significantly depending on the platform.
One could have condition modified by a parallel thread of the same process, but I'd think one should prefer to do that by way of a mutex or semaphore (i.e. condition may need to be more than a simple variable).
I hope that's helpful, or at least food for thought!
It is just an empty loop. It would help if you explained what the condition is.
If the evaluation of the condition does not modify a value that influences the condition itself, while(condition); is an empty infinite loop, meaning it will never terminate (and never do anything except consuming CPU time).
it is absolutely correct. it means doing nothing in the loop,just polling the condition.And it is common in embedded system`s codes.
Its just a while loop with no execution body
while(condition);
is same as
while(condition)
{
}
Just another usage not described here:
do
{
if(out_of_memory)
break;
if(file_does_not_exist)
break;
return ok;
} while(0);
return error;
This allows you to avoid several return calls or goto statements.
I just ran into some code that overuse semicolons, or use semicolon for different purposes that I am not aware of.
I found semicolons at the end of if-statements and at the end of functions. For instance:
int main (int argc, char * argv[]) {
// some code
if (x == NULL) {
// some code
}; <-----
// more code
return 0;
}; <---
It is compiling with cc, not gcc.
What do those semicolons do? I'm assuming that there is no difference because the compiler would just consider it as empty statement.
They do nothing. They're a sign of someone who doesn't understand the language terribly well, I suspect.
If this is source code you notionally "own", I would remove the code and try to have a gentle chat with the person who wrote it.
that's dummy statememt. You sample is identical to
if (x == NULL) {
// some code
do_something_here();
}
/* empty (dummy statement) here */ ;
// more code
some_other_code_here();
You are right, the compiler considers them empty statements. They are not needed, I guess the programmer somehow thought they were.
The first semicolon (after the if-statement) is just an empty expression which does nothing. I fail to see any point of having it there.
The second semicolon (after the function) is an error since it is outside of any block of code. The compiler should give a warning.
These semicolons are not needed (as you said, they are empty statements). Your code compiles with gcc, providing that 'x' is defined (check http://www.codepad.org). There's no reason why a C compiler would refuse to compile your code.
I think that the author may have been going for something like:
if(condition for tbd block)
;
else {
//Some code here
}
which you might do if you were scaffolding code and still wanted it to compile. There's a good chance that it's just an error as Jon suggests though.
These semicolons are useless as others have pointed out already. The only thing I want to add is that IMO, these are optimized out anyway i.e., compiler doesn't generate any real code for these.
I'm currently working through the excercises in 'The C Programming Language'. Here's one of my solutions:
int c;
while ((c=getchar()) != EOF) {
if (c == ' ') {
while ((c = getchar()) == ' ')
{} // do nothing?
putchar(' ');
}
putchar(c);
}
I found some solutions here that are quite different to mine and use an extra variable to keep track of what's going on, whereas I just use a while loop to skip through all the spaces. My solution feels a bit messy, as it seems bit hackish to have a while loop with nothing between the curly braces. I was wondering if there are any good reasons not to do this? Thanks for any advice :-)
Not at all - I believe you'll find do-nothing loops like these in K&R, so that's about as official as it gets.
It's a matter of personal preference, but I prefer my do-nothing loops like this:
while(something());
Others prefer the semicolon to go on a separate line, to reinforce the fact that it's a loop:
while(something())
;
Still others prefer to use the brackets with nothing inside, as you have done:
while(something())
{
}
It's all valid - you'll just have to pick the style you like and stick with it.
I think it is perfectly acceptable.
I would either write it:
//skip all spaces
while ((c = getchar()) == ' ') {}
to make it obvious that this one line of code does one thing.
Or I would write it like this:
while ((c = getchar()) == ' ') {
//no processing required for spaces
}
so that it matches the rest of your code's format.
Personally, I am not a fan of the
while ((c = getchar()) == ' ');
format. I think it is to easy to overlook the semi-colon.
Your question "Is using a while block to do nothing a bad thing?" may also be answered in terms of wasting CPU cycles. In this case the answer is "No", since, the process will sleep while it waits for the user to input a character.
The process will wake only after a character is input. Then the test will occur and if the test passes, i.e. c == ' ', the process will go to sleep again until a the next character is entered. This repeats until a non-space character is entered.
Well if you really don't like the empty braces, you could refactor that inner loop into
while (c == ' ') {c = getchar();}
This costs one extra comparison though, so a do while loop would be better.
A while that does nothing probably is a bad thing:
while(!ready) {
/* Wait for some other thread to set ready */
}
... is a really, really, expensive way to wait -- it'll use as much CPU as the OS will give it, for as long as ready is false, stealing CPU time with which the other thread could be doing useful work.
However your loop is not doing nothing:
while ((c = getchar()) == ' ')
{}; // skip
... because it is calling getchar() on every iteration. Hence, as everyone else has agreed, what you've done is fine.
I don't think the procedure is, but your formatting is pretty weird. There's nothing wrong with:
/* Eat spaces */
while ((c = getchar()) == ' ');
(that is, indicate there's intentionally not a body)
The canonical way — used since time immemorial, have a look, eg, at the Lyons book — is
while(condition) // Here's the whole thing
; // empty body.
In fact, in general the 'semicolor on a separate line' convention is used for a null statement. You will, for example, occassionally see
if( condition-1)
;
else if (condition-2)
stmt;
else {
// do stuff here
}
It's a lot more uncommon, but shows up either where condition-1 is very complicated, so you don't want to negate it and chance confusion, or where the code has been hand-optimized within an inch of its life, so that you want the most common case first.
The
while(condition) ;
form is to be slavishly avoided, because that's a common and annoying typo: you should make it clear that you did it on purpose. Empty braces
while(condition){
}
or its variants, are also trouble because they either don't stand out enough, or worse lead to other typos.
I would favor:
while ((c = getchar()) == ' ') /* Eat spaces */;
I've also been known to have a procedure named DoNothing specifically for calling in cases like this. It makes it very clear that you really mean to do nothing.
While non-existent loop bodies are perfectly acceptable it should be VERY clear that it's intentional.
I've used code like this. I don't think there's really any reason not to use it if the situation warrants it.
I thinks no problem in it. You can use it, In many situations i prefer it.
Well, not really but it depends on your architecture.
if (dosomething()) { ; }
The above is going to constantly be pushing and popping from your local stack, which has a memory overhead. Also, you will also be flushing your processors' pipelines with noop operations.
An alternative option which hasn't been mentioned yet:
while(condition)
(void)0;
I really do not prefer to write my loops this way, but I had a TA last semester who did.