《高c/c++》 1-6章

1-6 章 :编程风格,编程素养

书籍:《高质量c/c++》 林锐 博士

    半个小时读了《高质量c/c++》1-6章,属于对之前的知识点的复习与再整理。内容大部分是代码的编写风格与规范性。在函数返回值的部分较为重要,记忆引用传递的应用与原理。
1文件结构

编写风格
头文件.h:声明
定义文件.cpp:定义
版权声明。。。

头文件:ifndef。。结构作用:防止头文件被重复使用,产生预处理块
<>标准库  “”非标准库

(1)通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只 要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库 功能,而不必关心接口怎么实现的。编译器会从库中提取相应的代码。 (2)头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件 中的声明不一致,编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错 的负担。

2  程序版式
默认vs vim8.0 即可

3 命名规则
见名知意 下划线 蜂头式

4 表达式和基本语句
默认vs vim8.0 即可

5 常量

C语言:#define 来定义常量
C++:const常量  枚举常量 内联常量
区别及优缺点:
const优点
  1. const是一个数据类型,而宏是字符替换。所以编译器可以对const进行类型安全检查,对宏没有安全检查,并且字符替换可能造成意料之外的错误,边际效应。
  2. 有些集成化调试工具可以对cosnt进行调试
  3. const能在在类中创建常量,但是根据对象所变的,及不同的对象有不同的值。且只能在构造函数中初始化。
  枚举常量 enum {a = 10, b = 20};
    可以在类中表示常量,并被使用,但枚举常量只能使用整数,最大值有限。
    枚举常量占内存(常量区),枚举变量在赋值时分配内存(栈)

6 函数设计

接口设计:参数,返回值, 函数名
传递方式:
C语言:值传递,指针传递
C++:值传递,指针传递,引用传递
参数规则
(目的参数,源参数)
参数何时用const / cosnt常量不变修饰:
  • 如果参数是指针,且仅作输入作用,加const防止指针被意外修改
  • 如果输入参数以值方式传递,改为const&,可以省去临时对象的构造和析构过程,提高效率
函数参数不要太多,控制在5个以内
不要使用数目和类型不确定的参数,丧失严格的类型安全检查

返回值规则:
缺省的返回值类型为int,而不是void。所以没有返回值应该声明为void
getchar()返回值是int,很奇怪。名字与返回值不符

【规则 6-2-3】不要将正常值和错误标志混在一起返回。正常值用输出参数获得,而 错误标志用 return 语句返回。 回顾上例,C 标准库函数的设计者为什么要将 getchar 声明为令人迷糊的 int 类型 高质量 C++/C 编程指南,v 1.0 2001 Page 38 of 101 呢?他会那么傻吗? 在正常情况下,getchar 的确返回单个字符。但如果 getchar 碰到文件结束标志或发 生读错误,它必须返回一个标志 EOF。为了区别于正常的字符,只好将 EOF 定义为负 数(通常为负 1)。因此函数 getchar 就成了 int 类型。 我们在实际工作中,经常会碰到上述令人为难的问题。为了避免出现误解,我们应 该将正常值和错误标志分开。即:正常值用输出参数获得,而错误标志用 return 语句返 回。


为了增加灵活性和链式表达,可以附加返回值:
strcpy,可以对拷贝后的字符串再进行操作

函数的返回值是一个对象时:有时用引用返回会提高效率。 而有时会出错。
例如 :
  • 类的赋值函数返回值用引用-》
return *this; 会拷贝到保持返回值的外部存储单元,开销加效率。
  • 类的相加重载函数-》
在函数内部开辟了临时空间接受加后的值,但函数结束时,会释放tmp的空间,所以不能用引用。
  • 返回值传递时其实会开辟一个临时空间,故返回值较大或为对象时,会浪费空间与时间。使用引用可以把返回值直接赋值给外部。但是要确保返回值在函数结束时仍存在。

指针返回:返回局部变量:若是数组就gg,因为在栈空间,出来作用域空间就释放。 若返回的是指针,实际返回的是数据段中常量,所以不会变。

内部实现规则:
  • 入口处,对参数的检查,对特殊情况的判断
使用防御式编程:断言assert, 静态断言static_assert
  • 出口处:return
  1. 不可返回栈内存的指针或引用,栈内存:出了函数体就销毁,会访问非法值。同上相加值传递
  2. 返回类型:值 ,指针, 引用
  3. return String(s1 + s2) ; 这种写法编译器会把创建的临时变量直接放在外部单元,对于对象会省去拷贝和析构。
  4. 大佬都是单个输出口。linux线程中有老师写的代码。

【建议 6-4-1】函数的功能要单一,不要设计多用途的函数。 【建议 6-4-2】函数体的规模要小,尽量控制在 50 行代码之内。 【建议 6-4-3】尽量避免函数带有“记忆”功能。相同的输入应当产生相同的输出。 带有“记忆”功能的函数,其行为可能是不可预测的,因为它的行为可能取决于某 种“记忆状态”。这样的函数既不易理解又不利于测试和维护。在 C/C++语言中,函数 的 static 局部变量是函数的“记忆”存储器。建议尽量少用 static 局部变量,除非必需。 【建议 6-4-4】不仅要检查输入参数的有效性,还要检查通过其它途径进入函数体内 的变量的有效性,例如全局变量、文件句柄等。 【建议 6-4-5】用于出错处理的返回值一定要清楚,让使用者不容易忽视或误解错误 情况。

断言的使用
    <assert.h>
Debug版本下的一会宏,主要是程序员可以用来找到测试,找到错误,并对程序不造成影响。如何程序满足断言的错误,程序在执行时会在该地方报错,所以在断言后面注释好错误的直接的原因可以便于理解与排错。
assert :执行时报错
static_assert:编译时报错,更快。
Debug版本内部测试,添加调试信息。
 Release版本发行给用户使用。
assert(表达式)  表达式为0则出错,非零继续。
引用与指针的比较
<C++初期重点>

引用基本概念:引用就是起别名,给一个空间起了另一个变量名,俩个变量共用一个内存空间,进行骚操作。
int m = 666;
int &n = m;
在这里n是m的别名,n是引用,m是被引用物。相对与给小华起了个小名叫二毛。
基本规则:
    1.引用创建是必须被初始化,有被引用物。
二毛是个小名,你要知道是谁的小名,不然二毛也没意义。
    2.不能有NULL引用,引用必须与合法的存储单元关联。
    3.引用一旦被初始化,就不能被改变。
区别: 指针可以随时初始化,指针可以指向NULL,指针可以改变指向。

引用的骚操作:函数中的引用传递
引用传递优点:
    可以改变传入参数的值。不需要改变时要加const,相比于指针更安全
    传入时直接起别名,还是原来的空间,不需要额外开辟创造,相比于值传递减少开销,效率高。
指针传递,相当于传了地址,可以访问内存,所以权限太大,不安全












猜你喜欢

转载自blog.csdn.net/qq_32672481/article/details/80553519
1-6