将int
投射到int*
是否有效?如果是,那是什么意思?如果不是,问题是什么?
int a=10;
printf("%d", (int *)a);
只是a
而不是&a
。
它以devc ++打印10。 (int *)a
是不是指向地址10的指针而不是指向存储值10的某个地址的指针?
啊!我还是很困惑。我还有一个我无法弄清楚的情况。
int b = 516;
printf(“\ n%d”,((char *)b));
打印516.它不打印4吗? 请解释一下。
答案 0 :(得分:5)
根据C标准(6.3.2.3指针)
5整数可以转换为任何指针类型。除了 以前指定的,结果是实现定义的,可能不是 正确对齐,可能不指向引用的实体 类型,可能是陷阱表示.67)
在您的代码段中
int a=10;
printf("%d", (int *)a);
指针(int *)a
可能无法正确对齐,例如当sizeof(int *)等于4或8时。
还要考虑到printf的这个调用
printf("%d", (int *)a);
有未定义的行为,
来自C标准(7.21.6.1 fprintf函数 - 同样适用于printf)
9如果转换规范无效,则行为为 undefined.275)如果任何参数不是正确的类型 相应的转换规范,行为未定义。
至于此代码段
int b=516;
printf("\n %d",((char *)b));
然后编译器将堆栈值516作为地址但在函数printf内部推送,并且由于格式说明符%d
,该函数再次将该值视为整数对象并相应地输出它。
答案 1 :(得分:1)
int
到int*
的演员阵容未定义。这意味着任何都可能发生。什么是可能发生的是它将指向索引为10的内存块,无论这意味着什么。可以实施一些编译器,以便int
和int*
具有不同的大小,这会导致不同的问题。
知道,如果你运气好,(int *)a
指向10,并且你想看看那里有什么,你可以用
printf("%d", *(int *)a);
警告: 这可能/可能/可能导致类似于忘记malloc
内存的分段错误。
TL; DR:不要这样做。
答案 2 :(得分:1)
是的,您可以将整数强制转换为指针,但语义依赖于上下文。整数的位模式将被解释为一个地址,它可能有效也可能无效。
您的示例没有多大意义,而(int*)a
是一个等于0xA的地址,%d
格式说明符会导致printf()
在任何情况下将该值解释为整数 - 这就是为什么它打印10,但作为地址,它仍然具有值10 - 即使该地址无效。
考虑:
int a = 10 ;
intptr_t p = (int)&a ; // cast a valid pointer to integer
// large enough to hold an address
int ap = (int*)a ; // a reinterpreted as a pointer
printf( "%d\n", a ) ; // Print a
printf( "%p\n", &a ) ; // Print address of a
printf( "%d (0x%X)\n", p, p ) ; // Print p - an integer equal to &a
printf( "%p\n", ap ) ; // Print ap - a interpreted as a pointer