打印数组的最快格式

时间:2016-02-02 14:19:54

标签: c arrays

#include<stdio.h>

int main()
{
    int num[]={24, 34, 12, 44, 56, 17},i;
    for(i=0;i<=5;i++)
    {
        printf("%d\n",i[num]);
        printf("%d\n",num[i]);
        printf("%d\n",*(num+i));
    }
    return 0;
}

// C中是否允许所有三种格式打印数组,哪种格式最快?

4 个答案:

答案 0 :(得分:6)

全部相同

num[i] = *(num + i) = i[num]

当涉及哪个更快时,编译器在所有情况下执行相同的操作,因此它是相同的。

答案 1 :(得分:4)

所有3个案例都是允许的,因为num[i]仅为"syntactic sugar",因为可读性较低的格式为*(num+i)

这由标准6.5.2.1保证:

  

下标运算符[]的定义是E1 [E2]是   与(*((E1)+(E2)))

相同

那么你的3个案例归结为:

  • *(i + num)
  • *(num + i)
  • *(num + i)

+运算符的运算符的顺序不会影响性能,因此它们都是100%等效的。

答案 2 :(得分:3)

现代编译器将优化所有三种方法。这可能完全不同。

此外,这里的瓶颈将在整数值的字符串化和OS的缓冲中。

i[num]:我相信你在实践中不会这样做。

答案 3 :(得分:1)

如果到目前为止答案还没有让你确信所有三种方法都是相同的,那么下面是类似案例的汇编代码。用简单的赋值替换printf以简化操作。

取C代码:

 int main()
 {
     int num[]={24, 34, 12, 44, 56, 17},i;
     int dst[]={0,0,0,0,0,0};
     int dst1[]={0,0,0,0,0,0};
     int dst2[]={0,0,0,0,0,0};

     for(i = 0; i <=5; i++)
     {
         dst[0] = i[num];
         dst1[0] = num[i];
         dst2[0] = *(num+i);
     }

     return 0;
 }

编译:

  

gcc test.c -o test.out

使用otool(OSX)查看程序集

  

otool -tV test.out

在剥离不相关的东西后,对应于我们的3个作业的装配线:

@ For loop
0000000100000ed0    cmpl    $0x5, -0x88(%rbp)
0000000100000eda    jg  0x100000f20

@  dst[0] = i[num];
0000000100000ee0    movslq  -0x88(%rbp), %rax
0000000100000ee7    movl    -0x20(%rbp,%rax,4), %ecx
0000000100000eeb    movl    %ecx, -0x40(%rbp)

@ dst1[0] = num[i];
0000000100000eee    movslq  -0x88(%rbp), %rax
0000000100000ef5    movl    -0x20(%rbp,%rax,4), %ecx
0000000100000ef9    movl    %ecx, -0x60(%rbp)

@ dst2[0] = *(num+i);      
0000000100000efc    movslq  -0x88(%rbp), %rax
0000000100000f03    movl    -0x20(%rbp,%rax,4), %ecx
0000000100000f07    movl    %ecx, -0x80(%rbp)

@ For loop
0000000100000f0a    movl    -0x88(%rbp), %eax
0000000100000f10    addl    $0x1, %eax
0000000100000f15    movl    %eax, -0x88(%rbp)
0000000100000f1b    jmp 0x100000ed0

所以你可以看到,编译器以完全相同的方式处理所有操作,它们被转换为相同的汇编指令,因此需要相同的时间。