编程习惯与思想
前置
参考自: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
相关完整内容请访问该网址
养成良好的代码风格
做好代码缩进
不要滥用临时变量
一般而言,循环内最多同时使用多少个临时变量、我们就开多少个临时变量。通常不会超过 3 个(仅指用作指示下标的那些),也就是 i, j,k ,否则我们会考虑将内层循环包装成函数(具体详见下文),嵌套层数过多的循环也会极大地降低代码可读性
不要滥用 switch/case
- 当你需要使用多个重复性极强的 case 语句时,就应当思考其逻辑关联性,并对代码进行简化
- 写代码时要注意思考,只能用 case 或 if 大量穷举而没有任何办法精简代码的情形较为苛刻,至少初学者是遇不到的
使用语义明确的标识符名称
- 应当养成习惯,在给变量、函数或是自定义符合类型起名时,使用语义明确的名称。
使用统一的命名习惯
- 下划线命名法
- 驼峰命名法
- 只要命名统一,使用何种命名习惯并不重要
- 如果你需要进行团队合作,那么除了编程语言的习俗,更应当注重与你的团队保持相同的命名习惯
使用统一的大括号换行习惯
// 习惯 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); } }勤加注释
- 如输入、求解、初始化、对 xx 遍历每个 xx、对某一条件进行 xx、输出 等注释字眼。
善用函数与结构体
善用函数
- 当代码量多到一定程度时,把所有的代码都放在 main 函数里显然是不切实际的,因此你需要学会善用函数,尽可能地将功能不同的代码分别包装,不要把大量的代码塞在同一个函数里
- 好处:1、其一是可读性的提升;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];
在布尔表达式中勤加括号
避免对同一数据存放多个无关副本
对于同一份数据,我们应当尽量只存放一个副本。例如:
#define N 1000000 int data[N], id[N], sum[N], son[2][N]; double value[N];处理简单的错误输入
养成良好的编程习惯
关注变量初始化
养成习惯:对于任何一个新添加的变量,总是关注它是否有被合法地初始化。
关注问题的边界条件
养成习惯:在解决问题、实现接口或函数时,总是关注边界条件。
写循环时关注下标越界
养成习惯:当你在循环中使用间接的下标时,总是关注下标越界问题。例如你在一个 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 的调试工具进行调试,观测和追踪程序运行的过程;
- 利用输出流获取中间结果,并据此思考找到程序中的错误。