《代码大全》笔记

2023-05-16

最近将去年毕业时,大神推荐的《代码大全》看完了(已经过去一年了,要十分感谢推荐,还有凤林兄的《深入理解计算机系统》)。
零零碎碎的时间,发现很多东西虽然在书中标记了,
但是再去翻看时,还是有很多已经模糊的地方。
想来,还是需要留个笔记,供以后看看。


关于《代码大全》,
每章后边的CheckList都需要好好分析与思考,并能实际运用。


第六章
提出抽象数据类型,是进行模块化(原文为类)的基础。可以让我们只根据当前类型来理解代码,或者操作相应的功能。
良好抽象数据类型,让我们有效地隐藏一些数据以及实现的细节,同时提高程序的可读性,降低程序的复杂度(不用去关心底层具体实现),让程序更容易理解。避免使用全局数据,提高程序的可重用性。


第七章,
高质量子程序
何为子程序?
子程序是为实现一个特定的目的,而编写的一个可被调用的方法或者过程。发明子程序的作用,节省空间,提高性能。
子程序的作用,
可以降低复杂度,不必去关心子程序的具体实现。
避免代码重复,都是提高修改程序的效率(因为代码只出现一次,所以只在一处修改就可以)。
隐藏操作顺序,
隐藏指针操作,
提高可移植性,隔离硬件无代码和硬件底层代码,减少移植时需要修改的工作量。


对于子程序而言,提高子程序的内聚性是关键,而功能性的内聚性,是最有效的内聚性。


同时,好的子程序名字,提高程序的可读性,使代码更易读。更多的时候,阅读代码的次数,远远大于编写的次数。
描述子程序所做的事情,
避免使用无意义的,模糊的动词。
不仅仅通过数字来星辰不同的子程序名


合适的子程序长度一般在200以内,偶尔长的子程序,尽量不超过500行。


对于子程序的参数,尽量按照同样的顺序出现在同一个工程中,同样不把输入参数,用作工作变量(这个是经常做的事情)。使用所有输入参数。


对于宏和内联子程序,尽量不用。不到万不得已不使用,如果使用,按照子程序的方法来使用。


创建子程序的原因,
提高可读性,可靠性,可修改性,节省空间(一个次要的原因)。


第八章,
防御式编程,
原则,保证垃圾进,正确出。
检查输入参数,是最有效的方式。


其中断言是最好检查输入参数的方式。对于断言的使用要讲求方法,同时在正式代码中要避免存在断言。


在看到断言的时候,想起来自己之前使用断言的方式,
突然发现有些问题。
那个时候,总希望断言能够判断并决定是否返回值,或者不返回。
其实这里,只需要进行判断就行了。对于具体的处理,
由程序代码处理,
是返回值,或者不返回值。
当然,这里就需要,断言只是判断的代码,而没有执行的代码。


对于健壮性与正确性,是一对矛盾,根据需要,
合适的时候,选择合适的处理平衡。
断言处理,函数的前条件和后条件。


当然,对于错误处理的方式,有很多种,也需要根据需要,
选择合适的方式。
对于健壮性要求,和正确性要求,他们适合的方式,不一样。




工业类软件,及要求健壮性,也要求正确性。
要同时保证这两个。


如果可以,将断言单独做一块处理。
保证进入子函数的数据,都是正确的。


区分开发代码,和产品代码。在开发代码中,尽量采用进攻式编程,找出尽可能多的错误。
在发布的产品代码中,尽量使用防御式编程。


分级式防御。




第九章
对于伪代码编程,感觉更多的是编程前的构建,当然好的伪代码编程,可以直接将伪代码转换为注释。


对于程序的性能优化,最好的还是从高层进行优化。单独的对于一个函数,一个子程序进行优化,所起到的作用,都是有限的。


做到从迷信到理解的转变。


创建子程序是一个迭代的过程。在创建子程序的过程中,获得的认识常常会反过来影响子程序的设计。


在编程完成后,立即检查代码的成本是最小的。




第十章
关于变量的命名,使用以及初始化等内容,应该是很好的一段帮助提升代码可读性的内容。代码的逻辑性,本就复杂,如果代码的变量能够一定程度上指示此时的操作内容,可能会一定程度上提高代码的自说明性。
因为代码写的是给人读的程序,而不是给机器读的程序。


