C++引用和指针的区别

1、指针是一个变量,存储的值是一个地址,需要为指针分配内存空间;引用是给变量起别名,不需要分配内存空间;

// 需要为指针分配内存
int a = 10;
int *ptr = &a; // ptr 是一个指针,存储 a 的地址

// 内存布局:
/* 
   地址     | 值
   ---------|----
   0x1000   | 10     // 变量 a
   0x2000   | 0x1000 // 指针 ptr,存储的是 a 的地址
 */
// 引用不需要分配内存
int a = 10;
int &ref = a;        // ref 是 a 的引用,别名

// 内存布局:
/* 
   地址     | 值
   ---------|----
   0x1000   | 10     // 变量 a 和 引用 ref 指向同一地址0x1000
 */

 2、 引用必须初始化,初始化之后就不能改变引用;指针可以是空值,可以初始化之后改变;

// 引用必须初始化,且初始化之后不可改变引用
int a = 10;
int b = 10;
int &ref = a; // 引用必须初始化,绑定到变量 a
std::cout << "ref: " << ref << std::endl; // 输出 10
// ref = b; // 错误!引用一旦初始化后不能再改变绑定对象
a = 30;
std::cout << ref << std::endl; // 输出 30,引用跟随 a 的变化
ref = 40;
std::cout << a << std::endl; // 输出 40,ref是a的别名,ref值改变等于a值改变
// 指针可以初始化为空,初始化之后可以改变
int a = 10;
int b = 20;
int *ptr = nullptr; // 指针可以为空值
std::cout << "ptr: " << ptr << std::endl;

ptr = &a; // 指针初始化后可以改变指向
std::cout << "ptr points to: " << *ptr << std::endl; // 输出 10

ptr = &b; // 指针可以改变指向其他变量
std::cout << "ptr now points to: " << *ptr << std::endl; // 输出 20

3、const修饰指针,const修饰引用; 

// 指针和const的三种结合方式

// 方式1,指向常量的指针,不能通过指针修改变量的值
int value = 10;
const int *ptr = &value;  // ptr 是指向常量的指针,不能通过 ptr 修改 value
// *ptr = 20;             // 错误,不能修改通过 ptr 修改 value
value = 20;               // 合法,可以通过其他方式修改 value
cout << *ptr << endl;     // 输出20

// 方式2,常量指针,不能修改指针的指向
int value = 10;
int value2 = 11; 
int *const ptr = &value;  // ptr 是常量指针,不能修改 ptr 指向其他对象
// ptr = &value2;         // 不合法,不能修改常量指针的指向
*ptr = 20;                // 合法,可以通过 ptr 修改 value

// 方式3,const既修饰常量又修饰指针
int value = 10;
int value2 = 11;
const int *const ptr = &value; // ptr 是指向常量的常量指针
// *ptr = 20; // 错误,不能通过 ptr 修改 value
// ptr = &value2; // 错误,不能修改 ptr 指向其他对象
// 引用加const

// 普通引用
int x = 5;
int &ref2 = x; // ref2 是普通(非常量)引用,可以通过 ref2 修改 x
ref2 = 15; // 合法,通过 ref2 修改了 x 的值

// 常量引用
const int value = 10;
const int &ref = value; // ref 是常量引用,不能通过 ref 修改 value
// ref = 20; // 错误,不能修改通过 ref 修改 value
/×
引用本身就是常量指针(int *const ptr指向不可改,值可改)
×/

4、指针本身一个变量,引用不是对象;所以指针可以有多级,引用只能是一级(int **p或int ***p合法 而 int &&a是不合法的);

// 当需要在运行时动态分配内存时,多级指针可以用来管理分配的内存块
int **matrix; // 声明一个 int 类型的二级指针 matrix
// 动态分配内存给 matrix 的第一级指针,即分配 rows 个指针
matrix = new int*[rows];
// 循环分配内存给 matrix 的每一个一级指针指向的二级指针,即每一行分配 cols 个 int 类型的内存空间
for (int i = 0; i < rows; ++i) {
    matrix[i] = new int[cols];
}

// 在实现链表、树等复杂数据结构时,多级指针可以用来表示节点之间的连接关系
// 一个变量可以有多个引用
int a =10;
int &ref1 = a;
int &ref2 = a;
int &ref3 = a;  
ref2 = 20;         //改变ref2,ref2 = a = ref1 = ref3 = 20

