1.引用的基本用法
引用时C++对C的重要扩充。在C/C++中指针的作用基本都是一样的,但是C++增加了另外一种给函数传递地址的途径,这就是按引用传递(pass-by-reference),它也存在与其他的一些编程语言中,并不是C++发明的。
简单来说引用就是给变量取个别名。
int main()
{
int a = 10;
int &num = a; //&与别名结合表示引用
cout << a << num << endl;
}
注意:
- 引用必须初始化
- 引用一旦初始化,就不能再次修改别名
int main()
{
int a = 10;
int &num = a;
cout << a << " " << num << endl;
num = 100;
cout << a <<" "<< num << endl;
cout << "输出地址" << endl;
cout << &a << " " << &num << endl;
}
可以看到a和num的地址是一样的。
2.引用与数组(了解)
给数组取别名
方法一:
int main()
{
int arr[5] = {1,2,3,4,5};
int(&my_arr)[5] = arr;
}
“[]”的优先级比&高所以要加“()”
方法二:
int main()
{
int arr[5] = {1,2,3,4,5};
typedef int TYPE_ARR[5];
TYPE_ARR &my_arr = arr;
}
给arr[5] typedef一下
3.引用与函数
- 最常见看见引用的地方是在函数参数和返回值中。
- 当引用被用作函数参数的时,在函数内对任何引用的修改,将对还函数外的参数产生改变。当然,可以通过传递一个指针来做相同的事情,但引用具有更清晰的语法。
int fun1(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
int fun2(int *a, int *b) //a=&data1,b=&data2
{
int temp = *a;
*a = *b;
*b = temp;
}
int fun3(int &a, int &b) //a=data1,b=data2
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int data1 = 10, data2 = 20;
fun1(data1, data2); //交换失败
cout << data1 << " " << data2 << endl;
fun2(&data1, &data2); //交换成功
cout << data1 << " " << data2 << endl;
fun3(data1, data2); //交换成功
cout << data1 << " " << data2 << endl;
}
- 如果从函数中返回一个引用,必须像从函数中返回一个指针一样对待。当函数返回值时,引用关联的内存一定要存在。
- 函数当左值,必须返回引用。
int& fun1(void) //引用作为函数返回值类型
{
int num = 10;
return num; //局部变量返回
}
int& fun2(void)
{
static int num = 20;
return num;
}
int main()
{
int &ret1 = fun1(); //当fun1中的sum内存被释放时,会出现问题
int &ret2 = fun2();
cout << ret2 << endl;
fun2() = 100; //将函数返回值作为左值时,函数的返回值类型必须为引用。
cout << ret2 << endl;
}
4.引用的本质
int &a = data;//编译器内存转换:int * const a = &data;
5.引用与指针(了解)
void fun(char* &my_str)
{
my_str = (char*)calloc(1, 32);
strcpy(my_str, "hello world");
}
int main()
{
char *str = NULL;
fun(str);
cout << str << endl;
free(str);
}
6.常引用
常引用的定义格式:
const Type& ref = val;
常引用:不能通过别名修改原本变量的值
typedef struct
{
int num;
char name[20];
}STU;
//void printSTU(STU temp) 将结构体变量作为形参开销太大
void printSTU(const STU &temp)
{
cout << temp.name << temp.num << endl;
}
int main()
{
STU lingo = {100,"lingo"};
printSTU(lingo);
}
将函数的形参定义为常量引用的好处: 引用不产生新的变量,减少形参与实参传递时的开销。
由于引用可能导致实参随形参改变而改变,将其定义为常量引用可以消除这种副作用。如果希望实参随着形参的改变而改变,那么使用一般的引用,如果不希望实参随着形参改变,那么使用常引用。