硬件设计师最常见的工作内容是通过写代码来测试硬件。这10个C语言技巧(C语言仍然是常见的选择)可以帮助设计师避免因基础性错误而导致某些缺陷的产生并造成维护方面的困扰。

为了成功的推出一个产品,软件开发过程本身需要经历无数的实践风险和障碍。任何工程师最不希望的事情就是因所使用语言或工具而带来的挑战。因此,这就需要硬件设计师编写代码来测试硬件的工作状况,在资源受限的情况下,还需要开发硬件和嵌入式软件。尽管工具和结构化编程已经有了很大进展,但通常选择的仍然是C语言,基础性错误的不断发生,仍会导致某些缺陷的产生并造成维护方面的困扰。为竭力避免这些C编程陷阱,这里有10个C语言技巧供硬件工程师参考。

技巧1:不要使用“GOTO”语句

二十几年前,当计算机编程尚处于起步阶段时,程序流程是由“GOTO”语句来控制。该类语句允许程序员对当前代码行断行,而直接进入另一个不同的代码段。列表1为简单的示例。

列表1 使用GOTO语句

编程语言终究开始引入了函数的概念,即允许程序对代码进行断行。如果已经完成,不再使用goto语句来表示代码的断行。函数调用后,函数将回到下一条指令。列表2为示例。这一做法改善了程序结构,提高了可读性。自此,这被视为编写程序的正确方法。只要看到或想到goto语句,就会让软件工程师退缩,产生本能的厌恶。其中一个主要的原因是,一个遍布goto语句的程序会让让人很难抓住重心,不便于对程序的理解和维护。

列表2 用函数控制流程

技巧2:使用FOR(;;)或While(1)

如果goto语句已经过时,那么对程序创建无限循环应该如何去做呢,这是一些硬件工程师可能会疑惑的问题。毕竟,之前都是通过创建一个goto语句然后再返回到main语句。解决这一问题就要利用C语言中已经存在的循环语句for和while(列表3和4)。

列表3 使用一个无限的For循环

列表4 使用一个无限的While循环

列表中的循环条件相对比较简单。for循环无非是以无条件情况使用条件语句。而另一方面,while循环是语句为真即予执行,这等同对任何条件的非零值。

技巧3:使用合适的条件语句

除代码的可读性之外,程序的执行时间还主要依赖于做决定时所选择的条件结构类型。许多硬件工程师都熟悉简单的if语句的使用。然而,有时工程师可能没有意识到,如果第一个条件不正确,还可以使用else或else if语句。这可以节省处理器时间,而不必评估另一个条件语句。在列表5所示的前半部分代码中,如果Var值为1,则代码仍会查看Var是否为0。而在用了else语句的后半部分代码中,只评估第一个语句,之后就继续走下面的代码,这样就节省了时钟周期,使代码更加清晰。

列表5 用If/Else替代只用If

If/else if/else语句可能并不永远适用。如果需要检查若干个可能的条件,switch语句可能更合适。这样,处理器可以评估语句,然后从一个答案列表中选择下一步动作,而不用连续地评估一堆条件。列表6显示的例子与列表5示例的类型相同。

列表6 使用Switch语句

以上示例的寓意是,让条件语句的选择更开放,以选择出最适合的语句。这种做法使程序结构更简单,便于理解程序流程,缩短处理器的额外时钟周期。

技巧4:避免使用汇编语言

微处理器的自然语言为汇编语言指令。为低级别机器语言编程可能会为处理器提供更高效的代码。然而,人类并不是天生就会这种语言,并且经验表明,编写汇编语言会造成误解。误解会导致维护不当,更甚者,可能会使系统到处是bug.一般建议避免使用汇编语言。实际上,现在大多数编译器都能编译出非常高效的代码。采用C语言或C++语言等高级语言的开发,能获得更有序的结构,便于理解和维护,使代码的整体效果更好。列表7给出了一个示例,比较了使一个32位变量递增所使用的汇编代码和C语言代码。

列表7 用汇编和C语言完成一个变量的递增

汇编

C代码

当然,现在仍有一些场合适于使用汇编语言,但这种场合仍比较少。首个推荐的场合是开发引导装载程序。这种情况下,可能需要优化对启动过程中某个决策(启动应用或引导加载器)的速度。此时,分支判定用汇编代码就可能有意义了。另一种场合是开发一种在DSP上运行有严格时序要求的控制循环。为了从设备中的得到每个时钟周期,用汇编语言做控制循环的编码是有意义的。如果目前任务适合用汇编,应确保将其妥善存档便于有据可查,这样,未来的开发者(或未来的版本)会明白该代码的用途。

技巧5:充分利用模块化

