I have a pointer and a variable:
int *a;
int b;
Is there any difference between assignments
a = &b;
and
*a = &b;
and what are they called (like pointer declaration or something) ?
I have a pointer and a variable:
int *a;
int b;
Is there any difference between assignments
a = &b;
and
*a = &b;
and what are they called (like pointer declaration or something) ?
Types matter.
In case of a=&b
, the assignment is valid. You're assigning the address of an integer (type: int *
), to another variable of type int *
, so this is legit.
In case of *a=&b
, this is a constraint violation (for assignement operator, see chapter §6.5.16.1/p1, Constraints, for Simple assignment) and thus not a valid C syntax, thus not required to be compiled by any conforming compiler. To make it a valid C syntax, we need to enforce a typecast, something like
*a= (int) &b;
would make it a syntactically valid C statement which meets the required constraint.
Even, after that, the result is implementation defined.#note Here, you're basically trying to assign the the address of an integer (type: int *
) to another variable of type int
(*a
is of type int
). Conversion from a pointer to integer is implementation defined behaviour.
Quoting C11
, chapter §6.3.2.3, Pointers
Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. [....]
[....] And what are they called?
They both are assignment statements.
Note:
Considering a
points to a valid memory location already. Otherewise, dererefencing an invalid pointer invokes undefined behavior on it's own.
Pay attention to types on the left and on the right of =
.
&b
is int *
, a
is also int *
but *a
is int
.
It's a bit confusing that *
has different meanings:
int *a;
— here *
means that a
will be a pointer;
*a = ...;
— here *
means that we change not address stored in a
but value which is located at the address.
So a = &b
means "write the address of b
to a
",
but *a = &b
means "write the address of b
to *a
, i.e. to the address which is stored in a
".
Let's suggest that we have this situation:
Address Value
a 0x0001 0x0004
b 0x0002 70
0x0003 80
0x0004 90
At the moment a
is 0x0004
and *a
is 90
.
If you do a = &b
, a
will be 0x0002
and *a
will be 70
.
But if you do *a = &b
, a will not change, but *a
, i.e. value at the address 0x0004
, will change to 0x0002
.
One notable difference is that second assignment is ill-formed C (because of constraint violation):
*a = &b;
error: assignment makes integer from pointer without a cast [-Wint-conversion]
C11 §6.5.4/3, Cast operators:
Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast.
The requirement of explicit cast was introduced in C89, in order to to disallow bad practice of implicit conversion between integer and pointer types.
The only exception to this rule is that you can assign pointer value with 0
integer constant, which represents null pointer constant:
a = 0; // more idiomatically: a = NULL;
Given the types, the following assignments would be valid:
a = &b; // int * = int *
*a = b; // int = int
In the second case, a
must point to a valid memory location or the behavior is undefined.
*a = &b; // int = int *
is a constraint violation and the compiler will yell at you.
Is there any difference between assignments
a = &b;
and
*a = &b;
Yes. In first case, a
and &b
(address of b
) both are of type int *
. They are assignable.
In case of *a = &b
, *a
is of type int
while &b
is of type int *
. Bothe types are incompatible and type of &b
is not converted explicitly to the type of *a
. This is a constraint violation. That being said: int
types are not capable of holding pointer objects. The only integer types that are capable of holding pointer object are intptr_t
and uintptr_t
.
1 The following type designates a signed integer type with the property that any valid pointer to
void
can be converted to this type, then converted back to pointer tovoid
, and the result will compare equal to the original pointer:intptr_t
The following type designates an unsigned integer type with the property that any valid pointer to
void
can be converted to this type, then converted back to pointer tovoid
, and the result will compare equal to the original pointer:uintptr_t
These types are optional.
and what are they called (like pointer declaration or something) ?
They are assignment statements.
Like all the other answers have already pointed out, given the variables int *a
and int b
:
a = &b
is valid (and assigns the address of b
to the pointer a
, so that *a
can be used to access b
), whereas*a = &b
is a constraint violation, since it tries to assign the address of b
to the integer pointed to by a
, which is not allowed without an explicit cast.What might be confusing you, however, is that the variable declaration:
int b;
int *a = &b;
is valid, and does exactly the same thing as:
int b;
int *a;
a = &b; // not *a = &b!
That's a very convenient shorthand, since you nearly always want to initialize a variable as soon as you declare it (if only to make sure that you don't accidentally try to use it before it's initialized). But it can be confusing when you first encounter that syntax, since it looks as if you're assigning &b
to *a
, when it's actually a
itself that is getting initialized with the value &b
. This is just something that you'll have to learn: variable initialization is not the same as normal assignment, even though it looks confusingly similar.
The first, int a = &b; copies the address of the variable "b" to the "a".
The second, int *a = &b; copies the address of the variable "b" to the location "a" points to.
First one is ok but second one invokes UB. ( Unless a
is pointing to some valid memory)
Sure there are differents between them
&
represent pointer(from pointer you can get value)
*
represent value
a=&b
(represent a equal point of b)
*a=&b
(represent value a equal point of b)
First let me clear you the difference between integer variable and pointer variable:
(1) Integer variable ( e.g: int b, in this case ) is used to store the value of an integer ( of length 4 bytes ). The value of 'b' gets stored in some memory location ( say 0x00000001 ).
(2) Pointer variable (e.g: int * a, in this case) is used to store the memory location of an integer variable. That is, in 'a' we can store the address of an integer variable. The value pointed by a pointer variable can be dereferenced by using ' * ' operator. So 'a' will have the address and ' *a ' will have the value pointed by the value (address) contained in a.
Now answering to your question:
Let's assume that b = 4 and address of b ( &b ) is 0x00000001 ( hexadecimal notation ).
In first type assignment a = &b, the address of variable integer b gets stored in a ( since a is a pointer variable ). Now 'a' has the value 0x00000001 and ' *a ' will have 4.
In second type assignment *a = &b, the address of variable b gets stored in the memory location pointed by a, i.e, in 0x00000001 memory location will have the value 0x00000001 itself. Now 'a' has the value 0x00000001 and ' *a ' will also have the same value 0x00000001.
int *a;
int b;
Is there any difference between assignments `a = &b` and `*a = &b`.
Any variable var
of type T has some location in memory, whose adress is either allocated by the compiler or by the static or dynamic linkers. The adress of some variables can be obtained by &var and has the type pointer to T
. So, when you apply the &
operator you nest the type inside another pointer. a=&b is correct.
On the other hand, *a=&b
is not correct. You try to store in the variable *a (that has type int
) a pointer to the base address of the variable b (that has type pointer to int
). In the architectures where the pointer has 64 bits and int has 32 bits this will lead to failure. On the other hand, on the architectures where pointer and int have the same length, this is possible if you insert a cast. The compiler will not automatically insert a coercion from int*
to int
.