Reputation: 73
I am learning C. As I went through pointers there I noticed some strange behavior which I can't get it. When casting character pointer to integer pointer, integer pointer holds some weird value, no where reasonably related to char or char ascii code. But while printing casted variable with '%c', it prints correct char value.
Printing with '%d' gives some unknown numbers.
printf("%d", *pt); // prints as unknown integer value that too changes for every run
But while printing as '%c' then
printf("%c", *pt); // prints correct casted char value
Whole Program:
int main() {
char f = 'a';
int *pt = (int *)&f;
printf("%d\n", *pt);
printf("%c\n", *pt);
return 0;
}
Please explain how char to int pointer casting works and explain the output value.
Edit:
If I make the below changes to the program, then output will be as expected. Please explain this too.
#include <stdio.h>
int main() {
char f = 'a';
int *pt = (int *)&f;
printf("%d\n", *pt);
printf("%c\n", *pt);
int val = (int)f;
printf("%d\n", val);
printf("%c", val);
return 0;
}
Output:
97
a
97
a
Please explain this behavior too.
Upvotes: 0
Views: 12902
Reputation: 11
<#include <stdio.h>
int main()
{
//type casting in pointers
int a = 500; //value is assgned
int *p; //pointer p
p = &a; //stores the address in the pointer
printf("p=%d\n*p=%d", p, *p);
printf("\np+1=%d\n*(p+1)=%d", p + 1, *(p + 1));
char *p0;
p0 = (char *)p;
printf("\n\np0=%d\n*p0=%d", p0, *p0);
return 0;
}
Upvotes: 0
Reputation: 139
You have define f as a char. This allocates typically 1 byte of storage in most of the hardware. You take the address of f, cast it to (int *) and assign it to an int * variable, pt. Size of integer depends on the underlying hardware - it could be 2 or 4 or even more. When you assign address of f to pt, the address that gets assigned to pt depends on factors such as int size and the alignment requirements. That is why when you print *pt, you see a garbage value. Actually, the ASCII value of 'a' is contained in the garbage, the position of which depends on the int size, endianness of the hardware, etc. If you print *pt with %x, you will see 61 in the output (61 hex is 97 in decimal).
Upvotes: 1
Reputation: 155323
For what the C language specifies, this is just plain undefined behavior. You have a char
sized region of memory from which you are reading an int
; the result is undefined.
As for what is likely happening: The C runtime ends up dumping some random garbage on the stack before main
is even executed. char f = 'a';
happens to rewrite one byte of the garbage to a known value, but the padding to align pt
means the remaining bytes are never rewritten at all, and have "whatever the runtime left behind" in them. So when you read an int
out, on a little endian system, the low byte equals the value of 'a'
, but the high bytes are whatever garbage happens to be left in the padding space.
As for why %c
works, since the low byte is still the same, and %c
only examines the low byte of the int
provided, all the garbage is ignored, and things happen to work as expected. This only works on a little endian machine though; on a big endian machine, it would be the high byte initialized to 'a'
, but the low byte (garbage) would be printed by %c
.
Upvotes: 5