函数
1.函数基础
1.1、函数定义包含:返回类型,函数名字,有形参组成的列表,函数体。
1.2、函数调用:一是用实参初始化对应形参,二是将控制权转移给被调函数。
1.3、函数的返回类型不能是数组类型或函数类型,但可以是指向数组或函数的指针。
1.4、局部静态对象:static,在程序执行路径第一次经过对象定义时初始化,程序终止时销毁。
练习:
6.4、编写一个与用户交互的函数,要求输入一个数字,计算阶乘。
#include<iostream>
using namespace std;
int multiple(int val){
int ret = 1;
while (val > 1){
ret *= val--;
}
return ret;
}
int main(){
int num;
cout << "please enter a number:" << endl;
cin >> num;
int result = multiple(num);
cout << "The " <<num<< "! is " << result << endl;
system("pause");
}
6.5、编写一个函数输出实参的绝对值。
#include<iostream>
using namespace std;
double my_abs(double val){
if (val < 0)
return -val;
else
return val;
}
int main(){
cout << "please enter a number:" << endl;
double num;
cin >> num;
cout << "The abs of " << num << " is " << my_abs(num) << endl;
system("pause");
}
2、参数传递
2.1、引用形参:形参是引用类型的,对应的实参被引用传递,引用形参是对应实参的别名。
2.2、指针形参:当执行指针拷贝操作时,拷贝的是指针的值。
2.3、通过使用引用形参,允许函数改变一个或多个实参的值。
2.4、如果函数无需改变引用形参的值,最好将其声明为常量引用。
2.5、用实参初始化形参时会忽略掉顶层const。
2.6、不允许拷贝数组,使用数组时将其转换成指针。当为函数传递一个数组时,实际上传递的是它的首元素的指针。
2.7、当函数不需要对数组形参执行写操作时,数组形参应该是指向const的指针。
2.8、数组引用形参:f(int(&arr)[10])arr是具有10个整数数组的引用。
2.9、initializer_list:常量值列表模板类型。可以传递多个相同类型参数。
练习:
6.10、使用指针交换两个整数
的值。
#include<iostream>
using namespace std;
int change(int *p, int *q){
int temp = *p;
*p = *q;
*q = temp;
return 0;
}
int main(){
int num1 = 20, num2 = 10;
int *p = &num1, *q = &num2;
change(p, q);
cout << "num1=" << num1 << "and num2=" << num2 << endl;
cout << "*p=" << *p << "and *q=" << *q<< endl;
system("pause");
}
6.17、编写一个函数,判断string对象中是否含有大写字母.....
#include<iostream>
#include<string>
using namespace std;
void have_upper(const string &s){
int i = 0;
for (auto item : s){
if ('A' <= item <= 'Z')
cout<<"有大写字母"<<endl;
i=i + 1;
break;
}
if (i == 0){
cout << "没有大写字母" << endl;
}
}
void to_lower(string &s){
for (auto &item : s){
item=tolower(item);
}
cout << s << endl;
}
int main(){
string str;
cin >> str;
string &s = str;
have_upper(str);
to_lower(s);
system("pause");
}
6.21、编写函数,接受两个参数:一个int,另一个int指针.....
#include<iostream>
using namespace std;
int compare(int num,const int *p){
if (num > *p)
return num;
else
return *p;
}
int main(){
int num1 = 10, num2 = 5;
const int *p = &num2;
cout << compare(num1, p) << endl;
system("pause");
}
6.22、编写函数,交换两个int指针。
#include<iostream>
using namespace std;
void change(int &v1, int &v2){
int temp = v1;
v1 = v2;
v2 = temp;
}
int main(){
int num1 = 10, num2 = 20;
int *p = &num1, *q = &num2;
int &s1 = *p, &s2 = *q;
change(s1, s2);
cout << *p << endl;
cout << *q << endl;
system("pause");
}
6.25、编写一个main函数,接受两个实参,把实参内容连接成一个string对象输出。
#include<iostream>
#include<string>
using namespace std;
int argc = 5;
string argv[6] = {"awc","wecwe","erge","ryjty","efwe","erge"};
int main(int argc, char *argv[]){
string str="";
for (auto i = 1; i <= argc; ++i){
str += argv[i];
}
cout << str << endl;
system("pause");
}
6.27、编写函数,参数时initializer_list<int>对象,计算所有元素的和。
#include<iostream>
#include<initializer_list>
using namespace std;
int Sum(initializer_list<int> lst){
int result=0;
for (auto i : lst)
result += i;
return result;
}
int main(){
initializer_list<int> lst = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
cout << "sum of every item in lst is :" << Sum(lst) << endl;
system("pause");
}
3、返回类型和return语句
3.1、在含有return语句的混换后面应该也有一条return语句。
3.2、调用一个返回引用的函数得到左值,其他返回类型得到右值。
3.3、尾置返回类型:auto func(int i)->int(*)[10];//func 接受一个int类型实参,返回一个含有10个整数数组的指针。
练习:
6.33、编写一个递归函数,输出vector对象内容。
#include<iostream>
#include<vector>
using namespace std;
void Vec(vector<int> ivec,int i){
if(i==ivec.size())
return;
cout << ivec[i++] << " ";
Vec(ivec, i);
}
int main(){
vector<int> ivec = {1,2,3,4,5,6,7,8,9};
int i = 0;
Vec(ivec, i);
system("pause");
}
4.1、同一作用域的几个函数名字相同但形参列表不同,称为函数重载。
4.2、main函数不能重载。
4.3、不允许两个函数吃了返回类型外其他所有要素都相同。
4.4、拥有顶层const和没有顶层const的形参无法区分。
4.5、在不同的作用域无法重载函数名。
5、特殊用途语言特性
5.1、在给定作用域中一个形参只能被赋予一次默认实参。
5.2、默认实参负责填补函数调用缺少的尾部实参,所以只能省略尾部的实参。
5.3、constexpr函数:用于常量表达式,函数的返回类型及形参类型都得是字面值类型,函数体中有且只有一条return语句。
6、函数匹配
第一步:选定候选函数。一是与被调用函数同名,二是其声明在调用点可用。
第二步:考察本次调用提供的实参,选出可行函数。一是形参熟了和实参数量相等,二是实参类型一对应形参类型相同。
第三部:从可行函数中选取最匹配的函数。
7.函数指针
7.1、函数指针指向函数,而非对象。
7.2、重载函数的指针。指针类型比粗与重载函数中的某一个精确匹配。