了解指针?

时间:2012-03-17 02:16:54

标签: objective-c c

正如标题所示,我无法准确理解指针是什么以及它们被使用的原因。我已经搜索了一下但仍然不太懂。我主要在Objective-C工作,但从我读过的内容来看,这更像是一个C主题(所以我添加了两个标签)。

根据我的理解,前面带星号的变量指向内存中的地址?我不太明白你为什么要使用指向值的指针而不只是使用值本身。

例如:

NSString *stringVar = @"This is a test.";

在这个字符串上调用方法时,为什么它是指针而不是直接使用字符串?为什么不使用指向整数和其他基本数据类型的指针?

有点偏离主题,但我是否正确标记了这个?在我编写它时,我认为它更像是一个编程概念,而不是特定于语言的东西,但它确实专注于Objective-C,所以我用objective-c和c标记它。

6 个答案:

答案 0 :(得分:6)

  

我不太明白为什么你要使用指向值的指针而不是   只使用价值本身。

如果要引用值的特定实例而不是该值的副本,则使用指针。假设你想让我加倍一些价值。你有两个选择:

  • 你可以告诉我 的值是什么:“5”:“请为我加倍5。”这称为按值传递 。我可以告诉你,答案是10,但如果你有5个写下来,那5个仍然会在那里。引用该论文的任何其他人仍然会看到5。

  • 您可以告诉我其中的值是:“请删除我在此处写下的数字,并在其位置写入两倍的数字。”这被称为通过引用传递 。当我完成后,原来的5个已经消失,并且有10个代替它。引用该论文的任何人现在都会看到10。

指针用于引用某些内存,而不是复制某些内存。当您通过引用传递时,您将指针传递给您正在谈论的内存。

  

在这个字符串上调用方法时,为什么它是指针而不是直接使用字符串?

在Objective-C中,我们总是使用指针来引用对象。技术原因是对象通常在堆中动态分配,因此为了处理对象,您需要它的地址。考虑它的一种更实际的方法是,根据定义,对象是某个类的特定实例。如果将对象传递给某个方法,并且该方法修改了该对象,那么您希望之后更改传入的对象,为此,我们需要通过引用而不是值传递对象。

  

为什么不使用指向整数和其他基本数据类型的指针?

有时我们使用指向整数和其他基本数据类型的指针。但是,一般情况下,我们会按值传递这些类型,因为它更快。如果我想向您传达一些小数据,那么直接向您提供数据比告诉您在何处可以找到信息更快。但是,如果数据很大,则情况恰恰相反:我告诉你,起居室里有一本字典比我背诵字典的内容要快得多。

答案 1 :(得分:3)

我想也许你在指针变量的声明和指针的使用之间有点混淆。

任何带有星号的数据类型后面是数据类型值的地址。

所以,在C中,你可以写:
char c;
这意味着c的值是单个字符。但
char *p;
是char的地址。

类型名称后面的'*'表示变量的值是该类型事物的地址

让我们在c中加一个值:
c = 'H';

所以
char *p;
表示p的值是字符的地址。 p不包含字符,它包含字符的地址。

C运营商&产生一个值的地址,所以
p = &c;
意味着将变量c的地址放入p。我们说'p点在c'。

现在这里有点奇怪的部分。字符串中第一个字符的地址也是字符串开头的地址。

所以
char *p = "Hello World. I hope you are all who safe, sound, and healthy";
p包含'H'的地址,并且隐含地,因为字符是连续的,p包含字符串开头的地址。

要获得字符串开头的字符'H',请使用'get at the thing pointed to'运算符,即'*'。

所以*p是'H'

p = &c; if (*p == c) { ... is true ... }

当调用函数或方法时,要使用字符串,只需要将字符串的起始地址(通常为4或8个字节)传递给函数,而不是整个字符串。这既有效,也意味着函数可以对字符串起作用并对其进行更改,这可能很有用。这也意味着可以共享字符串。

答案 2 :(得分:1)

指针是一个特殊变量,用于保存另一个变量的内存位置。

