聊聊我对代码风格对看法、顺便给 xdx 们提一点Debug的建议。为啥放个 Python 的封面?因为我找不到写 C 的…

代码风格

  • 良好的代码风格是一个 coder 应该具备的基础。

什么是良好的代码风格

  • 每个人的审美不同,你觉得你的代码很好看,但是别人不一定。
  • 代码是用来展现编程思想的,其风格并不完全按照美丑评判,更重要的是如何最大程度上减少代码本身对传递编程思想带来的阻力(用人话来说就是让自己和别人更好理解),也就是增强可读性。
  • 所以说,良好的代码风格是一种大家公认的兼顾美观可读性的 coding 习惯。

为什么要有良好的代码风格

可读性强

一份整洁规范的代码不仅能够 愉悦心情 也能给自己或他人带来良好的 review 体验。

  • 省流:不好看的代码学长学姐不给 de

  • 目前大家写的程序最多也就几十行,未来我们可能接触到成百上千的代码源文件,如果代码风格很乱,会给理解代码带来不必要的难度。

例如以下两种情况,显然第二种分析起来更加清晰。

第一种

1
if(a==1){if(b==2){if(c==3)i++;}else j++;}

第二种

1
2
3
4
5
6
7
if(a==1){
if(b==2){
if(c==3) i++;
}else{
j++;
}
}

可维护性强

风格良好且统一的代码可以增强代码的可维护性。

  • 还是上面两种情况,如果我想在给if(c==3) 添加else 分支,很显然第二种风格实现起来更加容易(这就是可维护性)
出错概率低

良好的代码风格可以最大可能规避某些意想不到的错误。

例如以下两种代码

第一种

1
2
3
if(a==0){
b++;
}

第二种

1
2
if(a==0)
b++;

这表面上看只是控制 单条换行代码if 语句是否加大括号而已,但是如果我想再让if语句多控制一条代码 c--;,对于第一种大家显而易见会 下意识 加在大括号里;但是第二种情况就可能直接在b++;后换行,直接写上c--;,忘了添加大括号,这就会带来意外的逻辑问题。(你可能会想:“我怎么会傻到不加大括号???” 哼哼,等你真遇到了你就笑不出来了)

如何养成一个好的代码风格

强迫自己改成以下写代码的风格,慢慢就习惯了。

  • 每逢; 必换行
  • 给变量起个好名字

    • 变量起名最好用英文比如number ,count, answer,temp

      或者简写(一般是只留辅音):num,cnt,ans,tmp

    • 尽量避免用拼音

    • 较长的名字可用下划线隔开,或采用驼峰命名法(第二个单词起第一个字母大写)

      下划线: num_of_students

      驼峰法:numOfStudents

    • 变量起名切忌英文字母遍历(当然如果题目中有用字母表示,那你可以用对应字母命名)

      比如a,b,c,aa,ii.abc等,你也不想让别人管你叫 “二狗子” 吧(如果你真叫这名那我先道个歉)

    • for循环变量从i 开始往后命名

      比如i,j,k,l,m … (感兴趣的同学可以查一下为什么从i开始)

  • 左大括号{ 可换行可不换行

例如(循环也一样)

1
2
3
4
5
6
7
8
9
if(a==0){
//第一句
}
//或者
if(b==0)
{
//第一句
}
//以上两者均可,本人喜欢第一种(不喜勿喷)
  • 进入大括号内必缩进,大括号内语句左对齐

例如(循环也一样)

1
2
3
4
5
6
7
if(a==0){
//此处要缩进,一般而言为一个'Tab'键(大部分编辑器都是4个空格宽度)
if(b==0){
//此处要缩进
//与上一行在同一大括号内,左对齐
}
}
  • else 语句可跟在右大括号}后,或者重新换行

例如

1
2
3
4
5
6
7
8
9
10
11
12
13
if(){
//balabala
}else{
//balabala
}
//或者
if(){
//balabala
}
else{
//balabala
}
//以上两者均可,本人喜欢第一种(不喜勿喷)
  • else if 连行写,或者用大括号{}else里套if

例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if(a==0){

}else if(a==1){

}
//或者
if(a==0){

}else{
if(b==0){

}
}
//以上两个均可,类似于switch的情况时可以用第一个;判断情况较为复杂时可以用第二个
  • 控制一个语句的ifelse分支要么同行不换行 要么换行加大括号

例如(循环也一样)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if(a==0) c++;
else d++;
// 或者
if(a==0){
c++;
}else{
d++;
}
//以上两种均可,本人两个都用
//-------------------我是分割线-----------------
//最好不要这样写(见下)
if(a==0)
c++;
else
d++;
//虽然有人这么干,但本人觉得容易出错,比如上一部分的第3点的情况
  • 不同语义群之间的代码可以用空行隔开(高阶要求)

例如

1
2
3
4
5
6
7
8
9
10
11
//语义1
//语义1
//语义1

