2008|3

8

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

嵌入式:这三个C语言三要素要用好 [复制链接]

作为嵌入式工程师,怎么写出效率高、思路清晰的C语言程序呢?

要用C语言的思维方式来进行程序的构架构建

要有良好的C语言算法基础,以此来实现程序的逻辑构架

灵活运用C语言的指针操作

    

虽然看起来以上的说法很抽象,给人如坠雾里的感觉,其实就是用C语言进行遇到问题、分析问题和解决问题的过程。

    

嵌入式工程师在编写C语言程序的时候,要针对遇到的问题进行程序构架构建。

    

比如我们要处理“猴子选大王”的经典问题:一群猴子,手拉手排成一个圆,从任意一只猴子开始从1开始报数,当遇到要排除的数(预先设定)时该猴子退出该圈,从下一只猴子开始继续从1报数,如此反复,最终剩下的猴子便是猴子的大王。


用C语言的思维方式进行程序构架构建
    

程序分为三大部分:

a、数据获取,为了程序的运行,上面的问题要获得猴子的总数,从那只猴子开始和剔除的个数;

b、数据运算,需要从一堆数据中剔除相应的数据,注意逻辑的正确;

c、提高程序的运行速率,少用循环多用指针。


用C语言进行逻辑实现


a、 数据获取,通过printf和scanf进行参数的获取。


/* 读入问题条件 */
printf("input total num:");
scanf("%d", &n);
printf("from which num begin:");
scanf("%d", &k);
if(k>n||k==0)
{
printf("please input the right begin num");
return 1; 
}
printf("input the out num:");
scanf("%d", &m);
if(m>n||m==0)

printf("please input the right del num");
return 2; 
}
    

同时注意异常时的处理,比如上面两个if语句就是异常情况的判断,每种异常情况对应不同的返回值,这样便于程序过程的调试和数据的合法性。

b、 /* 定义链表节点类型 */


typedef struct node
{
int data;
struct node *next;
}linklist;
    

构建循环链表进行“猴子”的圆圈建设。


/* 创建循环链表,头节点也存信息 */
head = (linklist*) malloc(sizeof(linklist));
p = head;
p->data = 1;
p->next = p;
/* 初始化循环链表 */
for (i = 2; i <= n; i++)
{
s = (linklist*) malloc(sizeof(linklist));
s->data = i;
s->next = p->next;
p->next = s;
p = p->next;
}
    

通过该步骤后,head和p(present)都成了一个“猴子圈”的链表。在该链表的构建过程中需要注意一下几点:内存的开辟,此时遵守使用多少开辟多少的原则。

    

如果一下开辟过多,会引起内存泄露的问题,但是,这个小程序是不会遇到这种问题了。其次是熟悉循环链表的构建方法:链表的尾巴指向链表的头。这个时候有心的话还会联想到双向链表的情况。

c、 /* 找到第 k 个节点 */


p = head;
for (i = 1; i <= k; i++)
{
p = p->next;
}
    

找到从第几个位置开始计数。此时,p指向开始的“猴子”。因为采用了链表方法,这个过程只需要关注p指针的next指向即可。

a、 保存初始的“猴子”圆圈参数。


/* 保存节点总数 */

total = n;
printf("\nthe out num:");
q = head;
    

为什么要保留这个呢?首先要控制猴子数目,所以保留了全部的数目。其次用q(qurry)来保留剔除猴子前面的链表,并连接剔除猴子后的链表。这样,完成了循环链表的元素删除。

b、 猴子查数。

    

猴子查数是整个程序的关键,需要完成以下任务:a、找到开始的“猴子”数;b、删除该“猴子”;c、将删除掉的循环链表首尾连接起来。


/* 只剩一个节点时停止循环 */
while (total != 1)
{
/* 报数过程,p指向要删除的节点 */
for (i = 1; i < m; i++)
{
p = p->next;
}
/* 打印要删除的节点序号 */
printf("[%d] ", p->data);
/* q 指向 p 节点的前驱 */
while (q->next != p)
{
q = q->next;
}
/* 删除 p 节点 */
q->next = p->next;
/* 保存被删除节点指针 */
s = p;
/* p 指向被删除节点的后继 */
p = p->next;
/* 释放被删除的节点 */
free(s);
/* 节点个数减一 */
total--;
}
/* 打印最后剩下的节点序号 */
printf("\n\nthe last num:[%d] \n\n", p->data);
free(p);
}
    
通过以上数据运算,可以完成相应链表元素的删除,这或许就是C语言程序的魅力所在。


使用C语言的指针
    

比如本程序的链表指针的定义,p,s,q。

linklist *head, *p, *s, *q;
    

我们知道,指针操作不但可以减少数据操作需要的内存,还可以提高程序的运行速度。

    

指针的优势,或许在本程序中表现的不明显,在大量数据和对操作速度要求比较敏感的情况下会很明显,比如Linux内核中,就会有很好的体现。

    

总之,对于嵌入式工程师,不但能设计出好的硬件电路,如果也能写出好的软件程序就会让我们的生活更加美好。

此帖出自stm32/stm8论坛

最新回复

很有启发,谢谢分享。   详情 回复 发表于 2021-7-23 16:10

赞赏

1

查看全部赞赏

点赞(1) 关注
 

回复
举报

1942

帖子

3

TA的资源

版主

沙发
 

不错,讲的挺细致的!

此帖出自stm32/stm8论坛
 
 

回复

7671

帖子

2

TA的资源

五彩晶圆(高级)

板凳
 

谢谢分享

此帖出自stm32/stm8论坛
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 

回复

111

帖子

0

TA的资源

一粒金砂(中级)

4
 

很有启发,谢谢分享。

此帖出自stm32/stm8论坛
 
个人签名

 

 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表