编程习惯与思想

前置

参考自:https://blog.jm233333.com/programming-languages/c/develop-good-coding-style-and-programming-habits/#%E5%89%8D%E7%BD%AE%E7%9F%A5%E8%AF%86
相关完整内容请访问该网址

养成良好的代码风格

  1. 做好代码缩进

  2. 不要滥用临时变量

    一般而言,循环内最多同时使用多少个临时变量、我们就开多少个临时变量。通常不会超过 3 个(仅指用作指示下标的那些),也就是 i, j,k ,否则我们会考虑将内层循环包装成函数(具体详见下文),嵌套层数过多的循环也会极大地降低代码可读性

  3. 不要滥用 switch/case

    • 当你需要使用多个重复性极强的 case 语句时,就应当思考其逻辑关联性,并对代码进行简化
    • 写代码时要注意思考,只能用 case 或 if 大量穷举而没有任何办法精简代码的情形较为苛刻,至少初学者是遇不到的
  4. 使用语义明确的标识符名称

  • 应当养成习惯,在给变量、函数或是自定义符合类型起名时,使用语义明确的名称。
  1. 使用统一的命名习惯

    • 下划线命名法
    • 驼峰命名法
    • 只要命名统一,使用何种命名习惯并不重要
    • 如果你需要进行团队合作,那么除了编程语言的习俗,更应当注重与你的团队保持相同的命名习惯
  2. 使用统一的大括号换行习惯

    // 习惯 A
    for (i = 0; i < n; i ++) {
        foo(x, i);
        if (i == n / 2) {
            y = f(i);
            printf("%d\n", y);
        }
    }
    // 习惯 B
    for (i = 0; i < n; i ++)
    {
        foo(x, i);
        if (i == n / 2)
        {
            y = f(i);
            printf("%d\n", y);
        }
    }
  3. 勤加注释

    • 如输入、求解、初始化、对 xx 遍历每个 xx、对某一条件进行 xx、输出 等注释字眼。
  4. 善用函数与结构体

    1. 善用函数

      • 当代码量多到一定程度时,把所有的代码都放在 main 函数里显然是不切实际的,因此你需要学会善用函数,尽可能地将功能不同的代码分别包装,不要把大量的代码塞在同一个函数里
      • 好处:1、其一是可读性的提升;2、其二是可维护性的提升和代码的精简。
      • 在实际开发中,学会包装函数是尤为重要的基本功。如果你写出一个代码几百行的超巨大函数,别人不会觉得你很厉害,只会觉得你很蠢——除非真的有那么一个非常单一的功能,实现它就是需要这么复杂的计算,并且这个计算过程完全没办法划分成几个子过程,但我想这种情况是极其稀少的,至少我至今还没遇到过
    2. 善用结构体

      // 使用结构体
      struct Student {
          char name[20];
          int id;
          int age;
          int grade;
      };
      struct Student students[50];
      // 不使用结构体
      char name[50][20];
      int id[50];
      int age[50];
      int grade[50];
  5. 在布尔表达式中勤加括号

  6. 避免对同一数据存放多个无关副本

    对于同一份数据,我们应当尽量只存放一个副本。例如:

    #define N 1000000
    int data[N], id[N], sum[N], son[2][N];
    double value[N];
  7. 处理简单的错误输入

养成良好的编程习惯

关注变量初始化

养成习惯:对于任何一个新添加的变量,总是关注它是否有被合法地初始化。

关注问题的边界条件

养成习惯:在解决问题、实现接口或函数时,总是关注边界条件。

写循环时关注下标越界

养成习惯:当你在循环中使用间接的下标时,总是关注下标越界问题。例如你在一个 i∈[0,n-1]i∈[0,n−1] 的循环中会访问数组元素,而当你使用 a[i+1] 或 a[i−1] 时,就应当认识到循环条件需要更改。如果能够养成关注下标越界的习惯,你就不会写出类似下面这样的代码:

当然,这种错误本身也不难排查,只不过,如果养成习惯,只要使用间接的下标,就去考虑越界:

for (i = 0; i < n; i ++) {
    if (a[i] > // 当你即将写下 a[i + 1] 时
}

那么你就能在多数时候提前发现问题,很大地减少犯下此类错误的概率:

for (i = 0; i + 1 < n; i ++) { // 及时对循环条件进行应有的改变
    if (a[i] > a[i + 1]) {
}

多进行阶段性测试

养成习惯:在写代码量比较大或很大的程序时,每写完一个局部的代码后,都要考虑进行阶段性测试,保证这一部分的正确性。这样,当出现 BUG 时,我们可以认为错误大概率发生在新写的代码中,而错误出现在之前的代码中的概率很低。即便是出现在之前的部分中,你也能根据之前的阶段测试的结果,排除掉一些可能性。这可以提高我们的编程效率。

多考虑是否应该使用函数

养成习惯:在写代码时,总是考虑这段代码是不是一个独立的子功能,是否可以包装成函数。

常见名称缩写汇总

有一些非常常用的短小的名称,大家经常会对其进行“过度缩写”,因为几乎所有人都能理解这些缩写。但是初学者看到可能会很头大,为了减少初学者将来阅读和学习他人代码时遇到的阻力,特汇总于此。

缩写名称 可能的英文全称 对应中文释义
t, tmp, temp temporary 临时变量
res result 结果
ans answer 答案
tot total 全部的
num number
val value
ts time stamp 时间戳
a, arr array 数组
len length 长度
siz size 长度,大小
i, idx index 索引,下标
it iteration 迭代器
cnt count 计数器
s, str string 字符串
p, ptr pointer 指针
pos position 位置
prv, prev previous 前一个,前继
nxt, next next 下一个,后继
src source
dst destination 目标
row row
col column
mid middle 中值
缩写名称 可能的英文全称 对应中文释义
init initialize 初始化
def define 定义
del delete 删除
opt operate 操作
inc increment 增量
dec decrement 减量
mov move 移动
cpy copy 复制
cmp compare 比较
缩写名称 可能的英文全称 对应中文释义
dis, dist distance 距离
calc calculation 计算,求解
sum summation 总和
prod production 总乘积
avg average 平均值
exp expection 期望
exp exponential 指数函数 e**x
add addition
sub subtraction
mul multiplication
div division
mod modulo 模运算
sqr square 平方
sqrt square root 平方根
缩写名称 可能的英文全称 对应中文释义
mem memory 内存
buf buffer 缓冲区
img image 图片;镜像
ctrl control 控制
disp display 显示
msg message 消息
pkg package
freq frequency 频率

调试

调试 (DEBUG) 能力对于编程来说是非常重要的,即便你写程序写得再好再快再熟练,只要你还是个人,就无法保证自己不会犯错,因此能够快速查错也是一项非常重要的基本功。不如说,写代码能力和 DEBUG 能力本来就是编程能力的两个关系紧密的子集。

作为初学者,调试技巧是有必要掌握的,你不能每次都因为一些特别智障的错误去请教他人,次数多了会令他人感到反感,而且也无益于你自身能力的提升。即便你还功力尚浅,也至少应该学会去独立排查并解决一些简单的问题。毕竟,迟早你将不再是一名初学者,如果届时你未能掌握与写代码能力相匹配的 DEBUG 能力,你恐怕会遇到不小的麻烦。

学习调试技巧之前,你需要养成遇到 BUG 先自己独立尝试解决的习惯。如果你总是依赖于他人帮你 DEBUG 的话,你永远也学不会自己 DEBUG 。就像提高代码能力需要自己多写代码一样,学习调试也需要自己多去独立尝试。当然,如果你花费了很长时间也无法解决,或是经过认真思考也一头雾水毫无头绪,向他人求助才是合适的,再自己死磕就没有意义了。

求助:

xxx (学长/老师/...) 你好/您好,我在编程时遇到了无法解决的困难,下面是我的代码,可否请您帮我看看问题出在哪?谢谢!

概述

基本的调试方法说白了也就是两大类:

  • 利用 IDE 的调试工具进行调试,观测和追踪程序运行的过程;
  • 利用输出流获取中间结果,并据此思考找到程序中的错误。

编程习惯与思想
https://k3ppf0r.pages.dev/2020/01/01/心得/编程/编程习惯与思想/
作者
jm233333
发布于
2020年1月1日
许可协议