std::array 用 empty() 最安全;C 风格数组无内置空概念,需靠外部 size 或哨兵判断,sizeof 仅在栈数组未退化时有效。

std::array 用 empty() 最安全
原生 C 风格数组(比如 int arr[5])在编译期就固定大小,根本不存在“空”的概念——它永远占 5 个 int 的内存,哪怕你一个元素都没赋值。所以问“C++ int 数组是否为空”,实际得先分清你用的是哪种“数组”。
如果你用的是 std::array<int n></int>,它封装了长度信息,empty() 就是专为这事设计的:
std::array<int, 0> empty_arr; // 编译期长度为 0
std::cout << empty_arr.empty(); // true
<p>std::array<int, 3> arr = {1,2,3};
std::cout << arr.empty(); // false注意:empty() 检查的是模板参数 N 是否为 0,不是看里面有没有存有效值。哪怕 N=3 但三个元素全是 0,empty() 依然返回 false。
std::vector 用 empty() 或 size() == 0
绝大多数人真正想问的其实是“我这个可变长的 int 容器是不是没元素”,那大概率用的是 std::vector<int></int>。它支持运行时增删,empty() 是首选判断方式:
立即学习“C++免费学习笔记(深入)”;
-
empty()是常量时间操作,语义清晰,比size() == 0更直接 - 不要写
v.size() > 0或!v.size(),后者容易被误读,且对某些自定义容器可能隐含额外开销 - 切忌用
v.begin() == v.end()来判断——虽然等价,但可读性差、打字多、还容易漏括号
示例:
std::vector<int> v;
if (v.empty()) {
// 安全进入
}C 风格数组无法直接判断“空”,必须靠外部信息
像 int arr[10] 或 int* p = new int[10] 这类,编译器不记录“当前用了几个”,更不会标记“这是空的”。所谓“空”,只能是你自己约定的语义:
- 如果用指针 + 长度传参,必须额外传一个
size_t len,检查len == 0 - 如果用哨兵值(比如用
0或-1表示结束),要遍历找哨兵——这不是“判空”,是“找终止位置”,性能差且易出错 - 绝对不要对裸指针做
if (!arr)——除非arr是nullptr,否则它永远非零
错误示范:
void bad_func(int arr[]) {
if (!arr) return; // arr 是数组名退化成指针,这里永远不成立
// ……
}为什么不用 sizeof(arr)/sizeof(arr[0]) 判空?
这个表达式只在**数组名未退化为指针时**才有效,也就是仅限函数内部定义的栈数组:
void good_scope() {
int arr[0]; // 合法:长度为 0 的数组(C++14 起)
std::cout << sizeof(arr) << "\n"; // 输出 0
// 此时 sizeof(arr)/sizeof(arr[0]) 会除零报错,不能用
}但一旦数组作为参数传入函数,arr 就变成指针,sizeof(arr) 返回指针大小(通常是 8),结果完全不可靠。
更麻烦的是:int arr[0] 在不同标准和编译器下行为不一致,有些根本不允许;而 int arr[] = {} 在 C++ 中是非法的初始化写法。别碰它。
真正需要动态长度管理时,老老实实用 std::vector 或带长度参数的接口。裸数组的“空”不是语言特性,是你自己要维护的契约。










