我有 2 个表单,它们实际上输出了我不理解的不同结果
int x = *(int*)&M[index]
相比
int x = (int)M[index]
有人可以向我解释有什么区别吗?
如果 M 的数据类型不是 int[],它们可能会有所不同,以您有一个包含 2 个(16 位)short、0x0123 和 0x4567 的数组的情况为例。内存布局(大端)将/可能是;
0x01 0x23 0x45 0x67
在使用 M[0] 的后一种情况下,您将正确地将 short 分配给整数,因为您已读取 M[0] 并将其转换为整数 0x00000123
在第一种情况下,您将获取 M[0] 的地址并假设内存中有一个 integer,使用 32 位整数类型给出结果 0x01234567 (即将读取所有 4 个字节)
前者将内存的字节解释&M[index]
为好像 anint
存储在那里并为您提供int
.
后者获取 的数值M[index]
并将其转换为int
.
如果M[index]
是 type int
,显然没有区别。
第二个将值转换为 int,这意味着它以有意义的方式将其转换(如果无法进行转换将导致错误),第一个从内存中的位置获取 sizeof(int) 个字节并表示它们作为一个整数,即使这可能没有任何意义。
例如:
double a[10];
a[5] = 281907.2389727;
int x = *(int*)&a[5];
int y = (int)a[5];
printf("%d %d", x, y);
将输出(在我的机器/编译器上):
-189447571 281907
因为演员 (int) 将舍入双精度,而 * (int * ) 将拾取双精度的第一个 sizeof(int) 字节,并“假装”它是一个整数 - 这当然不会给出有意义的结果因为它们具有不同的大小和二进制表示。
你不明白的部分是什么?
第一个表达式由两个表达式组成:一个指针解引用和一个计算为指针的表达式。*(int *)
是第一部分,它引用必须跟随的指针,并且&M[index]
简单地表示“索引的地址:数组M的第一个元素”。
在你的两个例子中,假设M
是一个int
数组,强制转换是完全不必要的,应该被删除。你也可以使用:
int x = *(&M[index]);
这种形式的另一个好处是使两个部分更清晰;第一部分只是*
括号外的运算符,第二部分是括号内的代码。
或者
int x = M[index];
后一种形式是首选的形式,它很清楚而且中肯。