代码之家  ›  专栏  ›  技术社区  ›  Vijay

字符指针和整数指针(++)

  •  4
  • Vijay  · 技术社区  · 14 年前

    我有两个指针,

    char *str1;
    int *str2;
    

    如果我看一下这两个指针的大小,我们假设

    str1=4 bytes
    str2=4 bytes
    

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

    这背后的概念是什么?

    10 回复  |  直到 9 年前
        1
  •  16
  •   jweyrich    10 年前

    简单,在提供的场景中:

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

    这个 ++ 运算符按指针类型的大小递增指针。

        2
  •  9
  •   unwind    14 年前

    在指针上进行算术运算时,它总是以指向的对象为单位,而不是以字节为单位。

    所以一个目标对象是4字节的指针,当你加上一个时,它的实际数值会增加4。

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

        3
  •  4
  •   Justin Ardini    14 年前

    char 是1字节,一个 int 是(通常)4字节。当您增加一个指针时,您将增加所指向数据的大小。所以,当你增加 char* ,则递增1个字节,但当递增 int* ,则增加4个字节。

        4
  •  3
  •   Cipi    14 年前

    指针实际保存内存位置的地址,即4字节整数。str1指向一个容纳1byte的位置,因此如果您增加str1的地址,它将跳到1byte数据的下一个地址。但在另一种情况下,str2指向一个4字节的数据,所以如果增加这个地址,它必须跳过这个数据才能得到下一个4字节的数据,所以它会增加4。

    这就是存储在memmory中的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,它的地址变为ff33404,这是数字2的4字节数据的第一个字节。

        5
  •  1
  •   jamesdlin    14 年前

    提示: p[i] *(p + i) .

        6
  •  0
  •   Simon Nickerson    14 年前

    因为这种行为比另一种行为更有用,并且允许您不关心特定数据类型的大小。

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

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

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

        7
  •  0
  •   Jay    14 年前

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

    你可以直觉地想到数组索引是如何工作的。对于整数数组,[0]将指向第一个元素,[1]将指向第二个元素。在这种情况下,如果增量为1,则应增加4个字节以访问下一个整数。如果是字符,则必须是1。同样的概念适用于所有指针算术。

        8
  •  0
  •   TheJuice    14 年前

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

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

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

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

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

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

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

        9
  •  0
  •   Peter Mortensen Pieter Jan Bonestroo    9 年前

    简单的。这取决于编译器。

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

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

    Visual C++ ,它将添加4,因为Visual C++的int大小为4字节。

    char也是如此。

        10
  •  0
  •   Peter Mortensen Pieter Jan Bonestroo    9 年前

    这是根据指针运算得出的。就这样……

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

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

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