C++函数之函数与数组
首先来看一下什么是数组?
数组(array)是一种数据格式,能够存储多个类型的值。
要创建数组,可使用声明语句。语句声明应支出以下三点:
l 存储在每个元素中的值的类型
l 数组名
l 数组中元素个数
通用格式: typeNamearrayName [arraySize]
表达式arraysize指定元素数目,它必须是整形常数或const值,也可以是常量表达式,但不可以是变量。
例如:float loans[20]; loans的类型不是数组,而是float数组,强调了loans数组是使用float类型创建的,也是数组称为复合类型的原因。
数组的下标从0开始,但编译器不会检查使用的数组下标是否有效,编译器不会指出错误,但可能破坏数据或代码导致程序异常终止。
Sizeof运算符返回的是类型或数据对象的长度(单位字节),但如果用于数组名得到的是整个数组中的字节数,用于单个数组元素得到的是元素的长度。
数组的初始化:只有在定义数组时才能初始化,以后就不能使用,也不能把一个数组赋值给另一个数组,但是可以根据下标单独赋值。
在C++11的初始化中可以省略等号(=)。如:int cards[4] {3,6,5,8};
其次可以不在大括号内包含任何东西,表示所有元素为0
第三,列表初始化禁止缩窄转换
C++ STL提供了一种数组的代替品——模板类vector,而C++11新增了模板类array,这些替代品比内置的数组更复杂灵活,以后再详细讨论STL。
数组可以将数组名作为参数传递给函数,而不限定长度的数组还需要传递数组的长度。
Int sum_arr(int arr[], int n);
方括号表明arr是一个数组,为空则表明可以传递任何长度。但实际并不是这样!arr不是一个数组,而只是一个指针!然而,在编写函数的其余部分时,可以将arr看做一个数组。
通常情况下,数组名被视为指针,C++将数组名解释为第一个元素的地址:cookies==&cookies[0]
但有一些例外:数组声明使用数组名来标记存储位置;
例如:int sum=sum_arr(cookies,Arsize);
其中,cookies是数组名,而根据C++规则,cookies是其第一个元素的地址,因此函数传递的是地址。数组整体类型为int,所以cookies的类型必须是int指针,即int *。所以,正确的函数头为:
Int sun_arr(int *arr ,int n)//arr=arrayname,n =size.
其中用int *arr代替了int arr []。但当且仅当用于函数头或函数原型中,int *arr和int arr[]的含义才是相同的,都意味着arr是一个int指针。然而,数组表示法(int arr[])的arr不仅指向int,还指向int数组的第一个int。
记住两个恒等式:
arr[i]==*(ar + i) //values in two notations
&arr[i]==ar + I //addresses in two notations
将指针(包括数组名)加1,实际上是加了一个与指针指向类型的长度(单位字节)相等的值。相对于遍历数组而言,使用指针加法和数组下标时等效。
在数组做参数的函数中,并没有将数组的内容传递给函数,而是将数组的地址,元素类型以及元素数目提交给了函数。传递常规变量时,函数使用该变量的拷贝;但传递数组时,函数将使用原来的数组,是一个地址,而不是数组内容。将数组地址作为参数可以节省复制整个数组所需的时间和内存。
常见数组函数有:填充数组;显示数组及用const保护数组;修改数组。
函数除了用数组的起始处指针和数组长度做参数来使用数组外,还有一种方法,即指定元素区间,可以通过两个指针来完成,一个指针指向标识数组的开头,另一个指向尾部。
二维数组:
int data[3][4]={{1,2,3,4},{9,8,7,6},{2,4,6,8}};
int total = sum(data,3);
data是一个数组名,其中有3个元素,第一个元素本身就是一个数组,有4个int值组成。因此data的类型是指向由4个int组成的数组的指针,因此正确原型如下:
int sum(int (*ar2)[4], int size);
或
int sum(int (ar2[][4], int size);
两个原型都指出ar2是指针而不是数组,指向4个int组成的数组,指针类型指定了列数。
ar2[r]是编号为r的元素,而该元素本身又是一个数组,因此ar2[r]是由4个int组成的数组的名称。因此ar2是指向指针的指针。
如:ar2[r][c]==*(*(ar2+r)+c)
为了理解可以从内向外解析。
ar2+r //指向第r个元素
*(ar2+r) //指向第r个元素(4个int)中的第一个元素
*(ar2+r)+c //指向第r个元素(4个int)中的第c个元素
*(*(ar2+r)+c) //ar2[r][c]的值