C指针与Objective-C指针

我来自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; ),为什么我能够执行*pointerX = 5; 在C下,但我不能执行*stringPointer = @"Chocolate milkshake"; 在Objective-C下?

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

在第一个示例中, xpointerX具有不同的类型( (int)(int *) )。 在第二个示例中, stringstringPointer具有相同的类型( NSString * )。 尝试改为:

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

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

 NSString **stringPointer; 

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

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

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

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

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

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

在自己的行上定义每个变量总是一个好主意。 当你重写你的初始目标-с代码时

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

许多事情变得清晰。

问题是 – 你的字符串是不是?
第一个例子可能会奏效。
即使在非客观C编译器中,也可以通过链接器/编译器选项将文字字符串放在const存储器中。

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

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

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

你想做什么?

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

你似乎从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 

…除了其他人指出的明显的指针定义问题。