需要做的?
1.提供函数定义
2.提供函数原型
3.调用函数
定义函数
函数分成两类:有无返回值
没有返回值
ex:
void fun(param)
{
statement(s);
return;
}
有返回值
int max(int a, int b) {
if (a > b) {
return a;
}
else {
return b;
}
}
函数原型
为什么需要函数函数原型?
原型描述了函数到编译器的接口。
如何表述?
函数原型不要求提供 变量名,有类型列表就足够。原型中的变量名相当于占位符,因此不必与函数定义中的变量名相同。
void cheers(int);
函数参数和按值传递
用于接收传递值的变量被称为形参。传递给函数的值被称为实参。参数传递是将参量赋给参数。
函数内的变量是局部变量。关于变量作用范围,单独说。
在函数中修改形参的值,不会影响调用程序中的数据。
函数和数组
ex:
int sum_arr(int arr[], int n)
arr实际上并不是数组,而是指针。以下示例,数组名就是第一个元素的地址,即地址,指针。
#include <iostream>
const int ArSize = 8;
int sum_arr(int arr[], int n);
int main() {
using namespace std;
int cookies[ArSize] = {1,2,3,4,8,9,10,11};
int sum = sum_arr(cookies,ArSize);
return 0;
}
int sum_arr(int arr[], int n)
{
int total = 0;
for (int i = 0; i < n; i++)
{
total = total = arr[i];
}
return total;
}
由于数组的元素的类型为int,因此cookies的类型必须是int指针,即int *。这表明,正确的函数头应该是
int sum_arr(int * arr, int n)
这证明两个函数头都是正确的,当且仅当用于函数头或则函数原型中,两个的含义才是相同的。都意味着arr是一个int指针。
***记住两个恒等式。将指针加1,实际上是加上了一个与指针指向的类型的长度相等的值。指针的长度都是4。
arr[i] == * (arr + i)
&arr[i] == arr + i
数组作参数
传递常规变量时,函数将使用该变量的拷贝,但传递数组时,函数将使用原来的数组。将数组地址作为参数可以节省复制整个数组所需的时间和内存。另一方面,使用原始数组增加了破坏数据的风险。
使用数组区间的函数
ex:
int sum_arr(const int * begin, const int * end)
指针和const
指向常量的指针
int age = 39;
const int * pt = &age;
*pt的值为const,不能被修改。
尽可能使用const
将指针参数声明为指向常量数据的指针:
1.避免由于无意间修改数据而导致的编程错误
2.使用const使得函数能够处理const和非const实参,否则只能接受非const数据
如果条件允许,则应将指针形参声明为指向const的指针。
常量指针
这种声明使得finger只能指向sloth,但允许finger来修改sloth的值
int sloth = 3;
const int * ps = &sloth;
int * const fingetr = &sloth;
函数和二维数组
数组名被视为地址,和一维数组一样。
int data[3][4] = {(1,2,3,4),(9,8,7,6),(2,4,6,8)};
int tatal = sum(data, 3);
data时一个数组名,该数组有三个元素。第一个元素本身是一个数组,有4个int组成的。因此data的类型的是指向由4个int组成的数组的指针。因此正确的原型
int sum(int(*ar2) [4], int size);
如果不含括号,将声明一个由4个指向int的指针组成的数组,而不是由一个指向4个int组成的数组的指针。另外,函数参数不能是数组。还有另外一种格式,这种格式与上述原型的含义完全相同,但可读性更强。
int sum(int ar2[][4], int size);
指向数组的指针
指向数组的指针
指向数组的指针
函数和结构
传递和返回结构
struct travel_time
{
int hours;
int mins;
}
travel_time sum(travel_time t1, travel_time t2);
travel_time trip = sum(day1, day2);
传递结构的地址
struct polar
{
double distance;
double angle;
}
void show_polar(polar dapos);
void show_polar(polar dapos)
{
//###
using namespace std;
const double rad_to_deg = 57.1;
cout << "distance = " << dapos.distance;
}
//调用
show_polar(x);
//************
//改成传递结构的地址
//有三处发生变化
void show_polar(const polar * pda)
{
//***
using namespacae std;
const double rad_to_deg = 57.1;
cout << "distance = " << pda->distance;
}
//调用
show_polar(&pplace);
函数指针
把函数作为参数传递,允许不同的时间使用不同的函数。
- 获取函数地址 函数名即可
- 声明函数指针
double (*func)(int);
func是指针,*func是函数
3.使用指针来调用函数
doule y = (*func)(5);