2018-05-07

2018-05-08  本文已影响0人  try312

引用

左值引用 右值引用

void showit(int &&rnum) //右值引用
{
    cout << rnum << endl;
}

//左值引用往往引用内存里面值   右值引用往往引用寄存器里面的值

void main09xx()
{
    int num = 10;
    int& lnun(num);      //左值引用   变量别名
    int&& rnum(num + 4); //右值引用   快速备份   编译器 自动回收


    int a[5]{ 1,2,3,4,5 };
    int*p(a);

    int*  &rp(p);    // & 放在类型和变量名之间
    rp += 1;
    cout << *rp << endl;

    int* &&rrp(p + 2);  //右值引用 &&
    cout << *rrp << endl; //4

    int* &&rrrp(&a[1]);  //右值引用 &&
    cout << *rrrp << endl; //2

    showit(a[4] + 5);  //10

    showit(move(a[4]));  //5  move  移动语义  左值变右值 


    cin.get();
}

引用本质

void main10x()
{
    int num = 10;
    int data = 20;
    int &rnum(num); //引用一旦初始化 不会引用其他变量  引用必须初始化
    rnum = data;

    double db = 41;
    double &rdb(db);

    cout << sizeof(rdb) << endl;  //8字节  编译器优化处理  引用变量名别名

    struct  Da
    {
        double &rdb;
    };

    cout << sizeof(Da) << endl; // 4字节  引用的本质是指针实现的 简化程序

    cin.get();
}

引用指针

void mainxxxxx()
{
    int a(4);
    int*p(new int(5)); //开辟一块内存 并初始化为5
    cout << a << endl;
    cout << *p << endl;

    int &ra(a);  //引用变量
    int* &rp(p); //引用指针
    ra = 3;
    *rp = 12;
    cout << a << endl;
    cout << *p << endl;

    int &&rra(move(a)); //右值引用 有内存实体直接引用  没有开辟内存
    int* && rrp(move(p));

    cin.get();
}

int & 引用整数 本质指针
int && 引用整数 本质指针 能处理左值(需要move) 右值
int 整数类型

函数参数 返回值引用

参数引用 (以及 指针引用 括号括法)
int num1 = 10;
int num2 = 20;
void change(int* &rp)  //C++能用引用 别用指针
{
    rp = &num2;
}

int data1 = 100;
int data2 = 200;;
int *xp = &data1;

void change(int** &rpp)  //C++能用引用 别用指针
{
    *rpp = &data2;
}

void main()
{
    int *p(nullptr);
    int **pp(&p);
    //int** &rpp(pp);  //VS2015
    //int(** (&rpp))(pp); //VS2013 需要括号说明优先级   先括引用符 再括指针符

                    //  int (***ppp)(nullptr);  //VS2013
                    //  int(*** (&rppp))(ppp);   //VS2013

    int ***ppp(nullptr);
    //int*** &rppp(ppp);


    int** xpp = &xp;
    cout << **xpp << endl;
    change(xpp);

    cout << **xpp << endl;


    cin.get();
}

返回值引用
//返回一个引用

//函数返回值有副本机制
//栈区 自动回收 自动释放  返回值为指针  不能指向栈区  返回值为引用 不能引用栈区

int& getdata()
{
    int num = 1; //销毁 在内存
    return num;
}

int& getdata1()
{
    int*p(new int(5));
    return *p;
}

char* & getcode()
{
    char*p = "Guoshixian";
    return p;
 
}

void mainx7()
{
    //int &rnum = getdata(); //引用原来内存
    //int num = getdata(); //拷贝到新的内存

    char* &rp = getcode(); //等于引用原生p  p在内存 已销毁
    char*newrp = rp;       //保存rp储存代码区的地址

    cout << newrp << endl;  //正常打印
    cout << rp << endl;     //乱码
    cin.get();
}

引用数组

数组类别

指针数组: 数组 每一个元素都是指针
数组指针: 指针 指向数组的指针
多维数组名的本质就是一个数组指针

