• 第8章 函数探幽


    8.1C++内联函数

            内联函数,编译器将使用相应的函数代码替换函数调用,程序无需跳到另一个位置处执行代码,在跳回来。因此,内联函数运行速度更快,但是需要占用更多内存。

    • 在函数声明和定义前加关键字inline
    • 不能做递归函数

    C语言使用预处理器语句#define来提供宏----内联函数的原始实现。

    #define SQUARE(X) X*X;

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

    内联函数更安全。比如a = SQUARE(c++); //is replaced by d=c++*c++;

    8.2 引用变量

    1. int rats;
    2. int &rodents = rats;

    rodents rats指向相同的值和内存单元

    引用创建时必须初始化。

    右值引用(需要研究一下)

    右值引用详解_飞羚的博客-CSDN博客_右值引用

    返回引用,要避免返回函数终止时不再存在的内存单元引用。

    1. const free_throws &clone2(free_throws &ft)
    2. {
    3. free_throws newguy;
    4. newguy = ft;
    5. return newguy;
    6. }

    有两种常规方法避免上述问题:

    1、返回一个作为参数传递给函数的引用。

    1. free_throws &accumulate(free_throws &target,const free_throws &source)
    2. {
    3. target.attempts += source.attempts;
    4. target.made += source.made;
    5. set_pc(target);
    6. return target;
    7. }

    2、用new来分配新的储存空间。这种方法需要手动delete内存,容易忽略。

    1. const free_throws &clone(free_throws &ft)
    2. {
    3. free_throws *pt;
    4. *pt = ft;
    5. return *pt;
    6. }

    const 用于引用返回类型

    accumulate(dup,five) = four;

            函数返回值指向dup的引用,时一个可修改的内存,因此这条语句合法。常规函数返回值位于临时内存单元中,运行到下一条语句可能不再存在。

            要使用引用返回值,但又不允许上述函数赋值操作,将返回类型声明为const即可。

    const free_throws &accumulate(free_throws &target,const free_throws &source)

    对象、继承和引用

    示例代码

    1. #include <iostream>
    2. #include <fstream>
    3. #include <cstdlib>
    4. using namespace std;
    5. void file_it(ostream &os,double fo,const double fe[],int n);
    6. const int LIMIT = 5;
    7. int main()
    8. {
    9. ofstream fout;
    10. const char *fn = "ep-data.txt";
    11. fout.open(fn);
    12. if(!fout.is_open())
    13. {
    14. cout << "Can't open " << fn << endl;
    15. exit(EXIT_FAILURE);
    16. }
    17. double obj;
    18. cout << "Enter the focal length os your ";
    19. cin >> obj;
    20. double eps[LIMIT];
    21. for(int i=0;i<LIMIT;i++)
    22. {
    23. cout << "Eyepiece #" << i+1 << ": ";
    24. cin >> eps[i];
    25. }
    26. file_it(fout,obj,eps,LIMIT);
    27. file_it(cout,obj,eps,LIMIT);
    28. fout.close();
    29. cout << "Done\n";
    30. return 0;
    31. }
    32. void file_it(ostream &os,double fo,const double fe[],int n)
    33. {
    34. ios_base::fmtflags initial;
    35. initial = os.setf(ios_base::fixed); //将对象置于使用定点表示法的模式
    36. os.precision(0);
    37. os <<"Focal length of obj:" << fo << " mm\n";
    38. os.setf(ios::showpoint); //显示小数点模式
    39. os.precision(1); //显示1位小数点
    40. os.width(12); //设置下一次输出使用的字段宽度
    41. os << "f.1. eyepiece";
    42. os.width(15);
    43. os <<"magnification" << endl;
    44. for(int i=0;i<n;i++)
    45. {
    46. os.width(12);
    47. os << fe[i];
    48. os.width(15);
    49. os << int(fo/fe[i] + 0.5) << endl;
    50. }
    51. os.setf(initial);
    52. }

    运行结果:

    1. Enter the focal length os your 4
    2. Eyepiece #1: 1.1
    3. Eyepiece #2: 2.2
    4. Eyepiece #3: 3.3
    5. Eyepiece #4: 4.4
    6. Eyepiece #5: 5.5
    7. Focal length of obj:4 mm
    8. f.1. eyepiece magnification
    9. 1.1 4
    10. 2.2 2
    11. 3.3 1
    12. 4.4 1
    13. 5.5 1
    14. Done

    8.3默认参数

    char* left(const char* str,int n=1);

    对于带参数列表函数,必须从右向左添加默认值。

    1. int harpo(int n,int m=4,int j=5) //有效
    2. int harpo(int n,int m=4,int j) //无效

    8.4函数重载

    类型引用和类型本身不能作为重载函数

    1. double cube(double x);
    2. double cube(double &x);

    8.5函数模板

    1. template <typename AnyType>
    2. void Swap(AnyType &a,AnyType &b)
    3. {
    4. AnyType temp;
    5. temp = a;
    6. a = b;
    7. b = temp;
    8. }

    显示具体化:

    1. #include <iostream>
    2. template <typename T>
    3. void Swap(T &a,T &b);
    4. struct job
    5. {
    6. char name[40];
    7. double salary;
    8. int floor;
    9. };
    10. template <> void Swap<job>(job &j1,job &j2);
    11. void Show(job &j);
    12. int main()
    13. {
    14. using namespace std;
    15. cout.precision(2);
    16. cout.setf(ios::fixed,ios::floatfield);
    17. int i=10,j=20;
    18. cout << "i,j=" << i << "," << j << ".\n";
    19. cout << "using compiler generated int swapper:\n";
    20. Swap(i,j);
    21. cout << "Now i,j = " << i << "," << j << ".\n";
    22. job sue = {"Susan Yaffee",73000.60,7};
    23. job sidey = {"Sidney Taffee",78060.72,9};
    24. cout << "before job swappong\n";
    25. Show(sue);
    26. Show(sidey);
    27. return 0;
    28. }
    29. template <typename T>
    30. void Swap(T &a,T &b)
    31. {
    32. T temp;
    33. temp = a;
    34. a = b;
    35. b = temp;
    36. }
    37. template <> void Swap<job>(job &j1,job &j2)
    38. {
    39. double t1;
    40. int t2;
    41. t1 = j1.salary;
    42. j1.salary = j2.salary;
    43. j2.salary = t1;
    44. t2 = j1.floor;
    45. j2.floor = j1.floor;
    46. j1.floor = t2;
    47. }
    48. void Show(job &j)
    49. {
    50. std::cout << j.name << " :$" << j.salary << " on floor" << j.floor << std::endl;
    51. }

    运行结果:

    1. i,j=10,20.
    2. using compiler generated int swapper:
    3. Now i,j = 20,10.
    4. before job swappong
    5. Susan Yaffee :$73000.60 on floor7
    6. Sidney Taffee :$78060.72 on floor9

    显示实例化:template void Swap<int>(int ,int);

    具体实例化:template <> void Swap<int>(int &,int &); 或者 template <> void Swap(int &,int &);

  • 相关阅读:
    力扣刷题学习SQL篇——1-7 查询(修复表中的名字——利用字符串函数)
    VMware——WindowServer2012R2安装jdk1.8及环境变量配置
    逻辑漏洞笔记
    【从零开始的Java开发】1-4-1 Java继承:Object类、final关键字、注解
    盲盒商城源码 盲盒开箱源码 潮物盲盒商城源码 仿CSGO盲盒开箱源码
    跨境电商自养号测评干货分享:从环境搭建到安全养号
    Zookeeper Java SDK 开发入门
    【考研】数据结构考点——链式基数排序
    ELK企业级日志分析系统
    【C语言】字符串左旋(三种方法)
  • 原文地址:https://blog.csdn.net/m0_59666413/article/details/125414967