- 循环遍历数组:
- 场景示例:
在一个需要频繁访问数组元素的循环中,例如计算数组所有元素之和。
#include <stdio.h>
int main() {
int arr[1000];
for (int i = 0; i < 1000; i++) {
arr[i]=i;
}
int sum = 0;
int *ptr = arr;
// 减少指针解引用方式
for (int i = 0; i < 1000; i++) {
sum += *ptr;
ptr++;
}
// 常规数组下标方式(指针解引用较多)
// for (int i = 0; i < 1000; i++) {
// sum += arr[i];
// }
printf("Sum: %d\n", sum);
return 0;
}
- 原因:使用指针且减少指针解引用次数,每次循环只需一次指针解引用操作(
sum += *ptr;
)。而使用数组下标(如arr[i]
),编译器需要根据数组基地址、数组元素类型大小以及下标i
计算出实际的内存地址,然后进行解引用操作,这涉及多次计算和间接寻址,增加了开销。在循环次数很多时,这种开销积累起来会影响性能。
- 链表操作:
- 场景示例:
遍历链表并对每个节点的数据进行处理。假设有一个简单的链表结构:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
void processList(struct Node *head) {
struct Node *current = head;
while (current != NULL) {
// 减少指针解引用方式,先保存data到临时变量
int temp = current->data;
// 对temp进行处理,这里简单打印
printf("%d ", temp);
current = current->next;
}
}
int main() {
struct Node *head = (struct Node *)malloc(sizeof(struct Node));
head->data = 1;
struct Node *node2 = (struct Node *)malloc(sizeof(struct Node));
node2->data = 2;
head->next = node2;
node2->next = NULL;
processList(head);
return 0;
}
- 原因:如果每次都直接通过
current->data
来访问节点数据,每次访问都需要进行指针解引用操作。先将current->data
的值保存到临时变量temp
,后续处理使用temp
,这样对于每个节点只需要一次指针解引用获取数据,减少了重复解引用的开销,特别是在链表较长时,性能提升较为明显。