void mainx8()
{
    //VS2013 需要阔括号

    int a[5]{ 1,2,3,4,5 }; //一位数组
    int *pa[5]{a,a+1,a+2,a+3,a+4}; //指针数组
    int b[2][3]{ 1,2,3,4,5,6 }; //二维数组
    int *pb[2][3]{
        &b[0][0]    ,&b[0][0] + 1,&b[0][0] + 2,
        &b[0][0] + 3,&b[0][0] + 4,&b[0][0] + 5 
    }; //二维指针数组 每一个元素都是指针


    int*p1(new int[5]{ 1,2,3,4,5 }); //堆上一维数组
    int**pp = new int*[5]{ p1,p1 + 1,p1 + 2,p1 + 3,p1 + 4 };//堆上指针数组

    int(*p2)[4] = new int[3][4]{ {1,2,3,4},{5,6,7,8},{9,10,11,12} }; //堆上二维数组

    //pp2是一个指针 指向数组的一行 一行有4个元素
    int*(*pp2)[4]{new int*[3][4]};//堆上二维指针数组

    //int*(*pp)(nullptr); //初始化VS2013空余一个指针

    cin.get();
}
引用一个数组
//vs2015
void mainx9()
{
    int a[5]{ 1,2,3,4,5 }; //一位数组
    int(&ra)[5](a);
    for (auto i : ra)
    {
        cout << i << endl;
    }

    int *pa[5]{ a,a + 1,a + 2,a + 3,a + 4 }; //指针数组
    int* (&rpa)[5](pa);
    for (auto i : rpa)
    {
        cout << *i << endl;
    }


    int*p1(new int[5]{ 1,2,3,4,5 }); //堆上一维数组  
    int* &rp1(p1);
    for (size_t i = 0; i < 5; i++)
    {
        cout << rp1[i] << endl;
    }

    int**pp = new int*[5]{ p1,p1 + 1,p1 + 2,p1 + 3,p1 + 4 };//堆上指针数组
    int** &rpp(pp);
    for (size_t i = 0; i < 5; i++)
    {
        cout << *rpp[i] << endl;
    }

    cout << "==============================================" << endl;

    int b[2][3]{ 1,2,3,4,5,6 }; //二维数组
    int(&rb)[2][3](b); //引用二维数组
    for (int i = 0; i < 2; i++)
    {
        for (int j = 0;j < 3;j++)
        {
            cout << rb[i][j] << " ";
        }
        cout << endl;
    }


    int *pb[2][3]{
        &b[0][0]    ,&b[0][0] + 1,&b[0][0] + 2,
        &b[0][0] + 3,&b[0][0] + 4,&b[0][0] + 5
    }; //二维指针数组 每一个元素都是指针
    int*(&rpb)[2][3](pb); //引用二维指针数组

    for (int i = 0; i < 2; i++)
    {
        for (int j = 0;j < 3;j++)
        {
            cout << *(rpb[i][j]) << " ";
        }

        cout << endl;
    }

    cout << "==============================================" << endl;

    int(*p2)[4] = new int[3][4]{ { 1,2,3,4 },{ 5,6,7,8 },{ 9,10,11,12 } }; //堆上二维数组

    //指向数组的指针 用{}包含    用大括号初始化二维数组
    int(*p3)[4]{new int[3][4]{ { 1,2,3,4 },{ 5,6,7,8 },{ 9,10,11,12 } }}; //堆上二维数组

    int(*&rp2)[4](p2); //引用一个行指针
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0;j < 4;j++)
        {
            cout << rp2[i][j] << " ";
        }

        cout << endl;
    }
    cout << "==============================================" << endl;

    int*(*pp2)[4]{ new int*[3][4] }; //堆上二维指针数组
    int*(*&rpp2)[4](pp2);//引用二维指针数组

    cin.get();
}

const与 引用

常量指针 指针常量 指向常量的常量指针

//常量指针: 指向对象不可修改 可改变其指向 声明的对象是一个指向常量的指针(变量)
//const int *p; int const *p;

//指针常量: 指向对象可修改 不可改变其指向 声明的对象是一个常量,且它的内容是一个指针,也就是一个地址。
//int *const b = &a;

//指向常量的指针常量: 是一个常量,且它指向的对象也是一个常量
//const int a = 25;
//const int * const b = &a;

引用于const的关系
void show(const int &rint) //明确只读不写
{

}

