面试题答案
一键面试核心代码
假设自定义结构体如下:
#include <stdio.h>
#include <stdlib.h>
// 自定义结构体
typedef struct {
int id;
float value;
// 其他成员变量
} CustomStruct;
// 比较函数,用于qsort
int compare(const void *a, const void *b) {
CustomStruct *structA = (CustomStruct *)a;
CustomStruct *structB = (CustomStruct *)b;
if (structA->id < structB->id) return -1;
if (structA->id > structB->id) return 1;
return 0;
}
// 核心排序代码
void sortArray(CustomStruct *array, size_t size) {
qsort(array, size, sizeof(CustomStruct), compare);
}
在主函数中调用示例:
int main() {
CustomStruct largeArray[10] = {
{3, 1.2f}, {1, 4.5f}, {2, 3.1f}, {5, 2.7f}, {4, 5.3f},
{7, 1.9f}, {6, 4.1f}, {9, 3.7f}, {8, 2.2f}, {10, 5.9f}
};
size_t size = sizeof(largeArray) / sizeof(largeArray[0]);
sortArray(largeArray, size);
for (size_t i = 0; i < size; i++) {
printf("id: %d, value: %f\n", largeArray[i].id, largeArray[i].value);
}
return 0;
}
指针操作可能存在的效率瓶颈及优化措施
- 缓存命中率低
- 瓶颈分析:大数组情况下,由于内存空间不连续,可能导致缓存命中率降低。当通过指针访问数组元素时,可能频繁出现缓存缺失,需要从内存中读取数据,这会增加访存时间。
- 优化措施:尽量使用局部性原理,例如在排序算法中,对于相邻元素的操作较多,可通过合理的算法设计减少对远距离元素的访问。同时,可以考虑使用预取指令(如果硬件支持),提前将后续需要访问的数据加载到缓存中。
- 指针间接寻址开销
- 瓶颈分析:在通过指针访问结构体成员变量时,存在间接寻址的开销。每次访问成员变量都需要通过指针找到结构体首地址,再偏移到相应成员变量的位置,这会增加指令执行周期。
- 优化措施:如果可能,将经常访问的成员变量放在结构体的开头,以减少偏移量计算的开销。另外,可以通过将结构体成员变量加载到寄存器中,减少对指针间接寻址的依赖,提高访问速度。
- 内存对齐问题
- 瓶颈分析:结构体成员变量的内存对齐可能导致空间浪费和访问效率降低。当结构体中成员变量类型不同时,为了满足内存对齐要求,可能会在成员变量之间填充一些字节,这会导致数组整体占用内存空间变大,在缓存有限的情况下,降低缓存利用率。
- 优化措施:合理设计结构体布局,按照数据类型的大小顺序排列成员变量,尽量减少填充字节。同时,可以使用编译器特定的指令或属性(如
#pragma pack
)来控制结构体的内存对齐方式,以减少空间浪费,提高缓存利用率。