嵌入式自学第二十一天(5.14)
gdb逻辑调试器:
gcc 调试,发行版
gcc -g 调试版本,体积大,有源码。
一般调试:gdb a.out
b n.c:行数 :设置断点,运行到这个位置,程序暂停。(可以直接加行数)
r运行
n执行下一命令,若有函数,下一命令就是函数执行完的下一命令,s跟进自定义函数。
使用p命令,查看指针或变量数据。
q退出。
Start Main函数开始
n一步步执行
where找出段错误位置
Display 变量:每次执行下一步并查看变量值。
list列出函数
Valgrand 内存泄漏检测
/**回车,标准头文件备注格式。函数功能,参数介绍,返回值qq
今天还学习了剩下几个链表操作,尾部插入元素、指定位置插入元素、元素替换、和链表清空。代码如下:
int InsertTailLinkList(LinkList* ll, DATATYPE* data)
{
if (IsEmptyLinkList(ll))
{
return InsertHeadLinkList(ll, data);
}
else
{
LinkNode* newnode = malloc(sizeof(LinkNode));
if (NULL == newnode)
{
fprintf(stderr, "InsertTailLinkList malloc");
return 1;
}
memcpy(&newnode->data,data,sizeof(DATATYPE));
newnode->next = NULL;
LinkNode* tmp = ll->head;
while(tmp->next)
{
tmp = tmp->next; //tmp++;
}
tmp->next = newnode;
ll->clen++;
}
return 0;
}
int InsertPosLinkList(LinkList*ll,DATATYPE*data,int pos)
{
int len = GetSizeLinkList(ll);
if(pos<0 || pos>len)
{
return 1;
}
if(0==pos) //head
{
return InsertHeadLinkList(ll,data);
}
else if(pos == len) //tail
{
return InsertTailLinkList(ll, data);
}
else
{
LinkNode* newnode = malloc(sizeof(LinkNode));
if (NULL == newnode)
{
fprintf(stderr, "InsertPosLinkList malloc");
return 1;
}
memcpy(&newnode->data,data,sizeof(DATATYPE));
newnode->next = NULL;
int i = 0 ;
LinkNode* tmp = ll->head;
for(i = 0 ;i<pos-1;++i)
{
tmp= tmp->next;
}
newnode->next = tmp->next;
tmp->next = newnode;
}
ll->clen++;
return 0;
}
int ModifyLinkList(LinkList*ll,char*name,DATATYPE*data)
{
DATATYPE * tmp = FindLinkList(ll, name);
if(NULL == tmp)
{
return 1;
}
memcpy(tmp,data,sizeof(DATATYPE));
return 0;
}
int DestroyLinkList(LinkList**ll)
{
while(1)
{
LinkNode* tmp = (*ll)->head;
if(NULL == tmp)
{
break;
}
(*ll)->head = (*ll)->head->next;
free(tmp);
}
free(*ll);
*ll = NULL;
return 0;
}
顺序表和链表 优缺点
存储方式:
顺序表是一段连续的存储单元
链表是逻辑结构连续物理结构(在内存中的表现形式)不连续
时间性能,
查找 顺序表O(1)
链表 O(n)
插入和删除
顺序表 O(n)
链表 O(1)
空间性能
顺序表 需要预先分配空间,大小固定
链表, 不需要预先分配,大小可变,动态分配
循环链表
简单的来说,就是将原来单链表中最有一个元素的next指针指向第一个元素或头结点,链表就成了一个环,头尾相连,就成了循环链表。circultlar linker list