在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大家关心语义和可读性就可以了,而不必关心运行效率的区别.
阅读(1250) | 评论(1) | 转发(0) |