int tmp = a; //语义2 交换变量
a = b; //语义2 交换变量
b = tmp; //语义2 交换变量

//语义3
//语义3
//语义3
  • 计算表达式合理地用空格隔开(高阶要求)

例如

1
2
3
a=b*c+d;
//可以优化为
a = b*c + d;
  • 学会加注释
    • 加注释可不只是为了方便别人读代码,也是为了方便自己以后读代码(你信不信等过上一个星期你再看你的代码你就看不懂了)
    • 加注释可以按照自己的习惯,表意清晰即可。比如说,变量的注释可以用// 在定义变量的地方说明变量的用途;函数的注释可以用多行注释\**\放在函数体的开头,来说明函数的用途、参数范围、返回值等…
  • 其它能够让你的代码更加 pretty 的小细节…

debug 指南

大家刚开始学习C语言难免遇到些无法解决的问题,debug 是常有的事。

自己debug

下面给出一些初学者 debug 的常用方法:

  • 通篇阅读,用纸和笔模拟代码的运行过程
  • 逛逛 CSDN 、 Stack Overflow 等社区,或者问度娘
  • 了解自己所用 IDE 的调试方法,学会调试程序
  • 在程序对应位置加上 printf 语句,打印变量信息
  • 把自己的代码粘给 GPT ,找 GPT debug (GPT 不一定可信,仅作参考)
  • 自己出一些简单的输入输出样例,看看自己程序的结果
  • 再仔细读一遍题目
  • 看看有没有自己忽略的 warning
  • 先干点其他事情,说不定突然就灵光一现了呢

找学长学姐(或其他同学) debug

  • 在看下面的内容前,请举起右拳面向 Dennis Ritchie (C语言之父)的照片庄严宣誓:

    C语言之父

    我宣誓:

    ​ 有了 bug 一定先自己思考,努力靠自己解决问题,实在无法解决再请学长学姐(或其他同学)帮忙,学长学姐(或其他同学)不便时绝不强求,绝不向学长学姐(或其他同学)直接要代码。

    ​ 请教前,确保自己认真读过题目,了解题目中各个条件;

    ​ 请教时,要把问题说清楚、点明白,讲清自己不明白的地方以及尝试过的方法,必要时提供样例输入输出和自己的结果,学长学姐(或其他同学)没回复时绝不催促;

    ​ 请教后,感谢学长学姐(或其他同学)的倾情付出,努力做到不犯第二次错。

    若有违,WA 相随!

    ​ 宣誓人:XXX

找他人 debug 就难免会有线上沟通的情况了,此时应该做到以下几点:

  • 尽量不发语音,要打字
  • 较短的代码可以发截图(windows 快捷键 shift + win + S ,不要用手机拍
  • 较长的代码可以发源文件,或者学会使用 https://pastebin.ubuntu.com/
  • 讲礼貌,懂文明,尊重他人,不要让自己 debug 过程中的戾气扩散

Others

  • Think twice , code once.

    • 编程的绝大部分时间不应该放在写代码的环节,而应该放在构思代码的环节

      尝试在真正下手写代码前,先在大脑里想一想我要怎样设计我的算法、怎样不重不漏考虑到所有情况、我需要用到哪些变量或函数有哪些容易出错的地方

      前期设计好程序以后,后期出现 bug 的可能性就会远远降低(相信大家也体会到了什么叫 “编程 5 分钟,debug 两小时” 了吧)

  • 什么是程序员?什么是码农?

    • 私以为:程序员相比码农更具有编程思维和算法能力。程序员就好比一栋大厦的设计者,需要对自己的建筑进行最优的设计,比如说,怎么减少用料(代码量),怎么提高建筑的稳固性(增强程序可靠性与安全性),怎么缩短工时(代码执行效率),怎样在实现原有功能的基础上减少占地面积(内存空间占用)等等。最终由程序员出一份设计方案,交付给码农去实现。码农就好比一线的工人,拿到设计图后只负责按照图纸把代码敲出来。

    • 编程最重要的是思想 。因此当学长学姐告诉你,你的代码哪些地方思路逻辑有问题,其实就是在教会你思想。所以说,当你知道你的代码哪些地方有 bug 的时候,你已经获得了那张 “图纸” ,那就请按照图纸自己想办法实现,也就是说,不要和学长学姐要代码, 不仅对自己的提升没有帮助,也会浪费他人的时间(如果连做码农的环节都不愿意,就不要想着说成为程序员了)。

  • 学会画流程图 or 写伪代码

    • 这里当然不是要求你真正画出来一个流程图或者写一份完整代码出来,只是说在构思代码框架的时候,可以用一些简单的语言说明每一步要干什么,比如下面的东西:
1
2
3
4
5
6
7
8
9
//实现非负整数的阶乘:
1. 判断整数 a 是否为 0
若是,直接返回1
2. 令 ans = 1
3. ans = ans * a
4. a = a - 1
5. 判断 a 是否为 0
若是,直接返回ans
若不是,重复3~5

To be continued …