Why the output is not 0,1.Why it is 0,2.? - c

#include<stdio.h>
void f(int *p, int *q)
{
p = q;
*p = 2;
}
int i = 0, j = 1;
int main()
{
f(&i, &j);
printf("%d %d \n", i, j);
getchar();
return 0;
}
This code prints 0,2,why it does'nt print 0,1 because after *p=2 the value of j is assigned 1 right?can anyone help me

Inside f you are assigning the pointer p the pointer value of q.
Means - after p = q;, both p and q point to the same int which is j.
That's why you get 0,2.

"after *p=2 the value of j is assigned 1 right?"
No, function f() ends at the closing } brace, and
j was assigned the value of 1 before main() begins.
The line
int i = 0, j = 1;
could equally well be further up, before function f().

"because after *p = 2; the value of j is assigned by 1 right?"
No. You seem to confuse here something very hard in terms of control flow and scope. The definition of f is placed before the definitions of the global variables i and j.
That doesn't mean that the global variables get assigned after the function.
int i = 0, j = 1;
are definitions of i and j (declaration with immediate initializations) at global scope, not assignments.
The value of j 2 after the call to f is correct because:
j is passed by reference to f and its address is assigned to the pointer parameter q.
The value of the pointer q is assigned to the pointer p.
p is dereferenced then which points to j in the caller and assigns 2 to j.

Here is what happens:
statement i j p q
-----------------------------------------
int i = 0, j = 1; 0 1 - -
f(&i, &j); 0 1 &i &j
p = q; 0 1 &j &j
*p = 2; 0 2 &j &j
printf("%d %d \n", i, j); 0 2 - -

Related

Why is the output of the following program 2 97 and not 2 2?

In the following code why doesn't the address of j gets overwritten in p when we call the foo function?
#include <stdio.h>
int main()
{
int i = 97, *p = &i;
foo(&i);
printf("%d ", *p);
}
void foo(int *p)
{
int j = 2;
p = &j;
printf("%d ", *p);
}
You are printing with foo - which sets p to 2, then you call a print to p, which is still set to 97 in that scope. foo does not set p globally.
Because p in main is another variable than p in the function. Consequently, even if p is changed inside the function, the value of p in main is still the same and still points to 97.
In more details:
int main()
{
int i = 97, *p = &i; // i is 97 and p points to i
foo(&i);
printf("%d ", *p); // This prints what p points to, i.e. 97
}
void foo(int *p)
{
int j = 2; // Here p still points to i in main
p = &j; // Now p points to j, i.e. the value 2
printf("%d ", *p); // So this prints 2
}
Just to repeat: The important thing is that p in main and p in foo are two different variables.
If you want the program to print 2 2 you can change the function to:
void foo(int *p)
{
int j = 2;
*p = j; // Change this line. This will change i in main
// and thereby also the value that p in main points to
printf("%d ", *p);
}
Below are the steps:
int main()
{
int i = 97;
int* p = &i; // 1. p points to i, i is 97.
foo(&i); // 2. Pass the address of i by value.
printf("%d ", *p); // 6. Print the value of i as neither p nor i have not changed inside foo().
}
// I've renamed the parameter name from p to q for clarity. q is local to
// foo() only; changes made to q are only visible within foo().
void foo(int* q)
{ // 3. q contains a copy of i's address.
int j = 2;
q = &j; // 4. q is set to the address of j.
printf("%d ", *q); // 5. Print the value of j.
}
If you would have done *q = 2 inside foo() you would have changed i's value to 2. That's because q contains the address of i.
The p in main is a different object in memory than the p in foo. Writing to one has no effect on the other. If you want foo to update the value of p in main, then you must pass a pointer to p:
#include <stdio.h>
int main()
{
int i = 97, *p = &i;
foo(&p);
printf("%d ", *p);
}
void foo(int **p)
{
int j = 2;
*p = &j;
printf("%d ", **p);
}
WARNING - doing this will invoke undefined behavior, since p will point to an object that no longer exists - once foo exits, j no longer exists, and p will be an invalid pointer. You may get the output you expect, or you may not.
In order for a function to write to a parameter, you must pass a pointer to that parameter:
void foo( T *ptr )
{
*ptr = new_value(); // updates the thing ptr points to
}
void bar( void )
{
T var; // var is an instance of T
foo( &var ); // have foo update the value of var
}
This is true for any non-array type T, including pointer types. If we replace T with the pointer type P *, we get
void foo( P * *ptr )
{
*ptr = new_value(); // updates the thing ptr points to
}
void bar( void )
{
P * var; // var is an instance of P *
foo( &var ); // have foo update the value of var
}
The semantics are exactly the same - the only thing that's changed is that var starts out as a pointer type.
Things get weird with array types, which we're not going to go into quite yet.

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
}

