如何获取函数传入数组的元素个数——谈数组的退化和引用

来源:互联网 发布:hana数据库安全防护 编辑:程序博客网 时间:2024/06/07 03:22

在测试如何获取函数传入数组的元素个数时,写了下面这个例子(MFC),猜猜打印结果是什么?

void GetArrayLength(int* ArrayTest) { int ArrayLength = 0; CString Str = NULL; ArrayLength = sizeof(ArrayTest)/sizeof(ArrayTest[0]);               Str.Format("%d",ArrayLength); MessageBox(NULL, Str, "GetArrayLength", MB_OKCANCEL);} void GetArrayLength1(int (&ArrayTest)[88]) { int ArrayLength = 0; CString Str = NULL; ArrayLength = sizeof(ArrayTest)/sizeof(ArrayTest[0]); Str.Format("%d",ArrayLength); MessageBox(NULL, Str, "GetArrayLength1", MB_OKCANCEL);} template <typename T>void GetArrayLength2(T& ArrayTest) { int ArrayLength = 0; CString Str = NULL; ArrayLength = sizeof(ArrayTest)/sizeof(ArrayTest[0]); Str.Format("%d",ArrayLength); MessageBox(NULL, Str, "GetArrayLength2", MB_OKCANCEL);} void CGetArrayLengthDlg::OnBnClickedButton1() { int ArrayTest[88] = {0};GetArrayLength(ArrayTest); GetArrayLength1(ArrayTest); GetArrayLength2(ArrayTest); }

下面揭晓答案:

这里写图片描述

这里写图片描述

这里写图片描述

让我们先来看这样一段话(摘自C99):
Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type “array of type” is converted to an expression with type “pointer to type” that points to the initial element of the array object and is not an lvalue.

数组有退化现象,在除了3种情况外, 其他时候都要”退化”成指向首元素的指针.

这3种情况是例外的:
(char Array[10] = “abcde”)
(1) sizeof(Array)
(2) &Array
(3) 用来Array初始化其他数组

那就很容易理解了,虽然sizeof不会引起数组退化,但是void GetArrayLength(int* ArrayTest) 函数被调用过程中,数组传入时退化成为指向首元素的指针,输出结果自然为1。

和其他类型一样,数组形参可声明为数组的引用。如果形参是数组的引用,编译器不会将数组实参转化为指针,而是传递数组的引用本身。在这种情况下,数组大小成为形参与实参类型的一部分,编译器检查数组实参的大小与形参的大小是否匹配。void GetArrayLength1(int (&ArrayTest)[88]) 即为数组引用形式传参,这时sizeof(ArrayTest)得到的是数组的整体大小,所以结果为数组元素个数(88)。

如果传入时数组元素个数未知,而void GetArrayLength1(int (&ArrayTest)[]) 这种方式编译又无法通过,这时,可以使用模板,即void GetArrayLength2(T& ArrayTest) 同样能够保证数组不会退化成为指针。

1 0
原创粉丝点击