欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

c++-引用

程序员文章站 2022-06-05 18:14:42
c++中引用类型,引用是如何引用的呢? + 引用 引用概念,给变量起个别名,本质是给内存空间取个别名 引用是c++的语法概念、引用的意义(好用) 引用本质:有地址、定义时必须初始化,c++编译器内部按照指针常量 引用结论:间接赋值成立的三个条件的后两步和二为一 引用使用原则:当用引用时,我们不去关心 ......

c++中引用类型,引用是如何引用的呢?

  • 引用
    • 引用概念,给变量起个别名,本质是给内存空间取个别名
    • 引用是c++的语法概念、引用的意义(好用)
    • 引用本质:有地址、定义时必须初始化,c++编译器内部按照指针常量
    • 引用结论:间接赋值成立的三个条件的后两步和二为一
    • 引用使用原则:当用引用时,我们不去关心编译器引用是怎么做的;当分析奇怪的语法现象时,才去考虑c++编译器是怎么做的
    • 函数返回值是引用(若返回栈变量,不能成为其他引用的初始化)
    • 函数返回值当左值,必须返回一个引用
    • 指针的引用int gett(teacher * &myp )
    • 常引用
      • 用变量初始化const引用,然变量形参拥有只读属性
      • 用字面量初始化const引用,额外的分配内存空间
  • 引用概念,给变量起个别名,本质是给内存空间取个别名
  • 引用是c++的语法概念、引用的意义(好用)
  • 引用本质:有地址、定义时必须初始化,c++编译器内部按照指针常量
  • 引用结论:间接赋值成立的三个条件的后两步和二为一
  • 引用使用原则:当用引用时,我们不去关心编译器引用是怎么做的;当分析奇怪的语法现象时,才去考虑c++编译器是怎么做的
  • 函数返回值是引用(若返回栈变量,不能成为其他引用的初始化)
  • 函数返回值当左值,必须返回一个引用
  • 指针的引用int gett(teacher * &myp )
  • 常引用
    _ 用变量初始化const引用,然变量形参拥有只读属性
    _ 用字面量初始化const引用,额外的分配内存空间

这与c大有不同

1 引用没有定义, 是一种关系型声明。声明它和原有某一变量(实体)的关
系。故 而类型与原类型保持一致, 且不分配内存。与被引用的变量有相同的地
址。

2 声明的时候必须初始化, 一经声明, 不可变更。

3 可对引用, 再次引用。多次引用的结果, 是某一变量具有多个别名。

4 & 符号前有数据类型时, 是引用。其它皆为取地址

#define _crt_secure_no_warnings
#include <iostream>


using namespace std;
/*

*/

void change_value(int *p) // int p = a;
{
    *p = 30;
}

void change_value2(int & r)//int &r = a
{
    r = 30; //a = 30
}


int main(void)
{
    int a = 20;
    int b = 30;


    int *p = &a;
    *p = 30;

    p = &b;
    *p = 20;//b

    int &re = a; //int & 使用引用数据类型, re就是a的别名

    re = 50;
    &re;
    &a;

    re = b; //让re成为b的引用?   a = b
    re = 50;
    cout << "a =" <<a << endl;
    cout << "b = " << b << endl;
    int & re2 = b; //引用一定要初始化,

    re2 = a;


    int &re3 = re;

    re3 = 100;
    cout << "a =" << a << endl;
    cout << "re =" << re << endl;
    cout << "re3 =" << re3 << endl;



    cout << "-------------" << endl;
    cout << "a =" << a << endl;
    change_value(&a);//改变了值
    cout << "a =" << a <<  endl;
    a = 100;
    cout << "-------------" << endl;
    cout << "a =" << a << endl;
    change_value2(a);//改变了值
    cout << "a =" << a << endl;

    return 0;
}

引用示例

#define _crt_secure_no_warnings
#include <iostream>


using namespace std;

struct student
{
    int id;
    char name[64];
};

