第七章:函数——C++的编程模块
定义函数的基本格式:
return-type functioonName(int n)
{
statement(s);
return data;
}
C++函数不能直接返回数组 ,但可以将数组包含在结构中或作为对象组成部分返回;
返回值的实现机制是:函数将返回值写入到指定的CPU寄存器或内存单元中,主调函数会在执行完成后读取写入的数据;
如果函数体中有多条返回语句,函数会在执行完第一条返回语句后将使用全返回,编译器会对多条返回语句做出警告;
原型描述了函数到编译器的接口,可以直接在源代码头部定义函数来避免使用函数原型,但一般采取的方案是在源代码头部使用函数原型,在main()函数后定义完整的函数体;函数原型是一条语句,必须以分号结束;
在C++中,括号为空必须使用void关键字,未指定参数列表必须使用…三个句点组成的省略号;在C语言中括号为空表示在后面指出参数列表;
在编译阶段进行的检查被称为静态编译检查;
用于接受传递值的变量被称为形参,传递的值被称为实参;为了简化,在C++中形参称为参量,实参被称为参数;
在函数中声明的变量是该函数私有的,函数调用时计算机为这些变量分配内存,函数使用完毕时计算机自动销毁之前分配的内存;
cin.get()函数读取所有的字符(包括空白符),将空白符作为返回值返回;cin>>接受单词的变量 会忽视空白符,但当继续使用cin.get()函数时会首先读入之前遗留的换行符;
向函数传递函数需要这样编写函数头:
int sum_arr(int arr[],int n);
/*这是向函数传递数组的常规做法,前者是数组本体,后者是数组长度*/
int sum_arr(int *arr,n);
//这种写法也是正确的,*表示arr是指针
//这两种情况只有在函数声明中才是相同的
//可以在函数声明的参数列表中使用const防止数据破坏
//不要试图使用方括号来传递数组的元素个数
由于过于经典,这里再强调一次异常输入的清理方法:
if (!cin)
{
cin.clear();
while (cin.get() != '\n')
continue;
cout<<"检测到异常输入,请重新输入!"
break;
}
虽然传值调用中函数获得了数组的地址,它们仍然缺少一些知识,不能使用sizeof获得数组大小而只能依靠主调函数传入数组长度;
也可以向函数传递一前一后两个指针:
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限定符修饰指针
C++禁止将const的指针赋值给非const的指针;
比较两种const:
int *const figure = &data;//指针本身的值不可变
const int *figure = &data;//指针指向的值不可变
定义二维数组的一般格式:
int sum(int (*ar2)[4],int n);
int sum(int ar2[][4],int n);
//显然第二种更美观
//要注意第二个下标必须给出
//这里是不能使用const的,只能用于基本类型
C-风格字符串和一般字符数组的区别是:前者总是以’\0’结尾;
要让函数使用结构体,最好使用指针,传指调用会非常浪费时间;
C++库数学函数默认所有角度都是以弧度值表示的;
cin运算符作用后的返回值是一个cin对象;
当然也可以像函数传入string;如果需要多个字符串的数组,可以创建使用由string构成的数组;模板类array不但能够存储基本类型,还能存储更复杂的对象;
C++函式可以递归调用自己:
void recurs(argumentlist)
{
statements1;
if (test)
recurs(argumentlist);
statements2;
}
//满足某些条件时函数将调用自己
//C++不允许main()调用自己
函数的内存地址是存储机器码的内存的开始地址;函数名就是函数的地址,可以赋值;注意将一个函数的地址赋值给另一个指针时不能加上包含参数列表的括号;可以将一个函数作为参数传递给某个函数,这样就可以在那个函数内部使用该函数;
声明一个函数指针:
double (*pd) (int);//这是一个指向函数的指针
double *pd(int);//这是一个返回指针的函数
也可以直接像使用函数名那样使用指向函数的指针;
下面三个例子可以证明函数指针语法的灵活:
const double * f1(const double ar[], int n);
const double * f2(const double [], int)
const double * f3(const double *, int)
//这三种写法本质上是相同的
声明一个指向函数的指针数组:
const double * (*pa[3])(const double *, int)={f1,f2,f3};
//注意这里是不能使用auto关键字的
//要调用某个函数:
(*pd)[i](av,3);