撸代码时,有哪些习惯一定要坚持?

news2024/11/16 0:55:58

我从2011年开始做单片机开发,一直保持以下撸代码的习惯。

1.做好代码版本管理

有些人,喜欢一个程序干到底,直到实现全部的产品功能,我以前做51单片机的项目就是这样。

如果功能比较多的产品,我不建议这样做,迟早有一天,有一个项目,会让你崩溃的,特别是还不具备模块化编程能力的时候

之前我就踩过几次这种坑,一个程序版本实现了很多个功能,后面新增功能的时候,突然发现了一个BUG,怎么都调不出来。

这时候,如果有上一个版本,可以用上一个版本的代码,一点点代码复制过去看看,到底是哪个代码造成的。

从那次以后,我就养成了做代码版本管理的习惯,比如V1.0,V1.1,V1.2.....

然后每个程序版本里面,我都会写一个文档,描述下历史版本实现的功能记录,以防后面忘了。

2.多学习优秀的代码和思维

刚工作那会,主要用STC的51单片机做项目,主要维护之前工程师遗留的代码,升级产品功能为主,基本是一堆屎山代码,实现功能就行了。

不会考虑怎么把代码写得更好,主要是自己当时也没那能力,项目又急,能改出来应付工作就不错了,有时项目急,我逻辑又理不清,甚至用了goto语句走了捷径,可能很多人都没见过。

工作了几年,一直是维持在这种水平,没有提升,因为接触不到更复杂的项目,接触不到好的编程思维和代码。

后面跳槽到一家公司,接收了一个网关项目,需要自己从0到1,完成整个项目的代码。

这个项目难度,已经超过了我的知识范围,主要有两个问题:

第一,很多功能没做过,不知道啥原理

第二,功能太多了,不知道怎么很好地把它们整合协调起来。

我是怎么解决这两个问题的呢?

第一个问题,最快的方式就是问同部门的研发同事。

不过不要指望别人会手把手教你,哪怕领导发话,别人也没这义务。

最关键的,不是指望让领导去给他下发命令,就能让他带你,而是看自己懂不懂得做人的。

举个例子:有些老铁来找我领单片机入门到高级的教程+工具包,我都是无套路直接发链接。

为什么要在我的朋友圈才发?

因为我是卖课佬,我觉得我们的项目课确实能帮到一些人,成就一些人,万一哪天你需要,我们又正好专业,各取所需共赢,我觉得没毛病。

但,我也深知,要让别人认可你,那就先贡献价值出来,所以我就不断输出自己经验和送粉丝教程+工具包了。

我感觉人和人之间,挺有意思,也差别挺大。

有些人很懂得感恩,还会给我发个小惊喜,收不收看我有没有给到他对应的价值了。

有些人,趾高气昂,理所当然,像我欠了他的一样。

我就想,怎么会有这种傻杯,然后拉黑了。

扯远了。

回到找同事帮忙的问题,也是同理,你得付出相应的价值,得请吃饭、得请喝奶茶、帮的忙多了得送礼....这不是潜规则,是对别人起码的尊重。

不能因为领导发话了,叫他去带你,你就能像个伸手党一样,一直索取他的价值,不信?你试试多问几个问题以后,看他鸟不鸟你。

第二个问题,功能太多了,不知道怎么很好地把它们整合协调起来。

这个其实最难,因为涉及到程序架构的问题,不是某个功能点,更多的是经验积累到一定程度后,再学习别人优秀的程序架构,突然开悟了。

我是参考别人工程师写的代码,一点点积累起来的,然后根据时间片轮询原理,设计了一个程序架构,我在2019年也录过这个程序架构的教程。

老规矩,有礼貌的粉丝,可以找我安排。

编程思维、高阶代码技巧、程序架构这些,如果能冲我们无际单片机项目特训营,系统把我们几个项目做完,那直接就是走捷径了,都是我们踩坑10年以上总结出来的精华。

3.重视模块化

我第一次重视程序模块化,项目代码量编译完大概70kb+。

什么是模块化?

举个例子,以下两段代码,分别是非模块化写法和模块化写法:

非模块化写法:

C
#include <reg51.h> // 假设是51单片机

void main() {
    //
硬件初始化
    P1 = 0xFF; // 设置P1口为输入
    IT0 = 1;    // 设置外部中断0为下降沿触发
    EX0 = 1;    // 使能外部中断0
    EA = 1;     // 开启全局中断

    // 主循环
    while(1) {
        //
功能实现
        if(P1_0 == 0) {
            P1 = ~P1; //
如果P1.0被按下,翻转P1口的状态
        }
    }
}

//
外部中断0服务程序
void exint0() interrupt 0 {
    //
中断处理
    P1 = P1 << 1; // 每次中断,将P1口的值左移一位
}

在这个例子中,硬件初始化、主循环和中断服务程序都混合在同一个.c文件中,阅读和维护起来会困难很多,特别是后期随着代码越来越多。

模块化写法:

