About a static value in function's parameter in C - c

what should be the output of this code below? and why?
I am not sure if the int i declared in the main function acts like a local variable, or not.
static int i = 3;
void f(int*j){
j++;
}
int g(int* j){
return i+=*j;
}
void h(int j, int k){
printf("%d,%d,%d\n", i,j,k);
}
int main(){
int i = 3;
int j = 5;
int *p = &i;
f(&i);
f(p);
for(;i<5;i++){
*p = g(p);
}
h(i,j);
return 0;
}

These calls of the function f
f(&i);
f(p);
have no effect.
Within the function g there is changed the global variable i
int g(int* j){
return i+=*j;
}
As the function is called in the loop
for(;i<5;i++){
*p = g(p);
}
one time for i equal to 3 then the global variable i will be equal to i + 3 = 6. The local variable i will be equal to the returned value of the global variable i (equal to 6) from the function and then will be incremented in the loop. So after exiting the loop it will be equal to 7..
This call
h(i,j);
outputs the global variable i and passed as arguments the local variables i and j. So its output will be 6,7,5.

Related

Passing pointer to function value not changing [duplicate]

This question already has answers here:
Changing address contained by pointer using function
(5 answers)
Closed 4 years ago.
#include<stdio.h>
void foo(int*);
int main()
{
int i = 97, *p = &i;
foo(p);
printf("%d ", *p);
getch();
}
void foo(int *p)
{
int j = 2;
p = &j;
printf("%d ", *p);
}
Output is 2 97
Why not 2 2 ?
pointer p holds the address of j now so why 97 is printed ?
You can imagine the function call and its definition the following way. For clarity I'll rename the function parameter as q.
foo(p);
void foo( /*int *q*/ )
{
int *q = p;
int j = 2;
q = &j;
printf("%d ", *q);
}
As it is seen the function parameter (in this case q) is a local variable of the function that is initialized by the value of an argument (in this case by the value of the argument p)
So any changes of the local variable (q) do not influence on the original argument (p).
After exiting the function the local variable will not be alive.
If you want to change the argument itself you should pass it by reference. For example
void foo( int **p )
{
int j = 2;
*p = &j;
printf("%d ", **p);
}
However after exiting the function the original argument/variable p will be invalid because it stores the address of a non-alive local variable of the function j.
So an attempt to access the memory that was occupied by the function's local variable j results in undefined behavior of the program.
You could make the program correct by declaring the local variable j as having static storage duration. For example
void foo( int **p )
{
static int j = 2;
*p = &j;
printf("%d ", **p);
}
and call the function like
foo(&p);
In foo, you assign a new value to p. However this is a copy of the value of p in main, so the change is not visible in main.
If you dereferenced p, then it would change the value if i in main:
void foo(int *p)
{
*p = 2;
printf("%d ", *p);
}
p = &j;
just changes the value of the local variable p. This has no effect on the caller's p variable (because p was passed by value) or the variable that p previously pointed to (because you didn't indirect through it). If you want to change the caller's data, write:
*p = j;
Go through the above code line by line. Here I have written comments as control passes through each of the lines...
#include<stdio.h>
void foo(int*);
int main()
{
int i = 97, *p = &i; //Lets assume i has address 2000
foo(p); //p contains 2000 which is passed to foo. go to foo at 1.
printf("%d ", *p); // when control comes back no change to p it
//still points to 2000 which stores 97
getch();
}
void foo(int *p) 1: // in foo another local variable p is created.
//Let's call this lp. lp has now address 2000. i.e lp
//and p both point to i but one locally exists in a
// function and will be destroyed when control comes out
// of the function
{
int j = 2;
p = &j; // now local p i.e lp points to another var j
// address. Suppose lp has address 3000 now.
printf("%d ", *p); //val at address in lp is 2
}

How to modify a local variable of one function from other function?

