c - 为什么当我试图找到结构指针的差异时会出现垃圾值?

标签 c pointers struct

这是我试图做的:-

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/

相关文章:

c - 不兼容的指针类型警告 C

c - sizeof(*v) 在 C 中意味着什么?

c - C中的结构指针

c - 如何扫描文本文件并根据行数分成均匀分布的 4 个数组

c - 使用双指针为结构内的动态结构数组分配内存**

c - 使用函数的参数初始化静态变量

c - 如何在 C 中实现 next() PHP 函数

c++ - 数字时钟c++

c - 从 IEEE 754 double 窃取位

c - 我需要帮助在简单的 C 代码中声明参数