Not sure what I've done here (pretty new to C, have done some Python, Arduino and Java before).
int main(void){
unsigned long int sum = 0;
unsigned int count = 0;
for(unsigned long int i = 1; i <= 100; i++)
if(i%3 != 0 && i%5 != 0)
printf("cond%d\n", i);
count++;
sum += i; // $$here$$
return 0;
When I compile the code, I get 'error undefined identifier: i' on line 10 (indicated with $$here$$
C does not use indentation to structure program control (such as to indicate that more-indented statements are controlled by a less-indented statement above them). To group statements under the control of an if or other statement, you must use braces:
if(i%3 != 0 && i%5 != 0)
{
printf("cond%d\n", i);
count++;
sum += i;
}
The compiler error occurs because, due to the lack of braces, the scope of the for statements ends after the printf statement. So no declaration for i is visible at the sum += i; line, and the compiler complains.
The compiler will ignore most indentation and white space. When authors use indentation in C source code, it is to aid humans, not the compiler.
(C grammar does not require any braces around the if statement to keep it within the for statement’s control, because the if statement and the following lines form a single statement, once braces are added as shown above. However, many people would add braces just around the if statement to illustrate explicitly that it forms the body of the for statement. I treat this contextually, judging what is clearer in each situation.)
Related
I want to know exactly, what is a null statement in C programming language? And explain a typical use of it.
I found the following segment of code.
for (j=6; j>0; j++)
;
And
for (j=6; j>0; j++)
From the msdn page:
The "null statement" is an expression statement with the expression missing. It is useful when the syntax of the language calls for a statement but no expression evaluation. It consists of a semicolon.
Null statements are commonly used as placeholders in iteration statements or as statements on which to place labels at the end of compound statements or functions.
know more: https://msdn.microsoft.com/en-us/library/1zea45ac.aspx
And explain a typical use of it.
When you want to find the index of first occurrence of a certain character in a string
int a[50] = "lord of the rings";
int i;
for(i = 0; a[i] != 't'; i++)
;//null statement
//as no operation is required
A null statement is a statement that doesn't do anything, but exists for syntactical reasons.
while ((*s++ = *t++))
; /* null statement */
In this case the null statement provides the body of the while loop.
or (disclaimer: bad code)
if (condition1)
if (condition2)
dosomething();
else
; /* null statement */
else
dosomethingelse();
In this case the inner else and null statement keeps the outer else from binding to the inner if.
From C11, §6.8.4.1, 6.8.3 Expression and null statements:
A null statement (consisting of just a semicolon) performs no
operations.
The standard also provides a couple of common uses of it:
EXAMPLE 2 In the program fragment
char *s;
/* ... */
while (*s++ != '\0')
;
a null statement is used to supply an empty loop body to the iteration
statement.
6 EXAMPLE 3 A null statement may also be used to carry a label just
before the closing } of a compound statement.
while (loop1) {
/* ... */
while (loop2) {
/* ... */
if (want_out)
goto end_loop1;
/* ... */
}
/* ... */
end_loop1: ;
}
A null statement doesn't DO anything, hence the solo ';'
so....this code block will do nothing 10x in C/C++
for(int i = 0; i < 10; i++){//execute the following 10 times
;//nothing aka "null statement"
}//end for
Sometimes the null statement serves. In the "old days" the math hardware might not return an integer value when you needed one, such as returning 0.999... as sin(pi / 2), (that is sin(90 degrees)).
int i, j, k;
i = something;
for(j = 1; (2 * j) <= i; j *= 2);
Computes in j the largest integer power of 2 less than i. Not very efficient for large i but useful if you could not trust Log functions to return an exact integer value.
My C++ compiler does not accept the null statement as a function body, but does accept the "empty statement" which I think is just an empty statement block "{}".
Whether C or java, null has a special significance.
Whenever there is a need of re-intializing of values to variavle, null serves the purpose.
If there is a String i, and we want it to add a char value through a loop, then first we have to intialize i with null.
I don't know a whole lot about C, but I understand the basics and as far as I can tell:
int main() {
if (1 == 1) printf("Hello World!\n");
return 0;
}
and
int main() {
if (1 == 1)
printf("Hello World!\n");
return 0;
}
and
int main() {
if (1 == 1) {
printf("Hello World!\n");
}
return 0;
}
are all precisely syntactically equivalent. The statement is true; the string is printed; the braces are (apparently) optional.
Sometimes, especially here on SO, I see something like the following:
int main() {
if (1 == 1)
printf("one is one\n");
printf("is this inside the if statement??/who kn0WS\n");
return 0;
}
By the power vested in CodeGolf, I have been led to believe that C is whitespace-agnostic; the lexical analyser breaks the tokens up into their component parts and strips whitespace outside strings.
(I mean, the whole reason for the semicolons-on-every-statement-thing is so the parser can strip \n, \t, literal spaces and still know where each statement ends, right??)
So how is it possible to unambiguously parse the previous bit of code (or perhaps someone can come up with a better example of what I mean), if whitespace is to be disregarded?
If C programmers want to write in whitespace-dependent Pythonic syntax, why do they write C, and why is it taught wherever C is taught that it's okay to write lexically ambiguous (both to me, a programmer, and the computer) statements like this?
if (1 == 1)
printf("one is one\n");
printf("is this inside the if statement??/who kn0WS\n");
The second printf() should never execute inside the if statement.
The reason being that the previous line ends with a semicolon, which indicates the end of the if-block to execute.
(I mean, the whole reason for the semicolons-on-every-statement-thing
is so the parser can strip \n, \t, literal spaces and still know where
each statement ends, right??)
So how is it possible to unambiguously parse the previous bit of code
(or perhaps someone can come up with a better example of what I mean),
if whitespace is to be disregarded?
Parsing example:
if (1 == 1) // if - ( and ) - statements (or block) follow, skip all whitespace
// no { found -> single statement, scan until ; (outside quotes / comments)
printf("one is one\n"); // ; encountered, end of if-block
Without braces, only one statement belongs to the if-block.
But, as said already, it's a good habit to use braces. If you later add a statement (a quick temporary printf() for example), it will always be inside the block.
Special case:
int i = 0;
while(i++ < 10);
printf("%d", i);
Here printf() will only execute once. Mark the ; at the end of while().
In case of an empty statement, it's better to use:
while(i++ < 10)
;
to make the intention clear (or, as an alternative, an empty block {} can be used as well).
In C, an if statement takes exactly statement after the truth expression, regardless of indentation. Normally this statement is indented for clarity, but C ignores indentation. In any case, there is no amiguity in any of your examples.
What is ambiguous, in C and in many other languages, is the "dangling else". For instance, suppose you have a nested if statement with a single else after the second one. It could group as:
if (expr)
if (expr)
statement
else
statement
Or it could group as:
if (expr)
if (expr)
statement
else
statement
The only difference between these two is how they're indented, which C ignores. In this case, the ambiguity is resolved by using the first interpretation, i.e., the else statement binds to the nearest preceding if statement. To achieve the second interpretation, curly braces are needed:
if (expr) {
if (expr)
statement
}
else
statement
However, even in the first case, it's a good idea to include the curly braces, even though they aren't required:
if (expr) {
if (expr)
statement
else
statement
}
tl;dr The only ambiguity is in how difficult it is for a human to read. From the compiler's perspective, the syntax is perfectly unambiguous.
There are only two (compilable and syntactically acceptable) possibilities after an if statement:
Braces, as in
if(x) {
DoFoo();
}
// or
if(x) { DoFoo(); }
In this case, whatever is in the {...} will execute if the condition is met.
No braces, as in
if(x)
DoFoo();
// or
if(x) DoFoo();
In this case, only the next statement will execute if the condition is met.
You are correct that C is whitespace-agnostic. As a result, omitting the braces can lead to some tricky bugs. For example, in this code, DoBar() will execute whether or not the condition is met:
if(x)
DoFoo();
DoBar();
Inconsistent use of braces can also easily result in invalid code. For example, this looks valid (at a glance) from a human perspective, but it's not:
if(x)
DoFoo();
DoBar();
else
DoBaz();
None of the examples you posted are ambiguous from the compiler's perspective, but the no-braces versions are confusing from a human perspective. Leaving out the braces frequently leads to hard-to-find bugs.
Without braces it is just the next statement after the if. The whitespace does not matter
It is good practice and makes life easier to always use the braces. Good indentation as well. Code is then easy to read and does not lead to errors when people add/remove statements after the if
Readability is the only ambiguity in the statement:
if (1 == 1)
printf("one is one\n");
printf("is this inside the if statement??/who kn0WS\n");
The only time the first statement following the if(...) statement should execute, is if it is evaluated TRUE.
Braces, {...} help to remove readability ambiguities,
if (1 == 1)
{
printf("one is one\n");
}
printf("is this inside the if statement??/who kn0WS\n");
but the syntax rules are still the same.
Opinions vary, but I always choose to use braces.
Not using them is fine at the time code is written. But down the road, you just know someone will come along and add another statement under the first and expect it to be executed.
In general, in a statement or a loop with a single instruction, the curly brackets are optionals; instead, if you have two or more instructions you have to add them.
For example :
for(i = 0; i < 2; i++)
for(j = 0; j < 4; j++)
If(...)
printf(..);
else
printf(..);
Is equivalent to :
for(i = 0; i < 2; i++)
{
for(j = 0; j < 4; j++)
{
If(...)
{
printf(..);
}
else
{
printf(..);
}
}
}
As you may note this is more something related to indentation of the code. Personally I don't use curly brackets if I have a single instruction as doing that will make your code shorter and cleaner.
Another reason to use braces is that a simple typo can bite you hard:
#include <stdio.h>
int main(void) {
if (0 == 1)
printf("zero is one\n"),
printf("is this inside the if statement?? /who kn0WS\n");
return 0;
}
Look carefully...
I found the following code:
int func_prim (int zahl) {
int count;
if (zahl < 0)
return -1;
for (count = 2; zahl % count != 0 && zahl >= count; count++);
if (count == zahl)
return 1;
return 0;
}
The point of function is to check whether a number is a prime number or not.
I don't understand why the for-loop has ; at the end:
v
for (count = 2; zahl % count != 0 && zahl >= count; count++);
Without that, the code doesn't work properly.
What is the explanation?
It means exactly the same as:
for(count = 2; zahl % count != 0 && zahl >= count; count++)
{
}
A for loop has the for keyword, followed by parentheses containing three optional expressions separated by semicolons, followed by a body which executes in each iteration of the loop.
The goal of the for loop in your example is to set the value of count, which will be compared to zahl in the if statement that follows. This is achieved in the semicolon-delimited expressions, so the loop body doesn't need to do anything.
Since the loop doesn't need to do anything, it uses the empty statement as its body.
If the ; at the end were omitted and no other changes were made, then the if statement after the for loop would itself become the body of the for loop. (That is not intended and would break the program, as you have observed.)
However, making one's loop body consist of a single ; on the same line is not the only way to write an empty loop body, nor is it probably the most sensible way to do so. It works perfectly well, but the problem is that other readers - and perhaps the same programmer, returning to the project later - may wonder if it was actually an error. After all, one types semicolons at the ends of lines quite often when coding in a C-style language, so it's easy to type an extra one where it doesn't belong.
The other problem is that, in code where a one-line loop with ; as its body is the chosen style, it is difficult to recognize when someone actually has made the mistake of putting a ; when one doesn't belong.
Therefore, these alternatives may be preferable:
putting the ;, indented, on the next line -- as sh1 suggests
writing the loop body as an empty block, { }, rather than an empty statement
making the loop body a continue; statement, which simply causes the loop to move on to its next iteration (which is the same as what happens when the loop body is empty) -- also as sh1 suggests
The semicolon at the end of the for-loop means it has no body. Without this semicolon, C thinks the if statement is the body of the for loop.
Syntax of for loop (iteration statement) is
for ( clause-1 ; expression-2 ; expression-3 ) statement
statement can be a null statement (;). C11 6.8.3 says
A null statement (consisting of just a semicolon) performs no operations.
In para 5 it gives an example
In the program fragment
char *s;
/* ... */
while (*s++ != '\0')
;
a null statement is used to supply an empty loop body to the iteration statement.
Same thing is happening in
for (count = 2; zahl % count != 0 && zahl >= count; count++);
; is used to supply an empty loop body to the for statement. Without ; the statement next to the for loop will be considered as its body and will be executed.
In addition to what the other excellent answers already say, I would like to point out that
for(count=2; zahl % count != 0 && zahl >= count; count++);
(that is, a for loop with an empty statement used to increment a "counter") is equivalent to
count=2;
while(zahl % count != 0 && zahl >= count)
{
count++;
}
that would make the objective of the code even clearer than some of the listed alternatives: if not comments are present, as in the presented case, a loop with an empty statement might confuse another programmer that has to mantain or use the code (as was the case with the OP here).
The context might help discerning the true scope of the statement, but between a for loop with an empty statement and a while loop with a statement, the latter requires less work to understand its scope.
The ; after the for loop simply means that the for loop won't do anything more than increase the counter count.
for Statement:
The for statement is a loop statement whose structure allows easy
variable initialization, expression testing, and variable
modification. It is very convenient for making counter-controlled
loops. Here is the general form of the for statement:
for (initialize; test; step)
statement
[...]
Null Statement:
The null statement is merely a semicolon alone.
;
A null statement does not do anything. It does not store a value anywhere.
It does not cause time to pass during the execution of
your program.
Most often, a null statement is used as the body of a loop statement,
or as one or more of the expressions in a for statement. Here is an
example of a for statement that uses the null statement as the body of
the loop (and also calculates the integer square root of n, just for
fun):
for (i = 1; i*i < n; i++)
;
Here is another example that uses the null statement as the body of
a for loop and also produces output:
for (x = 1; x <= 5; printf ("x is now %d\n", x), x++)
;
A null statement is also sometimes used to follow a label that would
otherwise be the last thing in a block.
In your case, the ; is the Null Statement of the for Statement:
int func_prim (int zahl) {
int count;
if (zahl < 0)
return -1;
for (count = 2; zahl % count != 0 && zahl >= count; count++)
;
if (count == zahl)
return 1;
return 0;
}
Without it, the if becomes the for statement:
int func_prim (int zahl) {
int count;
if (zahl < 0)
return -1;
for (count = 2; zahl % count != 0 && zahl >= count; count++)
if (count == zahl)
return 1;
return 0;
}
Therefore, behaving differently.
The for loop is there just to increase the value of count.
a for loop will (normally) have a body,
where the body is enclosed in braces { }
However, for a single statement body, the braces are optional.
; is an empty statement.
Combining the above it becomes obvious that the for loop executes until the condition becomes false.
The for loop is basically looping through all the numbers that are less than or equal to zahl but greater than 2 and storing it in the variable count. As it loops through all these numbers it is checking to see if zahl is divisible by count. If zahl is divisible by count, the loop is stopped. Otherwise, the loop is stopped when count equals zahl.
The if statement after the for loop checks to see if count is equal to zahl. If it is, then that must mean that the loop went through all the numbers less than zahl and greater than 2. This means that zahl is divisible by all the numbers less than itself and greater 2, which makes zahl prime.
It indicates the statement the for loop is used for. It can't be empty. At least it should include a single statement. ; is the empty statement which the iteration is done for.
This following code is supposed to encrypt a sentence using the ceasers cipher, it is still WIP i haven't accounted for spaces, lower case letters etc etc.
int main(int argc,string argv[])
{
int k = atoi(argv[1]);
string value = GetString();
int n = strlen(value);
for(int i = 0;i<n; i++);
{
char temp = value[i];
int conv = temp - (int)'A';
int cipher = (conv + k)%26;
char final = cipher + (int)'A';
printf("%c\n",final);
}
}
I get
caeser.c:15:23 use of undeclared identifier i.
which is on the line char temp = value[i];
Remove the semicolon at the end of the for line:
for(int i = 0;i<n; i++);
Declaring int i there makes it local to the for block, but because of the semicolon that is an empty block.
So in the following code block (between the { }) i is not declared because it does not belong to the for.
This will also fix the program not executing the body of the for more than once (which it would, if it compiled). If this had compiled the for loop would have looped until n but not execute anything. Then after that the code between the curly braces would have been executed with i == n (assumed that i is then visible to that code block). So your code would always execute with temp == '\0' (the terminating null in value) and always print the same cipher value.
ENCORE: (as explained in the comments, but here for completeness' sake)
The casts of character-literals to ints (int conv = temp - (int)'A';) are unnecessary for two reasons:
Contrary to what may seem intuitive character-literals are ints, not chars (this is different in C++, I believe)
But even if 1. weren't the case, a char is always smaller than an int and will thus always fit inside an int so it can safely be promoted.
Your problem is here:
for(int i = 0;i<n; i++);
^
The ; ends your for loop, it runs n times but performs no operation since the ; just ends a null statement. So the {} afterward is just a compound statement with it's own scope which does not include the declaration of i:
{
char temp = value[i]; // i does not exist here since it declared in for loop
// and it's scope ends with the for loop
//...
}
The C99 draft standard tells us that what you have after the for is a statement expression, section 6.8.3 Expression and null statements has the following grammar for expression statements:
expression-statement:
expressionopt ;
and in paragraph 3 tells us that the empty statment is just a null statement:
A null statement (consisting of just a semicolon) performs no operations.
For years, I've gotten in to the habit of not using the value of a for loop iterator after the loop exits. I could have sworn that I did this, because it used to produce a compiler warning, but after I was challenged in a recent code review, I was proven wrong.
For example, I always did this (NOTE: our code standards prohibit the use of the "break" keyword):
int i, result;
bool done = false;
for (i=0; i<10 && !done; i++) {
if (some_condition) {
result = i;
done = true;
}
}
// Value of i may be undefined here
Now, obviously the result variable could be removed, if I can rely on the value of i. I thought that because of compiler optimization, you could not rely on the value of the loop iterator. Am I just remembering a phantom teaching? Or is this the standard (specifically regarding GNU C)?
There is nothing wrong in C89, C99, or C11 to access the iteration variable after the for statement.
int i;
for (i = 0; i < 10; i++) {
/* Some code */
}
printf("%d\n", i); // No magic, the value is 10
From C99, you can use also a declaration as the first clause of the for statement, and in that case of course the declared variable cannot be used after the for statement.
Different languages have different rules. In Pascal, the compiler is allowed to optimize away storing the loop index after the final increment, so it might be the first loop-terminating value or it might be the last valid value.
There are plenty of usage cases where the for loop is used for nothing else but advancing the iterator. This can be seen in some implementations of strlen (though admittedly there are other ways to do strlen), and other sorts of functions whose goal it is to find a certain limit:
/*find the index of the first element which is odd*/
for (ii = 0; ii < nelem && arry[ii] % 2 == 0; ii++);
As mentioned, the point of confusion may come from constructs where the iterator itself is defined within the for statement.
In general for statements are very very powerful, and it's unfortunate that they're usually never utilized to their full potential.
For example, a different version of the same loop can be written as follows (though it wouldn't demonstrate the safety of using the iterator):
#include <stdio.h>
int main(void)
{
int cur, ii = 0, nelem, arry [] = { 1, 2, 4, 6, 8, 8, 3, 42, 45, 67 };
int sum = 0;
nelem = sizeof(arry) / sizeof(int);
/* Look mom! no curly braces! */
for (
ii = 0;
ii < nelem && ((cur = arry[ii]) %2 == 0 ||
((printf("Found odd number: %d\n", cur)||1)));
ii++, sum += cur
);
printf("Sum of all numbers is %d\n", sum);
return 0;
}
In this particular case, it seems like a lot of work for this specific problem, but it can be very handy for some things.
Even though the value of that for loop's control variable is well defined, you might have been told to avoid using the for loop's control variable after the for loop because of the way scoping of that variable is handled, and especially because the handling has changed of the history of C++ (I know this question is tagged "C", but I think the rationale for avoiding using for loop control variable after the loop may have origins in this C++ history).
For example, consider the following code:
int more_work_to_do(void)
{
return 1;
}
int some_condition(void)
{
return 1;
}
int foo()
{
int i = 100;
while (more_work_to_do()) {
int done = 0;
for (int i = 0; i < 10 && !done; i++) {
if (some_condition()) {
done = 1;
}
}
if (done) return i; // which `i`?
}
return 1;
}
Under some old rules of scoping for the i declared in the for loop, the value returned on the statement marked with the comment "which i" would be determined by the for loop (VC++ 6 uses these rules). Under the newer, standard rules for scoping that variable, the value returned will be the i declared at the start of the function.
While I can't possibly know how your habit came to be, I can tell you how my habit to do the same did. It was by seeing code like this:
for (i=0u; (i<someLimit) && (found != TRUE); i++)
{
if (someCondition) found = TRUE;
}
foundIndex = i-1;
Basically, code like this is written when the break keyword is disallowed by some coding rules, e.g. based on MISRA. If you don't break out of the loop though, the loop will usually leave you with an "i" which is off by one from what you care for.
Sometimes, you can even find this:
for (i=0u; (i<someLimit) && (found != TRUE); i++)
{
if (someCondition) found = TRUE;
}
foundIndex = i;
This is just semantically wrong and can be found when the "forbid break keyword rule" is introduced into an existing code base which is not sufficiently covered by unit tests. May sound surprising, but it's all out there...