【问题标题】:Character pointers and integer pointers (++)字符指针和整数指针 (++)
【发布时间】:2010-04-09 07:17:26
【问题描述】:

我有两个指针,

char *str1;
int *str2;

如果我查看两个指针的大小,让我们假设

str1=4 bytes
str2=4 bytes

str1++ 会增加 1 个字节,但如果 str2++ 会增加 4 个字节。

这背后的概念是什么?

【问题讨论】:

  • 如果你想知道指针的“步长”,你想做sizeof(*p),而不是sizeof(p)。
  • 好吧,实际上在我的回答中,我告诉了你背后的整个概念,你已经接受了最基本的答案...... xD
  • char 占用内存位置的 1 个字节,因此 ptrchar ++ 将向前移动 1 个内存。而整数在内存空间中占用 4 个字节。所以下一个 ptrinteger ++ 将移动 4 个字节。同样,假设 float 占用 8 个字节,所以 floatptr++ 会将 float ptr 移动到 8 个字节。

标签: c++ c pointers


【解决方案1】:

简单,在提供的场景中:

  • char 长度为 1 个字节
  • int(在您的平台中)为 4 个字节长

++ 运算符将指针增加指向类型的大小。

【讨论】:

  • 如果 int 是 4 个字节,它恰好在他的平台/编译器上是这样。 -1,因为您没有明确说明它的平台依赖性。
  • 在OP提供的场景中,可以清楚的看到int类型是4字节长。我觉得没有必要详细说明其他平台/架构是否根据定义具有不同的大小,因为他要求解释增量运算符,而不是 int 本身。
  • 刚刚添加了一个与提供的场景相关的明确声明。谢谢@John。
  • 我只是对你很苛刻,因为这是公认的答案。 IMO 你应该清楚标准说 char 是一个字节并且 sizeof(int) >= sizeof(char)。还是删除了 d/v。
【解决方案2】:

在对指针进行算术运算时,总是根据指向的对象,而不是字节。

所以一个指针,其目标对象是例如四个字节,加一时实际数值增加四。

这比所有指针运算都以字节为单位更有用,并且更有意义。

【讨论】:

    【解决方案3】:

    char 是 1 个字节,int 是(通常)4 个字节。当你增加一个指针时,你会增加被指向的数据的大小。因此,当您增加 char* 时,您会增加 1 个字节,但当您增加 int* 时,您会增加 4 个字节。

    【讨论】:

      【解决方案4】:

      指针实际上保存了内存位置的地址,它是 4bytes 整数。 str1 指向一个保存 1byte 的位置,所以如果你增加 str1 的地址,它会跳转到 1byte 数据的下一个地址。但在其他情况下,str2 指向一个 4 字节的数据,因此如果增加该地址,它必须跳过该数据才能到达下一个 4 字节数据,因此它增加了 4。

      这是 1 字节数据序列在内存中的存储方式:

      ADDRESS:         FF334400  FF334401  FF334402  FF334403
      DATA (1BYTE):           1         2         3         4
      

      所以如果str1要指向数字2,它必须持有它的地址,即FF334401。如果增加 str1,它必须跳过 2s 地址并到达 3,为此它必须增加 1。

      其他情况:

      ADDRESS:         FF334400  FF334401  FF334402  FF334403 FF334404 ... FF334407
      DATA (4BYTE):           0         0         0         1        0            2
      

      现在如果str2指向数字1,它是整数,实际上是4字节的数据,它指向那个数据的开头,也就是地址FF334400。当你增加它时,它必须跳过所有1s数据的4个字节才能到达2s数据,所以它增加4并且它的地址变为FF334404,它是数字2的4字节数据的第一个字节。

      【讨论】:

        【解决方案5】:

        提示:p[i]*(p + i) 的简写。

        【讨论】:

          【解决方案6】:

          因为这种行为比替代方法更有用,并且让您不必关心特定数据类型有多大。

          考虑一个数组和一个指向该数组的整数指针:

          int p[10];
          int *q = p;
          

          那么 *(q+1) 与 p[1] 相同,即内存中的下一个int。如果它只指向前面一个字节,那就没那么有用了。

          【讨论】:

            【解决方案7】:

            指针增量总是将它指向的地址增加它所代表的类型的大小。因此,对于 char 指针,它递增 1,对于整数,递增 4。但是,指针变量本身需要 4 个字节来保存地址。

            您可以反过来思考数组索引的工作原理。如果是整数数组,a[0] 将指向第一个元素,a[1] 将指向第二个元素。在这种情况下,对于 1 的增量,它应该增加 4 个字节以访问下一个整数。如果是字符,它必须是 1。相同的概念适用于所有指针算术。

            【讨论】:

              【解决方案8】:

              指针是一种抽象,它允许您引用内存中的数据,以便将原始内存作为一个原子单元进行访问,以确保它针对所选类型进行适当的解释。

              指针本身由本机机器字长表示。在您的示例中,您有两个指向不同类型的指针,但它们仍然是指向内存中地址的指针,因此它们的大小相同。如其他答案中所述,要获得指针引用的数据类型的大小,您必须在 sizeof 操作中取消引用它,例如sizeof(*p).

              ++ 运算符允许您获得一个指针,该指针引用内存中适当类型的下一个地址。如果它只是将所有类型的地址增加一个字节,您最终可能会在内存中得到一个指向数据表示中间的地址

              例如对于两个无符号的 4 字节整数,分别表示十进制值 1 和 4,278,190,080,从内存中的地址 0x00 开始(注意这里的地址仅用于说明,并不代表真实系统,因为操作系统会为自己的目的保留它们)

              address                          0x00  0x01  0x02  0x03  |  0x04 0x05 0x06 0x07
              data value (4 byte integer)      0x00  0x00  0x00  0x01  |  0xFF 0x00 0x00 0x00
              

              如果指向整数的指针引用了地址 0x00 并且运算符 ++ 只是将指针地址增加了 1 个字节,那么您将拥有指向地址 0x01 的指针,如果您随后访问该地址(加上随后的 3 个字节)为一个整数,您将得到一个整数,它由数据字节 0x00 0x00 0x01 加上地址 0x04 的值(在本例中为值 0xFF)表示。这将导致一个十进制值为 511 的整数不代表存储在内存中的 2 个整数中的任何一个。

              要正确访问内存中的下一个整数,运算符 ++ 必须将指针的字节地址增加 4 个字节。

              【讨论】:

                【解决方案9】:

                简单。这取决于编译器。

                如果 int 有 4 个字节的大小,当你给它的指针加 1 时,它就会给它加上它的大小,也就是说,如果 int 是 2 个字节,那么它将把大小加 2 到一个指针中。例如在Turbo C++

                int *str = NULL;
                str + 1;    //It will add 2 as Turbo C++ has int size 2 bytes
                

                Visual C++,str+1; //Visual C++ 的 int size 是 4 字节,所以会加 4。

                char也是如此。

                【讨论】:

                  【解决方案10】:

                  这是根据指针算法。就这样吧。。

                  正如你所说,为所有指针分配的内存是相同的。但是当你使用带有指针变量的增量运算符时,这意味着应该使指针指向(增量)到内存中的下一个位置。

                  所以,如果您使用的是字符指针,那么如果您递增,您希望指向下一个字符,该字符是一个字节宽。类似地,如果你想增加一个整数指针,那么它就像要求它指向下一个 4 字节宽的整数。

                  我认为这足以澄清你的问题:)

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2016-03-27
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-06-26
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多