【问题标题】:Pointer difference指针差异
【发布时间】:2015-04-05 20:31:18
【问题描述】:

我正在研究 Obj-C 中的指针。考虑以下代码:

char c = 'Q';
char *charPtr;
charPtr = &c;

在第二行中,我们创建一个 char 类型的指针变量并将其命名为charPtr。据我了解,这只是指向包含char 类型值的内存地址的指针。

在第三行中,我们将charPtr 值(内存地址)分配给另一个包含值c 的内存地址。

我的问题是,charPtr 和 *charPtr 有什么区别?

当我写 *charPtr = &c 时,有一个“黄色”警告 - Incompatible pointer to integer conversion assigning to 'char' from 'char *'; remove &

如果启动应用程序崩溃 (exc_bad_access)

当我写 **charPtr = &c; 时,编译器警告我错误:Indirection requires pointer operand ('int' invalid)

总结一下,我想知道charPtr*charPtr的区别,什么是**charPtr(2个星号)。

【问题讨论】:

  • charPtrchar* 类型的指针。 *charPtrchar 类型;它是指针指向的char 对象。 **charPtr 是非法的,因为 *charPtr 不是指针。
  • @KeithThompson 在这种情况下有资格使用 2 个星号,这是什么意思?谢谢你的澄清。
  • @Evgeniy Kleban 假设您有一些抽象指针声明 T *ptr; T 可以是任何类型,ptr 可以是指向 T 类型对象的指针,其中 T 是任何类型。如果 T 又是指针类型,例如 char *,那么您将拥有 char * *ptr。现在,如果你想声明一个指向具有 char ** 类型的对象 ptr 的指针,你必须在表达式 T *ptr T 中替换为 char **,你将得到 char ***ptr;
  • @VladfromMoscow 谢谢你,这是有道理的。
  • 在您尝试学习 Objective-C 之前,请先学习 C 的基础知识。如果不这样做,你会得到很多错误的想法。

标签: objective-c c pointers


【解决方案1】:

charPtr 是一个变量,它保存一个指向char 类型值的指针。在第 2 行之后,它保存了变量 c 的地址。

*charPtr 是一个表达式,它取消引用指针并访问指向地址处的值。因为charPtr 指向char 类型的值,所以表达式*charPtr 具有char 类型。如果您从中读取,例如char foo = *charPtr;,您会在指向的位置获得char。在这种情况下,您将获得c 的值,即'Q'。如果你写信给它,比如*charPtr = 'A';,你会在指向的位置存储一个新值。在这种情况下,您更改了c 的内容。

**charPtr 是一个语法错误,因为charPtr 不是指针到指针的类型。该表达式具有双重取消引用的形式:第一个取消引用是*charPtr,就像上面一样。再次将* 运算符应用于它会尝试再次取消引用它,但*charPtr 的类型是char。它不是一个指针,所以它不能被取消引用。

你可能有这样的变量:

char **charPtrPtr = &charPtr;

现在,charPtrPtr 是一个变量,它保存了charPtr 变量的地址。它的类型是char**

*charPtrPtr 取消引用它持有的指针并获取它指向的值。这是charPtr 的值,又是指向c 的指针。

**charPtrPtr 是双重取消引用。这是一元* 运算符对*charPtrPtr 的应用。由于*charPtrPtr 实际上与charPtr 相同,所以**charPtrPtr*charPtr 实际上相同,与c 相同。

【讨论】:

  • 绝对是最好的答案,谢谢你,Ken,现在这一切都清楚了!
【解决方案2】:

简单地说,*charPtr 指的是charPtr 所指向的值。但是,由于 StackOverflow 的答案需要比单个句子长一点,我将尝试给您一个类比。

如您所知,指针有点像路标,上面写着“您要找的东西在 A/B/C 等处”。指针可以有多种使用方式。

首先,您可以将标志指向其他地方,相当于charPtr = &c,说“现在使用c 作为目的地,而不是A/B/C”。

其次,你也可以使用指针来改变它所指向的任何东西,这相当于*charPtr = 'Q',它并没有真正改变指针本身,而是改变了它所指向的字段的内容。按照路标的类比,就好像路标可以改变城市的名称(即var c的内容)

最后,指针本身也可以被指向,有点像一个指向下一个符号的符号。例如char **cc = &charPtr 将是指向原始符号的符号,在这种情况下,**cc 可用于访问实际值,而*cc 是第一个符号的内容(实际值的地址)。这可以扩展到眼睛所能看到的范围内,或者至少可以扩展到实际需要的范围内。

【讨论】:

  • 感谢 Henri,非常好的答案和路标的类比!
【解决方案3】:
  • char *charPtr; - 您正在声明一个名为 charPtr 的变量,类型为 char *,即“指向 char 的指针”
  • charPtr = &c; - 您正在为 charPtr 变量分配变量 c 的地址
  • *charPtr - 在这种情况下,'*' 字符是间接运算符,这意味着在 charPtr 指向的地址中获取 。在这种情况下,*charPtr 的类型将是 char(并且 NOT char*

现在,根据*charPtr = &c 语句中的上述内容,您正在尝试将变量 c (&c) 的地址分配给一个字符 (*charPtr),这就是您收到警告 Incompatible pointer to integer conversion assigning to 'char' from 'char *'; remove & 的原因。

当您运行应用程序时,您将尝试将地址(大小为 4 或 8 个字节)分配给 char 类型的变量(通常为 1 或 2 个字节),这就是您的应用程序在 @987654332 上崩溃的原因@

【讨论】:

  • 感谢 Amnon 的回答!尤其是错误解释。
猜你喜欢
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多