指针:是一个变量,存储一个变量的地址。
引用:是变量的别名。

1、初始化

  1. 指针定义时不必初始化,引用必须初始化。
  2. 指针初始化时可为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