我写了这段小代码来测试我的理解。但不明白背后的一些事实。我正在使用 64 位小端机器。所以任何指针都是8个字节。这意味着
#include<stdio.h>
int main(){
char *c = (char *)0x12345678889;
long a = 1;
int b = (long)(c-a);
/* int cc = (int)(c-a); gives compiler error */
printf("val = %x and b = %x", c-a,b);
return 0;
}
Output
val = 45678888 and b = 45678888
假设起始地址是 100。那么 char*
将作为 100->89、101->88 ... 105->12 存储在内存中,字节 106 和 107 将是没用过。我的这个假设首先是正确的吗?由于 int 和 long 在 64 位机器中是 4 个字节,它将从 100,101,102 和 103 开始,并且只考虑这些字节。所以45678889 - 1 = 45678888。我的理解正确吗?
最后,我不明白注释行给出了编译器错误。编译器隐式地对上面的行进行了类型转换。但为什么不在下面呢?
最佳答案
首先您不知道值是如何存储的,这取决于机器字节顺序。值可以从最低位到最高位或相反的顺序存储。你的是从低到高。
其次,在许多 64 位机器上,int 的长度为 4 个字节,而 long 的长度为 8 个字节。发生的事情是您的机器计算 c-a
,它是 (char *)
类型的 0x12345678888
,然后将其转换为 long
的值为 0x12345678888
,然后静默截断它(long 在 C 中静默转换为 int)。
注释给出了警告,因为 c-a
是 char *
类型并且不能静默转换为 int
(它被认为是dangerous dans long 到 int)。好的,然后你明确地转换了它,但编译器警告你它也很危险。请注意,这些是警告而不是错误(它可能取决于编译器选项...)。
关于c - 在数据类型之间使用 c 语言进行类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18746250/