函数探幽

函数探幽

  • 内联函数

    • c++为提高程序运行速度的一项改进。
    • 非内联函数在调用时来回跳跃并记录产生了一定的开销。
    • 内联函数编译器将使用相应的函数代码替换函数调用。无需跳到另一个位置去执行代码。
    • 内联函数运行速度比常规函数稍快,但代价是占用更多内存。
    • 如果程序在10个不同的地方调用同一个内联函数,该程序将包含该函数代码的10个副本。
    • 如果执行函数代码时间比函数调用时间短,则应该使用内联函数。
    • 要使用内联函数需要在函数声明和定义前加上inline关键字。
    • 通常的做法是省略声明,直接定义。
    • 有些函数即使声明了inline编译器也不一定会将其作为内联函数,可能的原因有函数过大或函数调用了自己。
    • 有些编译器没有实现内联函数。
    • 内联与宏
      • 内联代码的原始实现是宏
      • 宏不能按值传递
      • #define SQUARE(X) X*X
      • int c = 13
      • a = SQUARE(c++)
      • 则替换后的结果为a = c++*c++;
      • 将c递增了两次。
      • 但使用内联函数就只会递增一次。
      • 所以推荐使用内联函数。
  • 引用变量
    • 引用是一定义的变量的别名。
    • 引用变量的主要用途是用作函数的形参。
    • 通过使用引用变量作为参数,函数将使用原始数据,而不是副本。
    • 创建引用变量
      • &符号
      • int rats;
      • int & rodents = rats;
      • int &的意思是指向int的引用。
      • rodents和rats指向相同的值和内存单元。
      • 注意区别地址运算符和引用
    • 指针和引用的区别之一
      • 引用在声明是必须初始化,而指针不需要。
      • 引用更接近const指针。一旦与某个变量关联起来,就将一直效忠与他。类似于int * const pr = &rats;
      • 只能通过初始化声明来设置引用,但不能通过赋值来设置。
    • 引用变量的特别之处
      • 如果只是想使用变量中的数据,那么引用参数应该使用常量引用。如const double & a;
      • 在参数数据比较大时,引用参数很有用。
      • 按值传递的参数可使用多种类型的实参。
      • double z = cube(x+2.0);
      • z = cube(8.0);
      • int k = 10;
      • z = cube(k);
      • double yo[3] = {2.2, 3.3, 4.4};
      • z = cube(yo[2]);
      • 上述参数传递给接受引用参数的函数时,现代c++中这是错误的。在较老的编译器中会发出警告。
      • 早期c++允许将表达式传递给引用变量。
      • 具体方式是创建应该临时变量。
      • 临时变量
        • 如果实参与引用参数不匹配。c++将生成临时变量。
        • 现在只有参数为const引用时c++才允许,但以前不是。
        • 实参类型正确,但不是左值。非左值有表达式,字符串常量等。
        • 实参类型不正确,但可以转换为正确类型。
        • 现在常规变量和const变量都可被视为左值。因为可以通过地址访问他们。
        • 这些临时变量只在函数调用期间存在,此后编译器将随意将其删除。
        • 在现在的大多数c++编译器这种行为只对于常量引用可行。
        • 在早期c++较宽松时可以接受不是常量引用而创建临时变量,但达不到修改引用的目的。
  • 尽可能多的使用const
    • 1 使用const可以避免无意中修改数据的错误。
    • 2 const可使能够处理const和非const实参,否则只能接受非const数据。
    • 3 const引用使函数能够正确生成并使用临时变量。
  • c++11新增了另一种引用——右值引用
    • 使用&&声明
    • 使用右值引用实现移动语义。后面讲。
  • 为什么要返回引用
    • 如果不是返回引用,那么函数将返回结果复制到应该临时位置,再将临时位置中的内存拷贝到dup中。但返回值为引用时,直接把team复制到dup中。省去临时位置的步骤。
  • 避免返回指向临时变量的指针和引用。因为函数结束后临时变量将不存在。
    • 两种方法避免
    • 返回一个作为参数传递给函数的引用。
    • new来分配新的存储空间。
    • 但new来分配会存在一个释放内存的问题。auto_ptr 模板和c++11新增的unique_ptr可帮助程序员自动完成释放工作。16章介绍。
  • 假设要使用一个函数返回的引用,而不是给返回的引用赋值。那么应该将返回的引用声明为const引用。
  • 对象继承和引用
    • 基类引用可以指向派生类对象,无需进行强制类型转换。
  • 何时使用引用参数。
    • 对于使用传递的值而不修改的函数

      • 如果数据对象很小,如内置的数据类型或小型结构,则按值传递。
      • 如果数据对象是数组,则使用指针,并将指针声明为const指针。
      • 如果数据对象比较大,则使用const指针或const引用,提高效率。
      • 如果数据对象是类对象,则使用const引用。传递类对象的标准方式是按引用传递。
    • 对于修改调用函数中数据的函数
      • 如果数据对象是内置数据类型,则使用指针。
      • 如果数据对象是数组,则使用指针。
      • 如果数据对象是结构,使用指针或引用。
      • 如果数据对象是类,则使用引用。
  • 默认参数
    • 如何设置默认参数。
    • char * left(const char * str, int n = 1);
    • 为某个参数设置默认值,则必须为它右边的所有参数提供默认值。
    • 只有原型也就是函数声明指定了默认值,函数定义与没有默认参数时完全相同。
  • 函数重载
    • 可以通过函数重载来设计一系列函数,他们完成相同的工作,但使用不同的参数列表。
    • 如果参数数目不同或参数类型不同,则特征标也不同。但是一些看起来彼此不同的特征标是不能共存的。
    • 在函数调用时,将调用与函数最匹配的那一个。如果最匹配的没有,那么调用第二匹配的。以此类推。
  • 名称修饰(名称矫正)
    • 它根据函数原型中指定的形参对每个函数名进行加密。
    • 编译器将名称转换为不太好看的内部表示。
    • 对参数数目和类型进行编码。添加一组符号随特征标而异。
  • 函数模板
    • 函数模板是通用函数的描述。
    • 他们使用泛型来定义函数。
    template <typename T>//也可以使用template <class T>
    void Swap(T &a, T &b)
    {
      T = temp;
      temp = a;
      a = b;
      b = temp;
    }
  • 为特定类型提供具体化的模板定义。
  • 显示具体化不会根据模板生成函数定义,而是使用对特定类型定义的专用函数定义。
    • template<> void Swap(job &j1, job &j2);
  • 实例化
    • 代码中包含函数模板本身并不会生成函数定义。只是一个生成函数定义的方案。
    • 编译器为特定类型生成函数定义时得到的是模板实例。这种实例化方法被称为隐式实例化。例如直接调用Swap(a, b);
    • 最初编译器只能通过隐式实例化,来生使用模板生成函数定义。
    • 现在c++还允许显示实例化。
    • template void Swap< int >(int, int);
    • 还可以在函数中创建显示实例化
    • Swap< double >(a, b);
  • 编译器使用哪个函数版本
    • 第一步:创建候选列表。其中包含与被调函数的名称相同的函数和模板函数。
    • 第二步:使用候选列表创建可行函数列表。
    • 第三步:检测是否有最佳的可行函数。如果有使用它,如果没有函数调用出错。

