C++ 中指针类型的意义是什么?

发布于 2024-07-10 04:48:40 字数 1103 浏览 9 评论 0原文

假设我有一些被调用的指针:

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 个字节被复制到pChar+5bytelocations from pInt(4*5)bytelocations..难怪我遇到了访问冲突,我试图在我不应该读取的地方读取..:)

Let's say I have some pointers called:

char * pChar;
int * pInt;

I know they both simply hold memory addresses that point to some other location, and that the types declare how big the memory location is pointed to by the particular pointer. So for example, a char might be the size of a byte on a system, while an int may be 4 bytes.. So when I do:

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;

But what if I do this:

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?

Thanks.. Would appreciate any clarification here.. Is the pointer type simply for the ++ operation?

EDIT: So avp answered my question fittingly, but I have a follow up question, what happens when I do:

memcpy(pChar,pInt,2);

Will it copy 2 bytes? or 4 bytes? Will I have an access violation?

EDIT: THe answer, according to Ryan Fox, is 2 bytes, because they are typecasted to a (void*). Thanks! CLOSED!

EDIT: Just so that future searchers may find this.. Another piece of info I discovered..

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

doesnt copy 2 bytes of the memory block pointed to by pInt+5bytelocations,to pChar+5bytelocations.. what happens is that 2 bytes are copied to pChar+5bytelocations from pInt(4*5)bytelocations.. no wonder I got access violations, I was trying to read off somewhere I wasn't supposed to be reading.. :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

挽清梦 2024-07-17 04:48:40

“++”只是 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 字节。

"++" is just another name for X = X + 1;

For pointers it doesn't matter if you increment by 1 or by N.
Anyway, sizeof(type)*N is used. In the case of 1 it will be just sizeof(type).

So, when you increment by 2 (your second case):
for char is 2*sizeof(char)=2*1=2 bytes,
for int will be 2*sizeof(int)=2*4=8 bytes.

蝶…霜飞 2024-07-17 04:48:40

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

实际上有两点:

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

如果不知道指针的类型,这两种情况都是不可能的。

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

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

如果您超出了分配的内存范围,那么您可能会遇到访问冲突,但您也可能只是跨入为另一个变量分配的内存。 当程序执行时,几乎不可能知道什么到达哪里,因此这样做将导致相当不可预测的结果。


指针有三个主要优点:

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

PS 我知道问题是关于为什么指针是好的,仅使用算术作为示例,对吗?

Ahh, now I understand. You should have asked - "What is the point of pointers having types?"

There are two points, actually:

  • Pointer arithmetics;
  • Dereferencing (getting the value back that is stored in the address that the pointer is pointing to).

Both would be impossible without knowing the type of the pointer.

Added: Read the documentation of memcpy. The last argument is number of bytes, because memcpy has no idea what the type of the pointer is. Both arguments to it are void pointers.

Added 2: Access violation - it depends. If you aren't going outside of the memory that you have allocated for these pointers, there will be no access violation. The copy operation will copy everything byte-by-byte and you will get your results just like you expect them (although it might not make much sense).

If you are going outside your allocated memory bounds then you might get an access violation, but you might as well just cross over into the memory that was allocated for another variable. It's pretty much impossible to tell what gets where when your program is executed, so doing this will lead to quite unpredictable results.


There are three main advantages of pointers:

  1. You can pass arguments to function "by reference". This used to be more of an issue in C, which didn't have real references like C++, but it's still very useful in many cases, like when you have to cooperate with external libraries. Also notice, that passing by reference is not only useful when you want the function to modify the variable you're passing. It's also very good for passing large data structures as parameters.
  2. For building all kinds of nifty dynamic data structures like trees, linked lists, etc. This would be impossible without pointers.
  3. For being able to re-allocate arrays to bigger/smaller ones as needed.

P.S. I understand that the question was about why pointers are good, using the arithmetics only as an example, right?

一袭白衣梦中忆 2024-07-17 04:48:40

指针算术并不完全按照这种方式工作。 你的第一个例子是正确的,第二个例子就不那么正确了。

pChar+2; // increment the address pointed to by pChar by 2 bytes
pInt+2; // increment the address pointed to by pInt by 8 bytes

Pointer arithmetic doesn't work precisely that way. Your first example is correct, the second not so much.

pChar+2; // increment the address pointed to by pChar by 2 bytes
pInt+2; // increment the address pointed to by pInt by 8 bytes
梦忆晨望 2024-07-17 04:48:40

对于这部分:

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 个字节(尽管这对于整数数组来说是可以的)。

For this part:

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

First, "+" is evaluated, then, typecast.

So in bytes:

pChar+5 here "5" is 5 bytes,
pInt+5 here "5" is 5 ints, so 5 * 4 = 20 bytes.
Then everything is cast to void* and two bytes copied.

If instead of "5" you use counter, like here:

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

Then for pChar you will be overwriting one copied byte (the second) with the next copy command. And for pInt you will be jumping 4 bytes each step (which is ok for array of ints though).

诗酒趁年少 2024-07-17 04:48:40

我想说,C++ 中指针类型的要点是考虑 vtable 偏移量。

I would have said that the point of pointer types in C++ is to account for vtable offsets.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文