"数组引用"以避免"数组降阶"(c++)
2011-06-16 14:17
441 查看
数组降阶是个讨厌的事,这在C语言中是个无法解决的问题,先看一段代码,了解什么是"数组降阶"
#include <IOSTREAM>
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,坐等程序崩溃。在一些要求较高的场合就不能使用数组做参数。那么在C语言中怎样解决这个问题?
没办法,应该说没有好办法。a:做个结构,其中仅一个char array[20],然后用这个结构指针代替char array[20]。可见这是个很繁琐的办法,且不直观;b:在Test内部使用_msize来计算array长度。这更不行,首先它使得错误的发现被推迟到运行期,而不是编译期,其次_msize长度/元素大小>=array长度,也就是说就是new char[19]和new array[20]分配的大小是一样的,这样一来,虽不至于导致程序崩溃,但运算结果却不正确。
数组引用是怎样申明的呢?#include <IOSTREAM>
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 );
}
以上是他人博客内容。
使用这种方法也不能解决全部问题如:想用 char (&array)[][20]来声明一个数组作为函数的参数,这样编译器会报错。因为
char (&)[] 指的是声明一个 char[]类型的数组作为引用。因为[][20]未指明[]有多少个,因此系统并不知道这是哪种类型,所以会报错。这种情况下可以改用 vector类型。(我个人是不大喜欢vector这些容器类,因为在数据和使用之间加了一层隔离)。
http://blog.vckbase.com/bruceteen/archive/2004/05/20/232.aspx
#include <IOSTREAM>
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,坐等程序崩溃。在一些要求较高的场合就不能使用数组做参数。那么在C语言中怎样解决这个问题?
没办法,应该说没有好办法。a:做个结构,其中仅一个char array[20],然后用这个结构指针代替char array[20]。可见这是个很繁琐的办法,且不直观;b:在Test内部使用_msize来计算array长度。这更不行,首先它使得错误的发现被推迟到运行期,而不是编译期,其次_msize长度/元素大小>=array长度,也就是说就是new char[19]和new array[20]分配的大小是一样的,这样一来,虽不至于导致程序崩溃,但运算结果却不正确。
数组引用是怎样申明的呢?#include <IOSTREAM>
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 );
}
以上是他人博客内容。
使用这种方法也不能解决全部问题如:想用 char (&array)[][20]来声明一个数组作为函数的参数,这样编译器会报错。因为
char (&)[] 指的是声明一个 char[]类型的数组作为引用。因为[][20]未指明[]有多少个,因此系统并不知道这是哪种类型,所以会报错。这种情况下可以改用 vector类型。(我个人是不大喜欢vector这些容器类,因为在数据和使用之间加了一层隔离)。
http://blog.vckbase.com/bruceteen/archive/2004/05/20/232.aspx
相关文章推荐
- "数组引用"以避免"数组降阶"(c++)
- "数组引用"以避免"数组降阶"(c++)
- C++ 基础之 "引用形参" 和 "利用const引用避免复制" &
- "0x........"指令引用的"0x00000000"内存,该内存不能为"read"之解决方案
- PHP数组的"自然链接"
- "未将对象引用设置到对象的实例"异常的原因
- "Modern C++"为什么采用泛型编程
- 关于VC6.0 MSDEV.EXE-应用程序错误"0x5003eaed"指令引用的"0x0000000"内存错误的解决办法
- C++11 range for 遍历多维数组, 迭代变量添加引用 "&"的问题
- "The Design and Evolution of C++" 阅读笔记
- Eclipse with C++: "Launch failed. Binary not found."
- <C++学习笔记>引用中的&和&&区别
- C++ 中的&:“&引用” 和“&取地址符”的区别和作用
- "数组引用"以避免"数组降阶"
- 在DP中使用"滚动数组"
- C/C++,数据结构单链表(采用C++&quot;引用&quot;方法)(寻找节点、在某处插入结点、删除某位置结点)
- 托管c++中的资源管理--- "~"和"!"符号的作用
- C++的基础知识(十一)--数组做函数参数、数组名a与&a区别、数组名a的"数据类型"
- 【C语言】有一个字符数组的内容为:"student a am i",请你将数组的内容改为"i am a student".
- C++中的"delete this"