第4章心得 织程序与数据 Accelerate C++ 学习笔记 9

1 函数(子程序)

  • 用子程序(函数)来代替重复的计算。
  • 如果对计算命名,就能以更抽象的方式去思考————更加细致的考虑他的用途,而对它的使用的具体方式则考虑的较少。
  • 如果识别出问题中重要的部分并创建与这些部分相对应的具体程序段,那么程序将会更容易理解以及降低求解难度。
  • 函数中的变量只有在函数被调用时,才会创建。

2 异常

  • 如果程序抛出一个异常,程序就会在抛出异常的地方终止执行,并转移到程序的另一部分,并向这部分提供一个异常对象,异常对象中包含调用程序,可以处理异常的信息
  • 一般来说,一个异常异常被抛出的事实和异常对象的类型结合起来足以让调用程序知道该采取什么措施。

3 引用

  • 定义:一个引用是指这个名称是一个特定对象的另一个名称
  • 定义一个引用的引用与定义原来对象的引用效果是一致的
  • 如果我们定义一个非常量引用(一个允许写访问的引用),就不能让它指向一个常量对象或常量引用
  • 使用引用可以避免复制参数的额外开销
  • 使用常量引用(const vector&),可以让系统环境给予我们对变量直接访问权而无需我们复制,同时保证我们不会改变参数的值
  • 与非常量引用参数对应的参数必须是左值(非临时对象的值,一个产生算式值的表达式,如sum/count,并不是左值)
  • try和catch之间语句没有引发异常,而是正常结束,程序就会跳过全部的catch子句从而继续执行下一条句子。

4 重载

  • 定义:几个函数具有同样的函数名的概念
  • 系统会根据参数的类型来辨别我们所使用的函数

5 运算符 <<

  • 虽然系统环境需要从左到右执行<<运算符,但是他并不需要按照任何特定的顺序对操作数进行计算
    • eg,cout << "Your grade is << setprecison(3) << grade(mid,final, homework)<<setprecision(cout.precision);...这一句可能在输出Your grade is 之后就马上调用grade函数。

6 经验

  • 要保证一条语句中的副作用个数不会超过一个。
    • 抛出一个异常是一个副作用,因此一条可能引发异常的语句不应该再出现任何其他的副作用,尤其是那些包含输入和输出的语句。
  • C++要求函数的声明和定义在返回值类型、参数的个数以及类型这几个方面严格匹配。

7 分块编译

  • C++为了降低复杂度而为分块编译的概念提供支持,这允许我们将程序放进不同的文件中并独立和编译这些文件中的每一个;
  • #include指令中使用双引号,让编译器将于此名称对应的头文件中所有内容都复制到程序中;
  • 我们将自己的头文件称为头文件(C++环境中,头都是真正的文件),而系统环境提供的头文件称为标准头(standard header)而非标准头文件(系统头并不都是文件);
  • 头文件只应该声明必要的名称,限定了包含在头文件中的名称之后,要为用户保留最大限度的灵活度;
    • 头文件应该使用完整的限定名而不是使用using声明,应该给标准库的名称明确加一个前缀std::
  • 如果要将头文件不止一次的包含在对程序的编译中,那么头文件就必须保证多次包含是安全的(使用#ifndef #define #endif),#ifndef必须刚好位于文件的第一行,就算是注释也不能跑到它的前面

7 小结

  • 类型

    • T& 表示对类型的T的一个引用,通常被用来传递一个可以由函数修改的参数,与这个参数对用的参数必须是左值
    • const T& 表示对类型T的一个引用,不能对这个引用的值进行修改,可以避免复制函数所产生的开销
  • 结构

    • 结构是一种包含0个或多个成员的类型,每个结构类型的对象都包含自己的所有成员的实例
    • 结构的定义在一个源文件中只可以出现一次,因此它因该出现在一个有适当防护措施的头文件中
  • 程序结构

    • #include <系统头> 系统头可能是以文件的形式实现,但也可能不是
    • #include “用户定义的头文件名称” 通常情况,用户定义的头都有一个后缀.h
      • 为了防止对头文件的重复包含,可以用一条语句#ifndef GUARD_header_name指令将这个文件围起,在头文件中,我们应该避免声明它们无需用到的名称,不应该包含using声明,应该给标准库的名称明确的加一个前缀std::
  • 异常处理

    • cpp try{//coding 启动一个可能会引发异常的块语句}catch(t){//coding 终止try语句并处理与t类型匹配的异常}
    • throw e;终止当前函数并将值e传回给调用程序
    • 异常类
      • logic_error domain_error invalid_error length_error out_of_error runtime_error range_error overflow_error underflow_error
      • e.what()返回一个值,并报告问题的所在
  • 库工具

    • s.width(n) 为下次输出操作而将流s的宽度设置为n(如果省略了n,精度保持不变)。输出会被填充至给定的长度。返回原来的长度【标准输出运算符使用已有的宽度值,然后它们会调用width()来重置宽度】
    • setw(n) 返回一个streamsize类型的值,用于输出流,作用跟w.width(n)一样
  • 函数

    • ret-type function-name (parm-decls);//函数声明
      [inline] ret-type function-name(parm-decls)//函数定义
      • ret-type返回类型 ,parm-decls:有逗号分割开的函数参数的类型列表,调用前必须要先声明它们
      • inline:可选,它会在适当的条件下请求编译器将调用扩展成内联子过程——————避免调用额外的开销,编译器会用函数体的一个复制替换对函数的每一个调用并根据需要进行修改。内敛子过程通常在头文件中定义。
        • 引入内联函数的目的是为了解决程序中函数调用的效率问题,也是用内联函数取代带参宏定义(函数传参比宏更加方便易用);
        • inline定义的类的内联函数,函数的代码被放入符号表中,在使用时直接进行替换,(像宏一样展开),没有了调用的开销,效率也很高;
        • 可以使用inline函数完全取代表达式形式的宏定义;内联函数一般只会用在函数内容非常简单的时候;
        • 类体内部定义的函数默认就是内联函数.如果在类体外定义 inline 函数,则必须将类定义和成员函数的定义都放在同一个头文件中(或者写在同一个源文件中),否则编译时无法进行嵌入。
        • 内联函数和成员函数没什么区别,区别就在于怎样加快函数的执行速度而已。内联函数是浪费空间来节省时间的设置,因为函数的调用是很浪费时间的,写成内联函数可以在每次调用时用函数体内容代替函数调用,有点类似一个宏定义。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁星蓝雨

如果觉得文章不错,可以请喝咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值