揭开C/C++中数组形参的迷雾[VC/C++编程]
本文“揭开C/C++中数组形参的迷雾[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
楔子
去年,周星星大哥曾经在VCKBASE/C++论坛发表过一篇文章“数组引用"以避免"数组降阶”,当时我不能深化理解这种用法的含义;时隔一年,我的知识有几经锤炼,终于对此文章渐有所悟,所以把吾所知作想具体道来,竟也成了一篇文章.但愿本文能对新手有所启迪,同时也但愿大家发现本文中的疏漏之处后不吝留言指教.
故事发源于周星星大哥给出的两个Demo,为了节俭地方,我把两个Demo合二为一,也能阐明一样的问题:
#include <iostream>
其运行后果以下:
using namespace std;
void Foo1(int arr[100])
{
cout << "pass by pointer: " << sizeof(arr) << endl;
}
void Foo2(int (&arr)[100])
{
cout << "pass by reference: " << sizeof(arr) << endl;
}
void main()
{
int a[100];
cout << "In main function : " << sizeof(a) << endl;
Foo1(a);
Foo2(a);
}In main function : 400
pass by pointer: 4
pass by reference: 400
这段代码阐明了,假如数组形参是数组名情势(大概指针情势,下文谈论)时,利用sizeof运算符,将得不到本来数组的长度;假如用传送原数组引用的办法,则没有问题.
这段代码的确很难理解,因为这短短的十几行触及到了形参与实参的关系、数组名和指针的关系、引用的意义、申明和表达式的关系这4大类问题,只要有1层次解不透、大概理解不精确,就理解不透上面的这段代码.本文也就从这4个问题动手,把这4个问题首先办理掉,然后再探究上面的这段代码.固然这样看来非常繁复,但是我认为从根上动手来理解、学习,是条似远实近的道路.
1、函数形参和实参的关系
void Foo(int a);
Foo(10);
这里的a叫做情势参数(parameter),简称形参;这里的10叫做实际参数(argument),简称实参.形参和式参之间是什么关系呢?他们是赋值的关系,也就是说:把实参传送给形参的历程,可以看做是把实参赋值给形参的历程.上面的例子中,实参10传送给形参a,就相当于a=10;这个赋值的历程.(因为数据范例多的很,无法举例子举全面,所以这里就不举例子了;假如认为不好理解,就在vc中写个sample调试一下各种数据范例的情形,你就可以够考证这个结论了.)
2、数组名和指针的关系
这个问题是个历史性的问题了,在C语言中,数组名是当作指针来处理的.更切当的说,数组名就是指向数组首元素地址的指针,数组索引就是距数组首元素地址的偏移量.理解这一点很重要,很大都组利用的问题就是有此而起的.这也就是为什么C语言中的数组是从0开始计数,因为这样它的索引就对比好对应到偏移量上.在C语言中,编译历程中碰到有数组名的表达式,城市把数组名替换成指针来处理;编译器乃至无法辨别a[4]和4[a]的辨别!*2 但是下面这一点需求注意:
int a[100];
int *b;
这二者并不等价,第一句话声明了数组a,并定义了这个数组,它有100个int型元素,sizeof(a)将得到整个数组所占的内存大小,是400;第二句话只是声明并定义了一个int型的指针,sizeof(b)将得到这个指针所占的内存大小,是4.所以说,固然数组名在表达式中普通会当作指针来处理,但是数组名和指针还是有差别的,最最少有a==&a[0]但是sizeof(a)!=sizeof(a[0]).
并且在ANSI C尺度中,也明文规定:在函数参数的声明中,数组名北边一同当作指向该数组第一个元素的指针.所以,下面的几种书写情势是等效的:
void Foo1(int arr[100]){}
void Foo2(int arr[]){}
void Foo3(int *arr){}
C++尽大概的全面兼容C语言,所以这一部份的语法相同.
以上是“揭开C/C++中数组形参的迷雾[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |