智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 4307|回复: 10
打印 上一主题 下一主题

怎样培养优秀的编程风格

[复制链接]

489

主题

1691

帖子

1

精华

管理员

网站创始人&站长

Rank: 11Rank: 11Rank: 11Rank: 11

积分
85804

特殊贡献奖章资源大师奖章论坛骨干奖章推广达人奖章优秀版主奖章热心会员奖章论坛元老奖章在线王奖章活跃会员奖章优秀会员奖章

QQ
威望
56900
贡献
17334
兑换币
13112
注册时间
2007-6-8
在线时间
5785 小时
跳转到指定楼层
1#
发表于 2008-2-22 08:51:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
<><FONT size=3></FONT>&nbsp;</P><P><FONT size=3>作为一个初学者如何具有良好的程序设计风格呢?我想引用一个关于初学者请教编程大师的故事让读者自己去领悟。</FONT></P><P><FONT size=3>有一位编程大师,他写非结构化的程序,一位初学者刻意模仿他,也写非结构化的程序。当他让大师看他的进步时,大师批评了他的非结构化程序:“ 对一位编程大师合适的东西未必对一个初学者同样合适,在超越结构化之前,你必须理解编程之道。” 我个人认为作为一个初学者应该踏踏实实的打好程序设计的基础,不要急功近利,舍本逐末。我走过不少弯路,希望大家能和我一样能牢记编程大师的忠告:“对编程大师合适的东西未必对一个初学者同样合适”。 </FONT></P><P><FONT size=3>本文所描述的优秀编程风格适合于大部分语言,文章中可能提到你不是很了解的概念,没有关系,你放心的读下去,你什么都明白了。</FONT></P><P><FONT size=3>文件结构</FONT></P><P><FONT size=3>模块化的程序应该是有一个很好的程序结构的。AVR C语言程序有两种用户文件,.c程序文件,.h头文件,程序中编写过程中需要在.c文件中包含.h头文件。初学者往往出现重复包含或者头文件包含错误的问题,我当时也时常为这种错误而发愁。下面我以我写的电机驱动例程来给大家说明一下,优秀的编程文件结构。</FONT></P><P><FONT size=3>这个工程中有8个文件,一个说明文件,如下图:下载程序例子 电机控制案例 。 </FONT></P><P><FONT size=3>&nbsp;<IMG height=238 alt=文件结构 src="http://www.avrvi.com/start/images/file_srtuct.jpg" width=152></FONT></P><P><FONT size=3>我写的成型的程序的文件个数基本上都是偶数,因为每一个结构化的函数定义.c文件都会对应一个.h文件。main.c对应config.h。我们来看看各文件的包含关系。下面我们看看这些文件的包含关系与内容:[推荐的文件包含顺序与关系]</FONT></P><P><FONT size=3>所有.c文件都包含了config.h文件。如: #include "config.h" <BR>在config.h 中有如下代码:</FONT></P><P><FONT size=3>#include "delay.h"<BR>#include "device_init.h"<BR>#include "motor.h"这样做就不容易出现错误的包含关系,为了预防万一,我们还引入了宏定义与预编译。如下:</FONT></P><P><FONT size=3>#ifndef _UNIT_H__<BR>#define _UNIT_H__ 1&nbsp; <BR>//100us<BR>extern void Delay100us(uint8 n);<BR>//1s<BR>extern void Delay1s(uint16 n); //&nbsp; n &lt;= 6 ,when n==7, it is 1. <BR>//1ms<BR>extern void Delay1ms(uint16 n);</FONT></P><P><FONT size=3>#endif</FONT></P><P><FONT size=3>第一次包含本文件的时候正确编译,并且#define _UNIT_H__ 1,第二次包含本文件#ifndef _UNIT_H__就不再成立,跳过文件。<BR>预编译还有更多的用途,比如可以根据不同的值编译不同的语句,如下:<BR>//#pragma REGPARMS<BR>#if CPU_TYPE == M128<BR>#include &lt;iom128v.h&gt;<BR>#endif<BR>#if CPU_TYPE == M64<BR>#include &lt;iom64v.h&gt;<BR>#endif<BR>#if CPU_TYPE == M32<BR>#include &lt;iom32v.h&gt;<BR>#endif<BR>#if CPU_TYPE == M16<BR>#include &lt;iom16v.h&gt;<BR>#endif<BR>#if CPU_TYPE == M8<BR>#include &lt;iom8v.h&gt;<BR>#endif<BR>#include&lt;filename&gt; 与 #include "filename" 的区别 :前者是包含系统目录include下 的文件,后者是包含程序目录下的文件。 <BR>变量名与函数名</FONT></P><P><FONT size=3>变量以及函数命名应该按照尽量短,按需长,具有实际意义。可以通过下划线或者大小写结合的方法组合动词和名词组成变量函数名。下面对比好的命名方法与不好的命名方法:</FONT></P><P><FONT size=3>好的:&nbsp;&nbsp; Delay100us();<BR>不好的:&nbsp;&nbsp; Yanshi(); <BR>好的:&nbsp;&nbsp; init_devices();<BR>不好的:&nbsp;&nbsp; Chengxuchushihua(); <BR>好的:&nbsp;&nbsp; int temp;<BR>不好的:&nbsp;&nbsp; int dd; <BR>外部调用</FONT></P><P><FONT size=3>首先在模块化程序的.h文件中定义extern</FONT></P><P><FONT size=3>//端口初始化<BR>extern void port_init(void);</FONT></P><P><FONT size=3>//T2初始化<BR>void timer2_init(void);</FONT></P><P><FONT size=3>//各种参数初始化<BR>extern void&nbsp; init_devices(void);模块化程序的.c文件中定义函数,不要在模块化的程序中调用程序,及不要出现向timer2_init();这样函数的使用,因为你以后不知道你到底什么地方调用了函数,导致程序调试难度增加。可以在定义函数的过程中调用其他函数作为函数体。</FONT></P><P><FONT size=3>/**************************采用timer2 产生波形***********************/<BR>// PWM频率 = 系统时钟频率/(分频系数*2*计数器上限值)) <BR>void timer2_init(void)<BR>{<BR>&nbsp;TCCR2 = 0x00;&nbsp; //stop<BR>&nbsp;TCNT2= 0x01;&nbsp; //set count<BR>&nbsp;OCR2 = 0x66;&nbsp; //set compare<BR>&nbsp;TCCR2 = (1&lt;&lt;WGM20)|(1&lt;&lt;WGM21)|(1&lt;&lt;COM21)|0x06; //&nbsp; start timer 快速pwm模式,匹配清零,溢出置位 256分频<BR>//占空比=高比低为:(OCR2-0X01)/(0XFF-OCR2)&nbsp;&nbsp;&nbsp; OX01++++++(OCR2)__________OXFF (+表示输出高,_表示输出低)<BR>//即OCR2越大,输出越大<BR>}在少数几个文件中调用函数,在main.c中调用大部分函数,在interupts.c中根据不同的中断调用服务函数。</FONT></P><P><FONT size=3>void main(void)<BR>{</FONT></P><P><FONT size=3>/******************************************************************************/<BR>//初始工作<BR>/******************************************************************************/<BR>&nbsp; init_devices();<BR>&nbsp; <BR>&nbsp; while(1)<BR>&nbsp; {<BR>&nbsp;&nbsp; for_ward(0);&nbsp; &nbsp;&nbsp;&nbsp;//默认速度运转 正<BR>&nbsp;&nbsp; Delay1s(5); &nbsp;&nbsp;&nbsp;&nbsp;//延时5s<BR>&nbsp;&nbsp; motor_stop(); &nbsp;&nbsp;&nbsp;//停止<BR>&nbsp;&nbsp; Delay1s(5); &nbsp;&nbsp;&nbsp;&nbsp;//延时5s<BR>&nbsp;&nbsp; back_ward(0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //默认速度运转 反<BR>&nbsp;&nbsp; Delay1s(5); &nbsp;&nbsp;&nbsp;&nbsp;//延时5s<BR>&nbsp;&nbsp; speed_add(20);&nbsp;&nbsp;&nbsp;//加速<BR>&nbsp;&nbsp; Delay1s(5); &nbsp;&nbsp;&nbsp;&nbsp;//延时5s<BR>&nbsp;&nbsp; speed_subtract(20);&nbsp;&nbsp;//减速<BR>&nbsp;&nbsp; Delay1s(5); &nbsp;&nbsp;&nbsp;&nbsp;//延时5s<BR>&nbsp; }<BR>&nbsp;&nbsp;&nbsp; <BR>}宏定义</FONT></P><P><FONT size=3>宏定义主要用于两个地方:</FONT></P><P><FONT size=3>一是用得非常多的命令或语句,利用宏将其简化。</FONT></P><P><FONT size=3>#ifndef TRUE<BR>#define TRUE&nbsp; 1<BR>#endif<BR>#ifndef FALSE<BR>#define FALSE 0<BR>#endif<BR>#ifndef NULL<BR>#define NULL 0<BR>#endif<BR>#define MIN(a,b)&nbsp;&nbsp;&nbsp;((a&lt;b)?(a)b))<BR>#define MAX(a,b)&nbsp;&nbsp;&nbsp;((a&gt;b)?(a):(b))<BR>#define ABS(x)&nbsp;&nbsp;&nbsp;((x&gt;)?(x):(-x))<BR>typedef unsigned char&nbsp; uint8;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 定义可移植的无符号8位整数关键字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>typedef signed&nbsp;&nbsp; char&nbsp; int8;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 定义可移植的有符号8位整数关键字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>typedef unsigned int&nbsp;&nbsp; uint16;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 定义可移植的无符号16位整数关键字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>typedef signed&nbsp;&nbsp; int&nbsp;&nbsp; int16;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 定义可移植的有符号16位整数关键字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>typedef unsigned long&nbsp; uint32;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 定义可移植的无符号32位整数关键字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>typedef signed&nbsp;&nbsp; long&nbsp; int32;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 定义可移植的有符号32位整数关键字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>二是利用宏定义方便的进行硬件接口操作,再程序需要修改时,只需要修改宏定义即可,而不需要满篇去找命令行,进行修改。</FONT></P><P><FONT size=3>//PD4,PD5 电机方向控制 如果更改管脚控制电机方向,更改PORTD |= 0x10即可。<BR>#define moto_en1 PORTD |= 0x10<BR>#define moto_en2 PORTD |= 0x20<BR>#define moto_uen1 PORTD &amp;=~ 0x10<BR>#define moto_uen2 PORTD &amp;=~ 0x20<BR>//启动TC2定时比较和溢出<BR>#define TC2_EN TIMSK |= (&lt;&lt;1OCIE2)|(1&lt;&lt;TOIE2)<BR>//禁止TC2再定时比较和溢出<BR>#define TC2_DIS TIMSK &amp;=~ (1&lt;&lt;OCIE2)|(1&lt;&lt;TOIE2)关于注释</FONT></P><P><FONT size=3>为了增加程序的可读性,方便合作者读动程序,或者程序作者在一段时间之后还能看懂程序,我们需要在程序中写 注释。</FONT></P><P><FONT size=3>在比较特殊的函数使用或者命令调用的地方加单行注释。使用方法为:</FONT></P><P><FONT size=3>Tbuf_putchar(c,RTbuf);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 将数据加入到发送缓冲区并开中断<BR>extern void Delay1s(uint16 n); //&nbsp; n &lt;= 6 ,when n==7, it is 1. 在模块化的函数中使用详细段落注释:</FONT></P><P><FONT size=3>/***********************<BR>** 函数名称: Com_putchar<BR>** 功能描述: 从串行口输出一个字符c<BR>** 输 入: c:输出字符<BR>** 输出&nbsp;&nbsp; : 0:失败 1:成功<BR>** 全局变量: 无<BR>** 调用模块: <BR>** 说明:<BR>** 注意:<BR>********************/在文件头上加文件名,文件用途,作者,日期等信息。</FONT></P><P><FONT size=3>/*********************************************************************************************************<BR>**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; serial&nbsp;&nbsp; driver <BR>**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (c) Copyright 2005-2006, limaokui<BR>**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; All Rights Reserved<BR>**<BR>**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; V1.1.0<BR>**<BR>**<BR>**--------------文件信息--------------------------------------------------------------------------------<BR>**文&nbsp;&nbsp; 件&nbsp;&nbsp; 名:sio.c<BR>**创&nbsp;&nbsp; 建&nbsp;&nbsp; 人: ***<BR>**最后修改日期: 2005年7月13日<BR>**描&nbsp;&nbsp;&nbsp;&nbsp; 述: serial&nbsp;&nbsp; driver <BR>**<BR>**--------------历史版本信息----------------------------------------------------------------------------<BR>** 创建人: ***<BR>** 版 本: V1.00<BR>** 日 期: 2005年7月13日<BR>** 描 述: 原始版本<BR>** <BR>*********************************************************************************************************/要清楚,注释是为了方便阅读,增强程序的可度性,不要本末倒置,不要给很简单大家都能看明白的程序加注释,不要让注释淹没了你的程序结构。对于函数,变量等尽量使用文件名自注释的方法,及通过文件名就可以知道意思。</FONT></P><P><FONT size=3>&nbsp;</FONT></P><P><FONT size=3>&nbsp;</FONT></P>

