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

欢迎关注我的博客:http://blog.csdn.net/hit2015spring和http://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++学习笔记之——内联函数,引用的更多相关文章

  1. C++ primer(八)--内联函数 引用变量 引用传递函数参数 函数重载/模板/模板具体化

    一.内联函数     常规函数和内联函数的区别在于C++编译器如何将他们组合到程序中.编译过程的最终产品是可执行程序--由一组机器语言指令组成.运行程序时,操作系统将这些指令载入到计算机内存中,因此每 ...

  2. 《C++ Primer》笔记-inline内联函数

    inline 函数避免函数调用的开销 // find longer of two strings const string &shorterString(const string &s ...

  3. C++基础学习6:内联函数

    C++语言新增关键字 inline,用于将一个函数声明为内联函数.在程序编译时,编译器会将内联函数调用处用函数体替换,这一点类似于C语言中的宏扩展. 采用内联函数可以有效避免函数调用的开销,程序执行效 ...

  4. C++中对C的扩展学习新增语法——内联函数以及函数参数

    内联函数以及函数参数 内联函数 使用 inline 关键字必须和函数体放在一起. 内联函数具有内部链接属性. 内联函数会被编译器在编译阶段替换到函数调用的地方. 可以把内联函数定义写到头文件中,多个c ...

  5. python自动化测试学习笔记-4内置函数,处理json

    函数.全局变量 写代码时注意的几点事项: 1.一般写代码的时候尽量少用或不用全局变量,首先全局变量不安全,大家协作的情况下,代码公用容易被篡改,其次全局变量会一直占用系统内容. 2.函数里如果有多个r ...

  6. Python学习笔记-Day3-python内置函数

    python内置函数 1.abs    求绝对值 2.all 判断迭代器中的所有数据是否都为true 如果可迭代的数据的所有数据都为true或可迭代的数据为空,返回True.否则返回False 3.a ...

  7. [Python学习笔记-001] 内置函数getattr()

    如果某个实例foo有多个方法, 当对foo的每一个方法我们都需要使用try ... except ...进行包装的时候,内置函数getattr()可以用来精简代码. 1. getattr()的用法 # ...

  8. HTML5学习笔记3 内联SVG

    HTML5支持内联SVG 下面来介绍一下什么是SVG SVG可缩放矢量图形 可缩放矢量是基于可扩展标记语言(标准通用语言的子集),用于描述二维矢量图形的一种图形格式.它由万维网联盟制定,是一个开放标准 ...

  9. Python学习笔记-常用内置函数

    输出:print() 功能:输出打印 语法:print(*objects, sep=' ', end='\n', file=sys.stdout) 参数:objects----复数,表示可以一次输出多 ...

随机推荐

  1. resetroot_169route_python3(用于ubuntu16.04)

    #!/usr/bin/python3 import os import sys import json import urllib.request import urllib.parse import ...

  2. golang模拟新浪微博登录

    1.基于幽灵蛛pholcus开源项目的规则 直接贴代码,代码可以更改后用于其他爬虫项目 package pholcus_lib // 基础包 import ( // "github.com/ ...

  3. ubuntu中tensorflow安装

    首先加入了CUDA_HOM环境变量,然后下载了一个分析工具库,结果E: 无法定位软件包 libcupti-dev,在etc/apt 的sources.list 添加镜像源 deb http://arc ...

  4. sqlserver查询数据库中有多少个表,多少视图,多少存储过程,或其他对象

    sql server 数表: select count(1) from sysobjects where xtype='U' 数视图: select count(1) from sysobjects ...

  5. NO1——线段树

    /* 数组存储 */ /* 预处理 */ #include <iostream> #include <cstdio> #include <algorithm> #i ...

  6. rcnn caffe matlab 配置完成 14.04 cuda 7.0

    http://blog.csdn.net/real_myth/article/details/42672381 各种痛苦.实验室网速还是龟速. 莫名其妙的错误. gcc还降级到4.7,opencv 3 ...

  7. 【SSH】——Struts2中的动态方法调用(一)

    首先我们来看一个简单的调用: 1.在web.xml中配置拦截器StrutsPrepareAndExecuteFilter.StrutsPrepareAndExecuteFilter实现了filter接 ...

  8. IntelliJ IDEA 创建maven项目

    说明 创建Maven项目的方式:手工创建 好处:参考IntelliJ IDEA 14 创建maven项目二(此文章描述了用此方式创建Maven项目的好处)及idea14使用maven创建web工程(此 ...

  9. (转)String,StringBuffer与StringBuilder的区别??

    String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...

  10. Python 类和对象-下

    类的常用函数 #issubclass() 检测一个类是否是另外一个或者一组类中的子类 class Father: pass class Mother: pass class LaoWang: pass ...