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

在测试如何获取函数传入数组的元素个数时,写了下面这个例子(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) 同样能够保证数组不会退化成为指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值