【一分钟学C++】指针和引用

在这里插入图片描述

竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生~
公众号: C++学习与探索  |  个人主页: rainInSunny  |  个人专栏: Learn OpenGL In Qt

指针

普通指针

  指针是一个变量,它存储的是另一个变量的内存地址。通过指针,我们可以直接访问或修改存储在内存中的值。基本使用如下:

// 声明指针:要声明一个指针变量,需要在类型前面加上*符号。例如,声明一个指向整数类型的指针变量
int* ptr;

// 指针赋值:可以通过取地址符&将变量的地址赋给指针变量。例如,将整数变量num的地址赋给指针ptr
int num = 10;
int* ptr = #

// 解引用指针:通过解引用操作符*可以访问指针所指向的变量的值。例如,访问指针ptr所指向的整数变量的值
int value = *ptr; // value现在等于num的值,即10

// 修改指针所指向的变量的值:通过解引用操作符*可以修改指针所指向的变量的值。例如,修改指针ptr所指向的整数变量的值
*ptr = 20; // 现在num的值变为20

// 空指针:空指针是指不指向任何有效内存地址的指针,通常用nullptr表示
int* ptr = nullptr;

// 指针常量:指针本身是一个常量,即指针的值(即所指向的内存地址)不能改变,但指针所指向的值可以改变。声明指针常量时通常在指针变量名前面加上const关键字。例如:
int a = 0;
int b = 1;
int* const p1 = &a;
p1 = &b; // 错误,指针指向的地址不可以改变
*p1 = 2; // OK,指针指向的值可以改变

// 常量指针:指针指向的值是一个常量,即指针所指向的值不能改变,但指针本身的值(即所指向的内存地址)可以改变。在声明常量指针时通常在*前面加上const关键字。例如:
const int* p2 = &a;
p2 = &b; // OK,指针指向的地址可以改变
*p2 = 2; // 错误,指针指向的值不可以改变

// 指向常量的的指针常量:将上面两者结合,例如:
const int* const p3 = &a;
p3 = &b; // 错误,指针指向的地址不可以改变
*p3 = 2; // 错误,指针指向的值不可以改变

函数指针

  函数指针是指向函数的指针,可以用来动态地调用不同的函数。基本使用如下:

typedef int (*funcPtr)(int, int); // 定义返回值为int,函数参数为(int, int)的函数指针类型
int add(int a, int b)
{
    return a + b;  
}
funcPtr funcAdd = add; // 将add函数地址赋值给函数指针funcAdd
int result = funcAdd(1, 2); // 通过funcAdd调用函数add

注意事项

  • 使用指针之前,务必对指针进行初始化,可以将指针初始化为nullptr或指向有效的内存地址。
  • 避免使用未初始化的指针或已经释放的指针,这会导致未定义行为或程序崩溃。
  • 当浅拷贝一份指针的时候,确保使用它时它指向的对象还在生命周期内。
  • 在进行指针类型转换时要谨慎,确保转换后的指针类型匹配,避免出现类型不匹配导致的问题。

引用

左值引用

  • 左值:可以取地址的对象就是左值。
  • 左值引用:左值引用就是对左值的引用,给左值取别名。主要作用是避免对象拷贝。
  • 使用场景:一般用于函数参数传递,避免对象拷贝。如果用于接收函数返回值,需要保证返回值在离开函数作用域仍然处在生命周期内。
int& ra = a;
int& r = *p;
const int& rb = b;

右值引用

  • 右值:不能取地址的对象就是右值。
  • 右值引用:右值引用就是对右值的引用,给右值取别名。主要作用是把延长对象的生命周期,一般是延长到作用域的scope之外。
  • 使用场景:作为移动构造函数的参数,作为std::move的接收者。
int&& rr1 = 10;
double&& rr2 = x + y;
double&& rr3 = fmin(x, y);
int&& rr4 = std::move(a);

注意事项

  • 左值引用只能引用左值,不能直接引用右值。但是const左值引用既可以引用左值,也可以引用右值。
    • 在 C++11标准产生之前,是没有右值引用这个概念的,当时如果想要一个类型既能接收左值也能接收右值的话,需要用const左值引用,比如标准容器的push_back接口:void push_back (const T& val)。也就是说,如果const左值引用不能引用右值的话,v.push_back(1);写法就不行了。
  • 右值引用引用右值,会使右值被存储到特定的位置。也就是说,右值引用变量本身其实是左值,可以对它取地址和赋值。

指针和引用区别

  • 定义和初始化:
    • 指针需要通过 * 符号来声明和初始化,例如:int* ptr = #
    • 引用在声明时不需要使用特殊符号,直接通过 & 符号初始化,例如:int& ref = num;
  • 空值:
    • 指针可以指向空值(nullptr),即不指向任何对象或地址。
    • 引用在声明后必须引用一个对象,不能指向空值。
  • 重新赋值:
    • 指针可以被重新赋值指向不同的对象或空值。
    • 引用一旦初始化后,不能再引用其他对象,引用变量本身就是其所引用对象的别名。
  • 算术运算:
    • 指针可以进行算术运算,指针加减整数会移动指针指向的位置。
    • 引用不支持算术运算,因为引用本质上是对象的别名。
  • 传递给函数:
    • 当作为函数参数时,指针可以传递空指针,也可以传递指向数组或动态分配内存的指针。
    • 引用作为函数参数时,可以确保不为空,且不需要进行空值检查。
  • 修改对象:
    • 通过指针可以修改所指向对象的值。
    • 通过引用也可以修改引用对象的值,因为引用本质上是对象的别名。

在这里插入图片描述


关注公众号:C++学习与探索,有惊喜哦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值