11、指针和引用
指针:是一个变量,存储一个变量的地址。
引用:是变量的别名。
1、初始化
- 指针定义时不必初始化,引用必须初始化。
- 指针初始化时可为NULL,引用不能初始化为NULL。
int a = 10;
int *p = &a;
int &y = a;
cout << "a是" << a << endl;
cout << "p是" << p << endl;
cout << "*p是" << *p << endl;
cout << "y是" << y << endl;
cout << "&y是" << &y << endl;
2、const修饰
const修饰指针,const放在之前所指变量值不可改变,const放在之后,指针本身不能改变,指向的变量值可以改变。
int a = 10;
int b = 20;
const int *p1 = &a;
*p1 = 20; // 错误
p1 = &p2; // 正确
int a = 10;
int b = 20;
int const* p2 = &b;
*p2 = 30; // 正确
p2 = &a; // 错误
const修饰引用,放在&之前不能修改引用所表示的变量的值,放在&之后,const作用被忽略。
int a = 10;
const int &y = a;
y = 20; // 正确
3、引用从一而终
非常指针在指针赋值后可以改变指针值;引用在初始化后不能再作为别的变量的别名。
int a = 10;
int b = 20;
const int *p = &a;
int &y = a;
y = b;
cout << "a是" << a << endl;
cout << "p是" << p << endl;
cout << "y是" << y << endl;
cout << "&y是" << &y << endl;
// 输出
a是20
p是0xfc947ff794
y是20
&y是0xfc947ff794
y指向的地址没有改变,只是将b的值赋给a。
4、函数传参
指针和引用都是传入地址,在函数内部可以改变实参的值。
int test1(int a, int b)
{
a = 1;
b = 1;
return a + b;
}
int test2(int &a, int &b)
{
a = 1;
b = 1;
return a + b;
}
int test3(int *a, int *b)
{
*a = 1;
*b = 1;
return *a + *b;
}
测试test1
int a = 10;
int b = 20;
int c = test1(a, b);
cout << "a是" << a << endl;
cout << "b是" << b << endl;
cout << "c是" << c << endl;
// 输出
a是10
b是20
c是2
测试test2
int a = 10;
int b = 20;
int c = test2(a, b);
cout << "a是" << a << endl;
cout << "b是" << b << endl;
cout << "c是" << c << endl;
// 输出
a是1
b是1
c是2
测试test3
int a = 10;
int b = 20;
int c = test3(&a, &b);
cout << "a是" << a << endl;
cout << "b是" << b << endl;
cout << "c是" << c << endl;
// 输出
a是1
b是1
c是2
5、const修饰函数传参
// 引用
int test(const &int a,const &int b)
{
a = 1; // 错误:不能修改
b = 1; // 错误:不能修改
return a + b;
}
int test(int &const a,int &const b) // const失去作用
{
a = 1; // 能修改
b = 1; // 能修改
return a + b;
}
// 指针
int test(const int* a,const int* b)
{
*a = 1; // 错误:不能修改
*b = 1; // 错误:不能修改
return *a + *b;
}
int test(int *const a,int *const b)
{
*a = 1; // 值能修改,指针不能改变指向
*b = 1; // 值能修改,指针不能改变指向
int c = 20;
a = &c; // 错误,不能修改指向
return *a + *b;
}