C++引用小结

来源:互联网 发布:苹果电脑软件 编辑:程序博客网 时间:2024/05/21 23:32

引用的本质就是给同一个内存空间起不同的名字

#include <iostream>using namespace std;int main(){    int a =10;    int &b = a;    b =20;     //通过引用变量b和a指向同一个内存,改变b的值 就能够改变a的值   在这里虽然只是对b进行赋值//  printf("a = %d\n",a);   cout << "a = " << dec <<  a <<endl;   cout << "b = " << hex << b << endl;               system("pause");          return 0;}

引用必须要进行初始化

#include <iostream>using namespace std;//引用的基本基本知识void mySwap(int *a ,int* b){//在swap函数中要使用指针进行值的交换定义一个指针的时候必须顶一个变量这样能够防止没有初始化的指针会随意指向存放系统参数的内存地址,要是不进行初始化很可能会替换掉系统中重要的参数而导致不可预知的情况发生      int *c, d;      c = &d;      *c = *a;      *a = *b;      *b = *c;}int main(){    int x,y;    x = 10;    y = 20;    mySwap(&x,&y);    cout << "x =" << x << "y =" << y <<endl;    system("pause");          return 0;}
//这种函数是万万要不得的,因为很可能导致系统的崩溃void mySwap(int *a ,int* b){      int *c;      *c = *a;      *a = *b;      *b = *c;}
#include <iostream>using namespace std;//引用的基本基本知识void mySwap(int *a ,int* b){      int c;      c = *a;      *a = *b;      *b = c;}//使用引用void mySwap02(int &a ,int &b){    int c;    c = a;    a = b;    b = c;}int main(){    int x,y;    x = 10;    y = 20;    mySwap02(x,y);    //在调用的时候  a 就是x的别名,b就是y的别名其实就相当于取 &a = x; &b = y;    cout << "x =" << x << "y =" << y <<endl;    system("pause");          return 0;}

对复杂数据的应用

#include <iostream>using namespace std;//复杂数据类型的引用struct Teacher{    char name[64];    int age;};void printfT(Teacher &pT){    cout <<  pT.age  << endl;}void printfT2(Teacher &pT)      //引用相当于别名直接可恶意更改变量原来的数值{    pT.age  = 26;    cout << pT.age << endl;}int main(){        Teacher t1;    t1.age = 35;    printfT(t1);     printfT2(t1);    system("pause");          return 0;}

引用作为变量的别名存在,因此在一些场合可以替代指针
引用相对于指针有更好的可读性和实用性
在单独的定义一个引用的时候,必须进行初始化,因此引用就像一个常量

引用和原来的地址是一样的,这样来说引用是对同一块地址不同的别名:

#include <iostream>using namespace std;int main(){        const int c1 = 10;    int a = 12;    int &b = a;    printf("a = %d, b = %d\n",&a,&b);    cout << "hello world!" << endl;    system("pause");          return 0;}

输出的结果是一样的,引用的地址使用一样的,只是对同一块地址不同的别名,这是一点很重要的点;
引用就是同一内存空间内存门牌号的不同别名
普通引用也占内存空间
而且和指针占用的内存空间是一样的

在32位系统中指针的大小固定是4无论指针的类型是啥大小都是4,也就是说当系统的架构大小固定的时候指针的大小是固定的

因此可以看出引用的本身其实就相当于常量指针,
Type& name <==> Type * const name;

C++编译器在编译的过程中使用常量指针作为引用的内部实现,也因此引用所占用得到空间与指针的大小是相同的;、
但是从使用的角度来说引用给人的感觉是变量的别名,没有自己的存储空间,但是记住这只是C++的实用性遮蔽了引用的本质,引用变量本身是占内存的内部的大小和指针的相同,因为引用实现的细节就是常量指针;
不要使用C语言编译器的思想来思考C++编译器,在碰见左边的形式的引用的时候C++编译器会将其转化为→_→的形式,当C++发现a为引用变量的时候会将a自动加上取值符号;所以不能以简单的只针对额那一套来思考也引用,要考虑到C++的编译器的作用;
并且在调用的时候C++编译器会帮助我们取地址,因此调用的时候也只是将变量放到函数的就行例如:

void fun(int  &a){    a = 5;}int main(){    int x;    fun(x);    //就 这样调用函数就行了,因为在使用引用的时候,C++编译器会帮助我们取地址 ==> 相当于C语言环境中调用fun(&x);    system("pause");}

这里写图片描述

引用的难点

函数的返回值当引用,返回值为栈变量的时候,不能当其他引用变量的初始值,也不能当左值使用,因为栈变量有生命周期。
但如果是静态变量或者是全局变量就可以

当返回值为栈变量的时候,会出现错误

#include <iostream>using namespace std;//函数的返回值是一个引用int getAA1(void ){    int a;    a = 10;    return a;}int& getAA2(void){    int a;     //如果是返回栈上的引用有可能会出现问题    a = 10;    return a;}int* getAA3(void){    int a;    a = 10;    return &a;}            int main(){        int a1 = 0;    int a2 = 0;    a1 = getAA1();    a2 = getAA2();   // 返回a的副本,将返回的值赋给a2    int &a3  =  getAA2();       //返回a的值的时候使用引用接,会把a的地址传给&a3 这时a3其实得到的是就不变量的地址,再次使用的时候已经有可能被释放了   //打印的时候使用 a3因为a3是一个引用因此C++编译器会默认的使用*a3的得到情况去打印    cout << "a1 = " << a1<< endl << "a2 = " << a2 << endl << "a3 = "<< a3 <<endl;    cout << "hello world!" << endl;    system("pause");          return 0;}

当为全局变量或者静态变量的时候正常的使用

#include <iostream>using namespace std;//函数的返回值是一个引用int getAA1(void ){    static int a = 10;    a ++ ;    return a;}int& getAA2(void){    static int a = 10;    a ++ ;    return a;}int* getAA3(void){    static int a = 10;    a ++ ;    return &a;}            int main(){        int a1 = 0;    int a2 = 0;    a1 = getAA1();    a2 = getAA2();   // 返回a的副本,将返回的值赋给a2    int &a3  =  getAA2();       //返回a的值的时候使用引用接,会把a的地址传给&a3 这时a3其实得到的是就不变量的地址,再次使用的时候已经有可能被释放了   //打印的时候使用 a3因为a3是一个引用因此C++编译器会默认的使用*a3的得到情况去打印    cout << "a1 = " << a1<< endl << "a2 = " << a2 << endl << "a3 = "<< a3 <<endl;    cout << "hello world!" << endl;    system("pause");          return 0;}

神奇的引用,使用引用函数能够当左值,并且能够实现函数的对接调用

#include <iostream>using namespace std;////////////////////////////////////////////////////////////////////////////函数当左值//  [11/23/2017 Andrew]//返回变量的值int g1(){    static int a = 10;    a  ++;    return a;}//////////////////////////////////////////////////////////////////////////// 返回变量本身 [11/23/2017 Andrew]//返回变量所标识的内存空间         //---------//程序能够正常的通过说明返回引用能够当左值,因为返回引用返回的是变量本身int & g2(){    static int a = 10;    a  ++;    return a;}int main(){    // g1() = 100;   //不能够使用     g2() = 100;    system("pause");          return 0;}

在C语言中可以通过指针修改const 类型的值,因此C语言中的const是一个冒牌货

指针存在的最大的意义,就是使用二级指针间接的赋值

原创粉丝点击