void mainx10()
{
    int num = 100;
    int const &rnum(num); //让别人引用 限定权限
    const int &rnum1(num);    //等价 一样
    int  &const rnum2(num);  //const 放右边 被忽略

    int a[5]{ 1,2,3,4,5 }; //一位数组
    const int(&ra)[5](a);
    for (auto i : ra)
    {
        //i+=1;  //限定 不能修改
        cout << i << endl;
    }

    cout << "==============================================" << endl;

    const int *p(new int(5)); //指向常量
    const int *&rp(p);      //引用一个指向常量的指针

    int *const p1(new int(5)); //指向不可改变  指向的值可以改变
    *p1 = 10;
    int (*const (&rp1))(p1); //引用一个常量指针

    const int *const p2(new int(5));
    const int (*const (&rp2))(p2); //引用一个指向常量的 常量指针

    cout << "==============================================" << endl;

    int *xp(new int(5)); //指向常量
    const int *&rxp((const int*&)xp); //强转为常指针

    cin.get();
}

引用与函数指针

int gocmd(const char*str)
{
    system(str);
    return 1;
}

int showcmd(const char*str)
{
    cout << str << endl;
    return 1;
}

void change(int(*&pfun)(const char*)) //引用作为参数
{
    pfun = showcmd; //栈
}

int(*   getp()   )(const char*)  //getp 返回一个函数指针
{
    int(*pfun)(const char*)(gocmd);//栈

   //int(* &pfun)(const char*)= (int(*&)(const char*)) gocmd; //
    return pfun;
}

int(*    getitp(int(*&pfun)(const char*))    )(const char*)  //getitp 传递一个函数指针引用 返回一个函数指针
{
    pfun = showcmd;
    return pfun;
}

//参数是一个引用 返回值也是一个引用   =====  此函数等于输入输出都是操作原生变量
int(* &   getitpp(int(*&pfun)(const char*))     )(const char*)  
{
    pfun = showcmd;
    return pfun;
}


void mainx11()
{
    //
     int(*pfun)(const char*)(gocmd); //定义函数指针并初始化
    pfun("calc");
    change(pfun);
    pfun("sssssssssssssss");

    pfun = getp();
    pfun("notepad");

    getitpp(pfun)("hello "); //等价于 pfun("hello ");

    cin.get();
}

引用函数指针数组与函数二级指针

int add(int a,int b)
{
    return a + b;
}

int sub(int a, int b)
{
    return a - b;
}

int mul(int a, int b)
{
    return a * b;
}

int divv(int a, int b)
{
    return a / b;
}


void mainx12()
{
    int(*pfun[4])(int a, int b) { add, sub, mul, divv }; //函数指针数组 并初始化

    //二级函数指针 开辟函数指针数组
    int(**ppfun)(int a, int b) { new (int(*[4])(int a, int b)){ add, sub, mul, divv } };

    int(*(&rpfun)[4])(int a, int b)(pfun); //引用函数指针数组
    int(**(&rppfun))(int a, int b)(ppfun); //引用二级函数指针

    for (size_t i = 0; i < 4; i++)
    {
        cout << rpfun[i](100, 10) << "  ";
        cout << rppfun[i](100, 10) << "  ";
    }
    cout << endl;
    for(int(**ppx)(int,int)=ppfun;ppx<ppfun+4;ppx++)
    { 
        cout << (*ppx)(100, 10) << "  ";
    }

    cout << endl;
    cin.get();
}

引用结构体数组

struct info
{
    int id;
    int num;

    //没有返回值 名称和类型一致
    info(int nid,int nnum):id(nid),num(nnum)  //构造初始化函数
    {


    }

};

void mainx13()
{
    info infos[5]{ {1,1},{1,2},{1,3},{1,4},{1,5} };
    info (&rinfos)[5](infos);  //引用结构体数组
    for (auto i : rinfos)
    {
        cout << i.id << "  " << i.num << endl;
    }

    
    info *p(   new info[5]{    { 1,1 },{ 1,2 },{ 1,3 },{ 1,4 },{ 1,5 }   }   );
    info*(&rp)(p);

    for (int i = 0; i < 5; i++)
    {
        cout << rp[i].id << "  " <<rp[i].num << endl;
    }

    
    cin.get();
}
上一篇下一篇

猜你喜欢

热点阅读