指针的用例和优点是什么?[关闭]


10

我经常很难看到指针的优点(低级编程除外)。

为什么使用char *而不是String或char []或指针算法带来了什么好处。

那么指针的优缺点是什么?


6
这听起来有点精英主义,但是恕我直言,如果您不得不询问指针的优缺点,您很可能不需要它们。
Jas

3
大概!但是这个问题仍然有效!
Zolomon

1
这也不是完全与语言无关的,因为并非所有编程语言都具有C意义上的真实指针。
David Thornley,2010年

Answers:


6

指针对于动态内存位置,许多数据结构以及有效处理大量数据是必需的。如果没有指针,则必须在全局或函数或等效函数中分配所有程序数据,并且如果数据量超出了最初的允许范围,则将无处可寻。我犹豫在这里使用绝对值,但据我所知,所有现代计算机语言都有某种形式的指针。

在大多数使用指针的语言中,有某些类型的引用是指针,也许有某些类型的引用不是指针,并且在符号上没有进一步的区别。Lisp cons单元格是一对指针,尽管a fixnum不是指针。在Java中,用于类实例的变量是指针,但int不是。语言语法不能反映这一点。

C是不寻常的,因为指针是可选的,显式的,并允许显式指针算术。极有可能编写struct foo bar; struct foo * baz;,并且为baz您分配了内存后,就可以同时使用barbaz来表示struct foos。由于指针是可选的,因此在符号上有所不同很有用。(在C ++中,对于智能指针来说,这是必不可少的,如给定的那样boost::shared_ptr<foo> bar;,它bar.reset()具有一种含义,bar->reset()并且可能有很大不同。)

(实际上,在最初开发C时,显式指针经常在其他语言中使用,例如^在Pascal中。C是比当今大多数常用语言都更老的语言,它表明了这一点。)

C的设计目标之一是用Unix编写,因此它需要以详细的方式处理内存位置。(实际上,C是设计时常用的一系列系统实现语言中的一种,另一个例子是用于控制数据计算机的Cybol。C引起了很大的轰动。)因此,可以直接操纵C指针,分配内存地址并计算新地址。这也导致了C中的一些设计决策。C数组很大程度上基于指针算术,实际上数组在很多情况下都会沦为指针。通过引用将变量传递给C函数是通过指针完成的。不需要其他现代语言具有的通过引用传递数组和变量的强烈需求,因此C没有得到这些。

因此,答案是,在当今的大多数语言中,您经常使用指针而不会被提醒。在C语言(以及程度较小的C ++语言)中,您可以使用指针来执行低级操作,也可以使用指针来完成没有特殊符号的高级操作。


非常好的答案
凯特·格雷戈里

1
我接受这个答案,因为它最好地描述了C / C ++中的指针与Java中的Reference之间无法理解的区别。
OliverS

最好添加简短的解释,说明Java为什么不使用指针来更好地阐明Gosling(Java的主要创建者)所感知的“骗局”。
Guido Anselmi 2014年

10

复杂的数据结构。如果没有指针,就无法构建链表或二叉树之类的东西。

没有指针的“优点”和“缺点”。它们只是一把锤子之类的工具。


5
在Java中,没有指针。但是,可以建立链接列表和二叉树。引用(如Java)和指针(如C)之间是有区别的。
2010年

7
引用和指针之间没有区别。指针算法是C特定的;还有其他具有指针的语言,但是没有指针算术(例如,Pascal)。
zvrba 2010年

1
指针和引用不是您认为的同义词。阅读本文以了解差异。stackoverflow.com/questions/57483/...
StartClass0830

4
要解决该列表的前两项:可以重新分配Java引用,并且它们可以指向null。指针的独特功能是允许您间接引用另一个对象。我的试金石测试是:如果可以构建循环数据结构(可以使用Java引用构建),则它是一个指针。(请注意,您无法使用C ++引用构建循环数据结构。)
zvrba 2010年

