4.1 指针与 const
答:______________
✅ 查看答案与解析
答案 对
解析:const int* p 是“指向常量的指针”:*p 不能改,p 能改。int* const p 才是“常量指针”:指向不能改。
答:______________
✅ 查看答案与解析
答案 对
解析:NULL 在 C++ 里通常是整数 0,重载解析时会挑错函数;nullptr 是类型安全的空指针。
int*
int
编译错误
void*
答:______________
✅ 查看答案与解析
答案 B
解析:星号只跟着第一个名字。pa 是 int*,pb 是 int。想两个都是指针要写 int *pa, *pb;。
void f(int) { }
void f(int*) { }
f(NULL); // 想调用指针版本,实际调了 int 版本
✅ 查看答案与解析
答案 f(nullptr); // nullptr 是真正的空指针,会选指针版本
解析:NULL 是整数 0,重载解析选择了 f(int);nullptr 类型安全,一定选中 f(int*)。
提示:注意判空:if (!a || !b) return;
✅ 查看答案与解析
答案 参考答案:
解析:指针可能为空,使用前先判空;通过解引用 *a 修改原变量。
#include <iostream>
void swapPtr(int* a, int* b) {
if (!a || !b) { return; }
int t = *a; *a = *b; *b = t;
}
int main() {
int x = 3, y = 5;
swapPtr(&x, &y);
std::cout << x << ' ' << y << '\n'; // 5 3
return 0;
}4.2 数组退化与字符串
答:______________
✅ 查看答案与解析
答案 对
解析:void f(int arr[]) 等价于 void f(int* arr),长度信息在传参时就丢了。
答:______________
✅ 查看答案与解析
答案 错
解析:原生数组不检查越界,a[5] 只是访问了别人的内存,结果不可预测(未定义行为)。
指针大小
数组元素个数(5)
数组总字节数
编译错误
答:______________
✅ 查看答案与解析
答案 B
解析:在定义作用域里 sizeof(a) 是数组总字节数(20),除以单元素大小(4)得到个数 5。一旦退化成指针,sizeof 就变 8。
void printCount(int arr[]) {
int n = sizeof(arr) / sizeof(arr[0]); // 结果不对!
std::cout << n;
}
✅ 查看答案与解析
答案 函数参数里的数组写法只是装饰,arr 是 int*,sizeof(arr) 是 8。改成:
解析:要拿长度必须额外传参数,或用 std::vector<int>(自带 size())。
void printCount(int arr[], int n) { ... } // 额外传长度
// 或改用 std::vector / std::array / std::span提示:遍历时维护最大值变量。
✅ 查看答案与解析
答案 参考答案:
解析:需要动态长度时优先用 std::vector,而不是原生数组。
#include <iostream>
#include <vector>
int main() {
int n;
std::cin >> n;
std::vector<int> v(n);
for (int i = 0; i < n; ++i) { std::cin >> v[i]; }
int mx = v[0];
for (int x : v) { if (x > mx) { mx = x; } }
std::cout << mx << '\n';
return 0;
}4.3 动态内存:new 与 delete
答:______________
✅ 查看答案与解析
答案 对
解析:int* arr = new int[10]; 必须 delete[] arr;。只写 delete 是未定义行为。
答:______________
✅ 查看答案与解析
答案 错
解析:两套内存函数绝对不能混用:new 不能 free,malloc 不能 delete。混用是未定义行为,常表现为在毫不相关的地方崩溃。
int*
char*
void*
nullptr
答:______________
✅ 查看答案与解析
答案 C
解析:malloc 返回 void*,不能直接解引用和做算术,要转回具体类型。
int* a = new int[10];
std::free(a); // 错误 1:new 的内存不能 free
int* b = new int[10];
delete b; // 错误 2:new[] 必须配 delete[]
✅ 查看答案与解析
答案 delete[] a;
解析:两处都改成 delete[]。记住配对规则:new↔delete、new[]↔delete[]、malloc↔free。
delete[] b;提示:new int[5]{} 会把元素初始化为 0。
✅ 查看答案与解析
答案 参考答案:
解析:new[] 之后记得 delete[];更省心的做法是直接用 std::vector。
#include <iostream>
int main() {
int* arr = new int[5]{1, 2, 3, 4, 5};
int sum = 0;
for (int i = 0; i < 5; ++i) { sum += arr[i]; }
std::cout << sum << '\n'; // 15
delete[] arr;
return 0;
}4.4 RAII 与智能指针
答:______________
✅ 查看答案与解析
答案 对
解析:独占所有权:同一时刻对象只属于一个人。不能拷贝(拷贝会复制裸指针导致双重释放),只能 std::move。
答:______________
✅ 查看答案与解析
答案 对
解析:shared_ptr 维护引用计数,计数归零自动释放。代价是原子操作开销,只在真正需要共享所有权时用。
shared_ptr
unique_ptr
weak_ptr
裸指针
答:______________
✅ 查看答案与解析
答案 B
解析:unique_ptr 无额外开销、语义最清楚:同一对象只属于一个人。shared_ptr 只在确实需要共享时才用。
Node* raw = new Node();
std::shared_ptr<Node> a(raw);
std::shared_ptr<Node> b(raw); // 两个 shared_ptr 各自管理同一块内存
✅ 查看答案与解析
答案 从同一个 shared_ptr 拷贝:
解析:绝不用裸指针 new 之后交给两个 shared_ptr。要共享就从同一个 shared_ptr 拷贝。
std::shared_ptr<Node> a = std::make_shared<Node>();
std::shared_ptr<Node> b = a; // 计数变 2,归零时只释放一次提示:std::make_unique<Node>();Node 定义里 next 用 unique_ptr。
✅ 查看答案与解析
答案 参考答案:
解析:unique_ptr 析构时自动释放它持有的 next,递归释放整条链,不需要手写 delete。
#include <iostream>
#include <memory>
struct Node {
int value = 0;
std::unique_ptr<Node> next;
};
int main() {
auto head = std::make_unique<Node>();
head->value = 1;
head->next = std::make_unique<Node>();
head->next->value = 2;
std::cout << head->value << ' ' << head->next->value << '\n'; // 1 2
return 0; // 离开作用域自动释放整条链
}