ImageVerifierCode 换一换
格式:DOCX , 页数:33 ,大小:222.60KB ,
资源ID:3423233      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3423233.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(单片机C语言编程基础.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

单片机C语言编程基础.docx

1、单片机C语言编程基础优先级及预处理另外 ANSI 标准 C还定义了如下几个宏:_LINE_ 表示正在编译的文件的行号_FILE_ 表示正在编译的文件的名字_DATE_ 表示编译时刻的日期字符串,例如: 25 Dec 2007_TIME_ 表示编译时刻的时间字符串,例如: 12:30:55_STDC_ 判断该文件是不是定义成标准 C程序函数atoi与atof函数名: atoi 功 能: 把字符串转换成长整型数 用 法: int atoi(const char *nptr); 程序例: #include int main(void) int n; char *str = 12345.67; n =

2、 atoi(str); printf(string = %s integer = %dn, str, n); return 0;#函数名: atof 功 能: 把字符串转换成浮点数 用 法: double atof(const char *nptr); 程序例: #include int main(void) float f; char *str = 12345.67; f = atof(str); printf(string = %s float = %fn, str, f); return 0; #链表 链表是 C语言中另外一个难点。牵扯到结点、动态分配空间等等。用结构作为链表的结点是非常

3、适合的,例如: struct node int data; struct node *next; ; 其中 next 是指向自身所在结构类型的指针,这样就可以把一个个结点相连,构成链表。 链表结构的一大优势就是动态分配存储,不会像数组一样必须在定义时确定大小,造成不必要的浪费。用 malloc 和 free 函数即可实现开辟和释放存储单元。其中,malloc 的参数多用 sizeof 运算符计算得到。 链表的基本操作有:正、反向建立链表;输出链表;删除链表中结点;在链表中插入结点等等,都是要熟练掌握的,初学者通过画图的方式能比较形象地理解建立、插入等实现的过程。 typedef struct

4、node char data; struct node *next; NODE; /*结点*/ 正向链表 NODE *create() char ch=a; NODE *p,*h=NULL,*q=NULL; while(chdata=ch; if(h=NULL) h=p; else q-next=p; ch+; q=p; q-next=NULL; /*链表结束*/ return h; 逆向建立NODE *create() char ch=a; NODE *p,*h=NULL; while(chdata=ch; p-next=h; /*不断地把head往前挪*/ h=p; ch+; return

5、 h; 用递归实现链表逆序输出: void output(NODE *h) if(h!=NULL) output(h-next); printf(%c,h-data); 插入结点插入结点(已有升序的链表): NODE *insert(NODE *h,int x) NODE *new,*front,*current=h; while(current!=NULL&(current-datanext; new=(NODE *)malloc(sizeof(NODE); new-data=x; new-next=current; if(current=h) /*判断是否是要插在表头*/ h=new; e

6、lse front-next=new; return h; 删除结点 NODE *delete(NODE *h,int x) NODE *q,*p=h; while(p!=NULL&(p-data!=x) q=p; p=p-next; if(p-data=x) /*找到了要删的结点*/ if(p=h) /*判断是否要删表头*/ h=h-next; else q-next=p-next; free(p); /*释放掉已删掉的结点*/ return h; 文件包含文件包含是预处理的一个重要功能,它可用来把多个源文件连接成一个源文件进行编译,结果将生成一个目标文件。语言提供#include命令来实现

7、文件包含的操作,它实际是宏替换的延伸,有两种格式:格式 1:#include 其中,filename为要包含的文件名称,用尖括号括起来,也称为头文件,表示预处理到系统规定的路径中去获得这个文件(即 C 编译系统所提供的并存放在指定的子目录下的头文件) 。找到文件后,用文件内容替换该语句。格式 2:#include “filename”其中,filename 为要包含的文件名称。双引号表示预处理应在当前目录中查找文件名为filename 的文件,若没有找到,则按系统指定的路径信息,搜索其他目录。找到文件后,用文件内容替换该语句。需要强调的一点是:#include是将已存在文件的内容嵌入到当前文件

8、中。另外关于#include的路径也有点要说明:include支持相对路径,格式如 trackant(蚁迹寻踪)所写:.代表当前目录,.代表上层目录。代码书写首先我想说明我本文阐述的是纯粹从美学的角度来写出代码,而非技术、逻辑等。以下为写出漂亮代码的七种方法:1尽快结束 if语句例如下面这个JavaScript语句,看起来就很恐怖:1 function findShape(flags, point, attribute, list) 2 if(!findShapePoints(flags, point, attribute) 3 if(!doFindShapePoints(flags, poi

9、nt, attribute) 4 if(!findInShape(flags, point, attribute) 5 if(!findFromGuide(flags,point) 6 if(list.count() 0 & flags = 1) 7 doSomething();8 9 10 11 12 13 但如果这么写就好看得多:1 function findShape(flags, point, attribute, list) 2 if(findShapePoints(flags, point, attribute) 3 return;4 5 6 if(doFindShapePoint

10、s(flags, point, attribute) 7 return;8 9 10 if(findInShape(flags, point, attribute) 11 return;12 13 14 if(findFromGuide(flags,point) 15 return;16 17 18 if (!(list.count() 0 & flags = 1) 19 return;20 21 22 doSomething();23 24 你可能会很不喜欢第二种的表述方式,但反映出了迅速返回if值的思想,也可以理解为:避免不必要的else陈述。2如果只是简单的布尔运算(逻辑运算),不要使用

11、if语句例如:1 function isStringEmpty(str)2 if(str = ) 3 return true;4 5 else 6 return false;7 8 可以写为:1 function isStringEmpty(str)2return (str = );3 3使用空白,这是免费的例如:1 function getSomeAngle() 2 / Some code here then3 radAngle1 = Math.atan(slope(center, point1);4 radAngle2 = Math.atan(slope(center, point2);5

12、 firstAngle = getStartAngle(radAngle1, point1, center);6 secondAngle = getStartAngle(radAngle2, point2, center);7 radAngle1 = degreesToRadians(firstAngle);8 radAngle2 = degreesToRadians(secondAngle);9 baseRadius = distance(point, center);10 radius = baseRadius + (lines * y);11 p1x = roundValue(radiu

13、s * Math.cos(radAngle1) + centerx);12 p1y = roundValue(radius * Math.sin(radAngle1) + centery);13 pt2x = roundValue(radius * Math.cos(radAngle2) + centery);14 pt2y = roundValue(radius * Math.sin(radAngle2) + centery);15 / Now some more code16 很多开发者不愿意使用空白,就好像这要收费一样。我在此并非刻意地添加空白,粗鲁地打断代码的连贯性。在实际编写代码的过

14、程中,会很容易地发现在什么地方加入空白,这不但美观而且让读者易懂,如下:1 function getSomeAngle() 2 / Some code here then3 radAngle1 = Math.atan(slope(center, point1);4 radAngle2 = Math.atan(slope(center, point2);5 6 firstAngle = getStartAngle(radAngle1, point1, center);7 secondAngle = getStartAngle(radAngle2, point2, center);8 9 radA

15、ngle1 = degreesToRadians(firstAngle);10 radAngle2 = degreesToRadians(secondAngle);11 12 baseRadius = distance(point, center);13 radius = baseRadius + (lines * y);14 15 p1x = roundValue(radius * Math.cos(radAngle1) + centerx);16 p1y = roundValue(radius * Math.sin(radAngle1) + centery);17 18 pt2x = ro

16、undValue(radius * Math.cos(radAngle2) + centery);19 pt2y = roundValue(radius * Math.sin(radAngle2) + centery);20 / Now some more code21 4不要使用无谓的注释无谓的注释让人费神,这实在很讨厌。不要标出很明显的注释。在以下的例子中,每个人都知道代码表达的是“students id”,因而没必要标出。1 function existsStudent(id, list) 2 for(i = 0; i list.length; i+) 3 student = listi

17、;4 5 / Get the students id6 thisId = student.getId();7 8 if(thisId = id) 9 return true;10 11 12 return false; 13 5不要在源文件中留下已经删除的代码,哪怕你标注了如果你使用了版本控制,那么你就可以轻松地找回前一个版本的代码。如果别人大费周折地读了你的代码,却发现是要删除的代码,这实在太恨人了。/function thisReallyHandyFunction() /someMagic();/someMoreMagic();/magicNumber = evenMoreMagic();

18、/return magicNumber;/6不要有太长的代码看太长的代码实在太费劲,尤其是代码本身的功能又很小。如下:1 public static EnumMap getGroupCategoryDistribution(EnumMap sizes, int groups) 2 EnumMap categoryGroupCounts = new EnumMap(Category.class);3 4 for(Category cat : Category.values() 5 categoryGroupCounts.put(cat, getCategoryDistribution(sizes

19、.get(cat), groups);6 我并不是说非要坚持70个字符以内,但是一个比较理想的长度是控制在120个字符内。如果你把代码发布在互联网上,用户读起来就很困难。7不要在一个功能(或者函数内)有太多代码行我的一个老同事曾经说Visual C+很臭,因为它不允许你在一个函数内拥有超过10,000行代码。我记不清代码行数的上限,不知道他说的是否正确,但我很不赞成他的观点。如果一个函数超过了50行,看起来有多费劲你知道么,还有没完没了的if循环,而且你还的滚动鼠标前后对照这段代码。对我而言,超过35行的代码理解起来就很困难了。我的建议是超过这个数字就把一个函数代码分割成两个。#pragma

20、预处理在所有的预处理指令中,#pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma 指令对每个编译器给出了一个方法,在保持与 C 和C+语言完全兼容的情况下,给出主机或操作系统专有的特征。 依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。其格式一般为:#pragma para其中 para 为参数,下面来看一些常用的参数。.1,#pragma messagemessage 参数:Message 参数是我最喜欢的一个参数,它能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。其使用方法为:#

21、pragma message(“消息文本”)当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法#ifdef _X86#Pragma message(“_X86 macro activated!”)#endif当我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示“_X86 macro activated!”。我们就不会因为不记得自己定义的一些特定的

22、宏而抓耳挠腮了.2,#pragma code_seg另一个使用得比较多的 pragma参数是 code_seg。格式如:#pragma code_seg( section-name,section-class )它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。.3,#pragma once#pragma once (比较常用)只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在Visual C+6.0 中就已经有了,但是考虑到兼容性并没有太多的使用它。.4,#pragma hdrstop#pragma hdrstop表示预编译头文件到此为止,

23、后面的头文件不进行预编译。BCB 可以预编译头文件以加快链接的速度,但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文件。有时单元之间有依赖关系,比如单元 A依赖单元B,所以单元 B要先于单元 A编译。你可以用#pragma startup指定编译优先级,如果使用了#pragma package(smart_init) ,BCB就会根据优先级的大小先后编译。.5,#pragma resource#pragma resource *.dfm表示把*.dfm文件中的资源加入工程。*.dfm中包括窗体外观的定义。.6,#pragma warning#pragma warn

24、ing( disable : 4507 34; once : 4385; error : 164 )等价于:#pragma warning(disable:4507 34) / 不显示 4507和 34号警告信息#pragma warning(once:4385) / 4385号警告信息仅报告一次#pragma warning(error:164) / 把 164号警告信息作为一个错误。同时这个pragma warning 也支持如下格式:#pragma warning( push ,n )#pragma warning( pop )这里n 代表一个警告等级(1-4)。#pragma warn

25、ing( push )保存所有警告信息的现有的警告状态。#pragma warning( push, n)保存所有警告信息的现有的警告状态,并且把全局警告等级设定为 n。#pragma warning( pop )向栈中弹出最后一个警告信息,在入栈和出栈之间所作的一切改动取消。例如:#pragma warning( push )#pragma warning( disable : 4705 )#pragma warning( disable : 4706 )#pragma warning( disable : 4707 )/.#pragma warning( pop )在这段代码的最后,重新保

26、存所有的警告信息(包括 4705,4706和 4707)。.7,#pragma comment#pragma comment(.)该指令将一个注释记录放入一个对象文件或可执行文件中。常用的 lib关键字,可以帮我们连入一个库文件。 比如:#pragma comment(lib, user32.lib)该指令用来将 user32.lib库文件加入到本工程中。linker:将一个链接选项放入目标文件中,你可以使用这个指令来代替由命令行传入的或者在开发环境中设置的链接选项,你可以指定/include选项来强制包含某个对象,例如:#pragma comment(linker, /include:_mySymbol).8,#pragma pack这里重点讨论内存对齐的问题和#pragma pack()的使用方法。什么是内存对齐?先看下面的结构:struct TestStruct1char c1;short s;char c2;int i;假设这个结构的成员在内存中是紧凑排列的,假设c1的地址

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1