This question already has answers here:
Scope of variables in "for" loop
(2 answers)
New block scope for selection and iteration statement
(2 answers)
Closed 2 years ago.
The following program:
#include <stdio.h>
int main()
{
char i='u';
for (int i=0;i<=3;i++)
{
printf("%d\n",i);
}
return 0;
}
prints 0,1,2,3 in new lines, since the character variable i declared outside the for loop is "hid". But, the following program:
#include <stdio.h>
int main()
{
char i='u';
for (int i=0;i<=3;i++)
{
int i=8;
printf("%d\n",i);
}
return 0;
}
print 8 '4' times on new lines as if the variable i initialized as 8 has more priority than the variable i (counter) going from 0 to 3 .
The i in the for initialization and the i in the for loop are in the same block, but one seems to have more priority than the other. Does such a priority really exist and if yes, is there a defined order of priority?
What you're calling "priority" is actually referred to as scope.
Each variable and function has an enclosing scope in which the name is valid and in which it has a particular lifetime. If a variable in one scope has the same name as a variable at a higher scope, the variable(s) at the outer scope(s) is masked and only the one in the innermost scope is visible.
In the case of a variable declared in the initialization section of a for loop, these variables have a scope that is visible in the other parts of the for as well as the loop body. If the loop body is a compound statement, that starts another scope, and variables declared here will mask variables with the same name at higher scopes.
So in your second program you have three variables named i:
The scope of the first i is the body of the main function.
The scope of the second i is for statement.
The scope of the third i is the body of the for statement.
Such priority is defined by scoping rules:
The scope of any other identifier begins just after the end of its declarator and before the initializer, if any:
int x = 2; // scope of the first 'x' begins
{
int x[x]; // scope of the newly declared x begins after the declarator (x[x]).
// Within the declarator, the outer 'x' is still in scope.
// This declares a VLA array of 2 int.
}
unsigned char x = 32; // scope of the outer 'x' begins
{
unsigned char x = x;
// scope of the inner 'x' begins before the initializer (= x)
// this does not initialize the inner 'x' with the value 32,
// this initializes the inner 'x' with its own, indeterminate, value
}
unsigned long factorial(unsigned long n)
// declarator ends, 'factorial' is in scope from this point
{
return n<2 ? 1 : n*factorial(n-1); // recursive call
}
Related
#include <stdio.h>
int main()
{
int i;
for ( i=0; i<5; i++ )
{
int i = 10;
printf ( "%d", i );
i++;
}
return 0;
}
In this variable i is declared outside the for loop and it is again declared and initialized inside for loop. How does C allows multiple declarations?
The i outside the loop and the i inside the loop are two different variables.
The outer i will live for the entire duration of main.
The inner i will only live for the duration of one loop iteration.
The inner one shadows the outer one in this scope:
{
int i = 10;
printf ( "%d", i );
i++;
}
Due to shadowing rules, it is impossible to refer to the outer one while inside the aforementioned scope.
Note that it is impossible to declare two variables with the same name in the same scope:
{
int i = 0;
int i = 1; // compile-time error
}
Variables in one scope can mask variables at a higher scope.
In this example, the i defined inside of the loop masks the i defined outside. In the loop body, the printf prints the value of the inner i, which is 10. The i++ then operates again on the inner i setting it to 11.
When the loop hits the bottom and goes back up, the inner i goes out of scope. The second and third clauses of the for then operate on the outer i. When the loop body is entered again, a new instance of the inner i is defined and initialized to 10.
You should check out the following page for the definitions of the different type of scopes that variables can have in the C language.
http://aelinik.free.fr/c/ch14.htm
Your first int i is in the scope of the entire block, and your second int i only has scope from within that nested loop. Once outside the nested loop, the original block scope version of i is applicable again.
Here is small C program that I am trying to understand:
#include <stdio.h>
#include <stdlib.h>
typedef struct dm_user_params_t {
int x;
} dm_user_params;
dm_user_params xx;
void set_user_params(dm_user_params *yy) {
xx.x = yy->x;
}
int main() {
dm_user_params xx;
dm_user_params *yy;
yy = malloc(sizeof(dm_user_params));
yy->x = 217;
set_user_params(yy);
free(yy);
printf("2 %d" , xx.x);
return 0;
}
Output:
537340672
What should I do, so that value in xx.x should persist ?
Is reference is copied instead of value when I do xx.x = yy->x ? How to verify this ?
Your local variable xx is shadowing the global identical declaration (bearing the exact type & name)
set_user_params changes the global xx
Fix 1: remove the local variable. Also:
void set_user_params(dm_user_params *yy) {
xx.x = yy->x;
}
could be written:
void set_user_params(const dm_user_params *yy) {
xx = *yy;
}
so when you add more fields the set_user_params doesn't need to be updated.
Fix 2: remove the global variable and change prototype as is:
void set_user_params(dm_user_params *dest, const dm_user_params *src) {
*dest= *src;
}
then call like this set_user_params(&xx,yy);
The problem has nothing to do with yy or the free call.
Instead it's because you have two independent variables named xx. One is a global variable that the set_user_params function will use. The other is a local variable which the printf function will use. The local variable have not been initialized, so the value of it will be indeterminate.
The solution is to either remove the local variable. Or remove the global variable and pass a pointer to the local variable as an extra argument to the set_user_params function.
dm_user_params xx;
Within main() local variable xx is uninitialized whereas global xx is initialized . You are printing uninitialized value.
Delete the line
dm_user_params xx;
in your main and it will work.
You have two variables xx, one local and one global. You set the global one in your function set_user_params to 217, but later in your main you print the local one, which is not initialized and will result in undefined behaviour.
Try this:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int x;
} dm_user_params_t;
dm_user_params_t xx;
void set_user_params(dm_user_params_t *yy)
{
xx.x = yy->x;
printf("Got : %d \n",yy->x);
}
int main(void)
{
// dm_user_params_t xx; Note: Local object getting highest priority than global, that's why you are getting garbage value
dm_user_params_t *yy;
yy = malloc(sizeof(dm_user_params_t));
yy->x = 217;
set_user_params(yy);
free(yy);
printf("2 %d" , xx.x);
return 0;
}
The problem here is, the global xx outside main() is shadowed by the inner xx in main().
Quoting C11, chapter ยง6.2.1, Scopes of identifiers, (emphasis mine)
[...] If an identifier designates two different entities in the same name
space, the scopes might overlap. If so, the scope of one entity (the inner scope) will end
strictly before the scope of the other entity (the outer scope). Within the inner scope, the
identifier designates the entity declared in the inner scope; the entity declared in the outer
scope is hidden (and not visible) within the inner scope.
So, in your case,
printf("2 %d" , xx.x);
is making an attempt to access the uninitialized local variable xx.x, invoking undefined behavior.
Solution: Remove the local variable definition of xx from main().
Can a variable be used in an inner function if it was defined in the outer function? or should i modify the inner loop to take a third parameter which would be the array?
Example of the code i'm asking about?
perm_rec1 ( int nr_value , int N)
{
int array[];
secondFunction(int nr_value, int N)
}
The inner function:
secondFunction (int nr_value, int N)
{
int temp = array; //is This possible? Or third parameter?
}
Can a variable be used in an inner function if it was defined in the outer function?
C does not have nested functions, which is the only sense in which the "inner" and "outer" designations would make sense. When one function calls another, as in your example, it is the call that is "inside" the first function, not the called function.
In any event, variables declared at block scope, such as in your example, are visible only within the remainder of the lexical extent of the declaring block. They are not visible in the body of a function called from within that block -- not even if it is the same function, called recursively.
or should i modify the inner loop to take a third parameter which would be the array?
The most natural implementation would be, yes, to give the function a third parameter by which to provide (a pointer to the first element of) the array to that function.
There is no inner function here (nor there is in C). What you have is a function that calls another one; and no you can't access in the callee something that was defined in the caller except if you pass it explicitly as a parameter.
Interpreting what you need, you can use pointers to do that:
#include <stdio.h>
void test ( int *pointer, size_t size)
{
for (size_t i=0; i<size; i++)
{
printf("array[%zu] = %d\n", i, *pointer++);
}
}
int main(void) {
int array[] = { 1, 2, 3, 4, 5};
test(array, sizeof(array)/sizeof(array[0]));
return 0;
}
Any variable declared in the inner block shadows the outer variable declaration.
{
int a = 6;
{
int a = 9;
// won't affect the outer declaration
}
// value of a = 6 here
}
But as you are asking there cannot be any inner function in C. Only we can have inner blocks defined within braces.
Technically speaking, it is actually possible to misuse local variables to access the stack frame of a parent function, yes. But this is a very, very ugly solution, set aside platform-dependent. So just pass it as a parameter.
I have something like,
#include <stdio.h>
#include <stdbool.h>
int main()
{
int t,answer;
bool count;
long long int L;
scanf("%d",&t);
while(t>0)
{
answer = 0;
scanf(" %lld",&L);
bool count[L];
// .....restofthecode. NDA Constraint.
What would be the default value of all the elements of arr[x]?
Is it false always? Or true? Or any random value?
There is no type named boolean in C but there is _Bool and in stdbool.h a macro bool that expands to _Bool.
#include <stdbool.h>
#define X 42
bool arr[X];
arr elements have an initial value of false (that is 0) if declared at file scope and indeterminate if declared at block scope.
At block scope, use an initializer to avoid the indeterminate value of the elements:
void foo(void)
{
bool arr[X] = {false}; // initialize all elements to `false`
}
EDIT:
Now the question is slightly different:
long long int x;
scanf("%lld",&x);
bool arr[x];
This means arr is a variable length array. VLA can only have block scope, so like any object at block scope it means the array elements have an indeterminate value. You cannot initialize a VLA at declaration time. You can assign a value to the array elements for example with = operator or using memset function.
As per your code, in local scope
boolean arr[x];
itself is invalid. x is used uninitialized.
Just FYI, in global [file] scope, all the variables are initialized to 0. In local scope, they simply contain garbage, unless initialized explicitly.
EDIT:
[After the edit] All the variables in the arr array will have garbage value. It is in local scope [auto].
Why doesn't the following code give an error as i is defined multiple times as int i=10? Further,why isn't the iterating variable i affected? Why is there no conflict ? The output is 1010101010. How?
#include<stdio.h>
int main()
{
int i;
for(i=0;i<5;i++)
{
int i=10;
printf("%d",i);
i++;
}
}
Automatic variables are alive only in the scope {,} in which they reside.
You have two variables named i in your program:
The i declared in main has scope of entire main function.
While the i inside the for loop has scope only inside the loop.
Note that when you refer i inside the for loop the inner i shadows the i declared in the main.
int i=10; in for loop is only available inside the loop it doesn't know if it was previously defined outside the loop.
Scope of variable defined within a block of code is limited to that block only.
ie.,
int i=1;//outer i
{
int i=2;//inner i
printf("%d"&i);// this ll print 2
}
printf("%d"&i);// this ll print 1
same in for too., ie
int i=1;
for (int i=0;i<4;i++){
printf("%d",&i); // print 0 1 2 3
}
printf("%d",&i); // print 1
In your case every time you initializing inner i to 10 and printing it then you incremented inner i, so it everytime prints value of inner i you declared and initialized to 10
this is because of scope of variable
scope of variable lies within { to }
your first int i will be alive through out the main() while the int i inside for will be alive inside for loop only.
now why the output is 1010101010???
the simple explanation is when you enter for look your new i will be equal to 10, you print it then i++ makes it 11. again next time i = 10 you print it and i++ makes it 11 this continues for main() int i < 5 so five times you will get 1010101010.
hope it helps.....