【问题标题】:C pointer arithmeticC指针算术
【发布时间】:2010-01-22 13:35:11
【问题描述】:

鉴于此代码:

int *p, *q;

p = (int *) 1000;
q = (int *) 2000;

q - p 是什么以及如何使用?

【问题讨论】:

    标签: c pointer-arithmetic


    【解决方案1】:

    根据标准,它实际上是未定义的。指针算法不能保证工作,除非指针都指向同一个数组中的一个元素,或者仅仅指向同一个数组之外的元素。

    标准的相关部分是 6.5.6:9(c1x 的 n1362 草案,但自 c99 以来没有改变),其中规定:

    当两个指针相减时,都指向同一个数组对象的元素, 或者数组对象的最后一个元素;结果是 两个数组元素的下标。

    如果您的 int 数据类型是 4 个字节,您很可能会得到 250,但不能保证。未定义的行为(与实现定义的行为不同)意味着未定义。任何事情都可能发生,甚至包括大部分时空的彻底破坏。

    进修课程:

    • 定义的行为是标准规定的。实现必须这样做才能符合要求。
    • 实现定义的行为留给实现,但它必须清楚地记录该行为。如果您不太关心可移植性,请使用此选项。
    • 未定义的行为意味着任何事情都可能发生。永远不要这样做!

    【讨论】:

    • 这是正确的答案,但我想每个人都想相信答案无论如何都会是 1000/sizeof(int)。哦,好吧!
    【解决方案2】:

    q - p 是 250。

    2000 - 1000 = 1000
    1000 / sizeof(int) = 250
    

    指针运算,假设 sizeof(int) 为 4。


    编辑: 好的,澄清一下。在 C 中,当两个指针属于同一类型时,它们之间的差异定义为它们之间指向类型的事物的数量。例如,
    struct foo { int ar[1000]; } big[10];
    char small[10];
    
    struct foo *fs, *fe;
    char *ss, *se;
    
    fs = &big[0]; fe = &big[9];
    ss = &small[0]; se = &small[9];
    
    fe - fs == se - ss;
    

    也就是说,本例中两个指针的区别在于它们之间的数组元素个数。在这种情况下,它是 0、1、... 8 或 9 个元素。

    【讨论】:

    • 这就是我想要的。对于我的问题,我不关心-1。为什么要除以 1000/sizeof(int)?
    • 您最好声明“如果 sizeof(int) 为 4”。那是因为 sizeof(char) 总是 1.
    • @paxdiablo:对。大脑冻结。
    【解决方案3】:

    q-p 应该返回从pq 应该执行的增量步数。这是1000 / sizeof(int),等于250。记住q++实际上会转到下一个int类型的元素,而不是在它的中间,所以它应该在指针的实际值上加4。结果就是这样。

    【讨论】:

      【解决方案4】:

      答案: q-p 将是 250,假设您在一台 int 为 4 字节的机器上。

      计算是:

      q - p = 1000 1000 / 4(整数大小)= 250

      背后的理念

      指针算法背后的想法是,如果您有一个指向 1000 的 int 指针和一个指向 2000 的 int 指针,并要求两者之间的差异,那么您就询问 2000 是多少-1000。您要问的是,我可以在两者之间放置多少 int

      这对于各种操作都很方便,例如:

      int *i = 100;
      i++; // This is **not** 101, it is 104, cause you actually want the next place an int could fit in memory.
      

      这在处理数组时特别有用。一个整数数组(定义为int arr[10])基本上被视为一个指针。当你写 arr[5] 时,编译器会将其转换为 *(arr + 5),即在名为 arrint 指针上加 5,并获取该地址处的值。

      之所以有效,是因为arr + 5 不是的意思是“将 arr 的值加 5”,它的意思是“在 arr 的值上加任何必要的值以前进 5 @ 987654332@s”,或者更准确地说,“将 5 * sizeof(int) 添加到 arr 的值”

      【讨论】:

        【解决方案5】:

        由于 p 指向一个 int,所以 q,q-p 将是 1000。

        【讨论】:

        • @Pascal 为什么我们需要除以 sizeof(int)?
        • 它们是指针,所以你这样做会冒很大的风险......但是,整数数学是整数数学,无论你做对与否......跨度>
        • intint* 之间的转换留给其他人考虑,仍然存在(int)(p+1) 等于((int)p)+sizeof(int) 的事实。同样,当您减去指针时,如在(p+1)-p 中,您会得到结果1。但是如果你在转换后减去,如((int)(p+1)) - ((int)p),你会得到sizeof(int)
        猜你喜欢
        • 2012-07-27
        • 1970-01-01
        • 2010-10-20
        • 1970-01-01
        • 1970-01-01
        • 2013-06-03
        • 2023-01-30
        相关资源
        最近更新 更多