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

C 当我试图找出结构指针的差异时,为什么会出现垃圾值?,c,pointers,struct,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
{
    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,我得到的输出是ok的(输出是83)。即使是1997年、1998年和1999年的价值,它也给出了相同的价值。但对于2000年到2007年的价值,垃圾价值就来了。从2008年到2011年,产量为84。但从2012年到2019年,产出仍然是垃圾

现在考虑这个结构:

struct Test {
    int i;
    char s;
    float f;
    char s1;
};  

对于上述结构,无论maxedge的值是多少,输出都是正确的。我无法理解为什么上面的代码会出现垃圾值

>指针差异在C.可能会令您吃惊,它会考虑在数组内请求索引,例如,由于代码>数组[index ] < /> >与代码> >(数组+索引)< /代码>自然地,当<代码> p= &(数组[index ])< /C> > <代码> p-数组==index < /c> > /p> 你的结果看起来还是垃圾吗


嗯,也许你会考虑比小于<代码> SIEZOF(StuttTest)的偏移量,你在索引=i和index==i+1之间的某个地方。我怀疑在任何地方都指定了此行为,因此您可能不会期望任何结果。

将两个指针相减是未定义的行为,这两个指针并非都指向同一数组的元素(或一个指针超过该数组的末尾)


通常,编译器假定您的代码遵循标准,因此它生成类似于减去地址和除以对象大小的代码。如果代码已编译,则可以正常工作;如果代码未编译,则可能产生垃圾。

我已尝试过您的代码。它不打印垃圾,但它打印的值乍一看与其他值不相关。(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,只考虑较低的32位,则将数字除以3。这不适用于其他数字,但可能比除法更快


所以我们看到,若不满足某些条件,比如/4'的数字可再除以3,那个么奇怪的事情就会发生。但这没关系,因为不遵循这些条件是未定义的行为。

代码示例有点混乱。你到底想完成什么?你想做什么?很难从你的代码中猜出来。毫不奇怪,代码的行为完全符合C标准的要求(在本例中,是未定义的行为,因此打印的值可以是任何值),但您希望它做什么呢?我试图得到两个指针的差,这应该会产生一个整数值,这取决于结构的大小。我希望我很清楚。那样的话,你可能会这样做吗?在任何情况下,这只有在你为了好玩而试图戳到黑暗的C角时才有意义——在实践中,你应该尽可能远离指针算术。在这种情况下,“垃圾”是什么意思?我喜欢这个答案。这是我见过的最好的例子之一,说明“未定义的行为”真的能对你造成什么影响。说得很好!好的,我想补充一点,从我从其他来源学到的,如果结构大小恰好是2,4,8,16等等(2^n格式,我们应该排除2,因为它不能是结构的大小),那么对于“maxedge”的任何值,输出都是正确的(读“合理的”)。这是因为有两个移位(我不记得是左移位还是右移位),因此,在4(2个移位,在位级别,因此你得到了这个神奇的数字4)给定结构大小的合理值。“我希望我清楚这一点,”阿努拉格普里亚达希说。通常,如果指针的字节差不是结构大小的倍数,则永远不应该使用指针算术。我们刚刚看到了为什么,谁知道其他体系结构能从数据中产生什么…@ANURAGPRIYADARSHI这意味着,如果我的结构大小为16,但地址差为27字节,那么你就超出了规范。一般来说,我只想减去指向同一数组的指针。@ANURAGPRIYADARSHI顺便说一句,谁说2不能是一个结构的大小<代码>结构a{short a;}
结构b{char b[2];}在我的系统上都有大小2<代码>结构a{char a;}
结构b{char b[1];}两者甚至都有1个字节!