指针和循环 [英] Pointers and Loops

查看:277
本文介绍了指针和循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



 这个问题已经困扰了我一段时间了:是否有区别(如记忆方式)指针* somePointer; 
for(...)
{
somePointer = something;
//用somePointer
来做东西}

  for(...)
{
指针* somePointer = something;
//用somePointer来做东西


解决方案
如果我们打开汇编,我们可以看到第二个剪辑只需要执行另外两个指令:

代码片段1:

(c = 0; c <= 10; c ++)
(* p1)++;

  

0x080483c1< + 13> ;: lea -0x8(%ebp),%eax #eax =& g
0x080483c4< + 16> ;: mov%eax,-0xc ebp)#p1 = g
0x080483c7< + 19> ;: movl $ 0x0,-0x4(%ebp)#c = 0
0x080483ce< + 26>:jmp 0x80483e1< main + 45> #0在循环中跳跃
0x080483d0 <+ 28>:mov -0xc(%ebp),%eax #eax = p1
0x080483d3 <+ 31>:mov(%eax),%eax# eax = * p1
0x080483d5 <+ 33>:lea 0x1(%eax),%edx#edx = eax + 1
0x080483d8 <+ 36>:mov -0xc(%ebp) eax#eax = p1
0x080483db< + 39> ;: mov%edx,(%eax)#* p1 = edx
0x080483dd< + 41> ;: addl $ 0x1,-0x4(%ebp) #c ++
0x080483e1< + 45>:cmpl $ 0xa,-0x4(%ebp)#如果需要则重新循环
0x080483e5< + 49>:jle 0x80483d0< main + 28>

片段2:

 (c = 0; c <= 10; c ++){
int * p2 =& g;
(* p2) - ;
}
0x080483f0< + 60> ;: lea -0x8(%ebp),%eax #eax =& g
0x080483f3< + 63> ;: mov%eax,-0x10 %ebp)#p2 = eax
0x080483f6 <+ 66>:mov -0x10(%ebp),%eax#eax = p2
0x080483f9< + 69>:mov eax#eax = * p2
0x080483fb< + 71> ;: lea -0x1(%eax),%edx#edx = eax-1
0x080483fe< + 74> ;: mov -0x10(%ebp ),%eax#eax = p2
0x08048401< + 77> ;: mov%edx,(%eax)#* p2 = edx
0x08048403 <+ 79>:addl $ 0x1,-0x4 %ebp)#increment c
0x08048407< + 83> ;: cmpl $ 0xa,-0x4(%ebp)#如果需要,循环
0x0804840b< + 87>:jle 0x80483f0< main + 60>

好的,区别在于每个循环执行的代码片段#2的前两个指令,而在第一个片段中,他们刚刚进入循环之前执行。

希望我清楚。 ;)

This one has been bothering me for a while now: Is there a difference (e.g. memory-wise) between this

Pointer *somePointer;
for (...)
{
    somePointer = something;
    // do stuff with somePointer
}

and this

for (...)
{
    Pointer *somePointer = something;
    // do stuff with somePointer
}

解决方案

Well, first, in you second example somePointer will be valid only inside the loop (it's scope), so if you want to use it outside you have to do like in snippet #1.
If we turn on assembly we can see that the second snipped needs only 2 more instructions to execute:

Snippet 1:

for(c = 0; c <= 10; c++)
    (*p1)++;  

0x080483c1 <+13>:   lea    -0x8(%ebp),%eax          # eax = &g
0x080483c4 <+16>:   mov    %eax,-0xc(%ebp)          # p1 = g
0x080483c7 <+19>:   movl   $0x0,-0x4(%ebp)          # c = 0
0x080483ce <+26>:   jmp    0x80483e1 <main+45>      # dive in the loop
0x080483d0 <+28>:   mov    -0xc(%ebp),%eax          # eax = p1
0x080483d3 <+31>:   mov    (%eax),%eax              # eax = *p1
0x080483d5 <+33>:   lea    0x1(%eax),%edx           # edx = eax + 1
0x080483d8 <+36>:   mov    -0xc(%ebp),%eax          # eax = p1
0x080483db <+39>:   mov    %edx,(%eax)              # *p1 = edx
0x080483dd <+41>:   addl   $0x1,-0x4(%ebp)          # c++
0x080483e1 <+45>:   cmpl   $0xa,-0x4(%ebp)           # re-loop if needed
0x080483e5 <+49>:   jle    0x80483d0 <main+28>

Snippet 2:

for(c = 0; c <= 10; c++) {
    int *p2 = &g;
    (*p2)--;
}
0x080483f0 <+60>:   lea    -0x8(%ebp),%eax          # eax = &g
0x080483f3 <+63>:   mov    %eax,-0x10(%ebp)         # p2 = eax
0x080483f6 <+66>:   mov    -0x10(%ebp),%eax         # eax = p2
0x080483f9 <+69>:   mov    (%eax),%eax              # eax = *p2
0x080483fb <+71>:   lea    -0x1(%eax),%edx          # edx = eax - 1
0x080483fe <+74>:   mov    -0x10(%ebp),%eax         # eax = p2
0x08048401 <+77>:   mov    %edx,(%eax)              # *p2 = edx
0x08048403 <+79>:   addl   $0x1,-0x4(%ebp)          # increment c
0x08048407 <+83>:   cmpl   $0xa,-0x4(%ebp)          # loop if needed
0x0804840b <+87>:   jle    0x80483f0 <main+60>

Ok, the difference is in the first two instructions of snippet #2 which are executed at every loop, while in the first snippet they're executed just before entering the loop.
Hope I was clear. ;)

这篇关于指针和循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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