面试题答案
一键面试使用指针运算遍历并求和
#include <stdio.h>
int main() {
int arr[10000];
// 初始化数组,这里简单赋值为1到10000
for (int i = 0; i < 10000; i++) {
arr[i] = i + 1;
}
int sum = 0;
int *p = arr;
for (int i = 0; i < 10000; i++) {
sum += *p;
p++;
}
printf("指针运算求和结果: %d\n", sum);
return 0;
}
使用数组下标运算遍历并求和
#include <stdio.h>
int main() {
int arr[10000];
// 初始化数组,这里简单赋值为1到10000
for (int i = 0; i < 10000; i++) {
arr[i] = i + 1;
}
int sum = 0;
for (int i = 0; i < 10000; i++) {
sum += arr[i];
}
printf("数组下标运算求和结果: %d\n", sum);
return 0;
}
性能分析
- 优势:现代编译器在优化代码时,对于指针运算和数组下标运算通常能生成相似的机器码,性能差异不大。在一些情况下,指针运算可能有优势。指针运算直接对内存地址进行操作,减少了数组越界检查的开销(虽然在C语言中,数组越界本身不会自动检查,但使用指针时程序员可更灵活地控制地址访问)。例如在循环中,如果需要频繁地移动到数组的不同位置,指针运算通过直接修改指针的值,可以更高效地定位到目标元素,而数组下标运算每次都需要通过公式
base_address + index * sizeof(type)
来计算地址,指针运算在这种场景下可能会有轻微的性能提升。 - 劣势:指针运算如果使用不当,很容易造成内存访问错误,如野指针、越界访问等,这些错误可能导致程序崩溃或未定义行为,而数组下标运算相对更容易检查边界,代码可读性更好。如果编译器优化程度高,数组下标运算也会被优化成与指针运算相近的机器码,此时指针运算的优势就不明显了。
产生这些差异的原因主要是:指针运算直接操作内存地址,在内存访问的灵活性上有优势,但安全性较低;数组下标运算基于固定的计算方式获取元素地址,相对更安全,但灵活性略差。现代编译器的优化使得两者在很多情况下性能相近。