传值参数与传引用参数
#include<iostream>
using namespace std;
void a(int); //传值参数
void b(int&); //传引用参数
int main()
{
int s = 0, t = 10;
a(s); // 1
cout << s << endl; // 0
b(t); // 10
cout << t << endl; // 10
return 0;
}
void a(int i)
{
++i;
cout << i << endl;
}
void b(int& j)
{
++j;
cout << j << endl;
}
引用传递的优势:(1)可以直接操作引用形参所引的对象;(2)使用引用形参可以避免拷贝大的类类型对象或容器类型对象;(3)使用引用形参可以帮助我们从函数中返回多个值。
普通引用与常量引用(一般情况下,与普通引用相比,我们更应该选择使用常量引用作为参数类型)
bool is_empty(string& s) { return s.empty() ;}
//写法缺陷:1、给使用者误导,即允许修改变量s的内容 2、限制了函数所能接受的实参类型,
//我们无法把const对象、字面值常量或者需要进行类型转换的对象传给普通的引用形参。
//修改
bool is_empty(const string& s) { return s.empty(); }
关于交换两个int指针
//值传递,该函数既不交换指针,也不交换指针所指的内容,所有改变都局限于函数内部
void SwapPointer1(int *p, int *q)
{
int *temp = p;
p = q;
q = temp;
}
//值传递,该函数交换指针所指的内容,在函数内部通过解引用的方式直接访问内存并修改了指针所指的内容
void SwapPointer2(int *p, int *q)
{
int temp = *p;
*p = *q;
*q = temp;
}
//参数形式为int *&,其含义是,该参数是一个引用,引用的对象是内存中一个int指针,把指针当成对象,交换指针本身的值
//该函数和交换指针本身的值,即交换指针所指的内存地址
void SwapPointer3(int *&p, int *&q)
{
int *temp = p;
p = q;
q = temp
}
含有可变形参的函数
为了编写能处理不同数量实参的函数,C++11新标准提供了两种主要的方法:如果所有的实参类型相同,可以传递一个名为initializer_list的标准库类型;如果实参的类型不同,我们可以编写一种特殊的函数,即可变函数模板。
什么情况下返回的引用有效?
如果引用所引的是函数开始之前就已经存在的对象,则返回该引用有效;如果引用所引是函数的局部变量,则随着函数结束局部变量也失效了,此时返回的引用无效。
当不希望返回的对象被修改时,返回对常量的引用。
返回数组的引用或者指针
//函数声明,使其返回数组的引用并且该数组包含10个string对象
string (&func())[10];
//使用类型别名
typedef string arr[10];
arr& func();
//使用尾置返回类型
auto func() -> string(&) [10];
//使用decltype关键字
string str[10];
decltype(str) &func();
关于函数重载
int calc(int, int);
int calc(const int, const int);//非法,顶层const不影响传入参数的对象
int get();
double get();//非法,重载函数必须在形参数量或形参类型上有所区别
int *reset(int *);
double *reset(double *);//合法,重载关系,形参类型有区别
关于默认实参
int ff(int a, int b = 0, int c = 0);//声明正确
char *init(int ht = 24, int wd, char backgrand);//错误
//C++规定一旦某个形参被赋予了默认实参,则它后面所有形参都必须有默认实参
调用函数,实参按照其位置解析,默认实参负责填补函数缺少的尾部实参。
关于内联函数
内联函数以及函数声明都应该放在头文件中,在普通函数前加上inline,即成内联函数。内联函数在编译时展开,从而消除调用函数时产生的开销。内联机制适用于规模较小、流程直接、频繁调用的函数。
constexper函数
指用于常量表达式的函数,规定函数的返回类型及所有形参类型都得是字面值类型,而且函数体中必须有且只能有一条return语句。
关于调试帮助
#include<iostream>
#include<vector>
using namespace std;
//递归函数输出vector<int>的内容
void print(vector<int> vInt, unsigned index)
{
unsigned sz = vInt.size();
//设置在此处输出调试信息
#ifndef NDEBUG
cout << "vector对象的大小是:" << sz << endl;
#endif //NDEBUG
if(!vInt.empty() && index < sz)
{
cout << vInt[index] << endl;
print(vInt, index + 1);
}
}
int main()
{
vector<int> v = {1,3,5,7,9,11,13,15};
print(v,0);
return 0;
}
关于实参类型转换
关于函数指针
//函数指针的声明和使用
//函数声明
int func(int, int);
//vector对象,其为元素指向上述函数的指针
vector<decltype(func)*> vF;
#include<iostream>
#include<vector>
using namespace std;
int func1(int a, int b)
{
return a + b;
}
int func2(int a, int b)
{
return a - b;
}
int func3(int a, int b)
{
return a * b;
}
int func4(int a, int b)
{
return a / b;
}
void Compute(int a, int b, int (*p)(int, int))
{
cout << p(a,b) << endl;
}
int main()
{
int i = 5,j = 10;
decltype(func1) *p1 = func1, *p2 = func2, *p3 = func3, *p4 = func4;
vector<decltype(func1)*> vF = {p1, p2, p3, p4};
for(auto p : vF)//遍历vector中的每个元素,依次调用四则运算函数
{
Compute(i, j, p);
}
return 0;
}