int main ()
{
int a, b;
call(&b);
printf("%d, %d",a , b);
}
void call(int *ptr)
{
}
Desired output:
50, 100
How to write the call function so as to modify both the variables to get the desired output??
Not sure where the values 50 and 100 are coming from or exactly what you are asking but maybe this will help with your question.
Since C is pass by value you need to send pointers to actually change the value inside another function.
Since the call function will have pointer values you need to dereference the pointers before changing the value.
Here is an example:
void call(int *a, int *b)
{
*a = 50;
*b = 100;
}
int main()
{
int a, b;
call(&a, &b);
printf("%d, %d\n", a, b);
}
While we are exploring the many ways this output could be achieved, consider that the function could store state in a static variable:
#include <stdio.h>
void call(int *ptr);
int main(void)
{
int a, b;
call(&a);
call(&b);
printf("%d, %d\n",a , b);
}
void call(int *ptr)
{
static int store = 0;
store += 50;
*ptr = store;
}
Program output:
50, 100
Note that you may also be able to do this as follows, without any modifications to main(). But be warned that this method invokes undefined behavior! It is undefined behavior to write to a location past the end of an array object, and in the case of a and b, these are considered to be array objects of size 1. Here we are assuming that this write will work, and that a and b are stored next to each other in memory. We further assume that a has the higher address in memory.
I would say that you should never do this, but I can see no other way to modify a from the function call() without knowing the address of a. You have been warned.
void call(int *ptr)
{
*ptr = 100;
*(ptr + 1) = 50;
}
Try something like this:
void call(int *ptr)
{
*ptr = 100;
}
int main ()
{
int a, b;
a = 50;
call(&b);
printf("%d, %d",a , b);
}
See demo
Maybe you want this:
int main ()
{
int a, b;
call(&a, &b);
printf("%d, %d",a , b);
}
void call(int *ptr1, int *ptr2)
{
*a = 50;
*b = 100;
}
To change a local variable in function a by calling function b you have two options.
1) Let function b return a value that you assign to the variable in function a. Like:
int b() {return 42;}
void a()
{
int x = b();
printf("%d\n", x);
}
This does, however, not seem to be what you are looking for.
2) Pass a pointer to the variable to function b and change the variable through that pointer
void b(int* p) // Notice the * which means the function takes a pointer
// to integer as argument
{
*p = 42; // Notice the * which means that 42 is assigned to the variable
// that p points to
}
void a()
{
int x;
b(&x); // Notice the & which means "address of x" and thereby
// becomes a pointer to the integer x
printf("%d\n", x);
}
int main()
{
int a,b;
call(&b);
printf("%d, %d\n", a,b);
}
int call(int *ptr)
{
int *m;
m = ptr++;
*ptr = 50;
*m = 100;
}

Pointer as a parameter in C

