知识点整理
引用是C++的概念
引用和指针的区别
1.引用必须初始化,指针可以不需要初始化
2.引用不占内存空间,指针占内存空间
3.引用不能为空,指针可以为空
4.引用是直接引用,指针是间接访问
5.引用不能重新赋值,指针可以
6.常引用可以是常量的别名,而指针只能指向字符串常量
引用的使用
1.普通引用(必须要初始化)
引用的语法:int a = 10; int &b = a;
#include<iostream>
using namespace std;
int main()
{
int a=10;
int &b = a; //相当于把b的值修改为a的值 a和 b的类型要相同
b=100; //把a的值也修改为100
//int &c; //程序报错因为没有进行初始化
cout << "a = " << a << " b" << b << endl; 100 100
printf("%x %x\n",&a,&b); //地址相同
} //a和b是同一片空间
2.引用做函数参数(不用进行初始化)
两数字交换(引用 指针 + ^)
#include<iostream>
using namespace std;
void swap(int &a, int &b)//通过引用交换a和b的值 交换成功 ^
{
//
int c;
c = a;
a = b;
b = c;
}
void swap1(int *a, int *b)//通过指针交换
{
int c;
c = *a;
*a = *b;
*b = c;
}
int main()
{
int a = 10;
int b = 20;
swap(a, b);
cout << "a " << a << "b " << b << endl;//a = 20b= 10
swap1(&a, &b);
cout << "a " << a << "b " << b << endl;//a=10 b=20
}
3.复杂数据类型做函数引用
#include<iostream>
using namespace std;
struct Teacher
{
char name[64];
int age;
};
void priT(Teacher *pT) //通过指针
{
cout << "name = " << pT->name << endl;
cout << "age = "<<pT->age << endl;
//pT->age = 100; 修改pT则t1也会发生改变
}
void priT1(Teacher &pT) //通过引用
{
cout << "name = " << pT.name << endl;
cout << "age = " << pT.age << endl;
//pT.age = 22; 修改pT则t1也会发生改变
}
void priT2(Teacher pT) //通过形参 pT和t1是两个不同的变量
{
cout << "name = " << pT.name << endl;
cout << "age = " << pT.age << endl;
//pT.age=23 修改pT则t1不会发生改变
}
int main()
{
Teacher t1;
strncpy(t1.name, "sikui", 6);
t1.age = 18;
priT(&t1);
priT1(t1);//pT是t1的别名
priT2(t1);//pT是形参 t1拷贝一份给pT
}
4.引用本质
1.引用类型的变量会占用内存空间,占用的内存空间的大小和指针类型的大小是相同的。
2.引用在c++中的内部实现是一个常指针
#include<iostream>
using namespace std;
struct Teacher
{
char name[4];
int age;
double &a; //引用占用4字节
int &b; //引用占用4个字节
};
int main()
{
cout << sizeof(Teacher) << endl;//16
}
5.函数的返回值是引用(引用当左值)
c++引用使用时的难点:
当函数返回值为引用时:
若返回栈变量,不能成为其他引用的初始值,不能作为左值使用
当返回静态变量或全局变量时:
可以成为其他引用的初始值,即可作为右值使用,也可作为左值使用
#include<iostream>
using namespace std;
int getA() //返回局部变量
{
int a = 10;
return a;
}
int & getB() //错误,返回局部引用
{
int b = 20;
return b;
}
int * getBB() //错误,返回局部指针
{
int b = 20;
return &b;
}
int & getC()//返回静态区 引用
{
static int c = 30;
return c;
}
int main()
{
int a = 0;
a=getA();//值的拷贝
int b = 0;
b=getB(); //赋值
int &c = getB(); //错误将引用赋值给另一个引用作为初始值,由于是栈的引用,内存非法
int *cc =getBB(); //错误 指针是栈中的使用完成会自动释放。
int &d = getC(); //正确,使用的是静态变量区的值,既可以初始化,也可以做左值
getC() = 123; //可以做左值
cout << a << b << d<<endl;
}
6指针引用
#include<iostream>
using namespace std;
struct Teacher
{
char name[100];
int age;
};
void fun1(Teacher **p)
{
Teacher *t;
t = (Teacher *)malloc(sizeof(Teacher));
if (t == NULL)
{
return;
}
memcpy(t->name, "sikui", 6);
t->age = 100;
*p = t;
}
void fun2(Teacher * &p)
{
p = (Teacher *)malloc(sizeof(Teacher));
if (p == NULL)
{
return;
}
memcpy(p->name,"shushan",8);
p->age = 100;
}
int main()
{
Teacher *t=NULL;
fun1(&t);
cout << t->name << t->age << endl;
fun2(t);
cout << t->name << t->age << endl;
}
7常引用
#include<iostream>
using namespace std;
int main()
{
int a = 10;
int &b = a;
int x = 20;
const int &y = x;
cout << a << b << x << y << endl;
return 0;
}
#include<iostream>
using namespace std;
int main()
{
int x = 20;
const int &y = x; //常引用 让变量拥有只读属性 不能通过y来修改x;
//常引用初始化 用变量初始化 常引用
//用变量初始化 常引用
int x1 = 30;
const int &x2 = x1; //用变量初始化 常引用
//用字面量 初始化 常引用
const int a = 10; // c++编译器把a放在符号表中
//int &b = 40; //普通引用 引用一个字面量 字面量没有地址 会报错
const int &b = 40; //m有地址
}
常引用做函数参数
#include<iostream>
using namespace std;
struct Teacher
{
char name[64];
int age;
};
void getTeacher(const Teacher &teacher)
{
cout << teacher.age << endl; //只读不可修改
cout << teacher.name << endl; //只读不可修改
}
int main()
{
Teacher t1;
t1.age = 30;
strcpy(t1.name, "sikui");
getTeacher(t1);
}