数组迭代循环中使用下标和指针的区别

这篇博客探讨了在C语言中,使用数组下标和指针遍历数组时的效率差异。通过两组例子和对应的汇编代码分析,得出结论:在固定增量遍历时,指针可能更高效;寄存器指针比静态或堆栈指针效率更高;避免在运行时计算常量表达式。然而,考虑到可读性,通常以简洁和易懂为主,除非性能提升显著。
摘要由CSDN通过智能技术生成

我们来看一下2组例子:

第一组例子:

下标表达式:

a = get_value();
array[a] = 0;

指针表达式:

a = get_value();
*(array + a) = 0;

第二组例子:

下标表达式:

int array[10], a;
for(a=0; a<10; a+=1) {
    array[a] = 0;
}

指针表达式:

int array[10], *ap;
for(a=array; a < array + 10; ap++) {
    *ap = 0;
}

这2组例子都是一个使用下标,一个使用指针,每组例子的2中方式都实现相同的效果,但这2组例子使用下标和指针访问数组元素效率是一样的吗?

第一组例子效率完全一致,第二组例子循环体所有区别,计数器1和整形长度相乘,然后和指针相加,每次执行乘法迅运算都是相同的1和4。而指针每次都是相同的1和4相乘,而且只是在编译时执行一次,后面就是把指针和4相加。

它们到底怎么工作的呢?接下来,我们就来研究一下:

一、先看一个下标版本

#include <stdio.h>

#define SIZE 50
int x[SIZE];
int y[SIZE];
int i;
int *p1, *p2;

void try1() {
    for(i = 0; i < SIZE; i++) {
        x[i] = y[i];
    }
}


int main () {
    try1();
    return 0;
}

编译获得汇编代码:

	.file	"main.c"
	.text
	.globl	x
	.bss
	.align 32
	.type	x, @object
	.size	x, 200
x:
	.zero	200
	.globl	y
	.align 32
	.type	y, @object
	.size	y, 200
y:
	.zero	200
	.globl	i
	.align 4
	.type	i, @object
	.size	i, 4
i:
	.zero	4
	.globl	p1
	.align 8
	.type	p1, @object
	.size	p1, 8
p1:
	.zero	8
	.globl	p2
	.align 8
	.type	p2, @object
	.size	p2, 8
p2:
	.zero	8
	.text
	.globl	try1
	.type	try1, @function
try1:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	movl	$0, i(%rip)
	jmp	.L2
.L3:
	movl	i(%rip), %eax
	movl	i(%rip), %ecx
	cltq
	movl	y(,%rax,4), %edx
	movslq	%ecx, %rax
	movl	%edx, x(,%rax,4)
	movl	i(%rip), %eax
	addl	$1, %eax
	movl	%eax, i(%rip)
.L2:
	movl	i(%rip), %eax
	cmpl	$49, %eax
	jle	.L3
	nop
	nop
	popq
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值