// 可以引用引用
int a = 10;
int &ref1 = a;    // ref1 是 a 的引用
int &ref2 = ref1; // ref2 是 ref1 的引用
ref2 = 20;        // 输出ref2、ref1、a都是20 

5、sizeof引用得到的是引用所指向的变量的内存大小,而sizeof指针得到的是指针本身的大小; 

// sizeof指针
int *ptr;
std::cout << sizeof(ptr) << std::endl; 
// 输出 4 或者 8,取决于系统架构,32位系统占4字节,64位系统占8字节

// sizeof引用
int x = 10;
int &ref = x;
std::cout << sizeof(ref) << std::endl; // 输出 4,因为x是int类型占4字节

6、指针和引用的自增(++)运算意义不一样;

// 指针自增运算
int arr[] = {1, 2, 3, 4};
int *p = arr; // p 指向数组的第一个元素

std::cout << *p << std::endl; // 输出 1
p++; // p 自增,指向数组的下一个元素
std::cout << *p << std::endl; // 输出 2
*p = 99;      // 数组被改为arr[] = {1, 99, 3, 4};
std::cout << arr[1] << std::endl; // 输出 99
// 引用的自增
int a = 10;
int &ref = a; // ref 是 a 的引用
std::cout << ref << std::endl; // 输出 10
ref++; // ref 自增,即 a 自增
std::cout << ref << std::endl; // 输出 11
std::cout << a << std::endl;   // 输出 11

// 引用数组的某个元素
int arr[] = {1, 2, 3, 4};
int &ref = arr[1]; // 引用数组的第二个元素
std::cout << ref << std::endl; // 输出 2
ref++; // 自增引用的元素,即 arr[1]++
std::cout << ref << std::endl; // 输出 3
std::cout << arr[1] << std::endl; // 输出 3,数组的第二个元素也被修改

// 引用整个数组
int arr[] = {1, 2, 3, 4};
int (&ref)[4] = arr; // 引用整个数组
// ref++ 是非法的,不能对数组引用进行自增操作

7、引用访问一个变量是直接访问,而指针访问一个变量是间接访问。

int y = 30;
int *ptr = &y; // ptr 是指向 y 的指针
// 间接访问 y,通过指针 ptr
std::cout << "y: " << y << std::endl;     // 输出 30
std::cout << "Value pointed to by ptr: " << *ptr << std::endl; // 输出 30
// 通过指针修改 y 的值
*ptr = 40;
std::cout << "y after modification: " << y << std::endl; // 输出 40
// 访问引用是直接访问
int x = 10;
int &ref = x; // ref 是 x 的引用
// 直接访问 x 和 ref
std::cout << "x: " << x << std::endl;     // 输出 10
std::cout << "ref: " << ref << std::endl; // 输出 10

 

 

 

相关推荐

  1. c++指针引用区别

    2024-07-11 10:34:03       47 阅读
  2. C++里指针引用区别

    2024-07-11 10:34:03       27 阅读
  3. C++引用指针区别

    2024-07-11 10:34:03       20 阅读
  4. 引用指针区别

    2024-07-11 10:34:03       26 阅读
  5. C/C++ 引用指针区别及使用场景

    2024-07-11 10:34:03       25 阅读
  6. 面试题:指针引用区别

    2024-07-11 10:34:03       42 阅读
  7. C/C++指针指针*与引用&区别

    2024-07-11 10:34:03       54 阅读
  8. C++中传递指针传递引用应用场合区别

    2024-07-11 10:34:03       11 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 10:34:03       53 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 10:34:03       56 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 10:34:03       46 阅读
  4. Python语言-面向对象

    2024-07-11 10:34:03       57 阅读

热门阅读

  1. 3.数组基础

    2024-07-11 10:34:03       16 阅读
  2. Docker 日志丢失 - 解决方案

    2024-07-11 10:34:03       17 阅读
  3. 3D Web开发新篇章:threelab探索之旅

    2024-07-11 10:34:03       18 阅读
  4. 外科休克病人的护理

    2024-07-11 10:34:03       16 阅读
  5. axios get 请求发送 FormData 数据

    2024-07-11 10:34:03       21 阅读
  6. 数据库的更新方式有哪些

    2024-07-11 10:34:03       19 阅读
  7. VSCode, 请在windows下使用git bash终端

    2024-07-11 10:34:03       21 阅读
  8. R 数据重塑

    2024-07-11 10:34:03       14 阅读