6.1函数基础
return:
1.返回值2.将控制权从被调用的函数转回到主调函数。
函数的返回类型不能是数组类型或者函数类型,但可以是指向数组的指针或者指向函数的指针。
int(*fun(int,int))[10]; // 返回指针数组
int(&fun(int,int))[10]; // 返回数组的引用
自动对象:
把只存在于块执行期间的对象称为自动对象。
内置类型的未初始化局变量将产生未定义的值。
6.2.参数传递
熟悉C语言的程序员常常使用指针类型的形参访问函数外部对象,在C++语言中,建议使用引用类型的形参替代指针。
拷贝对象比较低效,最好使用引用,当函数无需修改引用形参的值时最好使用常量引用。
使用引用,返回额外的信息
// 返回s中c第一次出现的位置索引
// 引用形参occurs负责统计c出现的次数
string::size_type find_char(const string &s,char c,string::size_type occurs)
{
auto ret=s.size(); // 记录第一次出现的位置
occurs=0;
for(decltype(ret)i=0;i<s.size();++i)
{
if(s[i]==c)
{
++occurs;
if(ret==s.size())
ret=i;
}
}
return ret; // 返回c第一次出现的位置 c出现的次数通过occurs记录
}
6.3const形参和实参
顶层const作用于对象本身:
const int ci=42;
int i=ci;
int *const p=&i; // 顶层const,不能给p赋值
*p=0; // 正确
当用实参初始化形参的时候,编译器会忽略掉顶层const,例如:
void fcn(const int i){}
void fcn(int i){} // 错误:重新定义了fcn(int)
6.3.2指针和引用形参与const
int &r4=42; // 错误: 不能将字面值初始化一个普通引用
int i=42;
const int &r=i;
int &r3=r; // 错误:可以使用非常量初始化一个底层const对象,但是反过来不行
6.3.3尽量使用常量引用
把不会改变的形参定义成常量引用是比较明智的。
bool is_sentence(const string &s)
{
// 如果在s的末尾有且只有一个句点,那s就是一个句子
string::size_type ctr=0;
return (find_char(s,'.',ctr)==s.size()-1&&ctr==1);
}
6.4数组形参 // 一般用容器代替数组 因为数组越界编译器无法检查出来
数组的两个性质:
不允许拷贝数组及使用数组时将其转换成指向数组首元素的指针
使用标准库规范
void print(const int *beg,const int *end) // beg指向数组首元素的指针end指向尾后元素的指针
{
while(beg!=end)
cout<<*beg++<<endl; // 输出当前元素并将指针向前移动一个位置
}
int j[2]={0,1};
print(begin(j),end(j)); // 在这里,我们使用begin和end函数提供所需要的指针 size_t size=end(j)-begin(j);
数组引用形参:
// 形参是数组的引用
void print(int (&arr)[10]);
注意:为了确保返回值的安全,我们不妨提问:引用所引的是在函数之前就已经存在的对象还是自动对象??