I tried to run this code,
int *p;
float q;
q = 6.6;
p = &q;
Though it will be a warning, but i think &q
and p
are of same size, so p
can have an address of q
. But when I print &q
and p
I am getting different output.
This is my output
*p = 6.600000
q = 0.000000, p = 0x40d33333, &q = 0x7fffe2fa3c8c
What is that I am missing?
And p
and &q
is same when both pointer and variable type is same.
My complete code is
#include<stdio.h>
void main()
{
int *p;
float q;
q = 6.6;
p = &q;
printf("*p = %f \n q = %f, p = %p, &q = %p \n",*p,q,p,&q);
}
pointer is a address, and int float are stored in memory in different format. so you can not cast it.
A pointer is a variable that stores a memory address. Pointers are used to store the addresses of other variables or memory items. Pointers are very useful for another type of parameter passing, usually referred to as Pass By Address. Pointers are essential for dynamic memory allocation.
Pointer is a variable which can store address of another variable. And this quality of pointers in c as a variable makes it an important concept to learn in C programming. Pointer also can store address of any type be it – INTEGER , FLOAT ,STRING ,ARRAY,STRUCTURE and FUNCTION.
Integers can be converted to pointers, so you can point to absolute memory locations. A pointer variable cannot be declared to have any other data type.
You need to take compiler warnings more seriously.
C doesn't require compilers to reject invalid programs, it merely requires "diagnostics" for rule violations. A diagnostic can be either a fatal error message or a warning.
Unfortunately, it's common for compilers to issue warnings for assignments of incompatible pointer types.
void main()
This is wrong; it should be int main(void)
. Your compiler may let you get away with it, and it may not cause any visible problems, but there's no point in not writing it correctly. (It's not quite that simple, but that's close enough.)
int *p;
float q;
q = 6.6;
That's ok.
p = &q;
p
is of type int*
; &q
is of type float*
. Assigning one to the other (without a cast) is a constraint violation. The simplest way to look at it is that it's simply illegal.
If you really want to do this assignment, you can use a cast:
p = (int*)&q; /* legal, but ugly */
but there's rarely a good reason to do so. p
is a pointer to int
; it should point to an int
object unless you have a very good reason to make it point to something else. In some circumstances, the conversion itself can have undefined behavior.
printf("*p = %f \n q = %f, p = %p, &q = %p \n",*p,q,p,&q);
The %f
format requires a double
argument (a float
argument is promoted to double
in this context so float
would be ok). But *p
is of type int
. Calling printf
with an argument of the wrong type causes your program's behavior to be undefined.
%p
requires an argument of type void*
, not just of any pointer type. If you want to print a pointer value, you should cast it to void*
:
printf("&q = %p\n", (void*)&q);
It's likely to work without the cast, but again, the behavior is undefined.
If you get any warnings when you compile a program, don't even bother running it. Fix the warnings first.
As for the question in your title, pointers of type int*
and float*
are of different types. An int*
should point to an int
object; a float*
should point to a float
object. Your compiler may let you mix them, but the result of doing so is either implementation-defined or undefined. The C language, and particularly many C compilers, will let you get away with a lot of things that don't make much sense.
The reason that they're distinct types is to (try to) prevent, or at least detect, errors in their use. If you declare an object of type int*
, you're saying that you intend for it to point to an int
object (if it's not a null pointer). Storing the address of a float
object in your int*
object is almost certainly a mistake. Enforcing type safety allows such mistakes to be detected as early as possible (when your compiler prints a warning rather than when your program crashes during a demo for an important client).
It's likely (but not guaranteed) that int*
and float*
are the same size and have the same internal representation. But the meaning of an int*
object is not "a collection of 32 (or 64) bits containing a virtual address", but "something that points to an int
object".
You're getting undefined behaviour, because you're passing the wrong types to printf
. When you tell it to expect a float, it actually expects a double
- but you pass an int
.
As a result it prints the wrong information, because printf
relies entirely on the format string to access the arguments you pass it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With