#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
中是否允许所有三种格式打印数组,哪种格式最快?
答案 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
所以你可以看到,编译器以完全相同的方式处理所有操作,它们被转换为相同的汇编指令,因此需要相同的时间。