3

假设我有一些指针称为:

char * pChar;
int * pInt;

我知道它们都只是保存指向其他位置的内存地址,并且类型声明了特定指针指向的内存位置有多大。例如,一个 char 可能是系统上一个字节的大小,而一个 int 可能是 4 个字节。所以当我这样做时:

pChar++; // I am actually incrementing the address pointed to by pChar by 1 byte;
pInt++; // I am actually incrementing the address pointed to by pInt by 4 bytes;

但是,如果我这样做:

pChar+2; // increment the address pointed to by pChar by 2 bytes?
pInt+2; // increment the address pointed to by pInt by 2 bytes? what happens to the other two bytes?

谢谢..希望在这里得到任何澄清..指针类型是否仅用于 ++ 操作?

编辑:所以 avp 恰当地回答了我的问题,但我有一个后续问题,当我这样做时会发生什么:

memcpy(pChar,pInt,2);

它会复制2个字节吗?还是4个字节?我会有访问冲突吗?

编辑:根据 Ryan Fox 的说法,答案是 2 个字节,因为它们被强制转换为 (void*)。谢谢!关闭!

编辑:只是为了让未来的搜索者可以找到这个..我发现的另一条信息..

memcpy(pChar+5,pInt+5,2);

不会将 pInt+5bytelocations 指向的内存块的 2 个字节复制到 pChar+5bytelocations .. 发生的情况是 2 个字节从 pInt(4*5)bytelocations 复制到 pChar+5bytelocations .. 难怪我遇到访问冲突,我试图在我不应该阅读的地方阅读.. :)

4

5 回答 5

7

"++" 只是 X = X + 1 的另一个名称;

对于指针,递增 1 或递增 N 无关紧要。无论如何,使用 sizeof(type)*N。在 1 的情况下,它只是 sizeof(type)。

因此,当您增加 2 时(您的第二种情况):
对于 char 是 2*sizeof(char)=2*1=2 字节,
对于 int 将是 2*sizeof(int)=2*4=8 字节。

于 2008-12-19T09:11:13.223 回答
5

啊,现在我明白了。您应该问过 - “指针具有类型有什么意义?”

其实有两点:

  • 指针算法;
  • 取消引用(取回存储在指针指向的地址中的值)。

如果不知道指针的类型,两者都是不可能的。

补充:阅读 memcpy 的文档。最后一个参数是字节数,因为 memcpy 不知道指针的类型。它的两个参数都是空指针。

添加 2:访问冲突 - 视情况而定。如果您没有超出为这些指针分配的内存,则不会发生访问冲突。复制操作将逐字节复制所有内容,您将获得与预期一样的结果(尽管它可能没有多大意义)。

如果您超出分配的内存范围,那么您可能会遇到访问冲突,但您也可能只是越过为另一个变量分配的内存。当你的程序被执行时,几乎不可能知道什么会到达哪里,所以这样做会导致非常不可预测的结果。


指针的三个主要优点:

  1. 您可以“通过引用”将参数传递给函数。这在 C 中更多是一个问题,它没有像 C++ 这样的真正引用,但在许多情况下它仍然非常有用,比如当您必须与外部库合作时。另请注意,通过引用传递不仅在您希望函数修改您传递的变量时有用。它也非常适合将大型数据结构作为参数传递。
  2. 用于构建各种漂亮的动态数据结构,如树、链表等。如果没有指针,这将是不可能的。
  3. 为了能够根据需要将数组重新分配给更大/更小的数组。

PS我知道问题是关于为什么指针很好,仅以算术为例,对吧?

于 2008-12-19T09:16:15.570 回答
3

指针算术不能以这种方式精确地工作。你的第一个例子是正确的,第二个不是。

pChar+2; // increment the address pointed to by pChar by 2 bytes
pInt+2; // increment the address pointed to by pInt by 8 bytes
于 2008-12-19T09:12:01.380 回答
1

对于这部分:

memcpy(pChar+5,pInt+5,2);

首先,评估“+”,然后进行类型转换。

所以以字节为单位:

pChar+5 这里的“5”是 5 个字节,
pInt+5 这里的“5”是 5 个整数,所以 5 * 4 = 20 个字节。
然后将所有内容都转换为 void* 并复制两个字节。

如果您使用计数器而不是“5”,如下所示:

for (int i = 0; i<100; i++)
    memcpy(pChar+i, pInt+i, 2);

然后对于 pChar,您将使用下一个复制命令覆盖一个复制的字节(第二个)。而对于 pInt 你将每一步跳跃 4 个字节(虽然这对于整数数组来说是可以的)。

于 2008-12-19T13:57:31.457 回答
0

我会说C++中指针类型的意义在于考虑 vtable 偏移量。

于 2008-12-19T10:23:48.507 回答