C
// hardware.h
#ifndef HARDWARE_H
#define HARDWARE_H

void init_hardware();

#endif

// hardware.c
#include "hardware.h"

void init_hardware() {
    P1 = 0xFF; //
设置P1口为输入
    IT0 = 1;    // 设置外部中断0为下降沿触发
    EX0 = 1;    // 使能外部中断0
    EA = 1;     // 开启全局中断
}

// main.c
#include "hardware.h"
#include <reg51.h>

void main() {
    init_hardware(); // 初始化硬件

    while(1) {
        // 主循环功能实现
        if(P1_0 == 0) {
            P1 = ~P1; // 如果P1.0被按下,翻转P1口的状态
        }
    }
}

// exint0.c
#include <reg51.h>

// 外部中断0服务程序
void exint0() interrupt 0 {
    // 中断处理
    P1 = P1 << 1; // 每次中断,将P1口的值左移一位
}

在这个模块化的例子中,我们将硬件初始化放到了hardware.c和hardware.h中,主循环放在main.c中,而中断服务程序放在exint0.c中。这样,每个文件都有一个明确的作用,代码的结构更加清晰,也更好阅读和维护。

稍微复杂点的单片机项目,需要处理很多硬件接口和复杂的时序逻辑,还有各种产品业务逻辑组合,所以模块化尤其重要。

上面只是举了两个入门级模块化写法,高阶的模块化,远不止这些,首先是程序文件架构的模块化,分硬件层、中间层、应用层。

怎么实现多层之间依赖最少,这样后期万一需要更换单片机,只需要修改硬件层驱动代码就好了。

然后是里面每个功能模块化,怎么写方便后期增减功能。

这些其实都是系统的学问,所到之处全是细节,我们无际单片机特训营,都是通过这些思维和编程方式做的,特别是项目3和6。

提升这块的能力,主动学习意识和机遇都很重要,有些工程师做了4,5年,如果公司一直做简单的项目,那也是提升不了的,需要自己通过业余的时间,不断看别人代码摸索。

4.有条件,换个好点的椅子

撸代码的,长时间对电脑,经常一坐就是几个小时,好点的椅子能缓解颈椎、腰椎的疲劳。如果能换个立式办公桌就更好了。

5.不要做一个看完不点赞的冷漠青年

不知不觉,又写了两个多小时,原创不易,发财小手点起来...


最近很多粉丝问我单片机怎么学,我根据自己从业十年经验,累积耗时一个月,精心整理一份「单

片机最佳学习路径+单片机入门到高级教程+工具包」全部无偿分享给铁粉!!!

除此以外,再含泪分享我压箱底的22个热门开源项目,包含源码+原理图+PCB+说明文档,让你迅速进阶成高手

教程资料包和详细的学习路径可以看我下面这篇文章的开头

《单片机入门到高级开挂学习路径(附教程+工具)》

《单片机入门到高级开挂学习路径(附教程+工具)》

《单片机入门到高级开挂学习路径(附教程+工具)》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1574375.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

编译原理实验2(自上而下语法分析)

一、实验目的 给出 PL/0 文法规范&#xff0c;要求编写 PL/0 语言的语法分析程序。通过设计、编制、调试一个典型的自上而下语法分析程序&#xff0c;实现对词法分析程序所提供的单词序列进行语法检查和结构分析&#xff0c;进一步掌握常用的语法分析方法。选择有代表性的语法…

一款轻量、干净的 Vue 后台管理框架

开始之前 在开始介绍之前我想谈谈为什么要自己做一个后台管理&#xff0c;我知道很多人都用一些开源的后台管理项目&#xff0c;这些老前辈有很多亮点值得学习&#xff0c;但是存在的一些问题同样不可忽视&#xff0c;我认为很多开发者会被困扰(仅代表个人观点) 技术栈老旧不升…

面试(03)————多线程和线程池

一、多线程 1、什么是线程?线程和进程的区别? 2、创建线程有几种方式 &#xff1f; 3、Runnable 和 Callable 的区别&#xff1f; 4、如何启动一个新线程、调用 start 和 run 方法的区别&#xff1f; 5、线程有哪几种状态以及各种状态之间的转换&#xff1f; 6、线程…

Docker容器与虚拟化技术:OpenEuler 部署 ES 与 Kibana

目录 一、实验 1.环境 2.OpenEuler 部署 ES (EalasticSearch) 3.OpenEuler 部署 Kibana 4.部署 Elasticvue插件 5.使用cpolar内网穿透 6.使用Elasticvue 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 系统架构版本IP备注LinuxopenEuler22.03 LTS SP2 1…

flex布局align-items和align-content、justfiy-content的区别

justfiy-content&#xff1a;定义主轴的对齐方式align-items&#xff1a;定义交叉轴的对齐方式align-content&#xff1a;将flex子项作为一个整体起作用 只在两种情况下有效果&#xff1a; ①子项多行且flex容器高度固定 ②子项单行&#xff0c;flex容器高度固定且设置了fle…