void my_swap(int *a, int *b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

void my_swap2(int &a, int &b)
{
    int temp = a;
    a = b;
    b = temp;
}

void prints(struct student s) //student s = s1; 结构体整个值拷贝的动作
{
    cout << s.id <<" "<< s.name << endl;
    s.id = 100;
}

void prints1(struct student *sp)
{
    cout << sp->id << " " << sp->name << endl;
    sp->id = 100;
}

//引用在一定条件下能够取代指针的工作,也能作为函数参数。
void prints2(struct student &s)//student &s = s1;
{
    cout << s.id << "  " << s.name << endl;
    s.id = 300;
}

int main(void)
{
    int a = 10;
    int b = 20;

    my_swap2(a, b);
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;


    student s1 = { 10, "zhang3" };

    prints(s1);
    prints1(&s1);
    prints2(s1);

    cout << "si.id =" << s1.id << endl;

    return 0;
}

引用的本质

#define _crt_secure_no_warnings
#include <iostream>


using namespace std;

struct typea
{
    int &a;
};

struct typeb
{
    int *a;
};


struct student
{
    int id;
    char name[64];
};

void motify(int *const a)//int *const a = main::&a
{
    *a = 300;
}

void motify2(int &a) //当我们将引用作为函数参数传递的时候,编译器,会替我们将实参,取地址给引用
                    //int &a = main::&a
{
    a = 300; //对一个引用操作 赋值的时候,编译器提我们隐藏*操作。
}

//如果我们在去研究引用的时候,你可以将引用当做一个常指针去研究
//当你在使用引用编程的时候,你就把引用理解为变量的别名就可以了。


int main(void)
{
    cout << "sizeof(struct typea)" << sizeof(struct typea) << endl;
    cout << "sizeof(struct typeb)" << sizeof(struct typeb) << endl;
    //引用所占用的大小 跟指针是相等的。
    int a = 10;
    int &re = a; //常量要初始化,引用也要初始化, 引用可能是一刚常量。

    int *const p = &a;
    //综上两点, 引用 可能是一个常指针。


    motify(&a);

    motify2(a);

    return 0;
}

引用作为函数的返回值

#define _crt_secure_no_warnings
#include <iostream>


using namespace std;

char * getmem(int num)
{
    char *p = null;
    p = (char*)malloc(num);//分配空间

    return p;//ox11223344
}//0x1231321

int getmem2(char **pp, int num)
{
    char *p = null;
    p = (char*)malloc(num);

    *pp = p;

    return 0;
}//0


int geta1()
{
    int a = 10;

    return a;
}//a的值



void geta2(int *a)
{
    *a = 10;
}

//引用作为返回值,不要返回局部变量的引用。
int& geta3()
{
    int a = 10;
    return a;
}//int &temp = a;

int &geta4()
{
    static int a = 10;

    return a;
}

int main(void)
{
    int a = 0;
    char *pp = null;

    a = geta1();
    pp = getmem(10);

    cout << "-----------" << endl;

    int main_a = 0;

    main_a = geta3(); //main_a = temp; //数值拷贝

    cout << "main_a " << main_a << endl;

    cout << "-----------" << endl;

#if 0   
    int &main_a_re = geta3(); 

    cout << "main_a_re " << main_a_re << endl;
    cout << "main_a_re " << main_a_re << endl;
#endif

    int &main_a_re = geta4();
    cout << "main_a_re " << main_a_re << endl;
    cout << "main_a_re " << main_a_re << endl;


    //引用如果当函数返回值的话,函数可以当左值。
    geta4() = 1000;



    return 0;
}

指针引用

#define _crt_secure_no_warnings
#include <iostream>


using namespace std;

struct teacher
{
    int id;
    char name[64];
};


int get_mem(struct teacher** tpp)
{
    struct teacher *tp = null;
    tp = (struct teacher*) malloc(sizeof(struct teacher));
    if (tp == null) {
        return -1;
    }

    tp->id = 100;
    strcpy(tp->name, "li4");

    *tpp = tp;

    return 0;
}

void free_teacher(struct teacher **tpp)
{
    if (tpp == null) {
        return;
    }

    struct teacher *tp = *tpp;

    if (tp != null) {
        free(tp);
        *tpp = null;
    }
}


int get_mem2(struct teacher* &tp)
{
    tp = (struct teacher*)malloc(sizeof(struct teacher));
    if (tp == null) {
        return -1;
    }
    tp->id = 300;
    strcpy(tp->name, "wang5");

    return 0;
}

void free_mem2(struct teacher * &tp)
{
    if (tp != null) {
        free(tp);
        tp = null;
    }
}


int main(void)
{
    struct teacher *tp = null;

    get_mem(&tp);
    cout << "id =" << tp->id << ", name = " << tp->name << endl;
    free_teacher(&tp);

    cout << "00000000000" << endl;

    get_mem2(tp);
    cout << "id =" << tp->id << ", name = " << tp->name << endl;
    free_mem2(tp);

    return 0;
}