Let's say a have a pointer as a parameter, why doesn't it's value remain modified after the and of a function, and i have to use this syntax :
void function_name (int **p)
{
// code
}
and in main() :
int *v;
function name (&v);
I want to specify that i use a pointer to a struct type as a parameter.
C passes arguments by value. If you want to modify something in a function and make the modification take effect in the calling function, a pointer to the variable in the calling function has to be passed. Otherwise, any changes made to the variable in a function are only local changes and does not affect the value of the variable in the calling function.
Let's start with an int type variable.
void foo(int x)
{
x = 10;
}
int main()
{
int a = 100;
foo(a); // Value of a does not change in this function
}
In the above program, the value of a remains 100 in main. The line
x = 10;
in foo only affects the value of the variable in foo. To make the change in foo affect the value in main, you'll need to pass a pointer to a.
void foo(int* x)
{
*x = 10;
}
int main()
{
int a = 100;
foo(&a); // Value of a changes in this function
}
Take that analogy to a pointer.
void bar(int* x)
{
x = malloc(10*sizeof(int));
}
int main()
{
int* ptr = NULL;
bar(ptr); // Value of ptr does not change in this function
}
bar allocates memory for an array of 10 ints and assigns the memory to x but that change is local. main does not see it. In main, ptr is still NULL. To make the change in bar affect ptr, a pointer to ptr has to be passed to bar.
void bar(int** x)
{
*x = malloc(10*sizeof(int));
}
int main()
{
int* ptr = NULL;
bar(&ptr); // Value of ptr changes in this function
}
In C, arguments are passed by value. This means that when you pass an argument to a function, a copy of that variable is made. For example
int main()
{
int x = 6;
repchar(x, 'r');
printf("%d\n", x);
return 0;
}
void repchar(int n, char c)
{
while (--n >= 0)
putchar(c);
}
This program prints the letter r six times, and then at the last printf, prints out 6, not -1. The reason is that when repchar was called, x was copied. That way, when repchar decrements n, the caller's copy is not changed.
If we passed a pointer, however, n would be modified.
int main()
{
int x = 6;
repchar(&x, 'r');
printf("%d\n", x);
return 0;
}
void repchar(int *n, char c)
{
while (--(*n) >= 0)
putchar(c);
}
Instead of the variable being copied, now the address of the variable is being copied. Inside of repchar, *n is being counted down. This accesses the value that is being referenced by n, which is the same address as x and decrements it. As a result, the last printf will give -1.

Life of a variable defined in a function other than main

Here's a code written in c
#include<stdio.h>
int foo()
{
static int a=0;
a=a+1;
return a;
}
int main()
{
foo();
foo();
printf("%d",foo());
}
I've compiled this code using gcc11 in eclipse IDE and I've got 3 as my output.
Here's what I think should happen which leads me to the output as 1 not 3.
Function call-1: The main function calls the function foo and the
control goes to the function foo then the variable 'a' in foo is
created with an initial value of zero then it is incremented by
one and this incremented value (1) is returned to the main function. At this step the variables created for the function foo should have been destroyed.
Function call-2: Same as Function call-1:
Function call-3: Same as Function call-1:
In the end the value printed by the printf function in main should have been 1.
Why the output of the program is 3?
Try this with more printing.
#include<stdio.h>
int foo()
{
static int a=0;
a=a+1;
printf("a is now: %d",a);
return a;
}
int main()
{
foo();
foo();
printf("%d",foo());
}
You will notice that the variable a is initialised just the once and its value is retained across function call invocations.
See here: http://en.wikipedia.org/wiki/Static_variable
static variables are not destroyed when the function returns. Remove that keyword and it will work as you expected.
Edit:
The static variable is only present in the scope of its own function. You can create other variables with the same name (static or otherwise) in other functions.
void foo()
{
static int a = 0;
a++;
printf("%d\n", a);
}
void bar()
{
int a = 10;
a++;
printf("%d\n", a);
}
void baz()
{
static int a = 100;
a++;
printf("%d\n", a);
}
int main()
{
foo();
bar();
baz();
foo();
bar();
baz();
return 0
}
This will print:
1
11
101
2
11
102
Here, the variable a is a Static Variable.
Although the scope of variable has to be ended after the complete execution of function. But the Static variable has Scope through out the program and they are not deleted throughout the program.
if it was
int a;
in the place of
static int a;
The result would have been different.
Static variable inside a function keeps its value between invocations.
see the below example for difference between static and normal variable.
void sample()
{
int nv = 10;//nv refers normal variable.
static int sv = 10;//sv refers static variable.
nv += 5;
sv += 5;
printf("nv = %d, sv = %d\n", nv, sv);
}
int main()
{
int i;
for (i = 0; i < 5; ++i)
sample();
}
output:
nv = 15, sv = 15
nv = 15, sv = 20
nv = 15, sv = 25
nv = 15, sv = 30
nv = 15, sv = 35

How to get the information from a pointer [duplicate]

