可能重复:
C++: sizeof for array length
Sizeof array passed as parameter
#include "stdafx.h"
#include <iostream>
using namespace std;
void PrintArrayLength(int arr[])
{
cout << "Function Array length is: " << sizeof(arr)/sizeof(int) << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
int arr[] = {1, 2, 3};
cout << "Array length is: " << sizeof(arr)/sizeof(int) << endl; // print 3
PrintArrayLength(arr); // print 1
return 0;
}
为什么一个地方sizeof(arr)/ sizeof(int)给出的值为1而另一个地方的值为3?
答案 0 :(得分:19)
因为当你按值将一个数组传递给一个函数时,你实际上是在传递一个指针(到数组的第一个元素)。
void PrintArrayLength(int arr[])
{
cout << "Function Array length is: " << sizeof(arr)/sizeof(int) << endl;
}
实际上是 :
void PrintArrayLength(int* arr)
{
cout << "Function Array length is: " << sizeof(arr)/sizeof(int) << endl;
}
不要被允许你将数组声明为int[]
的句法糖误导。实际上,没有这种类型,你真正写的是:
int arr[3] = {1, 2, 3};
只是编译器可以从初始化程序中为您填写3
。
另外,如果您通过引用传递数组,可以保留维度。为方便起见,您可以使用模板,这样您只需要一个函数,无论数组具有什么维度(因为维度是类型的一部分):
template <size_t N>
void PrintArrayLength(int (&arr)[N])
{
cout << "Function Array length is: " << sizeof(arr)/sizeof(int) << endl;
}
对此的扩展是不使用sizeof
的好建议。你可以很容易地陷入你陷入的陷阱,以为你正在评估阵列的时候,真的,你不是。请改用:
template <typename T, size_t N>
size_t length_of_array(T (&)[N]) {
return N;
}
尝试在除了正确数组之外的任何内容上使用此函数将因编译器错误而失败,而不是像代码那样静默地给出误导性值。
当然,将原始数组的使用替换为boost::array
(或C ++ 0x中的std::array
)或std::vector
(可以调整大小)类型的对象是最好的做法。 :)
答案 1 :(得分:0)
Tomalak Geret'kal是对的。
对于您想要的功能,您可以使用:
void DoSomethingWithArray(int* arr, size_t n)
{
cout << "Function Array length is: " << n << endl;
}
template< size_t n >
inline void DoSomethingWithArray(int (&arr)[n])
{
// n == sizeof(arr)/sizeof(int)
DoSomethingWithArray( arr, n );
}
我正在使用函数void DoSomethingWithArray(int* arr, size_t n)
而不是直接在函数模板的主体内编写代码,因为如果函数的主体足够大,那么实例化单独的函数(专用于函数模板)将浪费资源对于在pogram中使用的每个数组n的大小。