0

主题

6

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
200
QQ
威望
178
贡献
22
兑换币
0
注册时间
2008-3-2
在线时间
0 小时
2#
发表于 2008-3-2 06:29:14 | 只看该作者

Re:怎样培养优秀的编程风格

<>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 优秀,我顶!!!</P><P>&nbsp;</P>
回复 支持 反对

使用道具 举报

0

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
248
威望
226
贡献
22
兑换币
0
注册时间
2008-2-19
在线时间
0 小时
3#
发表于 2008-2-22 16:45:41 | 只看该作者

Re:怎样培养优秀的编程风格

<><FONT color=#ff00ff size=4>先看看!</FONT> </P>
回复 支持 反对

使用道具 举报

0

主题

294

帖子

1

精华

功勋会员

Rank: 10Rank: 10Rank: 10

积分
4132

特殊贡献奖章

QQ
威望
2661
贡献
1407
兑换币
33
注册时间
2007-11-22
在线时间
32 小时
4#
发表于 2008-4-11 06:11:59 | 只看该作者

Re:怎样培养优秀的编程风格

<><FONT size=3>//端口初始化<BR>extern void port_init(void);</FONT></P><P><FONT size=3>这个没必要加extern 吧?</FONT></P>
回复 支持 反对

使用道具 举报

