这是我试图做的:-
struct Test
{
int i;
char s;
float f;
};
int main()
{
int sizestruct=sizeof(struct Test);
printf("size of struct=%d\n", sizestruct);
int maxedge;
printf("enter maxedge value");
scanf("%d", &maxedge);
struct Test *sptr1, *sptr2;
sptr1=(struct Test *) 1000;
sptr2=(struct Test *) maxedge;
printf("sptr1=%d, sptr2=%d\n",sptr1, sptr2);
printf("then sptr2-sptr1=%d\n", sptr2-sptr1);
return 0;
}
现在,如果 maxedge=1996(输出为 83),我得到的输出就可以了。即使对于值 1997、1998 和 1999,它也给出相同的值。但是对于 2000 年到 2007 年的值(value),垃圾值(value)来了。从 2008 年到 2011 年,输出为 84。但是从 2012 年到 2019 年,输出又是垃圾。
现在考虑这个结构:
struct Test {
int i;
char s;
float f;
char s1;
};
对于上述结构,无论maxedge的值是多少,输出都是正确的。我无法理解为什么上面的代码会产生垃圾值!!
最佳答案
我试过你的代码。它不打印垃圾,但它打印的值乍一看与其他值无关。 (83, -1431655682, 1431655849, 84)
我不确定为什么它会以这种方式运行,但一般来说,未定义的行为可能会导致意外行为(就像在本例中一样)。
如果指针的差异(以字节为单位)不是 12 的倍数(一个结构的大小),如我们所见,可能会发生更奇怪的事情。
除以 12 显然是以先除以 4 再除以 3 的方式发生的,而后者的执行方式使得这里发生这种情况。
让我们看看生成的汇编器输出:
movl 28(%esp), %edx
movl 36(%esp), %eax
subl %eax, %edx
movl %edx, %eax
这就是减法。
sarl $2, %eax
imull $-1431655765, %eax, %eax
movl %eax, 4(%esp)
这里我们首先除以 4,然后乘以值 -1431655765,这是无符号值 2863311531 的有符号错误表示。
如果我将该值乘以一个可被 3 整除的数字并且只考虑低 32 位,我得到该数字除以 3。这不适用于其他数字,但可能比除法更快。
所以我们看到,如果不满足某些条件,例如/4 数字再次被 3 整除,就会发生奇怪的事情。但没关系,因为不遵循这些条件是未定义的行为。
关于c - 为什么当我试图找到结构指针的差异时会出现垃圾值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25422602/