获取数组长度和大小
在C++中,获取数组长度(元素个数)和大小(内存占用量)的方法取决于数组类型和上下文。
1. 内置数组(C风格数组)
在同一作用域内获取
#include <iostream>
using namespace std;
int main() {
// 定义数组
int numbers[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 方法1:使用sizeof运算符
int length1 = sizeof(numbers) / sizeof(numbers[0]);
size_t size1 = sizeof(numbers); // 字节数
cout << "方法1 - 数组长度: " << length1 << endl;
cout << "方法1 - 数组大小: " << size1 << " 字节" << endl;
// 方法2:使用模板函数(更安全)
template<typename T, size_t N>
size_t getArrayLength(T (&arr)[N]) {
return N;
}
size_t length2 = getArrayLength(numbers);
cout << "方法2 - 数组长度: " << length2 << endl;
// 方法3:C++17结构化绑定(需要知道具体元素)
auto [a, b, c, d, e, f, g, h, i, j] = numbers;
cout << "方法3 - 数组长度: " << 10 << endl;
return 0;
}
在不同作用域(函数参数)中获取
当数组作为函数参数传递时,它会退化为指针,失去大小信息:
#include <iostream>
using namespace std;
// 错误示例:无法获取数组长度
void printArrayWrong(int arr[]) {
// 错误!这里arr是指针,不是数组
// int length = sizeof(arr) / sizeof(arr[0]); // 错误!
cout << "sizeof(arr) = " << sizeof(arr) << endl; // 输出指针大小
}
// 正确方法1:传递大小参数
void printArray1(int arr[], int size) {
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
// 正确方法2:使用模板(保留数组类型信息)
template<typename T, size_t N>
void printArray2(T (&arr)[N]) {
cout << "数组长度: " << N << endl;
for (size_t i = 0; i < N; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
// 正确方法3:使用指针和结束标志
void printArray3(int* begin, int* end) {
int length = end - begin;
cout << "数组长度: " << length << endl;
for (int* p = begin; p != end; p++) {
cout << *p << " ";
}
cout << endl;
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
// 方法1:传递大小
printArray1(arr, sizeof(arr)/sizeof(arr[0]));
// 方法2:使用模板
printArray2(arr);
// 方法3:使用指针范围
printArray3(arr, arr + sizeof(arr)/sizeof(arr[0]));
return 0;
}
2. std::array(C++11)
std::array提供了直接获取长度和大小的方法:
#include <iostream>
#include <array>
using namespace std;
int main() {
array<int, 5> arr = {1, 2, 3, 4, 5};
// 获取元素个数
cout << "元素个数: " << arr.size() << endl;
cout << "元素个数: " << arr.max_size() << endl; // 与size()相同
// 获取字节大小
cout << "总字节数: " << sizeof(arr) << endl;
cout << "元素大小: " << sizeof(arr[0]) << endl;
cout << "计算长度: " << sizeof(arr) / sizeof(arr[0]) << endl;
// 使用empty()检查是否为空
cout << "是否为空: " << (arr.empty() ? "是" : "否") << endl;
// 使用范围for循环遍历
for (int num : arr) {
cout << num << " ";
}
cout << endl;
return 0;
}
3. 多维数组
#include <iostream>
using namespace std;
int main() {
// 二维数组
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// 获取总大小
cout << "总字节数: " << sizeof(matrix) << endl; // 3*4*4 = 48
// 获取行数
int rows = sizeof(matrix) / sizeof(matrix[0]);
cout << "行数: " << rows << endl;
// 获取列数
int cols = sizeof(matrix[0]) / sizeof(matrix[0][0]);
cout << "列数: " << cols << endl;
// 获取元素总数
int totalElements = sizeof(matrix) / sizeof(matrix[0][0]);
cout << "元素总数: " << totalElements << endl;
// 遍历多维数组
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
return 0;
}
4. 动态数组
对于动态分配的数组,sizeof无法获取实际长度,需要手动跟踪:
#include <iostream>
using namespace std;
int main() {
// 动态分配数组
int size = 10;
int* dynamicArray = new int[size];
// 填充数组
for (int i = 0; i < size; i++) {
dynamicArray[i] = i * 10;
}
// sizeof只能获取指针大小,不能获取数组大小
cout << "指针大小: " << sizeof(dynamicArray) << " 字节" << endl; // 通常8字节
cout << "单个元素大小: " << sizeof(dynamicArray[0]) << " 字节" << endl;
// 无法通过sizeof获取动态数组长度!
// 必须手动跟踪大小
// 正确:传递大小参数
for (int i = 0; i < size; i++) {
cout << dynamicArray[i] << " ";
}
cout << endl;
delete[] dynamicArray; // 不要忘记释放内存
return 0;
}
5. 实用模板函数
创建通用工具函数来处理数组:
#include <iostream>
#include <type_traits>
using namespace std;
// 获取数组长度的模板函数
template<typename T, size_t N>
constexpr size_t arrayLength(T (&)[N]) {
return N;
}
// 安全打印数组的模板函数
template<typename T>
void printArray(T* arr, size_t size) {
cout << "数组长度: " << size << endl;
cout << "数组内容: ";
for (size_t i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
// 获取数组大小(字节数)的模板函数
template<typename T, size_t N>
constexpr size_t arraySize(T (&arr)[N]) {
return sizeof(arr);
}
int main() {
int intArray[] = {1, 2, 3, 4, 5};
double doubleArray[] = {1.1, 2.2, 3.3, 4.4};
cout << "intArray长度: " << arrayLength(intArray) << endl;
cout << "intArray大小: " << arraySize(intArray) << " 字节" << endl;
cout << "doubleArray长度: " << arrayLength(doubleArray) << endl;
cout << "doubleArray大小: " << arraySize(doubleArray) << " 字节" << endl;
printArray(intArray, arrayLength(intArray));
return 0;
}
6. 获取字符串数组长度
对于字符串数组(C风格字符串):
#include <iostream>
#include <cstring> // 用于strlen
using namespace std;
int main() {
// C风格字符串
char str1[] = "Hello";
char str2[] = {'H', 'e', 'l', 'l', 'o', '\0'};
// 方法1:sizeof(包括null终止符)
cout << "str1 sizeof: " << sizeof(str1) << endl; // 6
cout << "str2 sizeof: " << sizeof(str2) << endl; // 6
// 方法2:strlen(不包括null终止符)
cout << "str1 strlen: " << strlen(str1) << endl; // 5
cout << "str2 strlen: " << strlen(str2) << endl; // 5
// 字符串数组
const char* names[] = {"Alice", "Bob", "Charlie", "David"};
// 获取字符串数组的长度
int nameCount = sizeof(names) / sizeof(names[0]);
cout << "名字数量: " << nameCount << endl;
// 遍历字符串数组
for (int i = 0; i < nameCount; i++) {
cout << names[i] << " (长度: " << strlen(names[i]) << ")" << endl;
}
return 0;
}
总结比较
| 数组类型 | 获取长度方法 | 获取大小方法 | 注意事项 |
|---|---|---|---|
| 内置数组 | sizeof(arr)/sizeof(arr[0]) | sizeof(arr) | 在同一作用域内有效 |
| 函数参数数组 | 传递大小参数或使用模板 | 无法直接获取 | 数组退化为指针 |
std::array | arr.size() | sizeof(arr) | 推荐使用 |
| 动态数组 | 手动跟踪大小 | 无法直接获取 | 需要自己管理 |
| 字符串数组 | sizeof(arr)/sizeof(arr[0]) | sizeof(arr) | 区分sizeof和strlen |
最佳实践建议
- 优先使用标准库容器:使用
std::array(固定大小)或std::vector(动态大小)代替内置数组 - 传递数组时同时传递大小:避免数组退化为指针导致信息丢失
- 使用模板函数处理数组:可以保留数组类型信息
- 避免在动态数组上使用sizeof:
sizeof只能获取指针大小,不能获取分配的内存大小
// 推荐做法:使用std::array
#include <array>
#include <iostream>
int main() {
std::array<int, 5> arr = {1, 2, 3, 4, 5};
// 轻松获取信息
std::cout << "长度: " << arr.size() << std::endl;
std::cout << "是否为空: " << arr.empty() << std::endl;
// 安全遍历
for (auto& element : arr) {
std::cout << element << " ";
}
return 0;
}