一、引用:
1、整型数据占4个字节的空间,a是一个标识符,这个标识符代表这一块空间,
对这个标识符操作相当于操作这块空间
int a = 10;
给这个 4 字节的空间取个别名 a 是大名 其他都叫别名
类型 &别名 = 原名,b 是 a的一个别名, b 也代表a所表示的4字节空间
对 b 操作实际上就是对 a 操作, 引用的对象是不可改变的,所以引用必须要初始化
int &b = a; b = 20;
2、用途:代替指针,有更好的可读性和实用性
例如在交换两个数值时
void mySwap1(int *pa, int *pb) //地址传递
{
int tmp = *pa;
*pa = *pb;
*pb = tmp;
}
void mySwap2(int &a, int &b) //引用
{
int tmp = a;
a = b;
b = tmp;
}
3、
引用是有空间的 4字节
引用使用之前必须要初始化
引用的本质是一个常指针
char &b = a ==> char * const b = &a;
4、引用作为函数的返回值:
1、不能返回一个局部变量的引用,问题在于函数运行结束之后,栈空间会被释放
2、如果一个函数返回的是引用,则该函数可以作为左值使用
3、用一个普通变量去接这个引用,接回来的是这个值
int &b = test3_1(); // int *const b = test3_1(); ==> int *const b = &a;
cout << "b = " << b << endl;
int &c = test3_2();
c = 90;
test3_2();
// 如果一个函数返回的是引用,则改函数可以作为左值使用
test3_2() = 200;
test3_2();
// 用一个普通变量去接一个 引用 接回来的是个值
int d = test3_2();
d = 300;
test3_2();
指针引用
void init2(Teacher* &p)
{
p = (Teacher *)malloc(sizeof(Teacher)/sizeof(char));
if (p == NULL)
{
return;
}
p->age = 10;
p->name = (char *)malloc(sizeof(char)*100);
strcpy(p->name, "小明");
}
常引用:用普通变量去初始化常引用,不能通过引用来改变变量的值;
const int &a1 = a;
用一个常量去初始化常引用
如果是一个常量,编译器会分配一个空间去存储这个常量值,引用代表这一块空间
const int &a2 = 10; // const int *const a2 = &10;
二、内联函数
1、宏函数的优点:宏函数没有正常函数的出栈和入栈的开销,能提高运行效率
缺点:每一次展开,会使得整个程序显得冗长
例如:
#define MAX(a,b) (((a) > (b)) ? (a):(b))
2、C++建议用内联函数代替宏函数
内联函数 内联编译的函数和宏函数很像,都是做的代码替换,在调用的地方用
所以没有函数的入栈和出栈开销
内联函数的定义:在函数定义前加 inline 关键字
inline int mul(int a , int b)
{
return a*b;
}
特点:
1、内联函数在编译时处理, 而宏函数在预处理的时候处理
2、内联函数是一种请求,不一定成功
3、内联函数一旦成功,函数体在运行的时候是不存在的,因为其存放在符号表中
不能进行取地址操作,也不能作为回调函数
内联函数请求成功的因素:
1、函数体不要太大, 不要超过5行
2、不要有任何形式的循环语句
3、不要有很复杂的判断语句
三、函数默认参数
1、在函数定义的时候可以给函数的形参设置一个默认的值,如果调用时没有传入相应的参数,则使用默认参数
2、默认参数如果写在声明中,则在定义时,不要再写默认参数;相反,如果在定义时,写了默认参数,那么
声明时就不要写,二者择其一
int func5_1(int a = 3, int b = 5)
{
return a + b;
}
默认参数的规则:当函数的某一个形参有默认值以后,它的右边的所有参数都必须要有默认值
int func5_2(int a, int b = 5, int c = 1)
{
return a + b + c;
}
占位参数,只有类型声明,没有变量名
占位参数和默认参数可以一起使用
int func5_4(int a, int)
{
return a;
}
int func5_5(int a, int = 0)
{
return a;
}
四、函数重载
函数重载:用同一个函数名字,通过匹配不同的参数调用不同的函数
函数的参数个数不同
参数的类型不同
参数的顺序不同
函数的返回值类型不能作为重载的判断条件
函数默认参数和函数重载一起使用可能会造成歧义
//void Print(int a, int b = 0)
void Print(int a, int b)
{
cout << "a = " << a << ", b = " << b << endl;
}
void Print(char *str)
{
cout << "str = " << str << endl;
}
void Print(double d)
{
cout << "d = " << d << endl;
}
void Print(int a, char *str)
{
}
void Print(char *str, int a)
{
}