#include <stdio.h>
int main() {
int a,i,j;
FILE *fp,*fw;
fp=fopen("new.txt", "r");
fw=fopen("exam.txt", "w");
for (i=0; i<4; i++) {
int flag=0;
fscanf(fp,"%d",&a);
for(j=2;j<a;j++)
{
if(a%j==0){
flag=1;
}
}
}
if(flag==0){
fprintf(fw,"%d number is prime \n",a);
}
else
{
fprintf(fw, "%d number is not prime \n",a);
}
fclose(fp);
fclose(fw);
}
ı want to print to file exam.txt whether the numbers in file new.txt are prime or not but when ı run the code it always writing 'number is not prime' .
You are declaring flag inside the for loop. So it is not accessible outside the for loop. You need to declare it outside the for loop.
A declaration, like int flag=0;, only makes an identifier known (available for use) within a region of the source code. That region is called the scope of the identifier. Within int flag=0; inside the compound statement formed by { … }, its scope starts at the declaration and ends at the }.
Your if(flag==0) appears after that scope, so the identifier is not available for use at that point.
To make it available, move int flag=0; to earlier in the program, possibly just before the for statement.
The defined object also has a lifetime, which is the period of time during program execution that memory is reserved for it. Lifetimes are organized in classes called storage durations. An object defined inside a function without static or extern has automatic storage duration. For most objects with automatic storage duration, its lifetime begins when execution of its associated block starts and ends when execution of its associated block ends. If the object has a variable length array type, its lifetime starts when execution reaches its definition.
Related
I'm new to C. I cannot understand the result in following code. I use goto and jump the declaration of int a[N] array and int x. Although x is not initilized to 10, I can still get access to these variables.
#include <stdlib.h>
#include <stdio.h>
#define N 4
void printArray(int a[], int length) {
for (int i = 0; i < length; i++) {
printf("%d, ", a[i]);
}
printf("\n");
}
int main(void) {
goto done;
int a[N];
int x=10;
printf("x=%d\n", x);
done:
for (int i = 0; i < N; i++) {
a[i] = i;
}
printArray(a, N);
printf("x=%d\n", x);
return EXIT_SUCCESS;
}
result
0, 1, 2, 3
x=0
My question:
Why I can get access to these variables whose declarations have been jumped? How are variables declared in C? It seems that variable declarations are not run line by line.
Aside from "Variable Length Arrays (VLAs)", an automatic variable's "lifetime extends from entry into the block with which it is associated until execution of that block ends in any way." (§6.2.4) The initialization (if any) occurs a bit later, when the program passes through the declaration. It's legal to jump over the declaration if the program does not depend on the initialization of the variable. But regardless of whether the initialization will eventually happen, the variable exists from the moment your program enters the block, however that is done. (Jumping into a block from outside is also legal, and may also prevent initialization. But as soon as you're in the block, the variable exists.)
If the program attempts to read the value of an uninitialised variable, it receives an indeterminate value. (Most compilers attempt to detect the possibility that this might happen, but you'll need to enable warnings in order to see the report.)
The consequence of "hoisting" the lifetime of a variable to its enclosing block is that there is a portion of the program in which the variable exists but is not visible (since its scope starts where it is defined.) If you save the address of the variable and then jump back into this region of the program, you will be able to access the value of the variable through the pointer, which shows that scope and lifetime are distinct.
If the variable is a VLA, then it's lifetime starts at the declaration and the compiler will not allow you to jump over the declaration. VLAs cannot be initialised, so you must assign a value to every element in a VLA which you intend to access. Not all compilers implement VLAs. Your example does not show a VLA, since N is a macro which expands to an integer constant.
For objective info about the C standard, see rici's answer.
But I see you are asking how this behavior is possible from a C program, and remarking that:
It seems that variable declarifications are not run line by line.
In fact, most computer languages are not run line by line. There is almost always some kind of multi-line parsing step that happens beforehand. For example, even the Bash shell language is processed multiple lines at a time. When Bash finds a while loop, it seems to do extra parsing to make sure the done command is found before it runs any of the code in the while loop. If you don't believe me, try running this Bash script:
while [ 1 ]
do
echo hi
sleep 1
# file terminates before the expected "done" command that ends the loop
Similarly, a C compiler is capable of parsing your code, checking its syntax, and checking that your program is well-formed before it even executes a single line of your code inside any of your functions. When the compiler sees that you are using a or x, it knows what those things are because you declared them above, even if the execution of the program never passed through those lines.
One way that you could imagine that a compiler might work is that (after checking the validity of your code) it moves all the local variable declarations to the top of the function. So your main function might look like this in the internal representation in the compiler:
int main(void) {
int a[N];
int x;
int i;
goto done;
x = 10;
printf("x=%d\n", x);
done:
for (i = 0; i < N; i++) {
a[i] = i;
}
printArray(a, N);
printf("x=%d\n", x);
return EXIT_SUCCESS;
}
This could actually be a useful transformation that would help the compiler generate code for your function because it would make it easy for the compiler to allocate memory on the stack for all your local variables when the function starts.
Why doesn't this code give a redefinition error:
int main(void)
{
for (int i = 0; i < 2; i++)
{
int number = 5;
}
}
while this code does:
int main(void)
{
int number = 5;
int number = 5;
}
In the first code, the scope of number begins when execution reaches the opening of the for loop and ends when execution reaches the closing of the for loop. In this case, the body of the for loop is executed two times, and number is created and destroyed two times, and has two disjoint scopes. In the second code, the scope aren't disjoint as previous number is still persisting it's lifetime when the second one is defined, and they are in the same scope, so it's a re-definition error.
Redfinition errors are a compile-time issue, not a runtime issue. You don’t get a redefinition error in the loop because you only have one declaration for number within that scope.
In the second snippet you have two declarations for number within the same scope, hence the error.
Basically, creating a variable inside a loop will make the variable's scope stay in this very loop. "number" does not exist outside of your loop.
I'm trying to fully understand how static variables work in C. I understand that using the static keyword makes the lifetime of the variable equal to the duration of the program. The following example has one thing that confuses me though...
My static_test.c file:
#include <stdio.h>
void foo(){
static int counter = 0;
counter++;
printf("This function has been called %i times.\n",counter);
return;
}
int main(){
int i;
for(i=0;i<10;i++){
foo();
}
return 0;
}
When I first read this example it makes me wonder why the function doesn't print out 0 every time since we are assigning 0 to the static variable.
Is this because once a static variable is declared the compiler ignores another declaration of the same variable on the next calls to my foo() function?
Thanks!
Despite the use of =, this is an initialization, NOT an assignment. So it happens when the variable is initialized and not when the 'statement' is apparently 'executed'. Since it is a static variable, it is initialized once when the program starts, rather than every time the function runs.
Static variables are initialized exactly once at program start, before your function is ever called. The fact that it's a local variable doesn't affect this rule.
In addition, static storage class variables are automatically initialized to zero if not explicitly initialized; the = 0 in your program is superfluous.
From the C11 drafts standard (ISO/IEC 9899:201x), section 6.2.4 Storage durations of objects, paragraph 3:
An object whose identifier is declared … with the storage-class specifier static has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.
Yes, the compiler looks for an initial assignment after declaring a static variable and only executes it once, when the program starts.
This only happens when you declare the variable though. For example,
void foo(){
static int counter;
counter = 0;
counter++;
printf("This function has been called %i times.\n",counter);
return;
}
Would print 1 every time.
Static means the variable exists outside of the life time of the function. Think of it as a slightly clever global variable.
Following is the code, that I took as reference to understand how a sub scope (or) dummy scope (just {}) present within the function, impacts the structure of the stack frame.
#include <stdio.h>
int main()
{
int main_scope=0; /*Scope and life time of the variable is throughout main*/
{
//From below two statements I assume that there
//is no seperate "stack frame" created for just
//braces {}.So we are free access (scope exists) and
//modify (lifetime exists) the variable "main_scope"
//anywhere within main
main_scope++;
printf("main_scope++:(%d)\n",main_scope);
//I expected this statement to throw an error saying
//"Multiple definition for "main_scope".But it isn't????
int main_scope=2;
printf("Value of redefined main_scope:(%d)\n",main_scope);
}
printf("Finally main_scope in %s:(%d)\n",__FUNCTION__,main_scope);
return 0;
}
Sample output
main_scope++:(1)
Value of redefined main_scope:(2)
Finally main_scope in main:(1)
Based on the above behavior, I presume the following.
There is no stack frame creation for the scope {}.
By this way the auto variables, declared/defined in main and those within the sub scope {} share the same stack frame.
So the variables declared/defined in main are free to be accessed anywhere within the function (even within the sub scope).
On the other hand the variables declared/defined in the sub scope loses its scope out of the block.But its life time is valid as long as stack frame is present.
Question: If the above points are right, then why isn't the code failing when giving multiple definitions of the same variable, one within main and the other within {}.
The hardware stack is irrelevant here. It can grow only once for all local variables at function entry and shrink only once at function exit or it can grow and shrink every time a new local variable is defined and destroyed when the enclosing {} for it is left.
What's relevant is the "visibility" of variables.
int main_scope=0;
{
main_scope++;
printf("main_scope++:(%d)\n",main_scope);
// the main_scope variable that was assigned 0 is the most recent
// visible declaration of main_scope.
int main_scope=2;
// now, the previous declaration of main_scope is obscured by the new one,
// and so, you're going to access the new one
printf("Value of redefined main_scope:(%d)\n",main_scope);
}
printf("Finally main_scope in %s:(%d)\n",__FUNCTION__,main_scope);
// the previous scope inside {} is left, so, main_scope is going to be
// the one, to which we assigned 0
It is perfectly legal to define an object in an inner/sub-scope with the same name as in an outer/super-scope. The latter will be obscured for the duration of the {} scope.
Just for the reference, there are some other places, where variable definitions can occur, e.g. inside the first expression of the for(;;) statement: for (int i = 0; i < 10; i++) .... That variable i will only be visible inside the for's body, and you can hide it there as well by defining another i.
Local variable hides the outer variable main_scope.
int main()
{
int i=1;
{
int i=2;
printf("%d", i);
/* Whenever you use i here, it's always the local one that's used.
The outer i is hidden by the local i. But the local i will be deallocated
once the scope exits.*/
}
}
is perfectly legal in C. (Note that this is illegal in C++!)
In your example, certainly a stack frame is created for inner main_scope, but it'll be deallocated once program goes out that inner scope.
if a variable is defined in a block is it present in the block only or throughout the program?
for example
main()
{
int j=5;
{
int i=10
printf("%d",i);
}
printf("%d , %d ",i,j);
}
is it valid
main()
{
int j=5, *k;
{
int i=10
printf("%d",i);
}
k=&i
printf("%d , %d ",*k,j);
}
as variable remains in memory from the point of its declaration to the point wen function exits?
A non-global variable's scope is limited to the block it's defined in. Furthermore, for an automatic variable, once the block ends the variable's lifetime is over.
Consider this silly example:
void doit()
{
int *ps;
int *pa;
{
static int s = 1;
int a = 2;
ps = &s;
pa = &a;
}
// cannot access a or s here because they are out of scope
// *ps is okay because s is static so it's lifetime is not over
// *pa is not okay because a's lifetime ends at the end of the block
}
Your second printf line will not compile because i is not in scope.
It's only accessible within the block, so in your example the second printf() is illegal and will not compile.
Yes its scope is then limited to the block where it is located.
The scope of i is limited within the block where it is declared. In your case it is
{
int i=10
printf("%d",i);
}
Hence i is not accessible outside this scope
This question also relates to your question about local scope or an auto variable.
Scope can be defined as the module within which this variable is defined.
And a module may be a function or a file.
So you can declare an auto variable in a file - which would mean it can be accessed by every function in that file, or put another way - its scope is defined to be the file in this case.
If you declare the same variable as auto, but within a function, it would mean that it can only be accessed within that function - or its scope is defined to be the function in this case.
Think of auto as 'local' within a module (where module may be a function or a file).
In the example above, you have defined the scope by adding the braces, and therefore the scope of variable i is localised to within the braces, which is why you have limited access outside the braces.