Question:
C programming casting pointer?
bill k
2012-12-22 11:12:23 UTC
include

int main(void)
{
int i;
int number = 0x12345678;

// char *p = (char *)&number; //why is casting necessary? What exactly is going on here?
//declare char pointer p and make it point to address of number?

char *p; //
p= &number; //why does this give me a warning?

printf("Address of number is: %p\n",&number);

for(i=0;i {
printf("Address %p = %x\n",p+i,*(p+i));
}

return 0;
}
Six answers:
Jonathan
2012-12-22 15:54:18 UTC
As you've already heard, C checks the type of its pointers. There is a VERY GOOD reason for this, which I will get to in a moment. But when you do "&number" in your code, C says to itself, "the programmer wants a pointer to an int." Then you try assigning this to a "pointer to a char." So C complains because:



(1) They aren't the same type of pointer and it's possible you were making a mistake.



(2) It's possible that a pointer to an int may be of a different size (smaller) than a pointer to a char. That's not likely, but the standard permits the idea. The standard does say that a "void *" and a "char *" must both have the same size and alignment requirements, though. But it does NOT make such statements for other kinds of pointers, except to say that if you store some other kind of pointer into a "void *" pointer, that the void * pointer must be large enough to hold all of the other kinds data type pointers and that a conversion back and forth, say from int * to void * and then back to int *, should work okay so long as you are using it correctly.



(3) When using a pointer with autoincrement or autodecrement or with an index value, as in *p++ or p[5] for example, the C compiler needs to know the size of the object that is referenced so that the increment or decrement to the pointer is made properly to point to the next item of that type (or indexing into the array.) This is a semantic issue and is important. So the warning here ALSO is done to let you know that the C compiler won't make the same use of indices or autoincrement or autodecrement operations between the two pointers. That said, it is NOT the case that you can convert a char * to a double * and then convert it back to a char * and expect it to work -- it's possible that a double * is smaller than a char * and that some bits will be lost in the conversion and cannot be recovered. (Again, this isn't usually a problem, but can be on some machines.)



#3 is probably the most important reason for a warning.
Richard
2012-12-22 13:03:06 UTC
A pointer should be defined to match the size of the variable to which it points. An int variable is normally 4 bytes long (although a few compilers still refer to int as 2 bytes). However, a char variable is 1 byte long.



Some compilers will warn you when you have a mismatch between a pointer definition and the variable to which it points. If you deliberately want to point to an integer variable with a character pointer, then C allows you to state this explicitly by using a cast.



Consider the program:



#include



main()

{

int n = 0x12345678;

int x;

int *p1;

char *p2;



p1 = &n;

p2 = (char *)&n;



printf("%X\n", p1[0]);



for (x = 0; x < 4; x++)

printf("%X\n", p2[x]);

}



On my computer (an Android tablet), this program produces:



12345678

78

56

34

12



In the program, p1 is defined as a pointer to an integer, so the first printf prints out the complete integer. However, in the case of p2, this is defined as pointing to a character, so the second printf only prints out a single byte and not the complete integer. Four separate characters have to be printed to see the whole integer.



Note: this computer is what is called "Little endian" - this means that integers are stored with least significant part in the lowest addressed byte of the integer. Other computers are "Big endian" - which means that integers are stored with the most significant part in the lowest addressed byte.



My little program will not produce the same results in a big-endian machine. Instead, the results will look like this:



12345678

12

34

56

78



Using the wrong type of pointer to point to a variable can result in code that is not necessarily portable between different types of computer. Accessing variables using a different variable type from the type in which the variable was originally defined can limit code portability. As shown above, this can happen when you use a pointer of one type to point to a variable of a different type. It can also happen when you use a union to define the storage space for variables in two different ways:



union

{

int integer;

char character[4];

} variable;



I hope this helps.
2012-12-22 11:25:10 UTC
// char *p = (char *)&number; //why is casting necessary? What exactly is going on here?

//declare char pointer p and make it point to address of number?



you have a pointer to an int which is a data structure made up of 4 bytes, but you want to consider each byte as a separate data structure, so you "cast" it to character, which means "I want to consider this address as an array of characters (bytes) now"



char *p; //

p= &number; //why does this give me a warning?



it doesn't give me a warning. what does it say?

It might just be warning you of a 'possible loss of data' since a char is 1/4th the size of an int

but that's exactly what you want in this case
Eragon
2012-12-22 11:41:02 UTC
number is an integer data type and in pointers you cant point different data type pointers to different data types. take it as a rule the way c was made. that is why you place a typecast before you point your char pointer to the integer data type. even though the pointer sizes are all same you still can only point same pointer type to same data type. and the warning you get is for the very same reason again. the character pointer is being pointed to an integer type pointer. the program still works because there is no problem in p pointing to number but since they are of different data types it shows a warning. hope i helped! :)
Robert
2012-12-22 11:38:58 UTC
You may not necessarily get an error when compiling if you mismatch with pointers (because all pointers are actually unsigned long) but when you go to manipulate the pointer or display its contents then errors will occur.



So a pointer to an int should be declared as an int pointer ( ie. int *p; ).
2016-05-18 08:04:03 UTC
when you place a parameter in a call sequence the DATA may be LARGE, thus to avoid a LONG delay, when passing a whopping big array, it makes sense to pass a really small thing instead thats the ADDRESS of the array. Otherwise ALL programs would go seriously SLOW for no good reason at all. so its expecting a POINTER so its expecting &array


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...