Chinaunix首页 | 论坛 | 博客
  • 博客访问: 25913
  • 博文数量: 5
  • 博客积分: 1780
  • 博客等级: 上尉
  • 技术积分: 80
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-28 22:37
文章分类

全部博文(5)

文章存档

2009年(5)

分类: C/C++

2009-08-28 23:45:11

在c/c++里有两个基本的循环形式
     for(...)
     while(...)

在语义上是有些区别的,但通过编译器后,都要最后形成要执行的机器指令. 那么对于编译器的输出,这两种形式的最后结果是否一样呢? 这里以suse linux 10 64bit系统为例子,看看gcc输出的情况.

操作系统: suse linux 10 64bit
编译器:   gcc version 4.1.2 20070115 (SUSE Linux)

如下的c代码:
 其中函数f1()里用了for循环.
 其中函数f2()里用了while循环.
#include

int f1()
{
   int i;
   int n;
   int a[8];
  
   n=8;
   for(i=0;i   {
     a[i]=0;
   }
   return(i);
}

int f2()
{
   int i;
   int n;
   int a[8];
  

   n=8;
   i=0;
   while(i   {
     a[i]=0;
     i++;
   }  
   return(i);
}

int main()
{
  f1();
  f2();
  return(0);
}


看一下gcc 对应的输出:

    .file    "t1.c"
    .text
.globl f1
    .type    f1, @function
f1:
.LFB2:
    pushq    %rbp
.LCFI0:
    movq    %rsp, %rbp
.LCFI1:
    movl    $8, -4(%rbp)
    movl    $0, -8(%rbp)
    jmp    .L2
.L3:
    movl    -8(%rbp), %eax
    cltq
    movl    $0, -48(%rbp,%rax,4)
    addl    $1, -8(%rbp)
.L2:
    movl    -8(%rbp), %eax
    cmpl    -4(%rbp), %eax
    jl    .L3
    movl    -8(%rbp), %eax
    leave
    ret
.LFE2:
    .size    f1, .-f1
.globl f2
    .type    f2, @function
f2:
.LFB3:
    pushq    %rbp
.LCFI2:
    movq    %rsp, %rbp
.LCFI3:
    movl    $8, -4(%rbp)
    movl    $0, -8(%rbp)
    jmp    .L7
.L8:
    movl    -8(%rbp), %eax
    cltq
    movl    $0, -48(%rbp,%rax,4)
    addl    $1, -8(%rbp)
.L7:
    movl    -8(%rbp), %eax
    cmpl    -4(%rbp), %eax
    jl    .L8
    movl    -8(%rbp), %eax
    leave
    ret
.LFE3:
    .size    f2, .-f2
.globl main
    .type    main, @function
main:
.LFB4:
    pushq    %rbp
.LCFI4:
    movq    %rsp, %rbp
.LCFI5:
    movl    $0, %eax
    call    f1
    movl    $0, %eax
    call    f2
    movl    $0, %eax
    leave
    ret
.LFE4:
    .size    main, .-main
    .section    .eh_frame,"a",@progbits
.Lframe1:
    .long    .LECIE1-.LSCIE1
.LSCIE1:
    .long    0x0
    .byte    0x1
    .string    "zR"
    .uleb128 0x1
    .sleb128 -8
    .byte    0x10
    .uleb128 0x1
    .byte    0x3
    .byte    0xc
    .uleb128 0x7
    .uleb128 0x8
    .byte    0x90
    .uleb128 0x1
    .align 8
.LECIE1:
.LSFDE1:
    .long    .LEFDE1-.LASFDE1
.LASFDE1:
    .long    .LASFDE1-.Lframe1
    .long    .LFB2
    .long    .LFE2-.LFB2
    .uleb128 0x0
    .byte    0x4
    .long    .LCFI0-.LFB2
    .byte    0xe
    .uleb128 0x10
    .byte    0x86
    .uleb128 0x2
    .byte    0x4
    .long    .LCFI1-.LCFI0
    .byte    0xd
    .uleb128 0x6
    .align 8
.LEFDE1:
.LSFDE3:
    .long    .LEFDE3-.LASFDE3
.LASFDE3:
    .long    .LASFDE3-.Lframe1
    .long    .LFB3
    .long    .LFE3-.LFB3
    .uleb128 0x0
    .byte    0x4
    .long    .LCFI2-.LFB3
    .byte    0xe
    .uleb128 0x10
    .byte    0x86
    .uleb128 0x2
    .byte    0x4
    .long    .LCFI3-.LCFI2
    .byte    0xd
    .uleb128 0x6
    .align 8
.LEFDE3:
.LSFDE5:
    .long    .LEFDE5-.LASFDE5
.LASFDE5:
    .long    .LASFDE5-.Lframe1
    .long    .LFB4
    .long    .LFE4-.LFB4
    .uleb128 0x0
    .byte    0x4
    .long    .LCFI4-.LFB4
    .byte    0xe
    .uleb128 0x10
    .byte    0x86
    .uleb128 0x2
    .byte    0x4
    .long    .LCFI5-.LCFI4
    .byte    0xd
    .uleb128 0x6
    .align 8
.LEFDE5:
    .ident    "GCC: (GNU) 4.1.2 20070115 (SUSE Linux)"
    .section    .note.GNU-stack,"",@progbits

输出中对应的f1()和f2()如下:

f1()如下:
f1:
.LFB2:
    pushq    %rbp
.LCFI0:
    movq    %rsp, %rbp
.LCFI1:
    movl    $8, -4(%rbp)             //对应的变量n
    movl    $0, -8(%rbp)             //对应的变量i
    jmp    .L2
.L3:
    movl    -8(%rbp), %eax           //取数组下标 i
    cltq
    movl    $0, -48(%rbp,%rax,4)     //a[i]=0;
    addl    $1, -8(%rbp)             //i++
.L2:
    movl    -8(%rbp), %eax
    cmpl    -4(%rbp), %eax           //比较i和n
    jl    .L3
    movl    -8(%rbp), %eax           //返回值送eax
    leave
    ret

f2()如下:

f2:
.LFB3:
    pushq    %rbp
.LCFI2:
    movq    %rsp, %rbp
.LCFI3:
    movl    $8, -4(%rbp)           //对应的变量n
    movl    $0, -8(%rbp)           //对应的变量i
    jmp    .L7
.L8:
    movl    -8(%rbp), %eax         //取数组下标 i
    cltq
    movl    $0, -48(%rbp,%rax,4)   //a[i]=0;
    addl    $1, -8(%rbp)           //i++
.L7:
    movl    -8(%rbp), %eax
    cmpl    -4(%rbp), %eax         //比较i和n
    jl    .L8
    movl    -8(%rbp), %eax         //返回值送eax
    leave
    ret
所看到的情况是,f1()和f2()最后输出的结果是一样的.
因此在通常情况下,用for还是用while大家关心语义和可读性就可以了,而不必关心运行效率的区别.

阅读(1183) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-10-25 23:28:24

有输出不一样的编译器吧?