Chinaunix首页 | 论坛 | 博客
  • 博客访问: 950186
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2367
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

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 );
}

阅读(2156) | 评论(14) | 转发(0) |
给主人留下些什么吧!~~

网友评论2012-11-14 17:00:41

100000
void Test( char array[20] )不等同于void Test( char* const array ), 应该是void Test( char* array )

网友评论2012-11-14 17:00:28

过客
这样一来问题大了,你完全可以定义一个不足20个元素的数组,然后传给Test,坐等程序崩溃。

这样的情况不会出现

网友评论2012-11-14 17:00:13

过客
不是太明白,没有试过别的编译器,至少在vc的编译器中,数组永远不会按值传递,也就是说是按指针方式,编译器会处理为指针,传数组引用数组的长度则将会成为参数类型的一部分,c中如何不是太清楚,普通实现方法一定会再传入一个数组长度.

网友评论2012-11-14 16:59:56

waiting4you
传数组引用效率相当于传指针,而且包含更多信息,不是很好吗?
我不久前见过一个模板函数就和周星星的方法一样:
template<class T,size_t N>
        void Test(T (&array)[N])
{
        cout<<typeid(T).name()<<endl;
        cout<<N<<endl;
}

网友评论2012-11-14 16:59:37

ericsheng
传指针多好~~