笔者最常见的经历是着手由硬件工程师开启的一个新项目往往是杂乱无章的代码组织。通常我们会发现,代码由一个单一的主模块组成,其中有2.5万多行代码。在这些应用中,一切都是全局性的,函数寥寥无几,goto语句贯穿整个代码结构。15年前这算正常,但如今已不再适用了!C语言编程使工程师能够将代码分成独立的功能模块,这简化了代码导航,同时还能够使工程师使用封装等面向对象技术。代码可以被组织成逻辑模块,这很有意义。虽然可能要先花点时间(几分钟),但从长远来看,这将能省掉很多漫长之夜,和很多调试之苦!

技巧6:写千层饼式代码而非面条式代码

Beningo是一个意大利名字,和许多意大利人一样,我对意大利面食也是毫无保留地热爱。当拿意大利面食与软件相比时,我就会想到两种面食,即意大利面条和千层饼。意大利面条比较混乱,面条相互交织,纵横交错,结果完全没有任何类型的结构。编写非结构化代码就非常像意大利面条:咬一口,完全不知道吃的是哪部分。

另一种就是意大利千层饼!这种面食是分层的,是有结构的。分层开发的代码不仅更容易理解,还可以移走一层并添加一个新层,基本上能够实现重复使用和维护的简易性。图1为用千层饼式代码模型的一个简单软件模块示例。

图1 千层饼软件 模型

  驱动程序配置

  应用程序配置

  应用程序

  驱动程序库

  硬件

技巧7:使用描述式变量名称

编写易于理解和维护的较大软件有许多障碍,其中之一就是变量的命名习惯。为了尽力缩短变量名,开发者通常会自创一些较短的、令人费解的助记符,往往只有他们自己才能明白的符号。现代语言使一个变量名可以包含数百个字符。为了让事情清晰明确,“直截了当”地方法要好于其它方式。因此,变量名一目了然不仅有利于开发人员,也有利于未来的维护团队。列表8给出一个示例。

列表8 变量的命名

技巧8:少用#pragma语句

C语言中有一种特殊的#pragma语句。这些语句通常处理非标准的句法和特性,应尽可能避免使用这种语句,因为它们是非标准的,不能从一个处理器移植到另一个处理器。有些编译器可能要求用这类语句完成某项任务,例如定义一个中断服务程序。在这种情况下,可能除了使用#pragma语句以外别无它法。如果可能,将所有的#pragma语句放在一个模块或几个模块里。这有助于确保在代码移植时,只需要更新几处代码,而非整个代码库;此外,这也将有助于防止移植代码的首次编译所带来的困扰。

技巧9:错误往往并不是看上去那样简单

在调试一个C程序时,有一个让人当心的陷阱就是编译器错误。由于编译器的复杂性,当检测到一个错误时,通常错误位于程序中的其它地方,而非编译器所指示的位置。这主要与编译器生成程序的步骤有关。错误类型通常是一致的,工程师可以发现的一些错误中,90%都是根源:

*当心漏掉#include文件。这可能会使程序开发人员看到完美的代码行,但由于未包含必要的头文件,编译器便会将其标志为一个错误,表示有些东西未定义。

*当心漏掉分号。编写C代码时最常见的错误是忘记在句末加分号。

*当心漏掉括号。漏写括号是代码编写过程中又一常犯的错误,或是粗心漏掉,或是由于键入错误而产生一个错误字符。

*当心漏掉逗号。在复杂的定义中很容易忘记逗号!

一般情况下,当弹出一个奇怪的编译错误对话框时,要查看该行前已被编译的内容。很有可能就是错误所在!它可能是出现在一行上面,或中间部分,或在完全不同的文件里。

不要放弃!只要具备一定的经验,解决这些疑难问题就会成为一种第二天性。

技巧10:优秀的程序员编写的代码行数不一定少

人们常有这种误解,即认为较一般的程序员而言,一个优秀的程序员往往写较少的代码行就能解决问题。不要卷入这一错误的想法!一个优秀的程序员通常具备思维缜密、结构清晰的编码基础。变量命名和封装都恰如其分,系统中几乎不用全局变量。函数应保持简短有效。如果代码看起来很混乱,需要多写几行才能使其看上去更清晰,那就不妨多写几行!可以上网查看获得C代码编写最混乱殊荣奖项的代码用作前车之鉴。优秀程序员写的代码简洁、易于理解和维护,代码行数并非最少(图2)!

图2 简短程序

后台回复"技术关键词",即可领取几百G:"学习资料包"(已有167个关键词,如:电源、电机、嵌入式、信号系统、模电、华为、电子学、电路、c语言...),

扫码关注@面包板社区
每天学点电子技术

#推荐阅读#

  • 0欧电阻、电感、磁珠单点接地时有什么区别?

  • 闲来无事,拆个示波器玩玩

  • 汽车电源为何抛弃“12V”选择“48V”?

  • 牛人!5个I/O口,设置25个按键

  • 0.1μF电容不是想用就能用的

  • 各种“地”—— 各种“GND”

  • 工程师必备:硬件EMC设计规范

点阅读原文,下载《Python基础教程(第2版)》

