为啥我不用 * 声明 NSInteger

Posted

技术标签:

【中文标题】为啥我不用 * 声明 NSInteger【英文标题】:Why don't I declare NSInteger with a *为什么我不用 * 声明 NSInteger 【发布时间】:2010-11-04 02:01:18 【问题描述】:

我正在 iTunes U 上的斯坦福大学 iPhone 课程中尝试我的手,我对指针有点困惑。在第一个作业中,我尝试做这样的事情

NSString *processName = [[NSProcessInfo processInfo] processName];
NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];

产生了一个错误,在盲目地修补之后,我发现是 NSInteger 行中的 * 导致了问题。

所以我显然不明白发生了什么。我将解释我认为它是如何工作的,也许有人会很好地指出这个缺陷。

与 Web 开发不同,我现在需要 比 Web 开发更担心内存。所以当我 创建一个变量,它被分配一个 某处的内存位(RAM I 认为)。而不是通过 变量,我传递一个指针 周围的那一点记忆。和 指针是通过添加前缀来声明的 带 * 的变量名。

假设我是对的,让我感到困惑的是为什么我不需要为 NSInteger 这样做?

【问题讨论】:

【参考方案1】:

NSInteger 是原始类型,这意味着它可以本地存储在堆栈中。您不需要使用指针来访问它,但如果您愿意,您可以。行:

NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];

返回一个实际变量,而不是它的地址。要解决此问题,您需要删除 *:

NSInteger processID = [[NSProcessInfo processInfo] processIdentifier];

如果你真的想要,你可以有一个指向 NSInteger 的指针:

NSInteger *pointerToProcessID = &processID;

& 号是操作符的地址。它将指向NSInteger 的指针设置为等于内存中变量的地址,而不是指向变量中的整数。

【讨论】:

我怀疑这将是一个非常方便的提示。谢谢。 当我从 webdev 转向 iPhone 开发时,这对我来说是一个重大问题。另一个需要注意的是确保以 nil 终止 NSArray。 如果你双击 NSInteger 或其他你在 XCode 中感到困惑的类型,你可以得到它的定义,在这种情况下是: typedef int NSInteger;所以它毕竟是一个普通的旧 int。 这是无效的。 & 运算符需要一个左值,而方法调用是一个右值。 另请注意,此示例仅在您要在同一调用堆栈中使用 processID 指针时才有用。如果以后需要使用它,则需要使用 calloc 在堆上分配内存,然后将值存储到该内存中。像这样的东西: NSInteger *processID = calloc(1, sizeof(NSInteger)); *processID = [[NSProcessInfo processInfo] processIdentifier];【参考方案2】:

您不使用* 声明NSInteger 的原因是因为它不是对象。 NSInteger 只是一个 intlong

#if __LP64__
typedef long NSInteger;
#else
typedef int NSInteger;
endif

如果在 32 位应用程序中使用,则为 32 位整数,如果在 64 位应用程序中构建,则为 64 位整数。

当然,您可以NSInteger 作为指针传递,但大多数函数只是将参数作为NSInteger 而不是指向它的指针。

另一方面,对象只能作为指针传递给其他函数。这是因为对象具有为它们动态分配的内存,因此不能在堆栈上声明。因为intlong 为它们分配了固定数量的内存,所以这不是问题。

【讨论】:

【参考方案3】:

* 表示“指针”。对象变量持有一个指向对象的指针,所以它有一个*; NSInteger 变量包含一个 NSInteger,而不是指向 NSInteger 的指针,因此它没有*。将* 放在该变量上至少会给您一个警告,因为您将整数放入指针变量中。

【讨论】:

【参考方案4】:

NSInteger 只是 int 的 typedef,AFAIK。

【讨论】:

可以,但并非无处不在。在 64 位 Mac OS X 系统上,NSInteger 定义为 long。不难想象,有朝一日在运行 ios 的架构上可能会出现这种情况。【参考方案5】:

使用指针

NSInteger integer1 = 1;
NSLog(@"1. integer1:%ld &integer1:%p", integer1, &integer1);
//1. integer1:1 &integer1:0x7ffee59e8a98

NSInteger *integer2 = &integer1;
NSLog(@"2. integer2:%p &integer2:%p *integer2:%ld", integer2, &integer2, *integer2);
//2. integer2:0x7ffee59e8a98 &integer2:0x7ffee59e8a90 *integer2:1

*integer2 = 2;
NSLog(@"3. integer2:%p &integer2:%p *integer2:%ld \t integer1:%ld &integer1:%p", integer2, &integer2, *integer2, integer1, &integer1);
//3. integer2:0x7ffee59e8a98 &integer2:0x7ffee59e8a90 *integer2:2    integer1:2 &integer1:0x7ffee59e8a98

【讨论】:

以上是关于为啥我不用 * 声明 NSInteger的主要内容,如果未能解决你的问题,请参考以下文章

请问java里面为啥有时候声明对象的时候不用new??

c语言----为啥函数定义时不用加;

c#里为啥有的使用时函数需要new一个对象而有的不用?为啥不直接调用就好?

为啥Go中有int但没有float?

为啥我不用 npm 来安装 yarn?

为啥我不能在类声明中放置“使用”声明?