1 引用
- 指针保存的是变量的地址 引用是变量的别名
- 单纯给变量取别名没有任何意义,作为函数参数传递,能保证参数传递过程中不产生副本
- 引用可以直接操作变量,指针要通过取值(*p),间接操作变量,指针的可读性差
void main(){
int a = 10;
//b表示这个内存空间另外一个别名 &:c++中的引用
int &b = a;
cout << b << endl;
system("pause");
}
打印结果
10
2 指针和引用
void swap_1(int *a,int *b){
int c = 0;
c = *a;
*a = *b;
*b = c;
}
//引用值交换
void swap_2(int &a,int &b){
int c = 0;
c = a;
a = b;
b = c;
}
void main(){
int x = 10;
int y = 20;
printf("%d,%d\n",x,y);
swap_2(x,y);
printf("%s,%d,%d\n","使用引用交换后:",x,y);
swap_1(&x,&y);
printf("%s,%d,%d\n", "使用指针交换后:", x, y);
system("pause");
}
打印结果
10,20
使用引用交换后:,20,10
使用指针交换后:,10,20
3 引用的常用用法
引用常用语函数的参数或返回值
struct NBAPlayer{
char* name;
int age;
};
void myprint(NBAPlayer &t){
cout << t.name << "," << t.age << endl;
};
void myprint2(NBAPlayer *t){
cout << t->name << "," << t->age << endl;
}
void main(){
NBAPlayer t;
t.name = "Kobe";
t.age = 39;
myprint(t);
myprint2(&t);
system("pause");
}
打印结果
Kobe,39
Kobe,39
4 传递一个二级指针
void getPlayer(NBAPlayer **p){
NBAPlayer *tmp = (NBAPlayer*)malloc(sizeof(NBAPlayer));
tmp->age = 30;
tmp->name = "Rose";
*p = tmp;
}
void main(){
NBAPlayer *n;
getPlayer(&n);
cout << n->age << "," << n->name << endl;
system("pause");
}
当调用getPlayer()方法将&n传到方法中时,将会有:
&n=**p
而
*p = tmp
所以将会有
&n = *tmp
打印结果
30,Rose
5 指针常量 常量指针
void main(){
int a = 2, b = 3;
//指针常量 指针是常量,不改变地址的指针,可以修改内容
int *const p1 = &a;
//p1 = &b; //Error 表达式必须是可修改的左值
cout << a << endl;
cout << p1 << endl;
//常量指针,指向常量的指针,内容不能修改
const int *p2 = &a;
p2 = &b;
//p2 = 9;//Error 不能将int类型的值分配到“const int *”类型的实体
system("pause");
}
6 常引用
类似于java中的final
void printMethod(const int &a){
cout << a << endl;
}
void main(){
//引用必须有值,不能为空
//int &a = NULL;
//常引用
int a = 10, b = 20;
const int &c = a;
//不能重新赋值
//c = b;
//字面量
const int &d = 40;
printMethod(c);
system("pause");
}
7 引用的大小
struct NBAPlayer{
char name[20];
int age;
};
void main(){
NBAPlayer n;
NBAPlayer &n1 = n;
NBAPlayer *p = &n;
cout << sizeof(n1) << endl;
cout << sizeof(p) << endl;
system("pause");
}
24
4
引用是变量的别名,所以引用的大小和变量的大小相等所以sizeof(n1) = 24
指针保存的是内存地址,内存地址的大小即为int类型的大小所以sizeof(p) = 4
8 引用不能为空
由于引用不能为空,所以将不用判断所传的引用是否为空而导致崩溃。
struct NBAPlayer{
char name[20];
int age;
};
void constomPrintf1(NBAPlayer *n){
cout << n->name << "," << n->age << endl;
};
void constomPrintf2(NBAPlayer &n){
cout << n.name << "," << n.age << endl;
}
void main(){
NBAPlayer *p = NULL;
constomPrintf1(p); //将会报错,防止不报错,需要进行非空判断
//NBAPlayer &t = NULL; //引用不能为空 所以不需要进行非空判断
system("pause");
}
9 函数默认参数
函数有默认参数可以不传
void myPrintf(int x,int y = 1,int z=2){
cout << x << endl;
}
//重载
void myPrintf(int x){
cout << x<< endl;
}
10 可变参数的读取
void main(){
//myPrintf(30);//将会报错因为不知道去执行哪个方法
system("pause");
}
void func(int i,...){
//可变函数的指针
va_list args_p;
//开始读取可变函数,i是最后一个固定参数
va_start(args_p,i);
int a = va_arg(args_p,int);
char b = va_arg(args_p,char);
int c = va_arg(args_p,int);
cout << a << endl;
cout << b << endl;
cout << c << endl;
//结束
va_end(args_p);
}
void main(){
func(9,20,'b',30);
system("pause");
}
打印结果
20
b
30