zoukankan      html  css  js  c++  java
  • C++学习笔记之——内联函数,引用

    本文为原创作品,转载请注明出处

    欢迎关注我的博客:http://blog.csdn.net/hit2015springhttp://www.cnblogs.com/xujianqing/

    作者:晨凫追风

    一直想开始写C++的学习笔记,学习C++已经两个月了,今天开始写一下引用,内联函数,的一些概念和作用吧。那么开始吧!

        内联函数:

    我们写的程序最终都是要用编译器,进行编译链接形成一段机器可以知道的二进制代码,接着存到一个内存中,这时候每一段程序代码都会有自己的一个地址,计算机按照地址增1,依次执行这段代码,当遇到代码调用别的函数的时候,这时候就要存储目前程序执行的很多状态呀,把这些东西放入堆栈里面,然后去执行被调用的函数,执行完之后再返回原来的程序断点处继续执行。这样一来一去,就会浪费时间和一些内存。于是内联函数出现了,它就是在编译器对代码进行链接的阶段,在调用函数的位置,用调用的函数代码替换原来的函数调用,这样就不用调用来调用去,占去时间和内存。如果你的程序中有十个位置调用了内联函数,则这个函数将会在整个代码中存在十个副本。看图说话:

    要用到内联函数要采取下列两个措施之一:

    • 在函数声明前加关键字inline
    • 在函数定义前加关键字inline

    最常见的用法是定义函数和声明时一起来,

    上代码;

    #include<iostream>

    using namespace std;

    inline double square(double x) {return x * x; }

     

    int main()

    {

        double a, b;

        double c = 11.0;

        a = square(5.0);

        b = square(4.5 + 7.5);

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

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

        cout<<"square(C++) = " << square(c++) <<endl;

        cout<<"now c = " <<c<< endl;

    }

    内联函数总结:

    内联函数就是为了省去函数调用占用的一些时间和内存而出现的,当一些函数比较长时用内联函数显然不具有很大意义,执行时间远大于调用耗去的时间,所以一般情况下,如果函数定义超过多行时不太用内联函数,而且内联函数是不允许递归的。

    引用

    如果一个人叫"阿猫"它的小名叫"阿狗",这时你喊"阿猫"或者"阿狗"大家都明白是它,于是呢当你打"阿猫"时,"阿狗"也会受伤(同一个人)。引用就是这样的,同一个变量叫两个名字,你修改一个名叫"阿猫"的变量后,叫"阿狗"的肯定也变了。(记住无论在哪里改它,他们总是一起改变,从一而终)。

    举个例子:把int变量firstName取小名lastName;

    int firstName;

    int & lastName = firstName;

    取好名字之后两名字便一直依存。缠缠绵绵。开始了他和他的故事:

    注意:必须在声明引用变量的时候对引用变量进行初始化。如下面:
    int first Name;

    int & lastName;

    lastName = firstName; 不可以 。。。。不可以 。。。。。不可以。。。。

    引用变量有啥用呢?

    函数按值传递调用过程中,修改形参,相应的实参是不会改变的,因为在调用的过程中先是拷贝那个传递过来的值,然后用这个副本进行处理。这样被调用程序就不会访问调用程序中的那个变量。

    按值传递调用遇到大的结构体,复制一下,再用副本这样会占用时间,于是来一个按引用变量传递调用函数。这样相当于直接对原始的那个值进行操作。Ok不用复制,当然你也可以用指针对其进行访问,有同样的效果,就是指针用的不太明白,按照引用调用的话,只需按照按值传递调用那样调用程序就好了。

    按照指针调用的话,是对指针进行复制,然后用复制的副本进行一系列的操作。

    举个简单的例子:

    #include<iostream>

    using namespace std ;

    void swapr(int &a, int &b); //按照引用传递进行调用

    void swapp(int * p, int * q); //按照指针传递进行调用

    void swapv(int a ,int b); //按值传递进行调用

     

     

    int main()

    {

        int wallet1 = 100;

        int wallet2 = 200;

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

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

          

        

        cout << "引用传递"<< endl;

        swapr(wallet1,wallet2);

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

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

        

        cout << "指针传递"<< endl;

        swapp(&wallet1, &wallet2);

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

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

        

        cout << "按值传递"<< endl;

        swapv(wallet1,wallet2);

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

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

    }

     

     

    void swapr(int &a, int &b) //按照引用传递进行调用

    {

    int temp ;

    temp = a;

    a = b;

    b = temp;    

    }

    void swapp(int * p, int * q) //按照指针传递进行调用

    {

        int temp ;

    temp = *p;

    *p = *q;

    *q = temp;

        

    }

    void swapv(int a ,int b) //按值传递进行调用

    {

    int temp ;

    temp = a;

    a = b;

    b = temp;    

    }

    分析下程序:

    在按照引用传递进行函数调用的时候,把wallet1的引用指定为a,wallet2的引用指定为b,这样在函数中两个值互相交换,便可以修改原来的值。按值传递时只是对传递过来的副本进行交换,并没有改变原来的值,所以没有交换成功。

    最后进行一下总结:

    使用引用的原因:

    • 程序员能够修改调用函数中的数据对象
    • 通过传递引用而不是传递整个数据对象,可以提高运行速度,这一点也是指针参数存在的一个原因

    下面是一些指导原则:
    使用传递的值而不对原始值做修改的函数:

    • 数据对象很小,则按值传递
    • 数据对象是数组,使用指针(别无选择)并且将指针声明为指向const的指针
    • 数据结构较大时,使用const指针或者const引用
    • 数据对象是类对象,使用const引用

    使用传递的值并且对原始值做修改的函数:

    • 数据对象是内置数据类型,使用指针
    • 数据对象是数组,使用指针
    • 数据对象是结构,使用指针或者引用
    • 数据对象是类结构,使用引用

       

     

     

  • 相关阅读:
    问题:C# params类型参数;结果:C#的参数类型:params、out和ref
    问题:ExecuteNonQuery 与 ExecuteScalar 结果: ExecuteNonQuery方法和ExecuteScalar方法的区别
    问题:MSChart.exe;结果:微软图表控件MsChart使用方法及各种插件下载地址
    问题:部署到iis上后Chart图片不显示;结果:使用webchart过程中遇到的一些问题
    问题:C#发布的项目浏览时出现“Server Application Unavailable”错误;结果:Server Application Unavailable出现的原因及解决方案小结
    问题:oracle nvl;结果:Oracle中的NVL函数
    cookie的路径和域
    Spring MVC静态资源处理
    java.lang.ClassNotFoundException的解决方法
    ThreadLocal管理登录信息
  • 原文地址:https://www.cnblogs.com/xujianqing/p/5471785.html
Copyright © 2011-2022 走看看