一、数组作为函数参数:
int sum_arr(int arr[],int n);
注意,arr实际上并不是数组,而是一个指针!C++将数组名解释为其第一个元素的地址,因此函数传递的是地址。也可以这样声明函数头:
int sum_arr(int * arr,int n);
在C++中,当且仅当用于函数原型或函数头中,int * arr和int arr[]的含义才相同。通常,当指针指向数组的第一个元素时,采用数组表示法;当指针指向一个独立的值时,采用指针表示法。
数组名与指针对应的利弊:
首先,将数组地址作为参数可以节省复制整个数组所需的时间和内存。如果数组很大,则使用拷贝的系统开销将非常大,另一方面,使用原始数据增加了破坏数据的危险性。
二、数组保护
由于函数参数传递是值传递,若将数组作为参数,实际上是传递地址,形参将是地址的拷贝,对其指向的数据进行操作将访问原数组,而不是其拷贝。
由于会增加破坏原始数组的危险性,为防止函数中无意修改了数组内容,可在声明形参时用const限定:
int sum_arr(const int arr[],int n);
表明,arr指向的是常量数组,不可以使用arr对数据进行修改,即为只读。解释为const int * arr更好理解。
三、使用数组区间:采用两个指针,并遵照“超尾”原则,即对于数组而言,标记数组结尾的参数将是指向最后一个元素后面的指针,例如如下函数定义:
int sum_arr(const int * begin,const int * end)
{
const int * pt;
int total = 0;
for(pt = begin;pt!=end;pt++)
total = total + *pt;
return total;
}
四、指针与const
两种情况:让指针指向一个常量对象,可以防止使用该指针来修改所指向的值。此时,并不意味着指向的值实际上就是一个常量,只是对指针而言,这个值是个常量。这个值可以通过变量本身修改值,但不能通过指针去修改:
const int * pt = &age;//此时*pt是常量
另一种情况是,指针本身是常量,可以防止改变指针指向的位置:
int * const ps = &age;//此时ps是常量
C++禁止将const值的地址赋给非const指针。这样将可以通过非const指针修改const值。
原则:尽可能在数组作为参数时使用const:
1、避免无意间修改数据导致错误;
2、使用const使得函数能够处理const和非const实参,否则只能接受非const数据。
五、二维数组
ar2[r][c] == *(*(ar2+r)+c)
六、函数指针:分层设计,方便切换等作用
1、获取函数地址:传递函数名
2、声明函数指针:
double pam(int);
double (*pf)(int);
pf = pam;
或直接:double (*pf)(int) = pam;
3、通过指针调用函数:将(*pf)看作函数名,如:
double y = pf(5);
新闻热点
疑难解答