[原创] 结构体、共用体、位段和动态链链表在AVR上的应用

lzllong   2010-3-17 10:09 楼主
结构体、共用体、位段和动态链链表在AVR上的应用
//双向动态链表应用头文件==============================================================
//作者:LZL
//E-mail:lzllong@126.com   
//2009-8-27
//可动态的完成双向链表的创建、节点添加和删除
//=======================================================================
#ifndef _QUEUEOPERATION_H_
#define _QUEUEOPERATION_H_
//#include
#define  NULL  0
#define  LEN        sizeof(ReportStruct)
//自定义结构体,可根据具体需求修改
typedef struct   _ReportStruct
{
int     ReportNum;
char    ReportCode[21];
struct  ReportStruct* next;
struct  ReportStruct* last;
}ReportStruct,*pReportStruct;
struct ReportStruct* creat(void)      //创建链表,返回链表头,只有一个链表项
{
struct ReportStruct * head;
head=(ReportStruct *)malloc(LEN); //开辟新单元
memset(head,0,sizeof(ReportStruct));
return head;
}
int insert(ReportStruct* head ,ReportStruct* newmember,int Index)     //在链表的任意位置插入新的链表项  
{      //该项不存在,插入到末尾
ReportStruct* p1,p0;  
p1=head;
while(p1->next!=NULL&&p1->ReportNum!=Index)p1=p1->next;  
if(p1->next==NULL)                    //链表没有这么多项,新节点插入到链尾
{
  p1->next=newmember;  
  newmember->last = p1;  
  newmember->next = NULL;  
  newmember->ReportNum = p1->ReportNum+1;  
  return 1;  
}
if(p1->ReportNum==Index)             //当前是第Index项,插入该节点
{
  p0=p1->next;
  p1->next=newmember;  
  newmember->last = p1;  
  newmember->next = p0;  
  p0->last = newmember;
  newmember->ReportNum = p0->ReportNum;
  while(p0->next!=NULL)
  {
   p0->ReportNum = p0->ReportNum+1;
  }
  return 1;
}
return 0;  
}
int del(ReportStruct* head ,unsigned int Index)     //删除第Index项
{
ReportStruct* p0;
ReportStruct* p1;
ReportStruct* p2;
p1 = head;
if(p1->ReportNum==Index){free(head);return 1;}//只有一项
while(p1->next!=NULL)//两项或以上
{
  p1 = p1->next;
  if(p1->ReportNum == Index)
  {
   p0 = p1;
   p1 = p1->last;
   p1->next = p0->next;
   free(p0);
   goto DEAL;
  }
}
return 0;
DEAL:
while(p1->next!=NULL)
{
  p1=p1->next;
  p1->ReportNum-=1;
}
return 1;
}
#endif
主程序:
#include
#include
#include
#include "QueueOperation.h"
void delayms(int time)  //随意的延时函数
{
while(time--)
{
_delay_ms(200);
wdt_reset();
_delay_ms(200);
wdt_reset();
}
}

union  Pack_dat //共用体
{
struct Pack_LedIO //位段结构体
{
unsigned char LED0:1;
unsigned char LED1:1;
unsigned char LED2:1;
unsigned char LED3:1;
unsigned char LED4:1;
unsigned char LED5:1;
unsigned char LED6:1;
unsigned char LED7:1;
}LedIO;
unsigned char LEDIO;
}PackDat;

int main(void)
{
int time = 3;
DDRC = 0xff;
PORTC= 0x00;
PackDat.LEDIO = 0;
wdt_reset();
ReportStruct* p1;
ReportStruct* pErrorReportHead = creat();//创建动态链表
ReportStruct  newmember;                 //构造新的成员
newmember.ReportCode[2]=0x55;
insert(pErrorReportHead ,&newmember);    //将新成员插入链表末尾
ReportStruct  lasrmember;
lasrmember.ReportCode[0]=0xaa;
if(insert(pErrorReportHead ,&lasrmember))//插入第二个成员
{
while(time--)                   //循环3次
{
wdt_reset();           
PackDat.LedIO.LED3 = 1;
PORTC = PackDat.LEDIO;  //改变PC3输出高电平
delayms(5);
PackDat.LEDIO = 0;      //PC口全部置低
PackDat.LedIO.LED7 = 1;
PORTC = PackDat.LEDIO;  //改变PC7输出高电平

wdt_reset();
delayms(5);
PackDat.LEDIO = 0;
p1=pErrorReportHead->next;
PORTC = p1->ReportCode[2];//验证链表的第一个节点是否为newmember,head为第0个节点
wdt_reset();
delayms(5);
p1=p1->next;
PORTC = p1->ReportCode[0];    //验证链表的第二个节点是否为lasrmember,head为第0个节点

wdt_reset();
delayms(5);
}
wdt_reset();
p1->ReportCode[0] = 0x11;   //改变 lasrmember.ReportCode[0]为0x11
del(pErrorReportHead ,1);    //删除第一个节点  
p1=pErrorReportHead->next;   //然后再指向第一个节点
PORTC = p1->ReportCode[0];   //验证第一个节点变为了lasrmember
while(1)                     //等待
{
wdt_reset();
delayms(5);
}
}
return 1;
}
授之以鱼不如授之以渔!

回复评论 (2)

回复 楼主 lzllong 的帖子

关于这些结构的应用,请看谭浩强老师的C语言程序设计(第二版)273p-286p!
授之以鱼不如授之以渔!
点赞  2010-3-17 10:15
抱歉,头文件中Insert和主程序中insert参数对不上,因为主程序中insert为老版本,其原型为:
int insert(ReportStruct* head ,ReportStruct* newmember)     //在链表的末尾插入新的链表项
{
ReportStruct* p1;
p1=head;
if(p1->next==NULL)  //只有一项
{
p1->next = newmember;
newmember->last = head;
newmember->ReportNum = head->ReportNum+1;
newmember->next = NULL;
return 1;
}
else //两项或以上
{
p1=p1->next;
while(p1->next!=NULL)p1=p1->next;
p1->next=newmember;
newmember->last = p1;
newmember->next = NULL;
newmember->ReportNum = p1->ReportNum+1;
return 1;
}
return 0;
}
两函数间差异大家自己看吧!
授之以鱼不如授之以渔!
点赞  2010-3-17 10:39
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复