几个原则:
变量的初始化,是很关键的一项。变量在靠近第一次使用的时候初始化,既可以减小变量的作用域,又减小代码跨度,提高程序的阅读性,减少同一时间考虑的代码量。查看编译器警告,消除未初始化的变量。
因为程序读的次数,要比写的次数多,所以尽可能写出,容易读的程序。


灵活性与复杂性是一个对矛盾。绑定时间晚的程序灵活性大,但是复杂度高;绑定时间早的程序灵活性小,但复杂度低。


第十一章
好的变量名,反映的是问题,而不是解决方案。
好的变量名,是提高程序可读性的一项关键因素。


对于状态变量的命名,尽量采用能够反映状态的名称。


对于命名规则,有很多种,并没有最好的规则。采用适合的,团队使用的。
命名规则应该你呢够区分,局部数据,类数据和全局数据局。
代码阅读的次数,远远超过编写的次数。


第十二章
感觉这一章提到了很多平时忽视的细节。


尽量使用具名常量。
预防除零的情况。
C中,尽量使用强制类型转换。
避免不同类型之间的比较。同时对于浮点型的比较,不能使用等量判断,只能使用一定的精度值。
注意编译警告。


整数:
注意整数除法。
检查整数溢出,uchar型注意不超过255,uint16,注意不超过65535
检查计算中间的结果溢出。


浮点数:
避免数量级差别大的数之间运算。
避免等量判断。
处理舍入误差问题。


字符和字符串
使用具名常量,来代替神秘字符和字符串
避免off-by-one
避免使用不安全的字符拷贝函数,尽量使用strncpy(),等安全的字符串函数。


尽量使用具名常量


数组
避免下标越界
注意数组边界,避免off-by-one
在C中可以结合ARRAY_LENGTH()宏来判定数组长度。对于指针无效。


使用typedef,


第十三章
这一章,涉及了我们初学时,不经常接触,但是实际用时,却经常用的,
指针,结构,全局数据


在C,中可以将结构体当做“类”一样来使用,进而通过C,实现面向对象编程的思想。当然,会麻烦一些,但是对于所带了的可读性与可复用性,绝对是是值得的。


当然,结构体也有自己的优势:
明确数据关系,使得代码更易阅读
简化了对于数据块的操作
同时可以简化函数的参数列表(尤其当有很多变量需要传递时),
为以后的维护代码,减少工作量。


对于指针的运用尤其固有的复杂性,正确的使用指针要求你对所有编译器的内存管理机制有很好的理解。
指针的两部分:内存中的某处位置(内种中的地址),如何解释该位置的内容(指针的基类型)。


关于指针错误很难发现,也很难调试,
所以首先要避免造成指针错误,
其次编写代码后,尽快检测出指针错误。


几点方法:
把指针操作限制在子程序里,
同时声明和定义指针
在与指针分配相同的作用内删除指针(实际中,这种情况经常被违反)
使用前检查指针,
先检查指针所引用的变量,然后使用之
先填充无效数据,然后再释放的内存,
增加明显的冗余
用额外的指针变量,来提高代码清晰度。丛长久而言,代码的清晰度,远比代码的执行效率要重要。更何况,有时候这样做,还会提高执行效率。
简化复杂的指针表达式
按照正确的顺序删除链表中的指针
分配一片保留的内存后备区域
粉碎垃圾数据
在删除或者释放指针后,将他们设置为空值
在删除变量前,检查非法指针(指释放已经释过的指针,很可能会造成程序崩溃)
跟踪指针分配情况
采用非指针技术(记得以前考C二级的时候,指针还不怎么会用,就都用数组来替,竟然也都没有问题)




对于C指针而言的技巧
使用显示指针类型
避免强制类型转换
遵循参数传递的型号规则
在内存分配中使用sizeof()确定变量的大小(sizeof在编译时执行)




对于全局数据的使用要慎之又慎,只在万不得已的时候使用全局数据
全局数据减弱了模块化,增加了 耦合度,阻碍了代码重用,增加了复杂度(正好背离的软件的出发点,降低复杂度)