Mac安装配置Appium

一、安装 nodejs 与 npm 安装方式与 windows 类似 &#xff0c;官网下载对应的 mac 版本的安装包&#xff0c;双击即可安装&#xff0c;无须配置环境变量。官方下载地址&#xff1a;https://nodejs.org/en/download/ 二、安装 appium Appium 分为两个版本&#xff0c;一个是…

HarmonyOS实战开发-屏幕属性(仅对系统应用开放)

介绍 本示例主要展示了屏幕管理相关的功能&#xff0c;使用ohos.display、ohos.screen接口&#xff0c;ohos.display接口提供获取默认display对象、获取所有display对象&#xff0c;开启监听、关闭监听功能&#xff1b;ohos.screen接口提供创建虚拟屏幕、销毁虚拟屏幕、扩展屏…

LeetCode-热题100:118. 杨辉三角

题目描述 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2: 输入: numRows 1 输出: [[1]]…

什么软件可以保密公司文件?

#天锐绿盾# 天锐绿盾是一款专为企业设计的文件加密与数据防泄密软件&#xff0c;旨在通过一系列高级安全功能来保护公司的敏感信息和重要文件不被未经授权的访问、窃取或泄露。 PC地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfe…

蓝奏云直链获取在线解析网站源码

源码简介 蓝奏云直链获取在线解析网站源码 蓝奏云链接解析 本地API接口 支持有无密码和短期直链和永久直链&#xff0c;同时还可以显示文件名和大小。 这个解析器无需数据库即可搭建&#xff0c;API接口已经本地化&#xff0c;非常简单易用。 安装环境 php5.6 搭建教程 …

HTML - 你如何使H5页面禁止手动缩放

难度级别:初级及以上 提问概率:40% 我们知道,这道题其实是在考察meta标签的viewport属性,正常情况下设置viewport的代码为 <head><meta name="viewport" content="width=device-width,initial-scale=1.0" …

全网最详细的网络安全自学笔记

1.选择方向 首先是选择方向的问题&#xff0c;网络安全是一个很宽泛的专业&#xff0c;包含的方向特别多。比如 web安全&#xff0c;系统安全&#xff0c;无线安全&#xff0c;二进制安全&#xff0c;运维安全&#xff0c;渗透测试&#xff0c;软件安全&#xff0c;IOT安全&am…

【运输层】网络数据报协议 UDP

目录 1、UDP 的特点 2、UDP 的首部格式 UDP 只在 IP 协议之上增加了很少的一些功能&#xff0c;比如复用、分用以及差错检测等。 1、UDP 的特点 UDP是无连接的&#xff0c;即发送数据之前不需要建立连接&#xff0c;因此减少了开销和发送数据之前的时延。 UDP使用尽最大努力…

python函数练习2

找出10000以内能被5或6整除&#xff0c;但不能被两者同时整除的数&#xff08;函数&#xff09; def func():for i in range(1,50):if (i % 5 0 or i % 6 0 ):if i % 5 0 and i % 6 0:continue #利用continue跳过能被5和6整除的数print(i) func()写一个方法&#xff0c;计算…

Windbg查看函数调用过程中的内存布局

我们在分析问题的时候经常会需要查看进程的栈和帧中的值&#xff0c;下面我们就用一个简单的例子来分析一下这个过程。 源代码&#xff1a; #include <iostream> int add(int a, int b) {return a b; }int main() {int a, b;a 3;b 4;int ret add(a, b);std::cout &…

【Python】快速排序法 Leetcode 148. 排序链表

题目 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4] 代码 第一次使用朴素快速排序&#xff0c;基准值为头节点值&#xff0c;居然超时了&#xff0c;然后…

pymilvus创建IVF_FLAT向量索引

索引简介 索引的作用是加速大型数据集上的查询。 目前&#xff0c;向量字段仅支持一种索引类型&#xff0c;即只能创建一个索引。 milvus支持的向量索引类型大部分使用近似最近邻搜索算法(ANNS,approximate nearest neighbors search) 。ANNS 的核心思想不再局限于返回最准确…

什么是数据治理?你都了解吗?

在当今数字化时代&#xff0c;数据已成为企业重要的战略资产。有效管理数据对于企业提高运营效率、降低成本、做出更好的决策至关重要。数据治理作为一种重要的管理方法&#xff0c;可以帮助企业确保数据的质量、安全、合规性和有效利用。 一、数据治理的定义与重要性 近日&a…

2024.4.6-day11-CSS 背景和精灵图

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 作业2024.4.6学习笔记1 背景2 背景图片3 CSS 精灵图 作业 <!DOCTYPE html&…

C语言初阶—9函数

函数的声明 &#xff08;main函数前&#xff09;----告诉有一个函数 格式&#xff1a; 类型 函数名&#xff08;参数&#xff09;&#xff1b; 函数的声明 放到头文件add.c 函数的定义 ----创建函数----放到add.c 格式&#xff1a;类型 函数名(参数) { 语句项; } 在文…