I want to practice with pointers in C. I got an error showing "lvalue required as left operand of assignment". The error shows at &y=&x. So how could I over wright the address of x to y?
int main()
{
int x=3;
int y=4;
&y=&x;
printf("x=%p,y=%p",&x,&y);
return 0;
}
y is a variable, &y is not so can't be changed. &y is just a way to get the address of that variable.
The address of a variable is immutable. They are not allowed to be changed.
What you can do is store that address in a pointer variable, and later change that pointer to point to something else:
int x=3, y=4;
int *p;
p = &x;
*p = 2;
printf("p=%p, &x=%p\n", (void *)p, (void *)&x); // prints same value both times
printf("x=%d\n", x); // prints 2
p = &y;
*p = 7;
printf("p=%p, &y=%p\n", (void *)p, (void *)&y); // prints same value both times
printf("y=%d\n", y); // prints 7
Related
#include<stdio.h>
int main() {
int x = 5;
int* p = &x;
*p = 6;
int** q = &p;
int *** r= &q;
printf("%d\n",*p); //dereferencing p
printf("%d\n",*q); //getting address of q
printf("%d\n",**q); //dereferencing q
printf("%d\n",**r); //getting address of r
printf("%d\n",***r); //dereferencing r
}
Variable q has the memory address of p while variable r has the memory address of q, then why does when trying to print the memory address of q and r same results are getting produced?
Your comments show that you have misunderstood a few things here.
printf("%d\n",*q); //getting address of q
You're NOT getting the address of q. You're dereferencing q, which happens to be the address of p. The * IS the dereferencing operator. If you want to print the address of q, then do this:
printf("%p\n", (void*)&q); // No asterisk and you should use the %p specifier for printing pointers.
So, because you have made the assignment p=&x; q=&p; then
**q is the same as x or *p
*q is the same as p
q is the the same as &p
&q is the address of q
could you explain the following code,
int main() {
int value = 2;
int *ptrWithAmpersand = &value;
int *ptrWithoutAmpersand = value;
//printf("%d", *ptrWithoutAmpersand); 1) Why Runtime error.
printf("Pointer with & --> %d\n", *ptrWithAmpersand);
printf("Pointer withOUT & and * --> %d\n", ptrWithoutAmpersand); //2) Why this works??!!
getch();
}
As commented in the code
Why Runtime Error?
Why this works?
Output is
Pointer with & --> 2
Pointer withOUT & and * --> 2
In the line
int *ptrWithAmpersand = &value;
you are creating a pointer to int and assigning the address of the variable value to it. So far so good.
In the line
int *ptrWithoutAmpersand = value;
you are creating a pointer to int and assigning the contents of the variable value (2) to it. This leads to several problems:
You are attempting to assign a value of type int to a variable of type int *, which are not compatible types; the compiler should at least issue a warning of "incompatible types in assignment" or something like that (turn on all warnings)
On your system, 2 is not a valid object address, hence the runtime error when you try to dereference ptrWithoutAmpersand.
You have several other problems in your code. You should not use the %d conversion specifier to print out pointer values; always use %p for that purpose.
Here's a slight rewrite of your code to makes some things a little clearer:
#include <stdio.h>
int main() {
int value = 2;
int *ptrWithAmpersand = &value;
int *ptrWithoutAmpersand = value; // throws a warning in gcc; you should not do this
printf("value of expression \"value\" = %d\n", value );
printf("value of expression \"&value\" = %p\n", (void *) &value );
printf("value of expression \"ptrWithAmpersand\" = %p\n", (void *) ptrWithAmpersand );
printf("value of expression \"*ptrWithAmpersand\" = %d\n", *ptrWithAmpersand );
printf("value of expression \"ptrWithoutAmpersand\" = %p\n", (void *) ptrWithoutAmpersand );
return 0;
}
And here is the output of the code:
value of expression "value" = 2
value of expression "&value" = 0x7ffecb63cf44
value of expression "ptrWithAmpersand" = 0x7ffecb63cf44
value of expression "*ptrWithAmpersand" = 2
value of expression "ptrWithoutAmpersand" = 0x2
Note how the pointer expression are printed out vs. the integer expressions.
In short:
*ptrWithAmpersand == value == 2 type == int
ptrWithAmpersand == &value type == int *
ptrWithoutAmpersand == value == 2 mismatched types int * and int
In:
int *ptrWithAmpersand = &value;
printf("Pointer with & --> %d\n", *ptrWithAmpersand);
you correctly assign an address to the pointer and in the printf you correctly dereference it to print an int with the %d parameter.
In:
int *ptrWithoutAmpersand = value;
printf("Pointer withOUT & and * --> %d\n", ptrWithoutAmpersand);
You are incorectly assigning an integer value to a pointer, but because in the printf you do not dereference it, it will be printed as an int with the %d parameter. This will only cause a problem (UB) if sizeof(int *) != sizeof(int).
In:
int *ptrWithoutAmpersand = value;
printf("%d", *ptrWithoutAmpersand);
you get a runtime error because you are dereferencing a pointer that points to memory address 2, which is not yours and so the system aborts your program.
I'm working with the program that scans a number in the main program. After that this program calls for a function change_number(), and as an argument gives the numbers memory address. After this program should add 3 to the number in the sub-program, print it out in the subprogram and restore that new value. However, when trying to print the number out in the subprogram change_number(), it prints out it's memory address. My understanding is that a program should return integers value when referring to the pointer with * -notation or just by inserting a variables name. Another compiler which i have tried says the following error message, and does not even compile, either with x -notation or with *pointer_x -notation:
"You are trying to initialize a variable to a value that is of the wrong type.
code.c:20: warning: assignment from incompatible pointer type".
I don't understand because my pointer is introduced as an integer, just like the integer itself. Here is the code:
#include<stdio.h>
void change_number(int *x);
int main()
{
int x;
printf("Give number x: ");
scanf("%d", &x);
printf("In main program: x = %d\n", x);
change_number(&x);
printf("In main program: x = %d\n", x);
return 0;
}
void change_number(int *x)
{
int *pointer_x;
pointer_x = &x;
x = x + 3;
printf("In sub program: x = %d\n", *pointer_x);
}
The code you've pasted should fail to compile on the line pointer_x = &x; as both x and pointer_x are type int*
Using the address-of operator on a pointer variable gives you a pointer-to-pointer - in this case, &x yields a type of int**
In addition, the line x = x + 3 advances a pointer location in memory by 3*sizeof(int) bytes, it's not modifying the original int variable.
Perhaps you intended to write *x = *x + 3 instead?
void change_number(int *x)
{
int *pointer_x;
pointer_x = x;
*x = *x + 3;
printf("In sub program: x = %d\n", *pointer_x);
}
The parameter x already contains address of the variable x from main so it have to be written as
void change_number(int *x)
{
int *pointer_x;
pointer_x = x;
*x = *x + 3;
printf("In sub program: x = %d\n", *pointer_x);
}
When you write void change_number(int *x), x is received as an int *. So, x points to int and *x is int.
So you'll need to change the following:
pointer_x = x;
*x = *x + 3;
printf("In sub program: x = %d\n", *pointer_x);
Now this prints correctly. But to restore the value, just add this line at the end:
*x = *x - 3;
I put this code into eclipse and run it
main()
{
int *p, *q, *r;
int a = 10, b = 25;
int c[4] = {6,12,18,24};
p = c;
printf("p = %d\n" ,p);
}
the output I get is
p = 2358752
what is this number supposed to represent? Is it the address of the variable?
If what i'm saying above is true would my answer to the following question be correct?
so lets say the following are stored at the following locations
address variables
5000 p
5004 q
5008 r
500C a
5010 b
5014 c[0]
5018 c[1]
501C c[2]
5020 c[3]
so would would the line
p = c;
be 5014?
int *p,
The above statement defines p to be a pointer to an integer.
In the below statement, c is implicitly converted to a pointer to the first element of the array a.
p = c;
// equivalent to
p = &c[0];
Therefore, p contains the address of the first element of the array. Also, the conversion specifier to print an address is %p.
printf("p = %p\n", (void *)p);
// prints the same address
printf("c = %p\n", (void *)c);
Yes, p is the address of c, which is the same as the address of c[0]. And yes, in your second example, p would be equal to 5014.
as in the title, what's the difference because these two seem to get me the same results?
No they are not the same. Assume that d is a pointer to int:
int n = 0;
int* d = &n;
*d++; // d++ then *d, but d++ is applied after the statement.
(*d)++; // == n++, just add one to the place where d points to.
I think there is an example in K&R where we need to copy a c-string to another:
char* first = "hello world!";
char* second = malloc(strlen(first)+1);
....
while(*second++ = *first++)
{
// nothing goes here :)
}
The code is simple, put the character pointed by first into the character pointed by second, then increment both pointers after the expression. Of course when the last character is copied which is '\0', the expression results to false and it stops!
The increment ++ has higher operator precedence than the dereference *, so *d++ increments the pointer d to point to the next location within the array, but the result of ++ is the original pointer d, so *d returns the original element being pointed to. Conversely, (*d)++ just increments the value being pointed to.
Example:
// Case 1
int array[2] = {1, 2};
int *d = &array[0];
int x = *d++;
assert(x == 1 && d == &array[1]); // x gets the first element, d points to the second
// Case 2
int array[2] = {1, 2};
int *d = &array[0];
int x = (*d)++;
assert(x == 1 && d == &array[0] && array[0] == 2);
// array[0] gets incremented, d still points there, but x receives old value
In the official C terminology, these expressions do give you the same results, as they should. In the proper terminology, the "result" of a non-void expression is what that expression evaluates to. Both of your expressions evaluate to the initial value of *d, so not surprisingly, the results are the same.
However, an addition to a "result" every expression in C has zero or more so called "side effects". And side effects of these two expressions are completely different. The first expression increments the value of pointer 'd'. The second expression increments the value of '*d' (the pointed value).
The first increments the pointer, the second increments the value pointed to.
As an experiment, try this:
int main() {
int x = 20;
int *d = &x;
printf("d = %p\n", d);
int z = (*d)++;
printf("z = %d\n", z);
printf("d = %p\n", d);
int y = *d++;
printf("y = %d\n", y);
printf("d = %p\n", d);
}
They do return the same result, but the state change in your program is completely different.
This is easiest to understand if we just expand out the operations.
x = *d++;
// same as
x = *d;
d += 1; // remember that pointers increment by the size of the thing they point to
x = (*d)++;
// same as
x = *d;
*d += 1; // unless *d is also a pointer, this will likely really just add 1
I don't have a compiler handy.
a = (*d)++;
b = (*d);
is a==b? i don't think it is.