Reputation: 13
I've just began my journey in coding and i've been using cs50's IDE. everytime I declare an integer in the main body of do function, I get an error for using undeclared indentifier when I try using the same integer in the body of while function, is this not allowed? if yes, why so?
Here's the code for reference -
do{
int n = get_int("Height: ");
}
while(n < 1 || n > 8);
Upvotes: 1
Views: 113
Reputation: 794
The answers previous given are all good but you might have noticed a cautionary tale from all this. There is still a lot of code around that uses the C89 and before conventions, that has subsequently been added to modern projects. So beware of the following:
void my_old_function(int val)
{
/* define old C89 variables, often including i,j, or k, usually unitililized. */
int i;
for (i=0; i<val; i++)
{
/* our legacy code */
}
// some modern edit in C99 or after
do {
int i = 0;
// more new code
i++;
} while(i < val); // not what you think it is !!!!
}
I have come across this code before. Crazy hard to find when the function is more that 70 or 80 lines (page length).
As a personal reminder to myself when dealing with inherited code, I usually do a quick scan looking for uninitialized automatics, which were common back in the day, and move them or given them better names.
Upvotes: 0
Reputation: 2851
Caution: This answer shows an obscure construction.
If you are using GCC, check out this library. You can write something like this:
do(int n){
n = get_int("Height: ");
}
while(n < 1 || n > 8);
Upvotes: 0
Reputation: 67713
Since C99, you can declare automatic variables in any scope, including nested block scopes like the one you show.
However, the variable declared only exists inside that scope. At the closing brace ... it vanishes.
So, the reason you get an undeclared identifier error in the while
statement is that the identifier ceased existing at the }
immediately before the while
.
For reference:
void foo(int a) /* a will exist for the entire body of the function */
{
int b = 2 * a; /* so will b */
/* c is introduced at the start of the for statement ... */
for (int c = a; c < b; ++c)
{
int d = c; /* d is initialized and destroyed on each iteration */
} /* ... but c lasts until the end of the whole for statement,
which is here */
do
{ /* d will be initialized on every iteration */
int d = bar(); /* just like the (unrelated) d in our for loop above */
} /* and disappear at the end of each iteration */
while (d != a); /* ERROR - d doesn't exist here */
} /* a and b finally go out of scope */
FYI. in C89 - 99, you had to declare variables at the start of a block scope (typically the top-level function scope), after the opening {
but before any other statements. This isn't true any more, but you may still see old code in the old style.
Upvotes: 0
Reputation: 310910
The body (sub-statement) of the do-while statement forms a block scope. All that is declared within this block scope have the life-time limited by the bounds of the block (if not have the storage specifier static). But in any case such a declaration is invisible outside the block. So the variable n declared in this do while loop
do{
int n = get_int("Height: ");
}
while(n < 1 || n > 8);
is not alive outside the body (sub-statement) of the loop.
You have to declare the variable before the loop like
int n = 0;
do{
n = get_int("Height: ");
} while(n < 1 || n > 8);
According to the C Standard (6.8.5 Iteration statements) the do-while statement is defined like
do statement while ( expression ) ;
and
5 An iteration statement is a block whose scope is a strict subset of the scope of its enclosing block. The loop body is also a block whose scope is a strict subset of the scope of the iteration statement.
Upvotes: 2
Reputation: 67476
Yes you can. You can define them in any block of code including complex statement.
Bear in mind that the scope of those variables is the block they are declared in so in your case the do ... while() loop.
Upvotes: 0