Tricky C function testing knowledge static, global, local variables and pointers

Disclaimer: Yes this is a homework problem. I'm having a particularly difficult time understanding what the function f2 does.
#include <stdio.h>
int i = 10; /* global variable */
int j = 1; /* global variable */
/* Forward function declarations */
void swap(int, int); int f1(int);
void f2(int, int *);
int main()
{
{
int i = 1;
int j = 10;
swap(i,j); printf("i = %d j = %d\n", i,j);
j = f1(i++); printf("i = %d j = %d\n", i,j);
f2(f1(i),&j); printf("i = %d j = %d\n", i,j);
//which j does this refer to? The static variable, global, or local and why
}
j = f1(i/2); printf("i = %d j = %d\n", i,j);
f2(f1(i),&j); printf("i = %d j = %d\n", i,j);
return 0;
}
void swap(int a, int b)
{
int temp;
temp=b; b=a; a=temp;
}
int f1(int x)
{
static int j = 5;
i++;
j+=x;
return j;
}
void f2(int x, int *p)
{
*p+=x;
*p = (*p>20) ? 20 :*p++;
}
When I run this code into the compiler, I get the following answer:
i = 1 j = 10
i = 2 j = 6
i = 14 j = 14
i = 13 j = 14
i = 14 j = 20
I understand the first set of i and j, the reason being swap does nothing because the variables a and b are deleted in the heap.
For the second set, we increment the i in main and then we use the value 1 as x because i++ is post-increment. We create a static variable j, the global variable x gets increased to 11, and it returns j as 6 because x is added to j. After the function is completed, the i variable in the main gets incremented to 2. This leads to 2 and 6.
For the third print statement, I first call f1(i) which is equal to two, this resets j to 5 and increments the global variable i to 12. Then j gets set to 7 and we return 7 for f1(i). Then this is the part I am having difficulty on. We then pass the memory location of j as the parameter, but which j do we pass and why? From the output it seems as if the static j's memory is being passed but I'm not sure.
As we go into the function f2, we get *p+=x, which I believe gives the value 14 because x is set to 7 from earlier and j is also 7. What I do not get is the second line: "*p = (*p>20) ? 20 :*p++;". What does this even mean? From the output it seems to have copied the value of j into i.
What does the second line of code in the function f2 do and which j (the bolded one with a & sign in front of it) is called in the line "f2(f1(i),&j); printf("i = %d j = %d\n", i,j);".
The instructions of f2 do the following:
*p+=x;
This adds the value of x to whatever is stored at the location pointed to by p. The * dereferences pointer p.
*p = (*p>20) ? 20 :*p++;
If the value stored at p is larger than 20, then store 20 at p. Otherwise store the value of p at p and increment p, which is undefined behavior (pointed out by Cool Guy), as *p++ is equivalent to *p = *p; p++;

Why does the address of a pointer var change in this scenario?

