面试题答案
一键面试1. 设计基于链表的复杂数据结构及操作函数
假设链表节点的结构体如下:
#include <stdio.h>
#include <stdlib.h>
// 定义内部结构体
typedef struct InnerStruct {
int innerValue;
float innerFloat;
} InnerStruct;
// 定义链表节点结构体
typedef struct Node {
int value;
char ch;
InnerStruct inner;
struct Node *next;
} Node;
// 创建新节点的函数
Node* createNode(int val, char c, int innerVal, float innerFloat) {
Node *newNode = (Node*)malloc(sizeof(Node));
newNode->value = val;
newNode->ch = c;
newNode->inner.innerValue = innerVal;
newNode->inner.innerFloat = innerFloat;
newNode->next = NULL;
return newNode;
}
// 对链表节点进行复杂操作的函数
void complexOperation(Node *head) {
Node *current = head;
while (current != NULL) {
// 例如,根据特定规则对各节点的多个成员进行计算并更新
current->value = current->value + current->inner.innerValue;
current->inner.innerFloat = current->inner.innerFloat * (float)current->value;
current = current->next;
}
}
2. 传递结构体指针给函数可能遇到的问题及解决方案
问题:
- 内存管理问题:如果在函数内部对结构体指针所指向的内存进行了修改(如重新分配内存),调用者可能不知道如何正确处理这些修改后的内存。例如,如果函数内部为结构体中的某个指针成员分配了新内存,但调用者不知道,可能会导致内存泄漏(调用者没有释放新分配的内存)或悬空指针(调用者在函数返回后释放了原内存,而新内存无法正确访问)。
- 数据一致性问题:如果结构体中有多个成员相互关联,函数对其中一个成员的修改可能会影响到其他成员的一致性。例如,结构体中可能有一个表示总数的成员,和多个表示部分数量的成员,函数只修改了部分数量成员,而没有更新总数成员,导致数据不一致。
- 空指针引用:如果传递给函数的结构体指针为空指针,函数内部直接访问指针指向的结构体成员会导致程序崩溃。
解决方案:
- 明确内存管理责任:在函数文档中清晰说明对结构体指针所指向内存的操作情况。如果函数分配了新内存,应提供相应的释放函数,或者约定由调用者负责释放内存。例如,若函数为结构体中的某个指针成员分配了新内存,同时提供一个释放该内存的函数供调用者使用。
- 维护数据一致性:在函数内部修改结构体成员时,确保所有相关成员都得到正确更新。可以在函数内部封装一系列操作,保证数据一致性。例如,在修改部分数量成员后,同时更新总数成员。
- 空指针检查:在函数入口处对传入的结构体指针进行空指针检查,若为空指针,直接返回或进行相应的错误处理,避免空指针引用导致程序崩溃。例如:
void complexOperation(Node *head) {
if (head == NULL) {
return;
}
Node *current = head;
// 后续操作
}