数组传参的问题

来源:百度文库 编辑:神马文学网 时间:2024/04/28 07:17:47
CSDN首页新闻论坛小组Blog文档下载读书Tag网摘搜索.NETJava游戏视频人才外包第二书店程序员

搜索 | 收藏 | 打印 | 关闭
CSDN社区 > C/C++ > C++ 语言
有关数组传参的问题
losedxyz(我真的一无所有)2005-12-23 12:39:44 在 C/C++ / C++ 语言 提问
#include  
using   namespace   std;
void   Test(   char   array[20]   )
{
cout   <<   sizeof(array)   <<   endl;   //   输出   4
}
void   main(   void   )
{
char   array[20]   =   {   0   };
cout   <<   sizeof(array)   <<   endl;   //   输出   20
Test(   array   );
}
为什么同样申明的array一个输出20一个输出4?有没高人讲得详细些?最好讲讲原理,谢谢~ 问题点数:20、回复次数:17Top
Flood1984(峰子)(好男人 灌就灌出个模样)回复于:43:51 得分 5
数组名的蜕化
数组在作为函数参数时,数组名将蜕化为指针。书上为什么这么说呢?书上的意思是说这家伙已经蜕化得不知道自己有几个元素了。举个例子:
void   fun(char   array[5]);
在编译时编译器会当成是:void   fun(char   *array);你在这个函数中使用sizeof(a)得到的值是4,而在定义char   array[5]的函数中sizeof(array)   =   5,说明确实已经蜕化为指针了。所以你写:
char   *pa   =   array   ;   //正确,指针到指针
数组名退化为指针,在这里强调一下:数组的元素类型仍然存在!这里要注意的是多维数组的情况。
以2维数组为例:
void   fun2(char   arrayMulti[3][5]);
那么在函数fun2中,arrayMulti蜕化成的是char   (*)[5],即:指向char[5]类型的指针,因为前面分析过arrayMulti的元素的类型是char[5],所以在程序中:
char   **pm   =   arrayMulti   ;   //错误:从char   (*)[5]到   char   **的赋值
char   (*pm5)[5]   ;
pm5   =   arrayMulti   ;   //正确。
Top
bm1408(向va_list学习~不用VC好多年~)回复于:44:40 得分 0
这个问题最近问的太多了~
当数组作为函接参数时,会退化为同类型的指针~Top
bm1408(向va_list学习~不用VC好多年~)回复于:46:05 得分 0
你真快,还打了这么多字~Top
oyljerry(【勇敢的心】→ ㊣提拉米苏√㊣)回复于:00:09 得分 0
数组作为参数时   decay成指针了Top
hsuyuan(一切无法解释的问题都是人品问题)回复于:43:22 得分 0
2楼不光正解而且透彻Top
whyglinux(山青水秀)回复于:35:32 得分 10
>>   数组在作为函数参数时,数组名将蜕化为指针。书上为什么这么说呢?书上的意思是说这家伙已经蜕化得不知道自己有几个元素了。
很形象,也抓住了重点。
其实根据标准的规定,不仅仅是数组在作为函数参数时数组名将退化为指针——除了作为sizeof和&的操作数之外,在表达式中出现的数组名都不知道自己有几个元素,所以这时它的类型已经不再是数组类型了,而是decay为一个指针。
举例说明:
int   a[10];       //   定义   a   的类型为   int[10],数组类型
int*   p   =   a;     //   a   的类型为   int*,指针类型,不再是数组类型。
a[0]   =   0;         //   a   的类型为   int*,指针类型,不再是数组类型。并且   a[0]   =   *(a+0)   =   *a。
sizeof(   a   );   //   a   的类型为   int[10],数组类型。
p   =   &a;             //   a   的类型为   int[10],数组类型。因此,&a   的类型为int   (*)[10],是指针类型,但是跟   p   的指针类型(int*)不匹配,因此赋值非法。
总之,只要排除了sizeof和&这两种情况,在程序中把数组名作为指针来使用就是了,而且是一个指向数组首元素的指针(即数组名代表的值就是数组第一个元素的地址)。Top
beijibingshan(Zealot)回复于:38:17 得分 0
都很快阿Top
iamcaicainiao(老菜 ◆无为莫千钧●恨水梦少白▼)回复于:06:59 得分 0
计算内存容量
用运算符sizeof可以计算出数组的容量(字节数)。示例7-3-3(a)中,sizeof(a)的值是12(注意别忘了’\0’)。指针p指向a,但是sizeof(p)的值却是4。这是因为sizeof(p)得到的是一个指针变量的字节数,相当于sizeof(char*),而不是p所指的内存容量。C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。
注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。示例7-3-3(b)中,不论数组a的容量是多少,sizeof(a)始终等于sizeof(char   *)。
char   a[]   =   "hello   world";
char   *p     =   a;
cout<<   sizeof(a)   <<   endl; //   12字节
cout<<   sizeof(p)   <<   endl; //   4字节
示例7-3-3(a)   计算数组和指针的内存容量
void   Func(char   a[100])
{
cout<<   sizeof(a)   <<   endl; //   4字节而不是100字节
}
示例7-3-3(b)   数组退化为指针
Top
megaboy(飞天御剑流之杀神一刀斩)回复于:32:20 得分 5
形参中的array   type和incomplete   type会被转换为pointer   type,之所以会有这个转换,是由于ansi   committee认为,如果把整个数组传递给被调函数,效率太低,从提高效率着想,一律把形参中的array   type和incomplete   type转换为pointer   type。
要注意的是,这里涉及的是两种有差别的转换,以你的例子来说明:
对于main中的代码:
char   array[20]   =   {   0   };
cout   <<   sizeof(array)   <<   endl;   //   输出   20
Test(   array   );
array首先被定义为char[20]类型,然后作为实参传递给Test的时候,array首先被完全求值,其类型在表达式求值的过程中被临时转换为char*类型,这只是表达式计算过程中的需要而临时转换,array的类型本质上并没有被转换为char*,也就是说,Test(array)运行完后,array的类型仍然是char[20],而不会因此变成char*。
而形参中的转换跟以上转换又有一点不同,就是,虽然你在形参中写上
void   Test(   char   array[20]   )
但array并没有先定义为一个数组再转换类型,就是虽然你是以char   array[20]这样写的,但这个数组并没有进行定义,而是直接从形式上把array的类型看作char*,实际被定义的对象是char*类型,不存在char[20]类型,这种转换更准确地说应该是“看作”,因为没有array   type的实体被转换,array从来没有以一个数组出现过,因此在Test内部,sizeof(array)是一个指针的大小。同时,常数20被忽略。Top
whyglinux(山青水秀)回复于:33:03 得分 0
To   megaboy
>>   也就是说,Test(array)运行完后,array的类型仍然是char[20],而不会因此变成char*。
这样说不太准确。
因为数组名其实有两种身份:数组和指针。到底数组名作何解释,这要取决于数组名所处的上下文(context)环境:如果数组名是sizeof或者&的操作数,那么数组名是数组类型;否则,数组名就变成(或者说退化为、转换为)指针类型。
“橘生淮南则为橘,橘生淮北而为枳”,强调的就是环境因素对事物影响的重要性。Top
khyang(天佑)回复于:33:15 得分 0
数组名和指针有很大区别,在使用时要进行正确区分,其区分规则如下:
规则1 数组名指代一种数据结构,这种数据结构就是数组;
例如:
char   str[10];
char   *pStr   =   str;
cout   <<   sizeof(str)   <<   endl;
cout   <<   sizeof(pStr)   <<   endl;
输出结果为:
10
4
这说明数组名str指代数据结构char[10]。
规则2 数组名可以转换为指向其指代实体的指针,而且是一个指针常量,不能作自增、自减等操作,不能被修改;
char   str[10];
char   *pStr   =   str;
str++;   //编译出错,提示str不是左值
pStr++;   //编译正确
规则3 指向数组的指针则是另外一种变量类型(在WIN32平台下,长度为4),仅仅意味着数组的存放地址;
规则4 数组名作为函数形参时,在函数体内,其失去了本身的内涵,仅仅只是一个指针;很遗憾,在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。
例如:
void   arrayTest(char   str[])
{
cout   <<   sizeof(str)   <<   endl;   //输出指针长度
str++;   //编译正确
}
int   main(int   argc,   char*   argv[])
{
char   str1[10]   =   "I   Love   U";
arrayTest(str1);
return   0;
}Top
iicup(双杯献酒)回复于:39:58 得分 0
增长知识了.Top
huihuixong(狼尾巴)回复于:16:03 得分 0
解释的很完整,,,Top
vollin(林尚义)回复于:17:09 得分 0
这样就行了
template
void   Test(   _Ty&   array)
{
cout   <<   sizeof(array)   <<   endl;
}
int   main(int   argc,   char*   argv[])
{
char   array[20]   =   {   0   };
cout   <<   sizeof(array)   <<   endl;   //   输出   20
Test(array);//   输出   20
return   0;
}
Top
losedxyz(我真的一无所有)回复于:34:50 得分 0
谢谢各位~~Top
shenmea00000(学习中~~~)回复于:02:54 得分 0
真不错啊,学习中~~~~~~~~~~~~~~Top
fk827728(Andy)回复于:49:37 得分 0
8错,学习中,同时讨点分Top
相关问题
传递数组参数的问题,与指针有关
有关数组======>
二位数组传参怎末传?
openwithparm()能否传递数组参数
怎么向函数传数组参数?
如何传递多维数组参数?
请问JSP怎样传数组参数
传递数组参数的错误
关键词
指针
函数
内存
数组
类型
退化
元素
sizeof
参数
容量
得分解答快速导航
帖主:losedxyz
Flood1984
whyglinux
megaboy
相关链接
C/C++ Blog
C/C++类图书
C/C++类源码下载
广告也精彩
反馈
请通过下述方式给我们反馈

 网站简介-广告服务-网站地图-帮助-联系方式-诚聘英才-English-问题报告
北京百联美达美数码科技有限公司  版权所有  京 ICP 证 号
Copyright ©, CSDN.NET, All Rights Reserved