这不是典型的讨厌指针的问题,而是一个非常有趣的问题。
指针是一个非常强大的概念,但它就是这样:一个概念。那么为什么 C 编译器要发明这样一个专门用于指针的独立逻辑和语法呢?
不要误会我的意思,我喜欢指针给我们提供的机会及其当前的语法。它们是绝对重要的功能,实现了动态数据结构、对象和类、多线程内存共享、对象可变性、低冗余值重复等的演变。
但如果你想象 C 的发明事件,今天的指针似乎是一个比直观的第一个概念更令人印象深刻的想法。让我们更深入地了解我的意思。
如果你看一下指针的结构,它基本上是一个 unsigned long (又名 4[32 位系统] 或内存中的 8 个字节)。将指针与无符号长整型分开的东西是指针特定的功能。
指针有自己的声明语法和属性运算符:解引用器。
int a = 5; int *ptr = &a; //declaration int value = *ptr; //dereference
但是让我们想象一下,这从未被发明过。如果解除引用功能仅与任何整数类型相关联,则以下内容将很容易实现:
int a = 5; unsigned long adress = &a; int value = *adress;
在这种情况下,你甚至可以这样做:
int firstIntInMemory = *(0); //manually dereferences (4bytes at) adress 0`
说到解析器,这完全不是一个冲突的语法,因为作为解引用器的星号是一元运算符,而作为算术乘法器的星号始终是二元运算符。
正如我上面所描述的,这个虚构的解引用运算符实际上是指针概念的原始本质。将其与当前的实际实现进行比较,使得思考这个核心问题变得非常有趣。本来可以有很多结果。
指针算术唯一特殊的事情是将类型大小与计算相结合。当我有一个数组,并且想要获取第二个元素时,我只需向指针加 1 即可。如果它是一个 int 指针,这实际上会隐式地将值 4 添加到地址(如果您的系统上 sizeof(int) == 4):
int arr[5] = {1,2,3,4,5}; int second = *(arr 1);
但是说实话,如果您直观地思考内存,以下内容实际上更符合逻辑:
int arr[5] = {1,2,3,4,5}; int second = *(arr sizeof(int));
这只是标准的整数算术。如果你这样看,就根本没有理由发明指针算术。
当然,“*”语法使预期用途更加清晰。如果你看到它,你会立即知道这个变量用于内存操作。此外,每个内存操作库函数都是为指针设计的。
但是,如果它从未被发明,而是我们拥有这些可解引用的无符号长整型,人们就会想出设计和命名约定,例如附加带有“_p”后缀的指针变量标识符。内存操作库将围绕此发展。
所以说真的,如果你想一想,如果指针从未作为语言的一个特性而被发明的话,C 可能会像现在一样生存下来。它们只是由程序员作为一个概念发明的,其工作方式与当前存在的方式相同。
我发现这是一个有趣的故事,值得深入研究。
为什么C要发明指针?
这是否正是我们所期望的原因:一致性、清晰度和安全性,防止误用去引用?
或者是否有比我在这篇文章中介绍指针的方式更深层的原因和更复杂的逻辑,这使得它们实际上比对通用整数执行相同的操作更加有效?
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3