原文地址:https://www.cnblogs.com/yangzixiong/p/11960867.html

时间: 2024-10-21 10:34:37

函数探幽的相关文章

C++ primer plus读书笔记——第8章 函数探幽

第8章 函数探幽 1. 对于内联函数,编译器将使用相应的函数代码替换函数调用,程序无需跳到一个位置执行代码,再调回来.因此,内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存. 2. 要使用内联函数,需要在: 函数声明前加上关键字inline; 函数定义前加上关键字inline; 3. 程序员请求将函数作为内联函数时,编译器不一定会满足这种需求.它可能认为该函数过大或注意到函数调用了自己(内联函数不能递归). 4. 必须在声明引用变量时进行初始化 int rat = 101; int &

C++Premer Plus学习(五)&mdash;&mdash;函数探幽

一.内联函数 1.优点: 内联函数就是比较省资源,然后一般就是将简短,使用频率高的函数作为内联函数会比较合适. 2.一个demo #include "stdafx.h" #include<iostream> using namespace std; inline double Square(double x) { return x*x; } int _tmain(int argc, _TCHAR* argv[]) { int a = 16; cout << Sq

第八章:函数探幽

8.1题 1 #include<iostream> 2 void silly(const char * s,int n = 0); 3 int main() 4 { 5 char *pointer = "lala"; 6 silly("hello?"); 7 for(int i = 0; i < 5; i++) 8 silly(pointer,i); 9 } 10 void silly(const char * s,int n) 11 { 12 s

