你如何解释C++指向C#/Java开发人员的指针?[已关闭]
我是一名C#/Java开发人员,试图学习C++。当我试图学习指针的概念时,我被一个想法所震撼,即我以前一定处理过这个概念。如何仅使用 .NET 或 Java 开发人员熟悉的概念来解释指针?我真的从来没有处理过这个问题,它只是隐藏在我面前,还是我一直使用它而不这样称呼它?
我是一名C#/Java开发人员,试图学习C++。当我试图学习指针的概念时,我被一个想法所震撼,即我以前一定处理过这个概念。如何仅使用 .NET 或 Java 开发人员熟悉的概念来解释指针?我真的从来没有处理过这个问题,它只是隐藏在我面前,还是我一直使用它而不这样称呼它?
Java 对象等效于C++共享指针。
C++指针就像一个没有内置垃圾回收的 Java 对象。
C++有三种分配对象的方法:
动态存储持续时间对象
这些指针是通过新的和最接近C#/Java对象(AKA指针)
创建的,从技术上讲,指针需要通过 手动销毁。但这被认为是不好的做法,在正常情况下,它们被放置在控制其寿命的自动存储持续时间对象(通常称为智能指针)中。当智能指针超出范围时,它将被销毁,其析构函数可以调用指针。智能指针可以作为细粒度垃圾收集器。delete
delete
最接近Java的是shared_ptr,这是一个智能指针,它保留指针的用户数,并在没有人使用它时将其删除。
你在C#中一直在“使用指针”,它只是对你隐藏。
我认为解决这个问题的最好方法是思考计算机的工作方式。忘记.NET的所有花哨的东西:你有内存,它只保存字节值,处理器,它只是对这些字节值做一些事情。
给定变量的值存储在内存中,因此与内存地址相关联。编译器不必一直使用内存地址,而是允许您从中读取并使用名称写入它。
此外,您可以选择将值解释为要在其中查找另一个值的内存地址。这是一个指针。
例如,假设我们的内存包含以下值:
Address [0] [1] [2] [3] [4] [5] [6] [7]
Data 5 3 1 8 2 7 9 4
让我们定义一个变量,编译器选择将其放在地址 2 处。可以看出,的值为 1。x
x
现在,让我们定义一个指针,编译器已选择将其放在地址 7 处。的值为 。指向的值是地址 4 处的值,即 值 。获取该值称为取消引用。p
p
4
p
2
需要注意的一个重要概念是,就内存而言,没有类型这样的东西:只有字节值。您可以选择根据需要解释这些字节值。例如,取消引用 char 指针将仅获得表示 ASCII 代码的 1 个字节,但取消引用 int 指针可能会获得 4 个字节,构成 32 位值。
再看一个示例,您可以使用以下代码在 C 中创建一个字符串:
char *str = "hello, world!";
它的作用是说明以下内容:
str
如果你要查看 的值,你会得到一个整数值,它表示字符串第一个字符的地址。但是,如果我们取消引用指针(即,查看它指向的内容),我们将得到字母“h”。str
如果递增指针 ,它现在将指向下一个字符。请注意,指针算术是缩放的。这意味着,当您对指针进行算术运算时,效果乘以它认为它所指向的类型的大小。因此,假设系统上的宽度为 4 个字节,则以下代码实际上会将 4 添加到指针中:str++;
int
int *ptr = get_me_an_int_ptr();
ptr++;
如果你最终越过了字符串的末尾,没有人知道你会指向什么;但是您的程序仍然会尽职尽责地尝试将其解释为字符,即使该值实际上应该表示一个整数。但是,您可能正在尝试访问未分配给程序的内存,并且您的程序将作系统杀死。
最后一个有用的提示:数组和指针算术是一回事,它只是语法糖。如果您有一个变量 ,则char *array
array[5]
完全等价于
*(array + 5)