【问题标题】:Why does int pointer '++' increment by 4 rather than 1?为什么 int 指针 '++' 递增 4 而不是 1?
【发布时间】:2011-04-10 07:13:18
【问题描述】:

指针的值是变量的地址。为什么 int pointer 的值在 int 指针增加 1 后增加了 4 个字节。

在我看来,我认为指针的值(变量的地址)在指针递增后只会增加 1 个字节。

测试代码:

int a = 1, *ptr;
ptr = &a;
printf("%p\n", ptr);
ptr++;
printf("%p\n", ptr);

预期输出:

0xBF8D63B8
0xBF8D63B9

实际输出:

0xBF8D63B8
0xBF8D63BC

编辑:

另一个问题-如何访问int占用的4个字节?

【问题讨论】:

    标签: c++ c pointers


    【解决方案1】:

    当您增加 T* 时,它会移动 sizeof(T) 字节。† 这是因为移动任何其他值没有意义:如果我指向 @987654324 @ 那是 4 个字节的大小,例如,增量小于 4 会给我留下什么?部分int 与其他一些数据混合在一起:荒谬。


    在内存中考虑这个:

        [↓      ]
    [...|0 1 2 3|0 1 2 3|...]
    [...|int    |int    |...]
    

    当我增加那个指针时,哪个更有意义?这个:

                [↓      ]
    [...|0 1 2 3|0 1 2 3|...]
    [...|int    |int    |...]
    

    或者这个:

          [↓      ]
    [...|0 1 2 3|0 1 2 3|...]
    [...|int    |int    |...]
    

    最后一个实际上并不指向任何类型的int。 (从技术上讲,使用该指针是UB。)

    如果你真的想要移动一个字节,增加一个char*:char 的大小总是一:

    int i = 0;
    int* p = &i;
    
    char* c = (char*)p;
    char x = c[1]; // one byte into an int
    

    †由此得出的结论是您不能增加 void*,因为 void 是不完整的类型。

    【讨论】:

    • "你不能增加 void*,因为 void 是一个不完整的类型" -- 是的,但是 gcc 支持 void* 上的算术作为扩展(它把它当作 @987654338 @)。
    • “它没有意义”对于整数几乎总是如此,但对于像可变长度结构的数组这样的情况(“我有一个充满数据包的缓冲区,我要将 CurrentPacketPointer 移动到下一个数据包”)。
    • "如果你真的想移动一个字节,增加一个 char*:char 的大小总是 1" 不,它并不总是 1,你应该改用 uint8_t。
    • @Winter:sizeof(char) 始终为一。它可能不总是 8 位,但总是 1 字节。在 C 和 C++ 中,字节是最小的可寻址单元,不一定总是 8 位。
    • @Winter:不用担心。当您需要特定布局(例如 8 位字节)时,使用诸如 (u)intN_t 之类的类型是一个好主意。 :)
    【解决方案2】:

    指针按其指向的类型的大小递增,如果指针指向 char,pointer++ 将指针递增 1,如果它指向 1234 字节结构,pointer++ 将指针递增 1234 .

    第一次遇到这个可能会让人迷惑,但其实很有道理,这不是处理器的特殊功能,而是编译器在编译时计算出来的,所以当你写pointer+1时编译器编译为pointer + sizeof(*pointer)

    【讨论】:

      【解决方案3】:

      这个想法是,在递增之后,指针指向内存中的下一个 int。由于 int 是 4 个字节宽,所以它增加了 4 个字节。一般来说,指向类型 T 的指针会增加 sizeof(T)

      【讨论】:

        【解决方案4】:

        如您所说,int pointer 指向int。 int 通常占用 4 个字节,因此,当您增加指针时,它指向内存中的“下一个”int - 即增加 4 个字节。它以这种方式作用于任何大小的类型。如果你有一个指向A 类型的指针,那么增加一个A* 它将增加sizeof(A)。

        想一想 - 如果您只将指针增加 1 个字节,那么它将指向 int 的中间,我想不出有这样的机会。

        例如,在遍历数组时,这种行为非常舒服。

        【讨论】:

          【解决方案5】:

          指针指向内存中某事的开头。在内存中,一个 INT 占用 4 个字节(32 位),一个 DOUBLE 占用 8 个字节(64 位)。因此,如果您存储了一个 DOUBLE 数字,并且您希望在非常低的级别上指向下一个可用内存位置,则指针需要增加 8 个字节。如果出于某种原因您从 DOUBLE 值的开头指向 +4bytes,则会破坏它的值。内存是一个非常大的平坦领域,它本身没有良心,因此由软件来正确划分它并“尊重”位于该领域的项目的边界。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-05-30
            • 2011-09-07
            • 2011-10-03
            • 2011-09-17
            • 2018-09-18
            • 2018-09-13
            相关资源
            最近更新 更多