在以下代码中,b
的地址在块内时会发生变化。为什么?如果它为b
更改,为什么不为?
int b =42;
int *a = &b;
printf("%p", a);
printf("%p", &b);
void (^testBlock)(void) = ^(void)
{
printf("%p", a); //address not changed
printf("%p", &b); //address is changed
};
testBlock();
printf("%p", a); //address not changed
printf("%p", &b);//address not changed
答案 0 :(得分:1)
块类似于函数。考虑:
void testFunc(int *a, int b)
{
printf("%p", a);
printf("%p", &b);
}
int b =42;
int *a = &b;
printf("%p", a);
printf("%p", &b);
testFunc(a, b);
printf("%p", a); //address not changed
printf("%p", &b);//address not changed
对函数的调用已将a
和b
的值复制到testFunc()
中的局部变量(参数),这些变量恰好也被命名为a
和{ {1}}。这些变量与另一个范围中的b
和a
不同。它们具有相同的价值。因此,参数的地址不同于其他变量的地址。
如果是b
,您需要打印其值,而不是其地址。所以,这是相同的,因为价值是被复制的。在a
的情况下,您正在打印其地址。
答案 1 :(得分:0)
Blocks维护从周围范围捕获的非__block
局部变量的单独副本,因为块可能比它们创建的范围更长。您可以将此单独副本视为一种“实例变量”块在执行时透明地使用的块对象。这个单独的副本在创建块时初始化为外部变量的值。
由于它是一个单独的副本,因此它将具有与原始变量不同的地址(这就是&b
不同的原因)。但是,该变量的两个副本的值最初都是相同的(直到有人更改外部副本),因为块的副本是使用外部副本的值初始化的(这就是为什么{{1两者都是一样的。
答案 2 :(得分:-1)
int b
和int *a
完全不同,因为b
是一个值,而a
是一个参考。
Blocks捕获它们需要执行的变量,以避免在变量释放后访问它。这对于值类型的意义可能是它被复制(与将值传递给函数时复制的方式相同),这就是为什么你会看到b
的不同地址。