在使用全局数据时需要注意的:
首先吧每一个变量设置为局部的,仅当需要时才把变来那个设置为全局的。
区分全局变量和类变量
使用访问子程序(使用访问子程序还有需要需要注意的地方,这个慢慢消化)


结构体是程序更简单,更易理解,更易维护
指针很容易出错,
避免使用全局。


附:
《代码大全》推荐的几本书:
入门类:
《代码大全》
《编程珠玑》
《Software Project Survival Guide》


提高类/专业类:
《Rapid Development》
《编程精粹:编写高质量C语言代码(中文版)》
《重构:改善现有代码的设计》


工程类:
《软件工程:实践者的研究方法》


对于这些书的内容,大多数是不分语言的。
作者在《代码大全》中也一直强调深入一种语言去编程,而不是在一种语言上编程。


正确的时候,读合适的书!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《代码大全》笔记 的相关文章

  • Visual Studio 2008学习过程(之二)与MATLAB混合编程

    Visual Studio 2008学习过程 之二 MATLAB混合编程 上一篇我写的是我初识VisualStudio2008的过程 后来我又用它开发了几个小程序 至于怎么做的 过两天我再写 这篇文章我就写写VS和MATLAB联合开发程序的
  • HIVE迁移教程X86架构到ARM架构(CPU:鲲鹏920)

    centos8的hive迁移教程 1安装新的centos8环境 2 安装实验所需软件 2 1 安装OpenJDK yum span class token function install span java 1 8 0 openjdk 配
  • C++滑动窗口算法

    滑动窗口算法在一个特定大小的字符串或数组上进行操作 xff0c 而不在整个字符串和数组上操作 xff0c 这样就降低了问题的复杂度 xff0c 从而也达到降低了循环的嵌套深度 如下题 给你两个长度相同的字符串 xff0c s 和 t 将 s
  • C++和js交互方案对比

    c 43 43 和js交互方案对比 一 xff1a nodejs技术 nodejs技术是基于V8引擎的一套前后端交互技术 nan h为c 43 43 提供了与js交互的一系列V8 API 参考链接 缺点 xff1a 在Node js中 xf
  • C++实现HTTP服务

    一个多平台的系统基本架构 xff08 如下图 xff09 xff0c 数据库部分我们以后可以使用HDFS和MapReduce进行分布式存储 xff0c 之前大致介绍了js和c 43 43 交互的几种方式对比 xff0c 考虑到拓展性和访问效
  • gstreamer获取视频采集卡的数据

    gstreamer获取视频采集卡的视频数据 gstreamer可以用于采集硬件视频数据 xff0c 转码 xff0c 播放 xff0c 传输等 xff0c 但由于框架相对于FFmpeg较为小众 xff0c 所以资料较少 xff0c 整理一份
  • 使用c++来实现一个简单的数据库功能

    使用c 43 43 来实现一个简单的文件数据库功能 功能点1 xff1a 建表 1 创建和表同名的文件 2 在文件中存储表的信息 xff0c 包括attribute的name xff0c 数量 xff0c 类型 xff0c 是否唯一 3 添
  • 【性能优化】cpu时间抖动问题的解决修复

    问题描述 xff1a 边缘设备的cpu在低占有率时 xff0c 进程运行时间抖动较大 xff0c 在高占有率时 xff0c 运行时间抖动更稳定 低占有率运行情况图 xff1a 相同处理逻辑循环中 xff0c 两次处理的时间间隔 xff1a
  • pointRCNN 结果可视化

    由于pointRCNN源码的训练和inference很详细 xff0c 但是没有可视化的代码 xff0c 本文介绍其3d框结果的可视化方法 1 跑通pointRCNN https github com sshaoshuai PointRCN
  • C/C++学习笔记——C提高: 函数指针和递归函数

    函数指针 函数类型 通过什么来区分两个不同的函数 xff1f 一个函数在编译时被分配一个入口地址 xff0c 这个地址就称为函数的指针 xff0c 函数名代表函数的入口地址 函数三要素 xff1a 名称 参数 返回值 C语言中的函数有自己特
  • 算法基础22-最小生成树

    最小生成树 primkruskal prim 链接 acwing上一个关于prim很好的题解 prim 算法干的事情是 xff1a 给定一个无向图 xff0c 在图中选择若干条边把图的所有节点连起来 要求边长之和最小 在图论中 xff0c
  • C/C++学习笔记——C提高:预处理

    预处理的基本概念 C语言对源程序处理的四个步骤 xff1a 预处理 编译 汇编 链接 预处理是在程序源代码被编译之前 xff0c 由预处理器 xff08 Preprocessor xff09 对程序源代码进行的处理 这个过程并不对程序的源代
  • C/C++学习笔记——C提高:动态库的封装和使用

    库的基本概念 库是已经写好的 成熟的 可复用的代码 每个程序都需要依赖很多底层库 xff0c 不可能每个人的代码从零开始编写代码 xff0c 因此库的存在具有非常重要的意义 在我们的开发的应用中经常有一些公共代码是需要反复使用的 xff0c
  • FreeRTOS学习笔记——基础知识与移植(STM32F103)

    1 1 前后台系统 xff1a 早期嵌入式开发没有嵌入式操作系统的概念 xff0c 直接操作裸机 xff0c 在裸机上写程序 xff0c 比如用51单片机基本就没有操作系统的概念 通常把程序分为两部分 xff1a 前台系统和后台系统 简单的
  • STM32开源代码——MAX30100程序

    正点原子精英开发板 模块化封装 xff0c 入口函数简明 xff0c 易上手操作 展示main c代码 xff0c 完整代码请下载 xff08 数据打印到串口在MAX30100 PulseOximeter c xff09 点击下载代码 in
  • STM32开源代码——2.8寸TFTLCD屏虚拟键盘触摸程序

    正点原子精英开发板 模块化封装 xff0c 入口函数简明 xff0c 易上手操作 展示main c代码 xff0c 完整代码请下载 点击下载代码 include 34 sys h 34 include 34 delay h 34 inclu
  • STM32开源代码——光敏传感器

    正点原子精英开发板 模块化封装 xff0c 入口函数简明 xff0c 易上手操作 展示main c代码 xff0c 完整代码请下载 点击下载代码 include 34 led h 34 include 34 delay h 34 inclu
  • 个人项目——机智云开源APP基础修改教程(Android)

    之前写过一篇STM32接入机智云的教程 xff0c 最后说要有时间给大家写一篇修改机智云开源Demo APP的教程 xff0c 刚好楼主考完直流传动 xff0c 然后帮小学弟的一个32项目接入了机智云 xff0c 然后打算帮他修改一下Dem

