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

5

我有两个指针,

char *str1;
int *str2;

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

str1=4 bytes
str2=4 bytes

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

这背后的概念是什么?


4
如果你想知道指针的“步长”,你需要使用sizeof(*p)而不是sizeof(p)。 - Chris Burt-Brown
其实在我的回答中,我已经告诉了你整个概念,而你却接受了最基本的答案... xD - Cipi
字符在内存中占据1个字节的空间,因此ptrchar++将向前移动1个字节的内存。而整数占据4个字节的内存空间,所以下一个ptrinteger++将向前移动4个字节。同样地,浮点数占据8个字节的空间,所以floatptr++将把浮点指针移动到8个字节处。 - samprat
10个回答

18

在提供的情况下,简单来说:

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

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


1
如果int是4个字节,那只是在他的平台/编译器上恰好如此。-1是因为你没有清楚表明这种平台依赖性。 - John Dibling
1
在OP提供的场景中,我们可以清楚地看到int类型长度为4个字节。我认为没有必要深入探讨其他平台/架构是否根据定义具有不同的大小,因为他询问的是增量运算符的解释,而不是int本身。 - jweyrich
1
刚刚添加了一个明确的声明,表明它与提供的场景有关。感谢@John。 - jweyrich
1
我只是对你严格要求,因为这是被接受的答案。在我看来,你应该明确指出标准规定char是一个字节,而且sizeof(int) >= sizeof(char)。无论如何,已经将d/v移除了。 - John Dibling

10

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

因此,一个指向四个字节的目标对象的指针,在加一时其实际数值会增加四个。

这比所有指针算术都以字节为单位要更可用,更有意义。


4

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


3
指针实际上保存着内存地址,这是一个4字节的整数。str1指向保存1字节的位置,所以如果你增加str1的地址,它将跳到下一个1字节数据的地址。但在另一种情况下,str2指向4字节数据,所以如果你增加该地址,它必须跳过那些数据才能到达下一个4字节数据,因此它会增加4。
以下是1字节数据序列在内存中的存储方式:
ADDRESS:         FF334400  FF334401  FF334402  FF334403
DATA (1BYTE):           1         2         3         4

因此,如果str1想指向数字2,它必须持有其地址,即FF334401。如果你增加str1,它必须跳过2的地址并到达3,为了做到这一点,它必须增加1。

在其他情况下:

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

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

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

0

因为这种行为比另一种替代方案更有用,而且可以让你不必关心特定数据类型的大小。

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

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

那么 *(q+1) 就等同于 p[1],也就是内存中下一个 int。如果它只指向一个字节,那将会远不如此有用。


0

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

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


0

很简单,这取决于编译器。

如果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 大小为4字节,因此它将添加4。
char 也是同样的情况。

0

这是根据指针算术运算。它是这样的...

正如你所说,所有指针分配的内存是一样的。但当你使用增量运算符与指针变量一起使用时,那就意味着指针应该指向(增加)内存中的下一个位置。

因此,如果你使用字符指针,那么如果你增加了它,你就要指向下一个长度为一个字节宽度的字符。同样,如果你想增加一个整数指针,那么就像要求它指向下一个长度为四个字节宽度的整数。

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


0
指针是一种抽象,允许您引用内存中的数据,以便原始内存被访问为一个原子单元,以确保它被适当地解释为所选择的类型。
指针本身由本机机器字大小表示。在您的示例中,您有两个指向不同类型的指针,但它们仍然都是指向内存中的地址的指针,因此它们的大小相同。如其他答案中所述,要获取指针所引用的数据类型的大小,必须在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的值组成的整数,而在这种情况下,地址0x04的值是0xFF。这将导致一个十进制值为511的整数,它既不代表内存中存储的任何一个整数。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接