在c++中 能用引用绝不用指针
这句话充分说明了引用在c++中的重要意义;
引用是 c++对 c 的重要扩充。在 c/c++中指针的作用基本都是一样的,但是 c++增
加了另外一种给函数传递地址的途径,这就是按引用传递(pass-by-reference),它
也存在于其他一些编程语言中,并不是 c++的发明。
引用 给已有的的变量取个别名
语法:
1、&和别名结合表示引用
2、给某个变量取别名 就定义某个变量
3、从上往下替换
int num = 10;
int &a = num;//此处的&不是取地址,而是表明a是引用变量(a为num的别名)
注意:
1.引用必须初始化
2.引用初始化之后不得再次修改别名
给数组取个别名
方法一:
void test0()
{
int arr[5] = {10,20,30,40,50};
int (&my_arr)[5] = arr;
int i = 0;
for(i=0;i<5;i++)
{
cout << my_arr[i]<<"";
}
cout<<endl;
}
方法二:
void test1()
{
int arr[5] = {10,20,30,40,50}
//1、用typedef 给数组类型 取个别名
//TYPE_ARR就是一个数组类型(有5个元素 每个元素位int)
typedef int TYPE_ARR[5];
TYPE_ARR &myArr[5] = arr;
int i = 0;
for(i=0;i<5;i++)
{
cout << my_arr[i]<<"";
}
cout<<endl;
}
引用作为函数的参数
void my_swap1(int a,int b)
{
int tmp = a;
a = b;
b=tmp;
}
void my_swap2(int *a,int *b)//a=&data1,b =&data2;
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void my_swap3(int &a, int &b)
{
int tmp = a;
a = b;
b= tmp;
}
void test2()
{
int data1 = 10,data2=20;
cout<<"data1 = "<<data1<<", data2 = "<<data2<<endl;
//my_swap1(data1,data2);//交换失败
//my_swap2(&data1,&data2);//交换成功
my_swap3(data1,data2);//交换成功(推荐)
cout<<"data1 = "<<data1<<", data2 = "<<data2<<endl;
}
引用作为函数的返回值
int& my_data(void)
{
int num = 100;
return num;//err 函数返回啥变量 引用就是该变量的别名
//函数的返回值是引用时 不要返回局部变量
}
int& my_data1(void)
{
static int num = 200;
return num;//ok
}
void test3()
{
//ret是别名 ret是num的别名
int &ret = my_data();
//cout<<"ret = "<<ret<<endl;//非法访问内存
int &ret1 = my_data1();//ret1是num的别名
cout << "ret = " << ret1 << endl;
}
int& my_data2(void)
{
static int num = 200;
cout << "num = " << num << endl;
return num;
}
void test4()
{
my_data2() = 2000;
my_data2();//num = 2000;
}
引用的本质
引用的本质在c++内部实现是一个指针常量. Type& ref = val; // Type* const ref = &val;
c++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同,只是这个过程是编译器内部实现,用户不可见
int data = 10;
int &a = data;//a就是data的别名
//编译器内存转换:int * const a = &data;
a=100;//等价于data=100
//*a = 100;//*a == data
指针的引用
#include<stdlib.h>
#include<string.h>
void my_str1(char **p_str)//p_str = &str
{
//*p_str == *&str == str
*p_str = (char *)calloc(1,32);
strcpy(*p_str, "hello world");
return;
}
void my_str2(char* &my_str)//char* &my_str = str;my_str等价str
{
my_str = (char *)calloc(1,32);
strcpy(my_str, "hello world");
return;
}
void test07()
{
char *str = NULL;
//需求:封装一个函数 从堆区 给str申请一个空间 并赋值为"hello world"
//my_str1(&str);
my_str2(str);
cout<<"str = "<<str<<endl;
free(str);
}
常引用
常引用
typedef struct
{
int num;
char name[32];
}STU;
void myPrintSTU1(STU tmp)//普通结构体变量作为形参 开销太大
{
cout<<sizeof(tmp)<<endl;
cout<<"学号:"<<tmp.num<<", 姓名:"<<tmp.name<<endl;
}
void myPrintSTU2(const STU &tmp)//STU &tmp=lucy;tmp是lucy的别名 tmp没有开辟独立空间
{
//tmp.num = 2000;//err 因为tmp为常引用
cout<<"学号:"<<tmp.num<<", 姓名:"<<tmp.name<<endl;
}
void test08()
{
STU lucy = {100,"lucy"};
//需求:定义一个函数 遍历lucy成员(读操作)
myPrintSTU2(lucy);
}
常量的引用
void test09()
{
//给常量10取个别名 叫num
//int &针对的是int ,10是const int类型
//const int 针对的是const int, 10是const int类型
const int &num = 10;
cout<<"num = "<<num<<endl;//10
}