随机推荐

  • FreeRTOS学习笔记——FreeRTOS任务创建和删除实验(静态方法)

    6 3 任务创建和删除实验 静态方法 6 3 1 实验程序设计 1 实验目的 上一小节我们讲了使用函数xTaskCreate 来创建任务 xff0c 本节在上一小节的基础上做简单的修改 xff0c 使用函数xTaskCreateStatic
  • FreeRTOS学习笔记——FreeRTOS 系统内核控制函数

    FreeRTOS 中有一些函数只供系统内核使用 xff0c 用户应用程序一般不允许使用 xff0c 这些API 函数就是系统内核控制函数 本章我们就来学习一下这些内核控制函数 xff0c 本章分为如下几部分 xff1a 10 1 内核控制函
  • FreeRTOS学习笔记——FreeRTOS 时间管理

    在使用FreeRTOS 的过程中我们通常会在一个任务函数中使用延时函数对这个任务延时 xff0c 当执行延时函数的时候就会进行任务切换 xff0c 并且此任务就会进入阻塞态 xff0c 直到延时完成 xff0c 任务重新进入就绪态 延时函数
  • 算法基础23-二分图

    二分图 二分图的判断二分图的最大匹配数 可以去看acwing题解 二分图的判断 span class token comment AcWing 860 染色法判定二分图 span span class token macro propert
  • Router 选择

    Connected Dominating Set Example of a Connected Dominating Set Router 必须形成一个 CDS xff08 Connected Dominating Set xff0c 连接
  • devtool: unset _PYTHON_SYSCONFIGDATA_NAME

    问题 在 Ubuntu 20 04 1 LTS 上进行编译Yocto时报错 xff0c 出现如下错误 xff1a bb data smart ExpansionError Failure expanding variable SRCPV e
  • VsCode 配置PySide6及测试

    目录 VSCode插件安装安装Python插件安装PySide6插件 PySide6安装PySide6配置VSCode创建UI文件 在这里插入图片描述 https img blog csdnimg cn cbf7cd76d7d84048ab
  • Ubuntu 14.04 Desktop的Raid1安装总结

    Ubuntu 14 04 Desktop的Raid1安装总结 安装基于Ubuntu14 04 Desktop的Raid1 由于采用UEFI GPT方式作为系统启动方式 xff0c 在安装过程中出现了很多异常情况 本文记录安装的过程 安装步骤
  • sem_wait sem_post信号量操作进本函数

    sem wait sem post 信号量的数据类型为结构sem t xff0c 它本质上是一个长整型的数 函数sem init xff08 xff09 用来初始化一个信号量 它的原型为 xff1a extern int sem init
  • 常见gcc编译警告整理(开始)

    1 warning no newline at end of file 在文件最后一行加上回车键 解释 xff1a 在 Rationale for the C99 standard 一文中 xff0c 有C99的相关信息 xff1a A b
  • 对于结构体变量赋值的误区

    以前在使用结构体时没有在结构体变量之间直接赋值 xff0c 今天同事在查看别人的代码时 xff0c 发现有两个结构体变量直接赋值的语句当时感觉这个语句不对 xff0c 认为在一个结构体里边 xff0c 既有一般的无符号整形与数组 xff0c
  • 线程同步(互斥锁与信号量的作用与区别)

    信号量用在多线程多任务同步的 xff0c 一个线程完成了某一个动作就通过信号量告诉别的线程 xff0c 别的线程再进行某些动作 xff08 大家都在semtake的时候 xff0c 就阻塞在 哪里 xff09 而互斥锁是用在多线程多任务互斥
  • 误解程序运行(从单片机到开始)

    误解程序运行 从单片机到开始 关于程序的执行 xff0c 以前想的不多 xff0c 没有意识到一个程序在运行时 xff0c 从哪里读指令 xff0c 数据又写在哪里 最近在看CSAPP时这个念头经常在脑袋中晃荡 从单片机上知道 xff0c
  • Out-of-Bounds Memory References and Buffer Overflow

    callee pushl edp save edp on stack movl esp edp pushl ebx save ebx subl 20 esp popl ebx restore ebx popl edp restore
  • 嘉立创专业板stm32拓展板十分钟快速入门

    本文是为不想深入学PCB但是迫不得已需要用PCB的人或者想要做一个32的拓展版的童鞋们的快速入门并做出板子的博客 xff0c 因此 xff0c 本文内容不会深入讨论元件 xff0c 只会教授基础流程 xff0c 并且没有画芯片 本文内容 x
  • 电子信息工程四年学习之思

    毕业后 xff0c 回顾四年学习历程发现 xff0c 当时以为的明白 xff0c 到现在都是那时的不明白 或许是自己的经历 xff08 参加比赛比较多 xff09 导致了现在的反思 但是 xff0c 回顾那个时候的课程设置 xff0c 却都
  • 将要到来的三大技术革命与联系

    http www csdn net article 2013 02 14 2814128 2013大数据 http www csdn net article 2013 02 15 2814135 bigdata is coming 大数据
  • Keil的常见编译警告

    1 warning 767 D conversion from pointer to smaller integer 解释 xff1a 将指针转换为较小的整数 影响 xff1a 可能造成的影响 xff1a 容易引起数据截断 xff0c 造成
  • 《大数据时代》之后

    现在想想也不记得当时是怎么找到 大数据时代 这本书的 xff0c 好像是在查找数据库方面的书 xff0c 看到亚马逊推荐的书里有这本 xff0c 发现最近才出版的就买一本回来看看 然而这个过程中 xff0c 其实自己已经得到了大数据带来的影
  • 《代码大全》笔记

    最近将去年毕业时 xff0c 大神推荐的 代码大全 看完了 xff08 已经过去一年了 xff0c 要十分感谢推荐 xff0c 还有凤林兄的 深入理解计算机系统 xff09 零零碎碎的时间 xff0c 发现很多东西虽然在书中标记了 xff0