This question already has answers here:
Returning Arrays/Pointers from a function
(7 answers)
Closed 9 years ago.
Here is my code:
int *myFunction()
{
int A[3] = {1,2,3};
return A; //this will return the pointer to the first element in the array A
}
int main (void)
{
int A[3];
A = myfunction(); //A gets the return value of myFunction
for(int j=0; j==2; j++)
{
B[j] = 2* A[j]; //doubles each value in the array
}
printf("%d",B);
return 0;
}
But this does not work because the A that is returned is not the actual vector. How do I get the actual vector {1,2,3} in the main function?
The function myFunction allocates A, but this allocation only exists within the scope of the function. When the function returns the memory holding A is destroyed. This means that the function is returning a pointer to memory that has not been un-allocated.
The problem is that the variable A does not persist outside the function. You could use a global variable or pass a pointer to the buffer into myFunction
Global variable method:
static int A[3];
int* myFunction()
{
A[0] = 1; A[1] = 2; //etc
return A;
}
In this example, because A is a global, the memory pointed to by A persists throught your program's entire life time. Therefore it is safe to return a pointer to it...
As a side note, global variables should probably not be used in this way... it's a little clunky. The use of the static keyword means that A will not be accessible outside of this module (C file).
Pointer method:
void myFunction(a[3])
{
a[0] = 1; a[1] = 2; //etc
}
int main()
{
myA[3];
myFunction(myA);
// and continue to print array...
}
In this example the main() function allocates myA. This variable exists whilst the function is executing (it's an automatic variable). A pointer to the array is passed into the function, which fills the array. Therefore the main() function can get information from myFunction().
Another way to make the variable myA persist would be to allocate it on the heap. To do this you would do something like int *myA = malloc(sizeof(int) * NUMBER_OF_INTS_IN_ARRAY. This memory will then persist until you specifically desctroy it using free() or you program ends.
int A[3] = {1,2,3}; is being created on the stack, this is, it is a local array and it's memory can be used again after myFunction executes. You have to either make int A[3] static within myFunction or by placing it outside of all functions. Another option would be to create int A[3] within main and pass the address of A to myFunction so myFunction can directly modify the contents of A.
As is, your code isn't close to working anyway... your for loop is broken, you have undefined variables in main, you have function name mismatches, and your print isn't going to do what you want anyway...
The big problem as that you've got undefined behavior going on, you can't access A[] outside of the function where it was locally defined. The easiest way to rectify that is to use dynamic memory, malloc() some memory for A in your myFunction then use the values in main and free() the memory when you're done.
Here's the example fixing your other syntax issues:
int *myFunction()
{
int *A;
A = malloc(3 * sizeof(int));
A[0] = 1;
A[1] = 2;
A[2] = 3;
return A;
}
int main (void)
{
int *A = myFunction(); //A gets the return value of myFunction
int B[3] = {0, 0, 0};
int j;
for(j=0; j<3; j++)
{
B[j] = 2* A[j]; //doubles each value in the array
}
free(A);
printf("%d",B[0]);
return 0;
}
Pass the array to be filled as argument to the initisliser function along with its size:
size_t myFunction(int * A, size_t s)
{
int A_tmp[3] = {1,2,3};
size_t i = 0;
for (; i < s && i < sizeof(A_tmp)/sizeof(A_tmp[0]); ++i)
{
A[i] = A_tmp[i];
}
return i;
}
Then call it like so:
int main()
{
int myA[3];
size_t s = sizeof(myA)/sizeof(myA[0]);
size_t n = myFunction(myA, s);
if (n < s)
fprintf(stderr, "Caution: Only the first %zu of %zu elements of A were initialised.\n", n, s);
// and continue to print array...
}
#include <stdio.h>
int (*myFunction(void))[3]
{
static int A[3] = {1,2,3};
return &A;
}
int main (void){
int (*A)[3], B[3];
A = myFunction();
for(int j=0; j<=2; j++)
{
B[j] = 2 * (*A)[j];
}
for(int j=0; j<3;++j)
printf("%d ", B[j]);
return 0;
}

Resources