简体   繁体   中英

How casting of char pointer to int pointer works?

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.

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 .

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).

<#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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM