I'm very new to C. I come from a Java background, and I'm having a hard time understanding pointers. My understanding of what *x = 1 is take the memory address of x and assign it to 1, where as x = 1 means assign the variable x to the value 1.
Am I correct?
Well, as written you have it completely backwards, since you're saying assign x to the value 1 etc.
x=1 means store the value 1 to the variable x.
*x=1 means store the value 1 at the memory address x points to.
*x = 1;
means that x contains a memory address, assign 1 to that memory address.
x = 1;
means assign 1 to the variable x.
x = VARIABLE
*x = POINTER TO ADDRESS
By saying x=1 means you are directly assigning the value 1 into the x. Where as *x=1 has a bit different approach.
Say, int y = 10 and x is a pointer which is pointing to the address of y by defining int *x = &y. After declaration of *x, through out the program, *x will be treated as the value at the address of y. So, when *x=1 is used, the the value at the address of y, which was 10 earlier, will be changed to 1 now. Thus, y=1 and *x=1 are internally doing same thing.
You can follow this link for detailed understanding in simpler way about C pointers.
Related
If I run the following code:
int main(){
int x = 0;
int* y = &x;
&x = y;
}
I get the error:
lvalue required as left operand of assignment
I understand this means that when using the addressof operator, the pointer produced is not a valid lvalue, as is reflected in the c documentation.
My question simply is: why?
What is the reason that I cannot change the value of the pointer to my variable x? Is it to prevent the programmer from making mistakes, or does it fundamentally make no sense (in which case please explain why.)
In this line:
&x = y;
Sounds like you're trying to say "I want x to be stored in the address y".
When your declare a variable (x), its address (what you call "pointer value") is a constant value. It's NOT an "lvalue". ("l" for "left", a left part of an assignement operation, so something assignable.)
Also you're not meant to decide yourself where the system sets the datas in memory.
Plus, you're not even sure the "y" address is an allocated place allowed to be written by your process.
Three reasons here to not let you do that. :)
Here & operator gives you the address of the variable x and you are trying to assign something to that address, but that's not possible, it doesn't make sense.
If you want to change the value stored in x, just assign to it:
x = 5;
If you have a pointer (int*) y and you want to assign its value to x, use * operator to get the value y points to (stored in that address) and assign it to x:
x = *y;
If you want to assign the pointer y to x, it is not possible. Use another poiner for for that.
int *y1 = y;
In your code
&x = y
This line shows an error as &x is a constant pointer and hence cannot be changed after it has been initialized
I know this function swaps two int values, but I'm trying to understand it
minutely what is *x=*y exactly doing.
1 void swap (int* x, int* y){
2 int temp = *x;
3 *x = *y;
4 *y = temp;
5 }
6
7 int x,y;
8 x = 1;
9 y = 2;
10 swap(&x,&y)
The function receives two addresses, where x and y lives, correspondingly.
An int variable, temp, is created and is assigned the value 1 from a dereferenced pointer to x.
The value 1 from a dereferenced pointer to x is assigned the value 2 from a dereferenced pointer to y. So, by *x = *y, I'm reading 1=2
Thanks a lot.
Let's try to explain *x = *y; without using the word "dereference":
*x represents the integer object pointed to by x. As it is the left operand of the assignment, it means that this integer object is going to be updated.
*y represents the integer object pointed to by y. As it is the right operand of the assignment, it means that the content of the integer object (i.e. its value) is going to be used.
*x=*y updates the integer object pointed to by x with the integer object pointed to by y.
Note: To clearly distinguish pointers from other types in the code, I suggest you to change naming as follows, using a prefix like p_ for pointer variables for example:
1 void swap (int* p_x, int* p_y){
2 int temp = *p_x;
3 *p_x = *p_y;
4 *p_y = temp;
5 }
6
7 int x,y;
8 x = 1;
9 y = 2;
10 swap(&x,&y)
When you assign something like int abc = 5; int *ptr = &abc; understand that :
ptr is an integer pointer
&abc is the address of the variable abc
ptr stores addresss of the variable abc
Writing *ptr is the equivalent to writing abc, and not same as writing 5 (a constant), although all three evaluates to 5 in an expression.
The * operator dereferences to give you the the variable , whose address is pointed to by ptr (i.e abc). Therefore it can be used as an lvalue(on the left side of an assignment).
Now in your example, when you tried the assignment x = *y you are trying to store the value pointed to by y ( which is an integer value) to x (which expects an address).
Now assume you somehow made the assignment, let us also assume that &y(i.e address of y ) is something like 1056(only for example sake) and value pointed to by y is something like 5. Then from now on x points to the address location 5 (which is not the actual address), thereby resulting in some garbage value.
Now an assignment like x = y would work flawlessly. But that would make the pointers x point to same location as pointed by y swap their pointing. That is if initially if x was pointing to variable a which was at address 1000 and y was pointing to a variable b which was at address 2000 , after the assignment valu of both x and y would be 1000. It only means that now we have two pointers to the variable b at address 2000, but has no impact on the actual variables.
Whereas writing *x = *y is equivalent to writing a = b
Hope this helped.
Here in swap(&x, &y); you are passing the addresses of variable x & y as arguments to the function swap(int* x, int* y).
As parameters of swap function are int pointers, the addresses of x and y are now stored in another int pointer type variables x and y.
NOTE:
x and y coincidently have the same name in both the functions but the x and y used in swap function are int pointers and the x and y used outside the swap function are int variables.
The value 1 from a dereferenced pointer to x is assigned the value 2 from a dereferenced pointer to y. So, by *x = *y, I'm reading 1=2
*x=*y is actually using an assignment operator with a left to right associativity. assignment operator assigns the value of right operand to the left operand.don't read it as 1=2, it will as it may prove to be problematic later.
I tried to make some assumptions. By *x = *y, I think *x is not dereferencing x, but is the adress of x, and this is getting assigned the value 2 of the dereferenced pointer to y.
*x=*y here, *x is the value of x and not the address of x and as described in point 3, this statement will assign the value of *y i.e. 2 to *x.
But why, instead of *x=*y, shouldn't it just be x=*y?
it shouldn't because x is an int pointer and *y is an int variable.
Why and when should I use one method or another? I am trying to learn more about pointers, but I cannot understand this kind of usage scenario.
int i = 12;
i += 1; // 13
i = 55; // 55
int x = 6;
int * y = &x;
*y += 1; // 7
*y = 91; // 91
I have researched this question already but could not find an answer, thus the post on SO. I am not asking the difference between what they do, I understand their effect on memory. I do not understand which should be used in the style of scenario above. The title was updated to reflect this misunderstanding.
You'd use a pointer whenever access to an object needs to be done indirectly, such as:
when an object declared outside a function needs to be modified within a function (or when an array is passed to a function)
when an object is dynamically allocated with malloc or other allocation functions
when you're working with data structures (e.g. linked lists, tables, trees)
int i = 12;
i += 1; // 13
i = 55; // 55
In your example, you are creating a temporary integer variable i and storing the value 12 in it. You are then taking the value already stored in i (12) and adding 1 to it.
i += 1; is the same as i = i + 1; in your case i = i + 1 is equivalent to this math:
i = 12 + 1
You are then throwing away the value that you have just stored in i and replacing it with 55. You have overwritten the data stored in the temporary variable i.
int x = 6;
int * y = &x;
*y += 1; // 7
*y = 91; // 91
Now, in the case of x and y, you x is a temporary integer variable just like i above.
By saying int * y = [something]; however, you are declaring a temporary integer pointer to the memory location of some integer. Usually the memory address of some variable that has already been created. Setting y equal to the address of x sets the thing that the pointer is pointing to the location in memory of x. Under this setup, dereferencing y (*y) will yield the value of x, not the address of it. If you print out y, you will print the address of x. If you print out *y, you will print out the value of x. *y += 1 yields the value of x + 1. Setting *y to 91 resets the value of x, in the same way, that you have done above with i and 55.
Allow me to demonstrate the usefulness of this pointer through an example.
Let's say you had 4 integer pointers all set to point to the address of x (&x). Changing the value of any one of those pointers after dereferencing them (*ptr) will change the value stored in x and thus the value pointed to by each of the other 3 pointers you have initialized to the address of x.
By contrast, let's say you have 4 variables (int m, int n, int j, int k) all set equal to 4. When you increment k by 1, it will not change the value stored in m, n or j. It will only change k.
I know my answer will raise many eyebrows here but I can relate the question you asked here, so replying.
To keep your programming simple you can avoid the use of pointers as long as possible. Most of the programs you will write initially will not require pointers at all.
However, as you start writing complicated programs where you'll also need to keep the execution time as minimal as possible, you may want to use pointers.
Apart from time constraints, there are many other places where pointers will be used e.g. when you want to pass/return structures to/from a function. Because passing/returning structures as the value will put a load on the stack.
However, pointers are complicated and you may want to avoid them for writing simple programs if you really don't have any limitation of memory/time in your system.
You can anyways google (or read some books) about pointers for more information.
the basic difference between * and & as follows:
* - indicates the value of the operator
and
& - indicate the address of the operator
Given the following Code
int main()
{
int z;
int **x;
int * y;
x = (int**)malloc(sizeof(int*));
y = (int*)malloc(sizeof(int));
*y = 6;
*x = y; // Point 1
z = 3;
*x = &z; // Point 2
}
I am to draw box-and-circle diagrams of variables at point 1 and point 2.
Following is what i have got point 1.
Following is what i have got for point 2.
can anyone confirm if my approach is correct and my solution? sorry i am new to pointers and c.
Let's take this step by step. First, we reserve a few locations on the stack for the variables.
Next, allocate a small block the size of int pointer.
The newly allocated block should eventually be assigned an address of an int since X is a pointer to a pointer to an int. Next, allocate another small block.
Now put the address of y into the location pointed to by x
Lastly, assign 3 to z and change the value that x is pointing to, which will now be the address of z.
Hope this helps.
At point 1:
a. y contains the address of a dynamically allocated block of memory (let's call this "Block A") that contains the value 6
b. x contains the address of a different dynamically allocated block of memory (let's call this "Block B"), and "Block B" contains the address of "Block A".
c. z is an uninitialized int
At point 2:
a. y is unchanged from point 1
b. z now contains the value 3
c. x still contains the address "Block B", but "Block B" now contains the address of z rather than the address of "Block A".
Diagrammatically, where circles are variables with automatic storage duration (i.e. x, y and z) and rectangles are dynamically allocated blocks of memory:
NO!! This should clear your doubt. Consider the address(y)=300, address(z)=400. content(300)=6, content(400)=3
*x = y; // Point 1
The above statement says that the content of pointer x will be the address of y. So the pointer x is pointing to pointer y. (i.e. content(x)=300 )
*x = &z; // Point 2
The above statement says that the content of pointer x will be the address of z. So the pointer x is pointing to pointer z. (i.e. content(x)=400 )
NOTE: In order to access the values you have to do **x which will finally access the values.
We know that (*) is dereference operator.
Now lets try to access the values using above terminology.
Point 1: **x => *(*x) => *(address(y)) => *(300) => content(300) => 6.
Point 2: **x => *(*x) => *(address(z)) => *(400) => content(400) => 3.
I'm not wholly familiar with this, but x is of type pointer-to-pointer-to-int - two layers of indirection. Y is of type pointer-to-int - one layer. However, the diagram shows them both having the same indirection from the underlying storage. You do this for the second diagram where you take the address of z, but taking the address of z is the same level of indirection as assigning y to *x, as in both cases, you're telling x to point to a memory address that points directly to memory.
So in short, I think your "point 1" diagram should be similar to your "point 2" diagram, with x's "pointer box" pointing to y's "pointer box".
Edit: I'm also not sure about the "point 2" diagram in that it seems to imply that x is pointer-to-int, as its pointer points directly to z's memory - but it's been a long time since I've seen box-and-pointer diagrams (which this essentially seems to be) to know whether there's an alternative way to add that layer of indirection in. I actually think "Z" and "3" should be in the same box as in box-and-pointer diagrams, since z directly refers to the underlying storage.
What is the difference between *x=i and x=&i?
Code:
int i=2;
int *x;
*x=i; //what is the difference between this...
x=&i; //...and this??
//Also, what happens when I do these? Not really important but curious.
x=i;
*x=*i;
*x=i; //what is the difference between this...
This assigns the value of i to an integer stored at the address pointed to by x
x=&i; //...and this??
This assigns the address of i to x.
Note that in your example x is unassigned, so the behavior of *x=i is undefined.
Here is a better illustration:
int i = 2, j = 5;
printf("%d %d\n", i, j); // Prints 2 5
int *x = &j;
*x = i;
printf("%d %d\n", i, j); // Prints 2 2
int i=2;
int *x;
*x=i; // x is not initialized, this is undefined behavior
x=&i; // this assigns the address of i to x
and
*x=&i; // is invalid C. You cannot assign a pointer to an
// integer without an explicit conversion.
*x=i changes the value stored in the memory location pointed to by x to be equal to the value stored in i.
x=&i changes the memory location x is pointing to to i's memory location.
x=i is wrong. You will most likely get a segfault.
*x=*i is wrong. You cannot dereference i, because i is not a pointer.
*x=&i (actually, more properly, *x=(int)&i) will store the memory location of i as an integer in the memory location pointed to by x.
*x=i; dereferences the pointer x and assigns i.
x=&i makes the pointer x point at the variable i.
*x = i changes the value stored at the address which is stored in x. In your case, unedited, that will crash, because the address x is likely junk, possibly NULL. You would need a malloc() or new or something.
x = &i changes the address stored in x, so that is is the address of the variable i. This is perfectly safe in your example.
Well, when you say
*x = i
You're saying: make the variable x points to the value i.
When you say
x = &i
You're saying make the address x points to the address of i.
And I guess you should be able to figure the other ones out by yourself!
*x = i
This actually assigns the value of i to the memory location pointed to by x.
x = &i
This assigns the address of variable i to a pointer variable x. x should be a pointer.
When you do x = i, this will give you a runtime error, as you are trying to erroneously assign an address(which in this case is 2) which does not belong to the address space of your process. To successfully do this, i should also be a pointer and must point to an address which is in your address space.
When you do *x = *i, in your case will again give an error. If i is a pointer, then the address pointed to by x will get the value present at the address pointed to by i.
*x = i assigns 2 to the memory address pointed to by x. Note that this would probably crash because x hasn't been initialized to a memory address via malloc or an assignment to a buffer or address of a stack variable.
x = &i assigns the pointer x to the address of variable i.
x = i would assign the pointer x to the value of 2, which would most likely point to an invalid memory address and would require a cast.
*x = *i would depend on the current value of x. And since i is not a pointer you cannot dereference it.
*x = &i would write the address of i to the memory address pointed to by x, which would depend on the code preceding it. It would likely crash if you didn't assign x to a valid address.
Some of these calls would require a cast to be syntactically correct.