关于指针:在Objective-C中放置星号

Placement of the asterisk in Objective-C

我刚刚开始学习Objective-C,它来自于vb.net和c.net的背景。我理解指针的用法,但是在Objective-C示例中,我看到星号放在几个不同的地方,并且尽可能地进行搜索,我还没有找到一个答案来解释这是为什么。我尝试的每一次搜索都会找到各种关于指针的解释(我确实不需要),但没有一次提到星号不同位置的原因/影响。以下是我看到的一些例子:

1
2
3
4
NSString *string;
NSString * string;
(NSString *) string;
NSString* string;

星号的这些不同位置是什么意思?我相信这是一个简单的答案,但令人沮丧的是,到目前为止,还没能在苹果的任何教程和参考文档中或在线上找到它。

有人能结束我的痛苦,回答这个令人困惑的问题吗?谢谢!


没有区别,但是您应该知道,只有第一个"标记"(也就是说)定义了类型名,而*不是类型名的一部分。这就是说:

1
NSString *aString, bString;

创建一个指向NSString的指针和一个NSString。要使两者都成为指针,请执行以下任一操作:

1
NSString *aString, *bString;

或:

1
2
NSString *aString;
NSString *bString;


1
2
3
4
1.  NSString *string;
2.  NSString * string;
3.  (NSString *) string;
4.  NSString* string;

1、2和4完全相同。全是款式。随便拿你想要的,或者把它弄混。

choice 3还有另一个含义,它用于铸造。例如:

1
t = (NSString *)string ;

string强制转换为NSString指针。

但是choice 3是您可能在.h文件或.m文件中的函数定义中使用的语法。在实际函数中,在"运行"的代码中,它有不同的含义。


没什么区别——这是风格问题。它们都声明一个名为string的变量,该变量是指向nsstring的指针。在某些上下文(尤其是方法声明)中,括号是必要的,以便澄清它是一个类型声明。


1
2
3
4
1.  NSString *string;
2.  NSString * string;
3.  (NSString *) string;
4.  NSString* string;

1、2和4是等效的。C语言(和C的objective-C超集)指定了对空白不敏感的语法。因此,您可以在样式方面自由添加空间。所有相关语法均由非空白字符(如{};等)分隔[1]。

3要么是类型转换(告诉C编译器使用NSString*类型,而不考虑声明的string类型)。在Objective-C中,很少需要对象实例的类型转换。对于可以引用任何对象类型实例的变量,可以使用id类型。

在方法声明中,语法3(有时不带结尾分号)用于声明方法参数的类型。Objective-C方法可能如下所示:

1
- (void)myMethodThatTakesAString:(NSString*)string;

在这个声明中,名为string的参数的类型是NSString*类型(前面的-表示与类方法相反的实例方法)。具有多个参数的方法声明可能如下所示:

1
- (void)myMethodTakingAString:(NSString*)string andAnInteger:(NSInteger)intParam;

[1]这与使用空格作为块分隔符的Python等语言进行比较。


把星号放在哪里并不重要,所有语句都创建nsstring类型的指针。

当在一行中使用多个变量名时,您必须为每个变量写上星号。

1
NSString * nsstring, * nsstring2;


没有区别,在指针声明中放置*是不相关的。


完全没有区别。nsstring*mystring和nsstring*mystring相同。


没有区别,空白位置是不相关的。


*的工作方式与标准C中的相同。

这是一个很好的底漆,可以把*放在不同的地方,它的作用是:http://boredzo.org/pointers网站/


这两者完全没有区别。


实际上所有这些都是等价的:指向nsstring的指针!!


1、2和4等效,并定义指向nsstring的指针。我个人的喜好是尽可能地模仿K&R,所以我喜欢使用NSString *string;

(NString*)string;虽然是一个有效的语句,但它本身并没有做任何事情。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cat foo.m
#include <Cocoa/Cocoa.h>

void foo()
{
    NSString *string;

    (NSString*) string;  // doesn't do anything
    42;   // doesn't do anything either
}

$ gcc -Wall -c foo.m
foo.m: In function 'foo':
foo.m:7: warning: statement with no effect
foo.m:8: warning: statement with no effect

计算机的备选方案1、2和4可能没有任何差异,但代码的其他读者也有差异。

由于https://stackoverflow.com/a/1521382和https://stackoverflow.com/a/16040884和https://www.tutorialspoint.com/objective_c/objective_c_pointers.htm等解释使用了第一种替代方法:

1. NSString *string;

所有额外的变量都需要自己的星号,比如:

NSString *aString, *bString;

我谦虚的建议是我们使用备选方案1作为标准。


在xcode4文档示例代码中,您可以看到3。一直以来,例如在movemeview.m中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#if 1

- (void)growAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {

#define MOVE_ANIMATION_DURATION_SECONDS 0.15

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:MOVE_ANIMATION_DURATION_SECONDS];
placardView.transform = CGAffineTransformMakeScale(1.1f, 1.1f);
/*
 Move the placardView to under the touch.
 We passed the location wrapped in an NSValue as the context.
 Get the point from the value, then release the value because we retained it in touchesBegan:withEvent:.
 */

NSValue *touchPointValue = (NSValue *)context;
placardView.center = [touchPointValue CGPointValue];
[touchPointValue release];
[UIView commitAnimations];
}