那么什么是指针...看看上面提到的定义。让我们在下面的三个步骤中一步一步:

  

指针是一个保存内存位置的特殊变量   其他变量。

所以指针只是一个变量......它是一个特殊的变量。为什么它很特别,因为......读点2

  

指针是一个保存内存位置的特殊变量   其他变量。

它保存另一个变量的内存位置。通过内存位置我的意思是它不包含另一个变量的值,但它存储另一个变量的内存地址编号(可以这么说)。这个其他变量是什么,读取点3。

  

指针是一个保存内存位置的特殊变量   其他变量。

另一个变量可以是任何变量......它可以是float,int,char,double等。只要它是一个变量,它的创建存储位置就可以分配给指针变量。

答案 3 :(得分:0)

我听说过一个对象就像一个气球,你拿着它的字符串就是指针。通常,代码执行方式如下:

MyClass *someObj = [[MyClass alloc] init];

alloc调用将为对象分配内存,init将根据类使用一组已定义的默认属性对其进行实例化。您可以覆盖init

指针允许将引用传递给内存中的单个对象到多个对象。如果我们使用没有指针的值,你将无法在两个不同的地方引用内存中的同一个对象。

答案 4 :(得分:0)

回答你的每个问题:

  

(1)根据我的理解,前点带有星号的变量   到内存中的地址?

你可以或多或少地看到它。星号是一个取消引用运算符,它接受一个指针并返回指针中包含的地址的值。

  

(2)我不太明白你为什么要使用指向值的指针而不是   只使用价值本身。

因为指针允许不同的代码段共享信息,所以比在这里和那里复制值更好,并且还允许通过被调用的函数修改指向的变量或对象。此外,指针启用了复杂的链接数据结构。阅读这篇简短的教程Pointers and Memory

  

(3)为什么不使用指向整数和其他基本数据类型的指针?

String是一个指针,与int或char不同。字符串是指向包含字符串的数据的起始地址的指针,并从数据的起始地址返回所有值,直到结束字节。

例如,

string是比char或int更复杂的数据类型。事实上,不要将 sting 视为类似于int的类型。 string 是一个指向一块内存的指针。由于其复杂性,使用像NSString这样的类来提供有用的函数来使用它们变得非常有意义。见NSString

使用NSString时,不创建字符串;你创建一个对象,其中包含一个指向字符串起始地址的指针,另外还有一组允许你操作数据输出的方法。 / p>

答案 5 :(得分:0)

NSString *stringVar = @"This is a test.";
在这个字符串上调用方法时,为什么它是一个指针,而不是直接使用字符串?

这是一个相当存在的问题。我会这样说: 字符串,如果不是它的位置?如果你不能以某种方式引用对象,你将如何实现一个系统?通过名字,当然......但这个名字是什么?机器如何理解它?

CPU具有与操作数一起使用的指令。 “将x添加到y并将结果存储在此处。”这些操作数可以是寄存器(例如,对于32位整数,如可能存储的谚语i循环中的for),但这些寄存器的数量有限。我可能不需要说服你需要某种形式的内存。然后我会说,如果不是指针,你怎么告诉CPU在内存中找到那些东西?

您:“将x添加到y并将其存储在内存中。”
CPU:好的。在哪里?
你:呃,我不知道,喜欢,哪里......

在最低级别,它不像最后一行那样工作。您需要更具体地使CPU工作。 : - )

实际上,所有指针都是“X处的字符串”,其中X是整数。因为为了做某事你需要知道你在哪里工作。就像你有一个整数数组a,并且你需要取a[i]一样,i对你有意义。这有什么意义?那取决于你的程序。但你不能说这个i不应该存在。

实际上在其他语言中,你也在使用指针。你只是没有意识到这一点。有些人会说他们更喜欢这种方式。但最终,当你深入了解所有抽象层时,你需要告诉CPU要查看哪个内存部分。 :-)所以我认为,无论你最终建立什么样的抽象,指针都是必要的。