1
指针和引用之间有区别。例如,C#具有两者。(blogs.msdn.com/b/ericlippert/archive/2009/02/17/...
史蒂芬埃弗斯

2
  • 使用指针,您可以在运行时分配和取消分配内存。
  • 您可以在允许范围之外使用大型数据结构,而无需复制。

C ++,Java和其他相同类型的语言中的引用只是“安全指针”。这些引用在Java中使用很多。


1
C ++中的引用不是安全的指针。C ++中的引用与指针完全无关。C ++中的引用是别名。无法将它们分配给NULL,并且在创建之后就不能对其进行修改。
Billy ONeal,2010年

@Billy:C ++引用通常使用指针来实现,并且在某些情况下工作类似,因此人们一直将其视为某种受限的指针。
David Thornley,2010年

2

几乎所有计算机程序都需要检查和更改内存中的值(对于我们这些年龄较大的人来说,称为“窥视和戳戳”)。您需要控制这些值在内存中的位置,以便可以预测结果(在某些情况下,顺序很重要:加载可执行代码是一个示例)。因此,您需要具有一种表示内存中位置的数据类型。即使您的编程环境将其隐藏在抽象之下,它仍然存在。


2

char*是指针的拙劣示例。与相比,您可能最好使用std::string(或处理unicode / ansi / multibyte特殊性的更好类型)char*。但是,对于几乎任何其他指针示例(Employee*PurchaseOrder*...),都有许多优点:

  • 作用域大于单个函数-在堆上分配对象并长时间传递指针
  • 快速的函数调用大型对象,因为您无需传递值传递的复制成本
  • 一种使函数能够更改传递给它的参数的方法
  • 节省集合中的空间和时间,仅复制地址而不复制整个对象

实际上,指针是如此重要,以至于大多数似乎没有它们的语言实际上只有它们。C#和Java中的引用类型本质上是伪装成固体对象的指针。

现在,指针操作(p++在或上p += delta)是一个完整的故事。有人认为这很危险,有人认为这很棒。但这离您的问题还很远。


1

指针可以更快,并且可以减少数据结构中的开销,并可以减少程序执行的占用空间。(请注意“可以”一词。)

通常,规则是,如果您通过执行自己的分配或代表您执行某项分配来分配资源,则完成后释放它是您的工作。

进行上述操作的负担在于将责任重新分配给开发人员,而不是由运行时来完成。这具有更多的优点,因为它们可以生存更长的时间,或者可以越过边界,或者可以在更合适的时间进行处理,或者不需要携带垃圾收集器的重量。

在特殊情况下,通常涉及异常和范围,在某些极端情况下,如果避免进行代码清理的话,则需要格外小心。实际上,可以设计这些案例。我们数十年来一直没有托管代码。

通常,使指针“困难”的原因仅仅是不了解硬件级别的情况。无非就是间接。

指针为您提供了更多的原始访问权限,这可能非常有用,聪明或必要。您可以指向任何地方并将其视为几乎任何东西。如果您善用上帝般的力量,那将非常非常好。

通常,由于忘记释放某些东西,或者多次释放某个东西,或者在释放之后引用某个东西,或者在您不指向任何地方时引用某个东西,因此浪费了浪费。这些事情通常会导致严重的崩溃,并且说实话,通常表明您遇到了逻辑问题,而不是指针很脆弱。

如果您是一名扎实的开发人员,那么使用指针应该不会比其他任何数据结构都更麻烦。再说一次,这不是火箭科学,人们几十年来一直没有眨眼。这些天来教得很少。

综上所述,除非需要指针,否则良好的垃圾回收所提供的便利和麻烦的情况会使在托管环境中工作变得更好。能够获取一些内存,使用它并放弃它,这是很棒的,知道在以后的某个时候,如果有必要的话,它可能会被丢弃。编码器方面的代码要少一些,以换取运行时额外的工作量。


0

最佳答案实际上包含在问题中:指针用于低级编程。当然,如果您使用的是C语言,则不使用指针就像用一只手绑在背后来编程一样,但是答案是使用更高级的语言。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.