第8讲——函数探幽

前面的笔记都是行云流水,因为前面几章看过了,从这一讲开始,每一讲都是现学现做笔记的. 没人是天生的赢家,只有后天的loser. 由上一讲中的知识,我们了解到许多有关C++函数的知识,但需要学习的知识还很多.C++还提供许多新的函数特性,使之有别于C语言. 新特性包括内联函数.按引用传递变量.默认的参数值.函数重载(多态)以及模板函数. 这一讲中,我们将介绍C++在C语言基础上新增的特性,比前面各讲都多,这是我们进入(++)领域的重要一步. [内联函数] 这是为提高程序运行速度所做的一项改进. 内

函数探幽--引用变量

引用是已定义的变量的别名(另一个名称).如果将twain作为clement作为变量的引用,则可以交替使用twain和Clemente来表示该变量. 引用变量的主要用途是用作函数的形参.通过将引用变量用作参数,函数将使用原始数据而不是其副本. 创建引用变量 要将rodents作为rats变量的别名 int rats; int & rodents = rats; 这里的&不是地址运算符,而是类型标识符的一部分. 上述引用声明允许 rats 与 rodents 互换--他们指向相同的值和内存单元

《C++ Primer Plus》学习笔记3

<C++ Primer Plus>学习笔记3 第8章 函数探幽 =================================================================================================================== 1.C++内联函数和常规函数 1)常规函数调用使程序跳到另一个地址(函数地址),并在函数结束时返回.具体过程是执行到函数调用指令时,程序将在函数调用后立即储存指令的内存地址,并将函数参数赋值到堆栈,跳到

C++ 杂碎语法

C++ 中的布尔类型:布尔类型只占用一个bit ,但是如果连续定义多个布尔类型时,编译器可能会多个布尔类型定义在一起.true  编译器用1来表示.false  编译器用0来表示. 将一个其他类型的数据赋给布尔类型变量:C++编译器会将所有的非0的值转换为true(1),将0 转化为false(0). 三木运算符   ? :    :将一个三目运算符作为左值: (a>b?a:b) = 3 C语言不支持(三目运算符返回一个值),但在C++中支持(三目元算符返回变量).    但是如果可能的返回值有

C++ Primer Plus

第1章 预备知识 第2章 开始学习C++ 第3章 处理数据 第4章 复合类型 第5章 循环和关系表达式 第6章 分支语句和逻辑运算符 第7章 函数-C++的编程模块 第8章 函数探幽 第9章 内存模型和名称空间 第10章 对象和类 第11章 使用类 第12章 类和动态内存分配 第13章 类继承 第14章 C++中的代码重用 第15章 友元,异常和其他 第16章 string类和标准模板库 第17章 输入,输出和文件 第18章 探讨C++新标准 附录A 计数系统 附录B C++保留字 附录C AS

博文分类

Markdown教程 Markdown常用操作 C++ 第一至七章 第八章 函数探幽 第十章 对象与类 第十一章 使用类 Python爬虫 1. Requests库入门 2. Requests库入门实例 3. BeautifulSoup库入门 4. HTML遍历 原文地址:https://www.cnblogs.com/machine-lyc/p/10264380.html