What is a null statement in C? - c

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.

Related

What is the purpose of ";" at the end of for loop?

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.

why there is semicolon after loop while();

I am reading a code of my friend an I see this:
#include <stdio.h>
#include <conio.h>
void main()
{
char string1[125], string2 [10];
int i, j;
printf("\nstring 1: ");
gets(string1);
printf("\nNstring2 : ");
gets(string2);
i = 0;
while (string1[i] != 0)
{
j = 0;
while (string1[i++] == string2[j++] &&string1[i-1] != 0 && string2[j-1] != 0)
;//i dont know what it mean and why we can put ;after while loop
if (string1[i-1] != 0 && string2[j-1] == 0)
printf("\nfound at position %d", i-j);
}
getch();
}
why we can put ; after while loop , anyone can help?
The ; is just a null statement, it is a no op but it it the body of the while loop. From the draft C99 standard section 6.8.3 Expression and null statements:
A null statement (consisting of just a semicolon) performs no operations.
and a while statement is defined as follows from section 6.8.5 Iteration statements:
while ( expression ) statement
So in this case the statement of the while loop is ;.
The main effect of the while loop is here:
string1[i++] == string2[j++]
^^^ ^^^
So each iteration of the loop increments i and j until the whole condition:
string1[i++] == string2[j++] &&string1[i-1] != 0 && string2[j-1] != 0
evaluates to false.
Usually, in a while loop, you have initialization, a comparison check, the loop body (some processing), and the iterator (usually either an addition of an index, or a pointer traversal e.g. next), something like this:
index = 0 // initialization
while(index < 4) { // comparison, loop termination check
printf('%c\n', mystring[index]); // Some processing
index += 1; // iterate to next loop
}
Without at least the last item, you won't ever exit the loop, so normally the loop body has more than one statement in it. In this case, they use post-increments like this:
while (string1[i++] == string2[j++]);
This does the comparison (the ==) and the iteration (the post-increment ++) in the comparison statement itself, and has no body, so there's no reason to add any other statements. A blank loop body can be represented by just a semicolon.
Semicolon is like empty instruction. If we don't put any instruction after while or use loop while with {} we must use semicolon to tell compiler that all we want from while loop is doing this empty instruction.
That is called a semicolon. In programming standards, the ; signifies an end of statement, or in this case that it is a null statement. It is effectively a non operation in the body of the while loop, so it is not actually doing anything.

Undeclared identifier for [i] when creating variables dynamically

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.

In C why do you need a statement after a goto label?

I am writing some C code and in my code I have two nested loops. On a particular condition I want to break out of the inner loop and continue the outer loop. I tried to achieve this using a label at the end on the outer loop's code and, on the condition, goto that label. However gcc gives an error that I cannot have a label at the end of a compound statement. Why not?
Note 1: This is not a switch statement and that question has been answered elsewhere.
Note 2: This is not a question about style and whether I should or should not be using goto statements or conditional variables instead.
EDIT: People have asked for an example and I can give a slightly facile example of checking if an array is a subarray of another array
int superArray[SUPER_SIZE] = {...}, subArray[SUB_SIZE] = {...};
int superIndex, subIndex;
for (superIndex=0; superIndex<SUPER_SIZE-SUB_SIZE; superIndex+=1)
{
for (subIndex=0; subIndex<SUB_SIZE; subIndex+=1)
if (superArray[superIndex+subIndex] != subArray[subIndex])
goto break_then_continue;
// code that executes if subArray is a sub array
break_then_continue:
}
In the standard it's explicitly said that labels belong to a statement, therefore a simple semicolon (;) after your label can circumvent the problem you are running in to, since that counts as a statement.
There is even an example of the use of an "empty"1 statement in 6.8.3/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: ;
}
1 In the standard this is referred to as a null statement.
6.8.1 Labeled statements
Syntax
1 labeled-statement:
identifier : statement
case constant-expression : statement
default : statement
Notice that statement isn't optional in the above quotation.
open-std.org: n1124.pdf
You simply need to write:
label: ;
The semi-colon is an empty statement. You need it because the language is defined like that; you need to go to a statement, even if it is an empty one.
for (int i = 0; i < N; i++)
{
for (int j = 0; i < M; j++)
{
...
if (some_condition)
goto continue_loop1;
...
}
continue_loop1: ;
}
You can argue about the indentation on the label.
The label should point to a statement.
C mandates this:
(C99, 6.8.1 Labeled statements p4) "
Any statement may be preceded by a prefix that declares an identifier as a label name."
In your case you can use a null statement:
void foo(void)
{
goto bla;
bla:
;
}
Null statements perform no operation.
Or you can also use a compound statement (a block) if you have declarations:
void foo(void)
{
goto bla;
bla:
{
int x = 42;
printf("%d\n", x);
}
}

Any difference between these two while loops?

while ((R_SPI2SR & B_SPIF) != B_SPIF)
{
SERIAL_SERVICE_WDOG;
};
while ((R_SPI2SR & B_SPIF) != B_SPIF)
{
SERIAL_SERVICE_WDOG;
}
I like to know what is the purpose in putting semicolon..
The semicolon after the first loop is not a part of that loop at all. It is interpreted as a completely independent empty statement that sits between the loops. I.e. your actual loops are seen as absolutely identical by C language.
The statement executed by the while loop is the compound statement inside the curly braces. The semicolon is just a gratuitous empty statement. You could have written this loop as:
while ((R_SPI2SR & B_SPIF) != B_SPIF)
SERIAL_SERVICE_WDOG;
since the compound statement just has a single statement inside it, or as
while ((R_SPI2SR & B_SPIF) != B_SPIF)
{
SERIAL_SERVICE_WDOG;;;;;;;;;;;;;;;
};;;;;;;;;;;;;;
which of course is awful style.
An empty statement is used when you have a loop that needs no body.
/* Throw away remaining characters up to the end of line. */
while ( ( c = getchar() ) != '\n')
;
You want to watch out for the classic error of ending a loop prematurely:
int i = 1;
int j = 1;
while ( i < 10 ); /* The semicolon here ends the loop... */
j *= i++; /* ... so this statement is only executed once. */
Unnecessary semicolons are just clutter, so you should never use them.
the only different in the code is the additional semicolon.
but the compiled assembly are the same.

Resources