将char指针转换为int指针如何工作?

时间:2019-05-21 00:25:58

标签: c pointers casting char

我正在学习C。当我经过指针时,我注意到一些我无法理解的奇怪行为。当将字符指针转换为整数指针时,整数指针拥有一些怪异的值,在与char或char ascii代码合理相关的地方没有任何奇怪的值。但是,在用'%c'打印强制转换变量时,它会打印正确的char值。

使用'%d'打印得到一些未知的数字。

printf("%d", *pt); // prints as unknown integer value that too changes for every run

但是当打印为'%c'时

printf("%c", *pt); // prints correct casted char value

整个程序:

int main() {

char f = 'a';
int *pt = (int *)&f;

printf("%d\n", *pt);
printf("%c\n", *pt);

return 0;
}

请说明char到int指针强制转换的工作原理,并说明输出值。

编辑:

如果我对该程序进行以下更改,则输出将如预期的那样。请也解释一下。

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

输出:

97
a
97
a

请也解释这种行为。

3 个答案:

答案 0 :(得分:5)

对于C语言指定的内容,这只是简单的未定义行为。您有一个char大小的内存区域,您将从中读取一个int;结果是不确定的。

关于可能发生的情况:C运行时最终在甚至执行main之前将一些随机垃圾转储到了堆栈上。 char f = 'a';恰好将垃圾的一个字节重写为一个已知值,但是对齐pt的填充意味着剩余的字节根本不会被重写,并且在其中保留了“任何运行时”。因此,在小端系统上读取int时,低字节等于'a'的值,但高字节是填充空间中可能会留下的任何垃圾。

关于%c起作用的原因,由于低字节仍然是相同的,并且%c仅检查提供的int的低字节,因此忽略了所有垃圾,碰巧按预期工作。不过,这仅适用于小端机。在大型字节序计算机上,将是初始化为'a' high 字节,但是低字节(垃圾)将由%c打印。

答案 1 :(得分:1)

您已将 f 定义为字符。这通常在大多数硬件中分配1个字节的存储空间。您采用 f 的地址,将其强制转换为(int *)并将其分配给一个int *变量pt。整数的大小取决于基础硬件-它可以是2或4甚至更大。将 f 的地址分配给 pt 时,分配给pt的地址取决于诸如int大小和对齐要求之类的因素。这就是为什么在打印 * pt 时会看到一个垃圾值。实际上,'a'的ASCII值包含在垃圾中,其位置取决于int大小,硬件的字节序等。如果打印 * pt 使用%x ,您将在输出中看到61(十六进制的61是十进制的97)。

答案 2 :(得分:0)

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