0

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
427
威望
307
贡献
96
兑换币
74
注册时间
2008-3-23
在线时间
12 小时
5#
发表于 2008-5-12 00:15:06 | 只看该作者

Re:怎样培养优秀的编程风格

extern 是可加可不加的。<br>
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
威望
288
贡献
96
兑换币
74
注册时间
2008-4-19
在线时间
12 小时
6#
发表于 2008-6-12 07:17:01 | 只看该作者

Re:怎样培养优秀的编程风格

有些命令根本看不懂,还有很多要学啊
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

注册会员

Rank: 2

积分
123
威望
171
贡献
22
兑换币
0
注册时间
2009-2-4
在线时间
0 小时
7#
发表于 2009-2-4 23:16:37 | 只看该作者

Re:怎样培养优秀的编程风格

<IMG src="http://www.znczz.com/images/Emotions/28.gif">
回复 支持 反对

使用道具 举报

14

主题

586

帖子

0

精华

禁止发言

事人

积分
3226
威望
988
贡献
1966
兑换币
62
注册时间
2008-9-5
在线时间
136 小时
8#
发表于 2009-2-5 20:19:59 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

0

主题

13

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
238
威望
184
贡献
22
兑换币
0
注册时间
2009-3-19
在线时间
16 小时
9#
发表于 2009-5-19 22:49:17 | 只看该作者
不错,顶下!
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
230
威望
192
贡献
34
兑换币
10
注册时间
2009-6-16
在线时间
2 小时
10#
发表于 2009-6-16 19:38:54 | 只看该作者
很规范化!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-9-20 22:24 , Processed in 0.059637 second(s), 37 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表