面试题答案
一键面试指针传递参数更合适的场景及原理
- 允许空值情况
- 场景:在实现一个链表节点删除函数时,可能需要传入一个指针,该指针有可能为空(表示链表为空)。例如:
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
void deleteNode(ListNode* &head, ListNode* toDelete) {
if (toDelete == head) {
head = toDelete->next;
delete toDelete;
return;
}
ListNode* current = head;
while (current->next != toDelete) {
current = current->next;
}
current->next = toDelete->next;
delete toDelete;
}
- **原理**:引用不能为空值,而指针可以。这种场景下指针能更灵活地处理特殊情况,从内存管理角度,能避免对空引用操作导致的未定义行为;从安全性看,明确指针为空时不进行无效操作,提高程序健壮性。
2. 动态内存分配和释放 - 场景:在一个资源管理类(如智能指针的简化实现)中,需要通过指针来动态分配和释放内存,并且可能需要在不同函数间传递这个指针以控制资源生命周期。
class Resource {
public:
Resource() : data(new int(0)) {}
~Resource() { delete data; }
int* getData() { return data; }
private:
int* data;
};
void processResource(Resource* res) {
int* value = res->getData();
// 对value进行操作
}
- **原理**:指针能直接控制动态分配内存的生命周期,便于在不同函数间传递和管理资源。在内存管理上,通过指针能准确地在合适时机释放内存,避免内存泄漏;代码可读性上,指针操作明确表示了对动态内存的管理意图。
引用传递参数更有优势的场景及原理
- 代码可读性和简洁性
- 场景:在一个简单的数学计算函数中,如计算两个整数之和。
int add(int& a, int& b) {
return a + b;
}
- **原理**:引用语法简洁,直观地表示了参数是对原变量的引用,不需要像指针那样使用解引用操作符。从代码可读性角度,引用使代码更接近自然语言表达,让开发者更容易理解参数传递的本质;从安全性看,避免了因忘记解引用指针而导致的错误。
2. 安全性(防止空指针风险) - 场景:在一个对象方法中,该方法需要对传入对象进行操作,且确保对象一定存在。
class MyClass {
public:
void printValue(int& value) {
std::cout << "Value: " << value << std::endl;
}
};
- **原理**:引用在初始化后不能为NULL,所以在函数内部无需检查是否为空指针,提高了程序的安全性。从内存管理角度,不会出现对空指针进行操作导致的内存访问错误;代码可读性上,减少了不必要的空指针检查代码,使逻辑更清晰。