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中不起作用的幕后细节。 任何帮助是极大的赞赏。 谢谢! 🙂
在第一个示例中, x
和pointerX
具有不同的类型( (int)
和(int *)
)。 在第二个示例中, string
和stringPointer
具有相同的类型( 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
…除了其他人指出的明显的指针定义问题。