Você está na página 1de 3

up

vote8do
wn vote
When thinking about pointers, it helps to draw diagrams. A pointer is an arrow that points to an
address in memory, with a label indicating the type of the value. The address indicates where to look
and the type indicates what to take. Casting the pointer changes the label on the arrow but not where
the arrow points.
d in main is a pointer to c which is of type char. A char is one byte of memory, so when d is
dereferenced, you get the value in that one byte of memory. In the diagram below, each cell
represents one byte.
-+----+----+----+----+----+----+-
| | c | | | | |
-+----+----+----+----+----+----+-
^~~~
| char
d
When you cast d to int*, you're saying that d really points to an int value. On most systems today,
an int occupies 4 bytes.
-+----+----+----+----+----+----+-
| | c | ? | ? | ? | |
-+----+----+----+----+----+----+-
^~~~~~~~~~~~~~~~~~~
| int
(int*)d
When you dereference (int*)d, you get a value that is determined from these four bytes of
memory. The value you get depends on what is in these cells marked ?, and on how an int is
represented in memory.
A PC is little-endian, which means that the value of an int is calculated this way (assuming that it
spans 4 bytes): * ((int*)d) == c + ? * 2 + ? * 2 + ? * 2. So you'll see that
while the value is garbage, if you print in in hexadecimal (printf("%x\n", *n)), the last two
digits will always be 35 (that's the value of the character '5').
Some other systems are big-endian and arrange the bytes in the other direction: * ((int*)d) ==
c * 2 + ? * 2 + ? * 2 + ?. On these systems, you'd find that the value
always starts with 35when printed in hexadecimal. Some systems have a size of int that's different
from 4 bytes. A rare few systems arrange int in different ways but you're extremely unlikely to
encounter them.
Depending on your compiler and operating system, you may find that the value is different every
time you run the program, or that it's always the same but changes when you make even minor
tweaks to the source code.
On some systems, an int value must be stored in an address that's a multiple of 4 (or 2, or 8). This is
called an alignment requirement. Depending on whether the address of c happens to be properly
aligned or not, the program may crash.
In contrast with your program, here's what happens when you have an int value and take a pointer
to it.
int x = 42;
int *p = &x;
-+----+----+----+----+----+----+-
| | x | |
-+----+----+----+----+----+----+-
^~~~~~~~~~~~~~~~~~~
| int
p
The pointer p points to an int value. The label on the arrow correctly describes what's in the
memory cell, so there are no surprises when dereferencing it.
share|improve this answer answered Jun 23 '13 at 12:54



Gilles
36.7k980133
add comment
up
vote2do
wn vote
Casting pointers is usually invalid in C. There are several reasons:
1. Alignment. It's possible that, due to alignment considerations, the destination pointer type is not
able to represent the value of the source pointer type. For example, if int * were inherently 4-
byte aligned, casting char * to int * would lose the lower bits.
2. Aliasing. In general it's forbidden to access an object except via an lvalue of the correct type for
the object. There are some exceptions, but unless you understand them very well you don't want
to do it. Note that aliasing is only a problem if you actually dereference the pointer (apply
the * or ->operators to it, or pass it to a function that will dereference it).
The main notable cases where casting pointers is okay are:
1. When the destination pointer type points to character type. Pointers to character types are
guaranteed to be able to represent any pointer to any type, and successfully round-trip it back to
the original type if desired. Pointer to void (void *) is exactly the same as a pointer to a
character type except that you're not allowed to dereference it or do arithmetic on it, and it
automatically converts to and from other pointer types without needing a cast, so pointers to
void are usually preferable over pointers to character types for this purpose.
2. When the destination pointer type is a pointer to structure type whose members exactly match
the initial members of the originally-pointed-to structure type. This is useful for various object-
oriented programming techniques in C.
Some other obscure cases are technically okay in terms of the language requirements, but
problematic and best avoided.
share|improve this answer answered Jun 23 '13 at 12:45



R..
92.3k8104274
add comment
up
vote1do
wn vote
You have a pointer to a char. So as Your system knows, on that memory address there is
a charvalue on sizeof(char) space. When You cast it up to int*, You will work with data
of sizeof(int), so You will print Your char and some memory-garbage after it as an integer.
share|improve this answer answered Jun 23 '13 at 12:02



gkovacs90
1,2131923
add comment
up
vote1do
wn vote
I suspect you need a more general answer:
There are no rules on casting pointers in C! The language lets you cast any pointer to any other
pointer without comment.
But the thing is: There is no data conversion or whatever done! Its solely your own responsibilty that
the system does not misinterpret the data after the cast - which would generally be the case, leading
to runtime error.
So when casting its totally up to you to take care that if data is used from a casted pointer the data is
compatible!
C is optimized for performance, so it lacks runtime reflexivity of pointers/references. But that has a
price - you as a programmer have to take better care of what you are doing. You have to know on
your self if what you want to do is "legal"
share|improve this answer

Você também pode gostar