【问题标题】:C pointers vs. Objective-C pointersC 指针与 Objective-C 指针
【发布时间】:2009-12-07 22:48:13
【问题描述】:

我来自 Objective-C 背景,正在努力扩展我在 C 方面的知识。然而,有一件事让我感到困惑,那就是 C 和 Obj-C 中的指针之间的区别。正如您在下面的示例中所见,两种语言之间的行为似乎有些不同,我想知道您能否帮助解释原因?

C 代码工作正常:

void myFunction()
{
    int x, *pointerX; 
    pointerX = &x;
    *pointerX = 5;

    // Prints: "x is 5"
    printf("x is: %i", x);
}

Obj-C 代码失败:

- (void)myMethod
{
    NSString *string = @"Caramel coffee", *stringPointer;
    stringPointer = &string;                    // Warning:   Assignemnt from incompatible pointer type
    *stringPointer = @"Chocolate milkshake";    // Exception: Incompatible types in assignment

    NSLog(@"string is: %@", string);
}

问题:为什么不能把stringPointer赋值给string的内存地址(stringPointer = &string;),为什么C下可以执行*pointerX = 5;,但是不能执行*stringPointer = @"Chocolate milkshake"; 在 Objective-C 下?

我意识到 Obj-C 处理对象而 C 不处理,但我似乎无法弄清楚为什么它在 Obj-C 中不起作用的幕后细节。任何帮助是极大的赞赏。谢谢! :)

【问题讨论】:

  • 你是想弄清楚 C 部分还是 Objective-C 部分?从您的问题来看,您似乎想学习 C,但您正在编写看起来像 C 的 Objective-C 代码 ...
  • C 部分。很抱歉造成混乱。我的背景是我已经阅读了一些 Objective-C 书籍,现在正在阅读 C 书籍。让我感到困惑的是指针在 C 中是如何工作的,这似乎有点不同(尽管 Obj-C 是建立在 C 之上的)。
  • 我很确定指针在 C 和 Objective-C 中的工作方式相同,我认为您在使用 Cocoa 类而不了解如何使用它们时会感到困惑。最简单的方法是查找示例以了解如何使用 Cocoa 类来解决问题,正如我所说的,问题可能在于隐藏在您正在处理的接口类后面的类树。
  • 伟大的 stefanB,我想你可能是对的。我肯定会看更多的 Cocoa 示例。非常感谢! :)

标签: c objective-c pointers


【解决方案1】:

在您的第一个示例中,xpointerX 具有不同的类型(分别为 (int)(int *))。在您的第二个示例中,stringstringPointer 具有 same 类型 (NSString *)。试试吧:

NSString *string = @"Caramel coffee", **stringPointer;

【讨论】:

    【解决方案2】:

    您的NSString *string 本身就是一个指针。因此,为了指向它,您需要将stringPointer 声明为指向指针的指针。也就是说,像这样声明stringPointer

    NSString **stringPointer;
    

    然后一切都应该工作。请注意,相同的指针语义适用于 C 和 Objective-C。

    【讨论】:

      【解决方案3】:

      问题是当你创建一个对象时,你实际上总是通过分配给它的指针来操作它,因此是 (NSString *)。

      尝试在 C 中做同样的事情(使用字符串),也许它会变得更清楚:

      void myFunction()
      {
          char *string = "this is a C string!";
          char **ptr=&string;
      
      
          // Prints: "this is a c string"
          printf("ptr points to %s: \n",  *ptr);
      }
      

      如您所见,指针的工作方式与它们在 Objective-c 中的工作方式完全相同。请记住,objective-c 中的原语很少(int 是最明显的)。大多数时候,您正在创建对象 X 类型的指针(例如 NSString),然后分配一块内存(通过 [[Object alloc] init])并将该块的起始地址分配给您的指针。与我们在 C 中对字符串所做的完全一样。

      【讨论】:

        【解决方案4】:

        &string 的类型为NSString **,而stringPointer 的类型为NSString *,因此是警告。 然后您尝试将 NSString 的实例(类型为 NSString *)分配给类型为 NSString 的变量,从而出现错误。

        【讨论】:

          【解决方案5】:

          在自己的行上定义每个变量总是一个好主意。当你重写你最初的 Objective-с 代码时,比如

          NSString* string = @"Caramel coffee";
          NSString* stringPointer;
          

          很多事情都变得清晰了。

          【讨论】:

          • -1 仍然不能解决问题,因为指针类型不兼容。
          • @Quinn:在我写信息的那一刻,问题已经解决了。在 cmets 中编写此类与样式相关的消息可能会更好,但是没有代码格式化的能力。
          【解决方案6】:

          问题是 - 你的字符串是 const 还是不是?
          第一个示例可能会起作用。
          即使在非目标 C 编译器中,文字字符串也可以通过链接器/编译器选项放置在 const 内存中。

          在这一行: 字符串指针 = &string; 您正在将指针的地址复制到字符串 poitner 中。明显不兼容。

          在这一行:
          *stringPointer = @"巧克力奶昔";

          您正在尝试将字符串写入指针(指针是 4 字节地址)。在上面复制整个字符串不是一个好主意。

          【讨论】:

            【解决方案7】:

            你想做什么?

            不确定它是否会按您的预期工作。

            您似乎是从 C 中获取概念并将其应用于 Cocoa 类,我以为您正在学习 C。您在 Objective-C 代码中的任何地方看到对象的地址吗?

            Cocoa 类是使用Class clusters 实现的,这意味着它们共享相同的接口,但您将获得您操作的特定扩展类。

            在您的情况下,您正在获取可能扩展 NSString 的类的地址并将其分配给指向 NSString 的指针。

            例子:

            NSString * str = @"Caramel coffee";
            NSString * str2 = [NSString stringWithString:@"all"];
            
            NSLog(@"%@", [[str class] className]);
            NSLog(@"%@", [[str class] className]);
            

            输出(GNUStep linux):

            2009-12-08 10:49:29.149 x[25446] GSCInlineString
            2009-12-08 10:49:29.149 x[25446] NSConstantString
            

            ...除了别人指出的明显的指针定义问题。

            【讨论】:

            • NSError 模式可能是我们在 Objective-C 中获取对象地址的最常见情况:"NSError *error; [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"foo" error:&error] ;
            • 是的,但是我们将局部变量的地址传递给方法,因为我们期望返回值。但你通常不会看到像 NSString * str = &someotherNSStringObject; 这样的东西
            猜你喜欢
            • 2014-06-26
            • 2011-09-26
            • 1970-01-01
            • 2011-05-19
            • 1970-01-01
            • 1970-01-01
            • 2014-04-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多