Reputation:
I am trying to understand the pointer concepts in-depth. In the following code,
#include <stdio.h>
int main()
{
int i = 10;
int *iptr = &i;
printf("(float)* : %f\n", (float)*iptr);
printf("(float*) : %f\n", (float*)iptr);
printf("*(float*) : %f\n", *(float*)iptr);
return 0;
}
output:
(float)* : 10.000000
(float*) : 10.000000
*(float*) : 0.000000
I also got a warning for the type-cast (float*)
.
I find it difficult to even analyse the difference. If anyone can help me to analyse what is the exact usage of all three, it would be helpful.
Upvotes: 0
Views: 12570
Reputation: 9090
The first one is correct.
i
is an int
variable, and iptr
a pointer to that int
.
(float)*iptr
: *iptr
dereferences iptr
, which returns an int
. Then that int
is converted to a temporary float
containing the same value. And that float
is used by printf
.
*(float*)iptr
: Attempts to cast a pointer-to-int
into a pointer-to-float
. This is invalid, and should produce a compiler warning or error. It creates a pointer with the same address, but with the type saying that it points to a float
value.
The *
operator then dereferences it, so the int
is read as if it were a float
. So the resulting float
would be invalid, and it could result in a segfault because float
s are longer than int
s, so it reads more memory than there is allocated for the int
.
(float*)iptr
: Same problem, but it doesn't dereference the (invalid) pointer, and passes a pointer-to-float
into printf
, instead of a float
. But printf
expects a float
. Some compilers should also produce a warning/error here because the format string indicates what value types are expected.
If the format specifier indicates %p
, it expects a pointer (void*
, float*
, or any other). It will then print out the address, and not the value it points to. This can be useful in debugging for example.
Upvotes: 3
Reputation: 53016
The difference is
You are dereferencing the int
and casting it to float
in
printf("(float)* : %f\n", (float)*iptr);
which is fine.
You are casting the int
pointer to a float
pointer, and printing the float
pointer with the "%f"
specifier is undefined behavior, the correct specifier for printing pointers is "%p"
, so
printf("(float*) : %f\n", (float*)iptr);
is wrong, it should be
printf("(float*) : %p\n", (void *) iptr);
casting to float *
here is not meaningful, because the void *
address is the same as the float *
address and also the int *
address, the difference would be when you do pointer arithmetic.
You are casting the int
pointer to a float
and dereferencing the resulting float
pointer, although it will violate strict aliasing rules in
printf("(float*) : %f\n", *(float*)iptr);
which is also undefined behavior
Upvotes: 3