无法理解块的词法范围 [英] Unable to understand the block's lexical scope

查看:287
本文介绍了无法理解块的词法范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要理解块的词法范围,我已编写以下代码

To understand the lexical scope of block, I have write the following code

typedef int (^ MyBlock)(void);

MyBlock b[3];

for (int i=0; i<3; i++) {
    b[i]=^{return i;};
}

for (int i=0; i<3; i++) {
    NSLog(@"%d",b[i]());
}

NSLog(@"----------------------------");

int j=0;

b[0]=^{return j;};  
j++;

b[1]=^{return j;};
j++;

b[2]=^{return j;};

for (int i=0; i<3; i++) {
    NSLog(@"%d",b[i]());
}




  1. 第一次o / p是2,2 ,2

  2. 第二次o / p为0,1,2

我期待两个块执行都是2,2,2。

I am expecting 2,2,2 for both of block execution.

有人可以解释一下为什么会这样吗?

Can anybody please explain me why is it so?

推荐答案

我假设你一直在阅读 bbum在块上的帖子并且知道你的代码不正确,因为你没有将块从堆栈复制到堆中。

I assume you’ve been reading bbum’s post on blocks and know that your code isn’t correct since you aren’t copying the blocks from the stack to the heap.

那说:

for (int i=0; i<3; i++) {
    b[i]=^{return i;};
}

在每次迭代中执行以下操作:

does the following in each iteration:


  1. 在堆栈中为块变量分配空间。假设它的内存地址是 A ;

  2. 在堆栈中创建块并将其地址( A )分配给 b [i] ;

  3. 在迭代结束时,因为复合语句/范围( {} )已经结束,弹出堆栈中的任何内容并重置堆栈指针。

  1. Allocates space in the stack for a block variable. Let's say its memory address is A;
  2. Creates the block in the stack and assign its address (A) to b[i];
  3. At the end of the iteration, since the compound statement/scope ({}) has ended, pops whatever was in the stack and resets the stack pointer.

堆栈在开始时增长每次迭代,并在每次迭代结束时收缩。这意味着所有块都在相同的内存地址中创建,即 A 。这也意味着 b 数组中的所有元素最终都指向同一个块,即最后创建的块。您可以通过运行以下代码来测试:

The stack grows at the beginning of each iteration, and shrinks at the end of each iteration. This means that all blocks are being created in the same memory address, namely A. This also means that all elements in the b array end up pointing to the same block, namely the last block that was created. You can test this by running the following code:

for (int i = 0; i < 3; i++) {
    printf("%p", (void *)b[i]);
}

应该输出如下内容:

0x7fff5fbff9e8
0x7fff5fbff9e8
0x7fff5fbff9e8

所有元素都指向同一个块,最后一个元素指向内存地址 A = 0x7fff5fbff9e8。

All elements point to the same block, the last one created in the memory address A = 0x7fff5fbff9e8.

另一方面,当你执行以下操作时:

On the other hand, when you do the following:

b[0]=^{return j;};  
j++;

b[1]=^{return j;};
j++;

b[2]=^{return j;};

没有复合语句为所有块定义相同的范围。这意味着每次创建块时,其地址都在堆栈的下方,有效地为每个块分配不同的地址。由于所有块都不同,它们正确捕获 j 的当前运行时值。

there’s no compound statement that defines the same scope for all blocks. This means that each time you create a block its address is further down the stack, effectively assigning a different address to each block. Since all blocks are different, they correctly capture the current runtime value of j.

如果打印的地址为如前所述,你应该获得类似于的输出:

If you print the address of those blocks as described earlier, you should get an output similar to:

0x7fff5fbff9b8
0x7fff5fbff990
0x7fff5fbff968

显示每个块位于不同的内存地址。

showing that each block is at a different memory address.

这篇关于无法理解块的词法范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