NO.2 C++ 指针

零蚀


指针基础

  • 指针申明&初始化
    int *point=0;
    int *point=NULL;
    int *point= nullptr; // c++ 推荐方式
    int *point= &x;
    
    • 指针和别名的区别
    int &a=c; // 申明一个引用,指向一个int类型的数据
    int *b=c; // 申明一个指针,指向一个int数据
    

    在这里插入图片描述

    • 指针解引用
    int *p=&a;
    *p=a;
    // int *p等同于int* p
    

    这里的int *p 不是申明的int了一个 *p 对象,因为 *p是p指针的地址值,这里可以这么理解,int * 是一个申明,申明了一个p指针,而 *p 只是获取 p指针的内容。

    • 动态内存分配

    cpp中申请内存的关键字是new,不同于c中的malloc。

    // 栈内存
    int a=1;
    // 堆内存(存储时间更长)
    int *a1 = new int(2);
    cout << *a1 << endl; //2
    delete a1; 
    cout << *a1 << endl; //2
    a1= nullptr;
    

    new int(2)是申请了一个堆内存空间,大小为int的大小,而内存中所存储的值为2。 申请出来的内存需要手动释放掉,释放空间但是这里我们delete后还能看到可以输出值,其实原理很简单,如下图所示:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YAA4kv1p-1583214509740)(media/15829700510433/15831256899996.jpg)]

    • 数组和指针
    int array[]={1,2,3,4,5};
    int *p=array;
    cout << *array << endl;// array[0]
    cout << *p << endl; // array[0]
    cout << *(p+1) << endl; // array[1]
    cout << *(p+2) << endl; // array[2]
    
  • 常量指针
    • 指向常量的指针
    const int *p=&a;
    // 不能 *p=?
    int b=2;
    p=&b;
    

    *p 是只读类型,也就是不能被赋值,编译器就会报错,但是可以改变p的指向。

    • 常量指针
    int *const q=&a;
    *q =10;
    

    常量指针与指向常量的指针相反,可以赋值,但不可以改变地址

    • 指向常量的常量指针
    // 不能修改任何东西的指针
    const int *const q=&a; 
    
    • 指针参数
    #include <vector>
    void iterator(vector<int> *v){
        //v->size();
        for (int i = 0; i < (*v).size(); ++i) {
    
            cout << (*v)[i]<< endl;
        }
    }
    
    • 指针参数关于foreach
    void func_iterator(vector<int> *v){
        //v->size();
        //以下方式不会改变v的内容,因为int v:(*v)相当于又创建了一个v的v的参数。
        //for (int v:(*v)) { // 此处应该是 int &v:(*v)
        //  if(v==45){
        //     v=15;      // 此处改变的是int v 和 *v无关
        //  }
        //}
        // 以下方式可以改变*v的内容
        for (int i = 0; i < (*v).size(); ++i) {
            if((*v)[i]==45){
                (*v)[i]=15;
            }
        }
    }
    
  • 函数指针
    • 返回值指针
    int* max(int *a,int *b){
        return *a>*b?a:b;
    }
    
    • 二级指针
    void func(int **p){
        *p=new int(4);
    }
    
    int *p= nullptr;
    func(&p);
    cout << *p << endl;
    delete p;
    p= nullptr;
    
    • 函数指针
    int add(int a,int b);
    int blod(int a,int b,int (*add)(int,int));
    
    int main() {
        //函数名单独使用会转化为指针
        //add_param相当于参数,add是函数指针
        //函数指针可以作为函数参数传递。
        int (*add_param)(int ,int) = add;
    
        int result=blod(4,6,add_param);
        cout << result << endl;
    
        return 0;
    }
    
    int add(int a,int b){
        return a+b;
    }
    
    // 函数指针的目的是将函数转化为参数
    int blod(int a, int b ,int (*add)(int,int)){
    
        return add(a,b);
    }
    
    • typedef

    名称替换(起别名)

    //typedef vector<int> vi;
    typedef int(*add_param)(int,int);
    int main() {
        int result=blod(4,6,add);
        cout << result << endl;
    
        return 0;
    }
    
    
    int add(int a,int b){
        return a+b;
    }
    
    int blod(int a, int b ,add_param){
    
        return add(a,b);
    }
    

引用

  • 引用简介
    1. 是变量或者对象的别名
    2. 引用不能改变自己指向
    3. 申明引用时必须对其初始化
    4. 引用不会引发新的空间开销
    5. 引用不能建立数组引用。
  • 右值引用
    • 左值&右值

      不能以等号的左右来判断是否是左值右值。左值: 是否能取地址,或者是否能起名。右值: 具体的数值,或者具体的表达式。

      int a = 33;
      |左值|  |右值|
      int a = b;
      |左值|  |左值|
      int a = b  +  3;
      |左值|  |  右值  |
      int a = get() // 不能被取地址,虽然它有函数地址和指针
      |左值|  |  右值  |
      

      左值引用必须都是左值.

      int &c =a;
      get_num(int &v){....}
      
    • 右值引用

      为了支持移动概念,添加了右值引用,绑定一个即将销毁的对象,左值具有持久的状态,有独立的内存空间。而右值就是表达式在求职过程中创建的临时对象。

      int &&c=4;
      int &&c=a+4
      int a(int &&a,int b){}
      a(1,2)
      int b(int &a,int b){}
      b(c,2)
      

      右值引用必须都是右值.


🔗 前言
🔗 C++ 高级列表
🔗 NO.1 C++ 基础
🔗 NO.3 C++ 特殊函数
🔗 NO.4 C++ 重载&继承&lambda
🔗 NO.5 C++ 虚函数&智能指针
🔗 NO.6 C++ I/O
🔗 NO.7 C++ 模版编程&容器
🔗 NO.8 C++ 常用函数&线程
🔗 NO.9 C++ QT 入门
🔗 NO.10 C++ QT 绘制&自定义组合控件
🔗 NO.11 C++ QT 绘制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零蚀zero eclipse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值