函数基础
- 函数包括:返回类型、函数名字、0个或多个形参组成的列表
形参和实参
- 实参是形参的初始值
局部静态对象
在程序的执行路径的第一经过对象的语句时初始化,并且直到程序终止才被取消。在此期间即使对象所在的函数结束执行也不会对它有影响。
#include <iostream>
size_t count_calls()
{
static size_t ctr = 0;//调用结束后这个值仍有效,只初始化一次
return ctr++;
}
int main()
{
std::cout << "Hello World!\n";
for (size_t i = 0; i != 10; i++)
{
std::cout << count_calls() << std::endl;
}
}
参数传递
- 引用传递:形参绑定到对应的实参上
- 值传递:实参的值拷贝到形参上,两者相互独立
最好用引用传递,值传递往往低效。如果无需修改形参的值,最好用const引用
引用形参返回额外的信息
一直以来我都是用自定义数据类型来返回的。。。。。。(愚蠢)
-
有一种非常简单的方法,多给函数传入一个额外的实参引用!!
#include <iostream>
bool count_calls(const int & a, int& b)
{
if (a % 2 == 0)
{
b = 1;
return 1;
}
else
{
b = 0;
return 0;
}
}
int main()
{
int b = 0;
int a = 0;
if (count_calls(a, b))
{
std::cout << b;
}
}
const 形参和实参
- 当实参初始化形参时会忽略掉顶层const,当形参有const时,传给它常量或者非常量都是可以的
const int ci=42;//不能改变Ci,const是顶层的
int i=ci;//正确:当拷贝ci时,忽略了它的顶层const
int *const p=&i;//const是顶层的,不能给p赋值
*p=0;//正确:通过p改变对象的内容是允许的,现在i变成了0
void fcn(const int i)
{
'''
fcn能读取i,但是不能向i写值
'''
}
指针或引用形参与const
直接上例程
int i=42;
const int *cp = &i;//正确:但是cp不能改变i
const int &r=i;//正确:但是r不能改变i
const int &r2=42;//正确
int *p=cp;//错误:p的类型和cp的类型不匹配
int &r3=r;//错误:r3的类型和r的类型不匹配
int &r4=42;//错误:不能用字面值初始化一个非常量引用
应用到参数传递上如下
int i=0;
const int ci=i;
string::size_type ctr=0;
reset(&i);//调用形参类型是int*的reset函数
reset(&ci);//错误:不能用指向const int 对象的指针初始化int*
reset(i);//调用形参类型是int&的reset函数
reset(ci);//错误:不能把普通引用绑定到const对象ci上
reset(42);//错误:不能把普通应用绑定到字面值上
reset(ctr);//错误:类型不匹配,ctr是无符号类型
find_char("Hello World!",'o',ctr);//正确:find_char的第一形参是对常量的引用
尽量用常量引用
举个栗子~~~
string::size_type find_char(string &s,char c,string::size_type &occurs);
find_char ("hello World",'o',ctr);//错误,string &s 无法引用字面初始值
参考:C++primer 第五版