繁体   English   中英

了解指针?

[英]Understanding pointers?

就像标题所暗示的那样,我在准确理解什么是指针以及为什么使用它们方面遇到了麻烦。 我搜索了一下,但仍然不太了解。 我主要是在Objective-C中工作,但是从我读到的内容来看,它实际上更多地是一个C主题(因此我添加了两个标签)。

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

例如:

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

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

有点偏离主题,但我是否正确标记了? 在我写它的时候,我认为它更多是一个编程概念,而不是某种特定于语言的语言,但是它确实专注于Objective-C,因此我用Objective-C和C对其进行了标记。

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

当您要引用某个值的特定实例而不是该值的副本时,可以使用指针。 假设您要我增加一些价值。 您有两种选择:

  • 您可以告诉我值是什么 :“ 5”:“请为我加倍5。” 这就是所谓的按价值传递。 我可以告诉你答案是10,但是如果您在某个地方写下了5个字,那么5个字仍然会存在。 引用该论文的其他人仍将看到5。

  • 您可以告诉我该值在哪里 :“请删除我在此处写下的数字,并在该位置写两倍的数字。” 这称为通过引用传递。 当我完成后,原来的5个消失了,而它的位置是10个。 现在,其他引用该论文的人都将看到10。

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

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

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

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

有时我们使用指向整数和其他基本数据类型的指针。 通常,尽管如此,我们通过值传递这些类型,因为它更快。 如果我想向您传达一些小数据,直接告诉您比告诉您在哪里可以找到信息的速度更快。 但是,如果数据很大,则相反:我告诉你客厅里有一本字典要比我背诵字典的内容快得多。

我认为在指针变量的声明和指针的使用之间可能有些困惑。

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

因此,在C中,您可以编写:
char c;
这意味着c的值是一个字符。
char *p;
是一个字符的地址。

类型名称后面的“ *”表示变量的值是该类型对象的地址

让我们在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”,请使用“获取指向的东西”运算符,即“ *”。

所以*p是'H'

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

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

指针是一个特殊变量,用于保存其他变量的存储位置。

那么什么是指针……看一下上面提到的定义。 让我们在下面的三步过程中一次执行一次此步骤:

指针是一个特殊变量,用于保存其他变量的存储位置。

因此,指针不过是一个变量,而是一个特殊的变量。 它为何如此特别,因为……阅读第2点

指针是一个特殊变量,用于保存其他变量的存储位置。

它保存另一个变量的存储位置。 内存位置是指它不包含另一个变量的值,但是它存储了另一个变量的内存地址号(可以这么说)。 什么是其他变量,请阅读第3点。

指针是一个特殊变量,用于保存其他变量的存储位置。

另一个变量可以是任何东西……可以是float,int,char,double等。只要它是一个变量,就可以将其在其上创建的内存位置分配给一个指针变量。

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

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

alloc调用将为对象分配内存,而init将使用定义的一组默认属性实例化该内存,具体取决于类。 您可以覆盖init

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

要回答您的每个问题:

(1)据我了解,变量前面带有星号指向内存中的地址?

您或多或少可以看到这种方式。 星号是一个取消引用运算符 ,它使用一个指针并在该指针包含的地址处返回值。

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

因为指针允许代码的不同部分共享信息,所以比在这里和那里复制值更好,并且还允许被调用的函数修改指向的变量或对象。 此外,指针使复杂的链接数据结构成为可能。 阅读此简短教程“ 指针和内存”

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

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

例如,字符串是比char或int更复杂的数据类型。 实际上,不要认为字符串像char的int这样的类型。 字符串是指向一块内存的指针。 由于其复杂性,拥有一个像NSString这样的类来提供有用的函数来使用它们变得非常有意义。 参见NSString

使用NSString ,不创建字符串。 您将创建一个对象 ,该对象包含一个指向字符串的起始地址的指针 ,此外,还包含一组方法,这些方法使您可以操纵数据的输出。

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

这是一个相当存在的问题。 the string if not its location? 我会这样定位:如果不是字符串,字符串什么? 如果您无法以某种方式引用对象,您将如何实施系统? 按名称,当然...那是什么名字? 机器如何理解它?

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

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

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

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

实际上,在其他语言中,您也正在使用指针。 您只是不知道它。 有人会说他们更喜欢这种方式。 但是最终,当您遍历所有抽象层时,您将需要告诉CPU要查看的内存部分。 :-)因此,我认为无论最终构建什么抽象,指针都是必要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM