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
Related
I am a beginner with the programming language C. I am working from example code online and am trying to analyze the following,
int x = 0, y = 16;
*x_ptr = &x
It's the second line that I want to make sure I'm understanding syntactically. I have only just encountered the concept of pointers and am trying to crack that nut conceptually. How then should I read the code on line 2?
The code you posted doesn't include a declaration of x_ptr, but for the code to be valid, the type of x_ptr must be int**: a pointer to a pointer to an integer.
The expression *x_ptr means the thing that x_ptr points to. Since x_ptr is a pointer to a pointer to an integer, *x_ptr is a pointer to an integer.
Since x is an integer variable, &x is the address of that variable. So what the assignment is doing is taking the address of the variable x and storing it into the place in memory that x_ptr points to.
A variable is a storage location.
A storage location stores a value.
A storage location is associated with a type.
A storage location of type T holds a value of type T.
A storage location is not a value.
Using a storage location to produce a value produces the value stored in the storage location.
Applying the & operator to a storage location of type T produces a value. The type of the value is "pointer to type T".
Applying the * operator to a value of type "pointer to type T" produces a storage location of type T.
From these facts you can deduce the meaning of your program fragment.
However, your program fragment as given is almost certainly a typo. You meant to say
int x = 0, *x_ptr = &x;
Let's write that out in a longer form to make it easier to read.
int x;
int *x_ptr;
x = 0;
x_ptr = &x;
x and x_ptr are storage locations. The first of type int, the second of type pointer to int.
The value zero is assigned to the location x.
The & operator is applied to storage location x producing a value of type pointer to int.
That value is assigned to storage location x_ptr.
If you then said
*x_ptr = 123;
then the * takes the value stored in location x_ptr and turns the pointer back into a storage location -- x -- and then stores 123 into that storage location. x is now 123, not 0.
Make sure you have this solid. This is the key to understanding all of C.
If value are stored in an address, then what does this declaration do
int a = 10;
It store the value in a or in address of &a. And if it store the value in address of a, then why we can't using indirection to this variable like this:
printf("%d", *a);
If not, then how we can say that the each value has an unique address and we can access them using indirection operator.
Edit: If I think that indirection is used only on pointer, then consider this:
int b[10];
b[0] = 4; // Give it some value
Now we know that b[0] is a scalar quantity and can be used anywhere where scalar value are required. But in this case, we can use indirection to it like this:
printf("%d", *b); // print 4
Isn't interesting to see that we can use pointer on this scalar variable, but cannot use on variable declare without array.
In my opinion, compiler automatically generates an indirection for variable declare like this:
int a = 4;
So, indirection is not possible on this because we are putting another indirection on it which is not legal except in cases when variables are declares like that:
int a = 4;
int *b = &a;
int **c = &b;
Edit 2: You can take scanf("%d", &a) as a proof which says store the value in address of a not in a.
Up to a certain point you are right: a stores an int and lives at the address &a.
But indirection can only be used on pointers. So you could do either of
int a = 10;
int *p = &a;
printf("%d", a);
printf("%d", *(&a));
printf("%d", *p);
When the variable is of type int (rather than int *), the compiler knows that it needs to do the indirection for you, and you shouldn't try to make it do it. That is, when you have int a = 10;, the compiler stores the value at a memory location which is represented by &a (ignoring registers) and it knows that when you write printf("%d\n", a); it is required to fetch the value stored at &a automatically without you having to think about telling it to dereference something.
When the variable is of type int * (e.g. int *p), there are two ways you can read the value:
Fetch the value (an address) that is held in p
Fetch the value held at the address stored in p
These are two different operations, so two notations are needed:
int a = 10;
int *p = &a;
int *q = p;
int r = *p;
Of course, p also has its own address.
It's not really clear what the question is here, so I'll just explain the situation...
Each (global) variable is located somewhere in memory. When it is assigned a value, that value will in memory at the location of the variable.
If you, in C, use the variable, you actually use the value stored at the location of the variable.
One way to see this is that if & takes the address of an object, and * dereferences (follows) a pointer, then * &a is the same as simply a.
When you do
int a = 10;
The compiler allocates memory of enough size to accomodate an int. This location has to be identified(this is at this particular place i.e. the address) and labelled(this location is called a).It then stores the data at that point. The label allows you easier access. If the language was designed in a way that you would only have access to locations via pointers (i.e dereferencing them to get values) it will be difficult.
You can say its like, You live on some piece of land which can be pinpointed by an exact latitude and longitude. But its better to keep a name for that location, MyHouse etc. rather than referring to the latitude/longitude everytime. Both name and longi/lati refer to the same thing.
a is the label. &a is more like longi/lati
Edit: Regarding int b[10]. array names are not plain labels. They also act as pointers and hence you can use * to dereference them
First of all, you cannot use the indirection operator on anything that does not have a pointer type.
Remember that declarations in C are based on the types of expressions, not objects; the declaration
int a = 10;
says that the expression a has type int, and will evaluate to the value of 10 (at least until someone assigns a different value to it). So when you write
printf("%d\n", a);
the compiler knows to retrieve the value stored at the memory location bound to the expression a. Think of this as a direct access.
Now consider the declaration
int *p = &a;
This declaration says that the expression *p has type int, and will evaluate to the value of whatever p is currently pointing to (in this case, *p will evaluate to 10 since p is initialized with the address of a); the indirection operator is part of the declaration (and is bound to the declarator *p, not the type specifier int). The variable p is a pointer to an integer, and it stores the address of another integer variable (in this case, the address of the variable a). Thus, if we want to access the integer value, we must dereference p:
printf("%d\n", *p);
This is an indirect access to the value 10; instead of accessing it through the variable a, we're accessing it through p which points to a.
I'm experiencing a mind-blowing doubt concerning the use of pointers in C. So, I've searched a lot about this, but no satisfatory answer was presented to me. Here is the thing:
I declare a pointer of type INT, and a variable of type INT (e.g int x, *pointer). So, let's suppose that both of them occupy sequential addresses in RAM, like 0x102 and 0x106, respectively. No surprises so far. Then, I declare x = 5. My memory map should be like this, shouldn't?
int x, *pointer;
x = 5;
Ok. In the college I learned to assign a pointer this way:
pointer = &x;
And my memory map should be like this:
So far so good. But the question is: if, instead of above, I assign a pointer like this:
*pointer = x;
The memory address of 'x' shouldn't be stored in the pointer's memory address? I always wondered something like the "Memory Map 2", but the result is the same of the "Memory Map 1", that is, the 0x106 address holds a garbage number. So how the program KNOWS where I'd like to point to, if the memory address of 'x' isn't stored at pointer's memory address? Where this information is stored?
It looks like a simple question, but I can't understand. :(
Thanks in advance! :)
Getting how pointers work is tricky. Here's something that might help.
You wrote
int x, *pointer;
which is not just idiomatic; this is telling you something important. It is telling you that the expression x is a variable that can hold an integer; that is hopefully clear. It is also telling you that the expression *pointer is also a variable that can hold an integer.
When you say
x = 123;
that means "store the value 123 in the variable x".
And so when you say
*pointer = 456;
that means "store the value 456 in the variable *pointer".
When you say
pointer = &x;
that means "the expression *pointer -- which remember is a variable that can hold an integer -- is the same variable as x". They are aliases -- two names for the same variable.
So your question is:
How does the program know where I'd like to point to, if the memory address of x isn't stored at pointer's memory address?
Let me rephrase that question using the terminology I've established:
How does the program know which variable *pointer refers to if I do not initialize pointer?
It does not know. If you say:
int x;
printf("%d", x);
then you can get any integer printed; this is undefined behavior. You haven't said what value you want the variable x to have, so it can have any value. When you say:
int *pointer;
*pointer = 123;
Then you are saying "store 123 in variable *pointer", but you haven't said what variable *pointer is. So, just as x can have any value, *pointer can be any variable. Again, we have undefined behavior.
Is that now clear?
int x, *pointer;
*pointer = x;
This is undefined behaviour, because pointer does not point to a valid memory location.
int x, *pointer;
x = 5;
pointer = &x;
*pointer = x;
The last line of this is basically the same as x = x, because pointer points to x;
Since * is the dereference operator, then you will try to:
store the value of x (since there's no addressof, & operator before its name)
to the memory pointed to by pointer (and not into the pointer itself, which wouldn't make sense anyway), which is indeterminate, since your pointer hasn't yet been initialized.
This is not storing the address of x into pointer; what you want is achieved solely by writing pointer = &x;, nothing else will do that. By the way, because of the assignment to the memory pointed to by an uninitialized pointer, *pointer = x invokes undefined behavior.
Doing
*somePtr = someVar
assigns the value of somevar in the place pointed by somePtr ..
To be more comprehensive,
int x = 2, y =3;
int * pointer;
pointer = &x;
*pointer = y;
asiigns the value of y in x . That's it!
I am new to the pointer concepts.. i dont understand the following program.. please tell about the logic of this program..
function (int *p,int *q){
return(*p = (*p + *q) - (*q = *p));
}
int main(){
int y = 15, z = 25;
function(&y, &z);
printf("%d\t%d", z, y);
}
This program invokes undefined behavior. It both modifies and uses the value of *q without a sequence point between.
C99 standard, Section 6.5, paragraph 2:
Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.
*q is read in the sub-expression (*p + *q), and this is not done to determine the value to store in the sub-expression (*q = *p).
The intent appears to be to swap the two values pointed to, but a completely reasonable alternate interpretation also exists: evaluate (*q = *p) first, then (*p + *q) (which would equal *p + *p thanks to the assignment). This would result in *p being assigned *p + *p - *p, or just *p. As a result, z would be assigned the value of y (15), while y would remain 15.
I must emphasize that because this is undefined, your compiler can do pretty much whatever it wants, not just limited to this interpretation or swapping the two.
Pointer means you pass the address of the variables instead of the value.
You can then dereference(get the value pointed to by this address) and perform operations using that value.
If you pass a variable by value, that is without using &, a new copy will be created inside the function. Any changes done, will not be visible outside the function. If you pass pointers, then manipulations done to the content of the pointer will be visible outside the function.
On last note, pointers are complex to understand for new programmers. You better read tutorials and spend some time thinking about how things are working.
This is example of function where you pass by reference that is you pass the location of actual variable instead of making a copy of it and passing.so in you function p is basically pointing to y which is 15 and q is pointing to z=25 .It should be easy from there on to find the answer. *p= (15+25)-(15) *q=15.So y=25 z=15 .
First of all you have to know about the pointer...
Pointer is a variable that contain memory address of another variable...
In above program...you have declared 2 variables y and z... and you have created a function
namely function(&y,&z).... means ...it sends the reference (memory address) of y and z to the funcion...function(*p,*q)
so *p contain 15 and *q contain 25...
*p=(*p+*q) means y= 15+25 which is 40....
Variable, like y and z in your program, have ranges. They exist only in a limited logical space. For instance, y and z only "exists" in main ; that's why they're called "local variable". Would you write :
int x,y;
void main
{
// Stuff
}
x and y would be global variables, that any function in this file could access. Since global variable make things harder to debug, when you need to access variable declared in a function, you can use pointer (it's only one of the uses of pointers, useful in your example).
When you give parameters to a function, by default, those parameters are copies, not the original. So, function(int p, int q) creates two new variables : you can do whatever you want to q and p, the x and z would not change.
When you use pointers, you create a special variable, containing the adress of the variable. You can get the adress of any variable with the "&" sign. This is why, to call function(int* p, int* q) you need to write function(&y, &z).
To access the content of a pointer, you need to use the * sign in front of the pointer. Beware ! If you don't do this, you're not modifying the variable the pointer is pointing to, but the adress of the pointer (in your case, that would not be useful ; but in array manipulation, for instance, it can be very useful).
So, your function gets the adresses of two variables, and then do some computing.
This function does two things :
It computes something and give the result ;
During the computing, it gives to q the value of p, so z's value becomes y's value in the main.
Do some printf in your main, checking the value of your variables, before and after the function. Do it with a function using pointers and another one that does not use them, and it'll be much clearer to you.
And add a "int" in front of your function, since it returns something.
wnoise's answer is correct with but if you want to understand why you have such results below you can find reasoning.
this is not a pointer challenge but rather operator precedence.
Just treat *p and *q as You would use y & z
and with this code:
return(*p = (*p + *q) - (*q = *p));
remember that result of assigment is assigned value thus with *p = y = 15 and *q = z = 25
you have:
return(*p = (15 + 25) - (*q = *p));
return(*p = 40 - (*q = 15)); //*q -> z becomes 15
return(*p = 40 - 15);
return(*p = 25); // *p -> y becomes 25
return(25);
Consider a typical environment, why is the following code illegal in C?
{
int x;
&x = (int*) malloc(3*sizeof(int));
...
}
You can't assign something to the address of x because he address of x is not an lvalue
(An lvalue is "something that can be assigned to", i.e. it cannot be on the Left side of an equals sign)
Try
int* x;
x = (int*) malloc(3*sizeof(int)); // TODO: Call free(x)
Now x points to your allocated memory and you can do things like
int foo = *x;
int bar = x[0];
You can assign the address of x to something else, by using the & operator this way:
int x = 1;
int* y = &x; // y now holds the address of x
*y = 2; // Now x = 2
Becauase the address of x is not an lvalue - it is not something that can be modified. C allows you to change things that addresses point to - it does not allow you to change the addreses themselves.
Everyone is correct. The address of X at the time your code executes is a CONSTANT. In other words it says "Hey you can CHANGE where I, the compiler, store the 'x' variable."
you could do this
int main()
{
int* x;
*(&x) = malloc(3*sizeof(int));
}
The address of a variable cannot be changed. Instead you most likely want something like this:
int *x = (int *)malloc(3 * sizeof(int));
...
free(x);
&x returns pointer to x. You can't use it in the left part of an assignment, only on the right.
If you want to assign something to a pointer you have to declare it as a pointer, just like int *x;
Not that this is entirely valuable, but since no one else brought it up (all the above answers are correct, btw, and redundant, I agree that people should vote the right answer up, rather than saying the same thing over and over).
In your example, x is a stack variable. malloc gives you heap memory. That's probably not anything you need to think about too much in today's programming, but if you ever work in an environment where memory is at a premium, you'll want to save your stack as much as possible.
It's also worth noting that for some reason you're allocating 3*sizeof(int). Even if you COULD allocate memory to the stack, in your example, since you're only trying to get 1 int you'd only need 1* sizeof(int), the rest would be wasted.
That's the way the language is designed. To do what you want, use a pointer.