2012年(158)
分类: C/C++
2012-11-14 16:56:01
"数组引用"以避免"数组降阶"(本文曾贴于VCKBASE\C++论坛)
受[hpho]的一段模板函数的启发,特写此文,如有雷同,实在遗憾。
数组降阶是个讨厌的事,这在C语言中是个无法解决的问题,先看一段代码,了解什么是"数组降阶"
#include
using namespace std;
void Test( char array[20] )
{
cout << sizeof(array) <<
endl; // 输出 4
}
int main( void )
{
char array[20] = { 0 };
cout <<
sizeof(array) << endl; // 输出 20
Test( array );
}
为什么同样申明的array一个输出20一个输出4?这是因为void Test( char array[20] )中的array被降阶处理了,void
Test( char array[20] )等同于void Test( char array[] ),也等同于void Test( char* const
array ),如果你BT(开玩笑),它也等同于void Test( char array[999] )。
就是说
void Test( char
array[20] )
{
cout << sizeof(array) <<
endl;
}
被降成
void Test( char* const array )
{
cout <<
sizeof(array) << endl; //
既然是char*,当然输出4
}
这样一来问题大了,你完全可以定义一个不足20个元素的数组,然后传给Test,坐等程序崩溃。在一些要求较高的场合就不能使用数组做参数,真TMD心有不甘。
那么在C语言中怎样解决这个问题?
没办法,应该说没有好办法。a:做个结构,其中仅一个char array[20],然后用这个结构指针代替char
array[20]。可见这是个很繁琐的办法,且不直观;b:在Test内部使用_msize来计算array长度。这更不行,首先它使得错误的发现被推迟到运行期,而不是编译期,其次_msize长度/元素大小>=array长度,也就是说就是new
char[19]和new array[20]分配的大小是一样的,这样一来,虽不至于导致程序崩溃,但运算结果却不正确。
感谢[hpho],受其启发,C++中有C所没有的"引用",但数组引用是怎样申明的呢?经过几番试验,Look
#include
using namespace std;
void Test( char (&array)[20] ) // 是不是很像 char *p[20] 和 char (*p)[20]
的区别?
{
cout << sizeof(array) << endl;
}
int main( void )
{
char array[20] = { 0 };
cout <<
sizeof(array) << endl;
Test( array );
}
网友评论2012-11-14 16:58:40
鬼龙之舞
这样的引用只会降低通用性,我还是觉得
main(int argc, char ** argv)这样的形式好
如果觉得每次要传入数组的大小比较麻烦,更带来安全要威
还可以用宏
#define macro_showarr(arr) showarr(sizeof(arr)/sizeof(arr[0]),arr)
template <class T>
void showarr(int count,T * p)
{
for (int i=0;i<count;i++)
{
printf("%d %d\n",i,p);
}
}
int main(int argc, char* argv[])
{
int arr1[10]={10,20,30,40,50,60,70,80,90,1