So, I'm following "Let Us C" book, and they have an example for pointers, can you explain why the value of i and j change values in this scenario?:
main( )
{
int i = 3, *j, **k ;
j = &i ;
k = &j ;
printf ( "\nAddress of i = %u", *k ) ;
printf ( "\nAddress of j = %u", &j ) ;
}
Output
Address of i = 65524 Address of j = 65522
I understand in C that new variable declarations for example int i =3; int k=5 are assigned different memory locations by C, just cant seem to wrap my head around why this is outputting different values?
You are expecting *k (Same as address of i) and &j (address of j) to be same. They are different type int * v/s int ** and different values.
Never use %u to print addresses rather use:
printf ( "\nAddress of i = %p", (void *)*k ) ;
On the other hand, if you compare &j and k, those should be same.
For example:
printf ( "%p v/s %p\n", (void *)&j, (void *)k);
Because you are printing the pointer to k in the first printf statement, not the actual value of k. k holds the value of j's reference, so if you wanted the two statements to be equal, just print k.
Point 1: use %p to print the address. Also, cast the corresponding argument to (void *)
Point 2: *k (type int *) and &j (type int **) are two different things. Maybe you wanted to print either of
k and &j (both int **)
*k and j (both int *)
printf ( "\nAddress of i = %u", *k );
Here *k prints the value stored at j not the address of j.
To get the address of j, you need to print k without de-referencing it.
Assume that your variables are stored in following location.
Note: Addresses are just an assumption.
Now *k means de-reference the value stored at k (ie) value stored at memory location 200.
Value stored at 200 is 100 which is the address of i,not the address of j.
When your program start, the OS kernel decides, based on many criteria, where to put your program and how to map it into memory.
So, when you start it several time in a row, the memory location may or may not change.
This is why you can't hard-code absolute memory location in your program, you always pick a start point how know (for instance, the first element of an array) and navigate in your memory from here.
when your program starts, each variable gets a place in memory:
int i = 3, *j, **k ;
in your case, we know these adresses got decided:
address of (int i) = 65524
address of (int* j) = 65522
address of (int** k) = unknown
the operator & gets the adress of the variable, so you get the output you observe.
Given the code
int i = 3, *j, **k ;
j = &i ;
k = &j ;
then the following are true:
**k == *j == i == 3
*k == j == &i
k == &j
That is, the expressions **k, *j, and i all have type int and evaluate to 3, the expressions *k, j, and &i all have type int * and evaluate to the address of i, and the expressions k and &j have type int ** and evaluate to the address of j.
So,
printf( "value of i = %d\n", i );
printf( "value of i (through j) = %d\n", *j );
printf( "value of i (through k) = %d\n", **k );
printf( "address of i = %p\n", (void *) &i );
printf( "address of i (through j) = %p\n", (void *) j );
printf( "address of i (through k) = %p\n", (void *) *k );
printf( "address of j = %p\n", (void *) &j );
printf( "address of j (through k) = %p\n", k );
printf( "address of k = %p\n", (void *) &k );
Use the %p conversion specifier to print pointer values. It expects a void * as its corresponding argument, and this is one of the few places (probably the only place) in C where you need to explicitly cast a pointer value to void *.

Questions on compound literals in C

COMPOUND LITERALS:
#include<stdio.h>
struct s{
int x;
int y;
};
int main(){
int j = 5;
printf("\n &j : %p \n",&j);
struct s *p = &(struct s){j++};
printf("\n p : %p &j : %p x : %d y : %d \n",p,&j,p->x,p->y);
return 0;
}
o/p:
-----
&j : 0x7fff416b74ec
p : 0x7fff416b74d0 &j : 0x7fff416b74ec x : 5 y : 0
a] Why is p not holding the address of j ?
b] why is j not being typecast to struct s ?
a) p not holds the address of j because p point to freshly created structure.
if you want, that p point to j, you should write:
int * p = &j;
b) j is int local (stack) variable, so i see no way, how it can be cast into the structure.
#David C. Rankin, i've reformed my answer
The statement
struct s *p = &(struct s){j++}; // compiler should raise a warning
is incomplete. It should be like
struct s *p = &(struct s){.x = j++};
or
struct s *p = &(struct s){.y = j++};
The uninitialized member will be set ti 0 by default.
The reason that p doesn't hold the address of j is clear that p is holding the address of new object (compound literal), not the address of j itself.
for your first question,, p is of struct type and j is of integer type and you have to make the pointer and the variable of same datatype...
like int *p = &j; //where j is of int type.
j is of integer type(primitive data) and you are trying to convert it into complex datatype(object).. thus, you are trying to do boxing and unboxing.. which are not concepts of c or c++...

Resources