c语言goto语句用法_硬件工程师必知的10个C语言技巧相关推荐

  1. c语言goto语句用法_C语言中的goto语句该不该使用?

    关于C语言的goto语句存在很多争议,很多书籍都建议"谨慎使用,或者根本不用".这里先不做过多的讨论,存在即合理,既然是C语言中的一个知识点,我们还是有必要学会使用.先看一些got ...

  2. c语言goto语句用法_C语言的9种控制结构

    点击蓝字关注我哦 C语言语句 goto语句:无条件转向; if语句:判断语句;while循环语句; do-while语句:先执行循环体,然后判断循环条件是否成立. 之后继续循环;for语句:循环,可替 ...

  3. 单片机c语言goto语句用法,goto语句的使用

    C语言提供了可随意使用的goto语句以及标记跳转位置的标号.从理论上来说goto语句是没有必要的,但是在某些情况下goto语句还是用的着的,最常见的就是终止程序在某些深度嵌套的结构中处理过程,比如跳出 ...

  4. 李洪超 硬件工程师_硬件工程师必阅--如何“0基础”从入门到精通?(附CAD使用指南)...

    作为一个好的硬件工程师实际上就是一个项目经理,你需要从外界交流获取对自己设计的需求,然后汇总,分析成具体的硬件实现.那么需要哪些具体的技能呢? 掌握硬件总体设计所必须具备的硬件设计经验与设计思路 1) ...

  5. 20种硬件工程师必知必会基础元器件|最新更新至8.13

    ** 如有错误,感谢指正** 如有错误,感谢指正,请私信博主,有辛苦红包,拜"一字之师". 请根据目录寻找自己需要的段落 本章知识为硬件工程师基础课程之基本元器件 首先我们需要知道 ...

  6. 程序员必知的10个C语言技巧

    点击蓝字 关注我们 硬件设计师最常见的工作内容,就是通过写代码来测试硬件.这10个C语言技巧(C语言仍然是常见的选择)可以帮助设计师避免因基础性错误而导致某些缺陷的产生,并造成维护方面的困扰. 为了成 ...

  7. c语言goto语句用法_C语言32个关键字9种控制语句34种运算符整理

    相信这么努力的你 已经星标了我 老九学堂 你身边的IT导师 32个关键字,如下表所示: 关键字 说明 auto 声明自动变量 short 声明短整型变量或函数 int 声明整型变量或函数 long 声 ...

  8. dos命令行设置网络优先级_网络工程师必知的Linux命令,精品!

    Linux命令是对Linux系统进行管理的命令.对于Linux系统来说,无论是中央处理器.内存.磁盘驱动器.键盘.鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心. 线上查询及帮助 ...

  9. 网络工程师常备工具_网络安全工程师应该知道的10种工具

    网络工程师常备工具 If you're a penetration tester, there are numerous tools you can use to help you accomplis ...

最新文章

  1. js 判断一个元素是否存在
  2. Atitit main函数的ast分析  数组参数调用的ast astview解析
  3. python在哪里写代码比较适合-程序员面试被要求手写代码,你与顶级程序员的差别在哪?...
  4. 影响软件测试未来的5件事 (译)
  5. AlphaGo之父哈萨比斯: 先解决智能 再用智能解决一切
  6. VR来了,3D人脸重建跟上《三维人脸重建-3DMM》
  7. 互联网内容平台到底要用到多少AI技术?
  8. Bootstrap3 栅格系统-栅格参数
  9. mysql子分区多少层_MYSQL子分区修剪
  10. mqtt协议详解_IoT物联网设备上云技术方案详解
  11. 你不懂js系列学习笔记-类型与文法- 02
  12. week06 12 我们准备数据 前端调用rpc 前后端联调一下
  13. 25.摘要认证(2)
  14. 基于UDP的文件传输软件 (C#)
  15. 微信小程序服务器配置https站点
  16. 般若波罗蜜多心经(观音心经)注解
  17. python 三角函数计算
  18. 星际争霸2Beta测试版单机模式已经破解
  19. ANSYS FLUENT——最基本操作(以一个简单的案例为例)
  20. 方差分析(ANOVA)分类、应用举例及matlab代码

热门文章

  1. onmounted vue3_基于项目时间阐述vue3.0新型状态管理和逻辑复用方式
  2. 一线城市数据分析师的薪资分布......
  3. SAP UI5 应用开发教程之四十八 - 如何在 SAP UI5 应用里开发条形码扫描功能
  4. jQuery find 和 filter 方法的区别
  5. jMeter parallel controller 无法使用 CSV Data config 提供的变量?
  6. 使用命令行运行 jMeter 测试项目
  7. 一个使用:focus-within伪类实现的button选中动画效果
  8. Angular路由跳转时,如何传递信息
  9. SAP ui5 ABAP repository handler class的 get_webcontent方法
  10. cus.crm.notes.Component.extend(cus.crm.notes.ext.Component, {