嵌入式学习第二篇——C语言基础14

目录

内存

1.内存管理:

    1.malloc 

    2.free

2.内存溢出:

3.内存泄露:

4.内存碎片:

链表:

1,为什么要使用链表:

2,链表类型的定义:

3,头链表的创建:

4,新链表的写入:

5,链表的输出:

6,链表内容的替换:

7,链表数据的删除:

8,链表空间的释放:


内存

1.内存管理:


    1.malloc 


      void *malloc(size_t size);
      功能:
        申请堆区空间
      参数:
        size:申请堆区空间的大小
      返回值:
        返回获得的空间的首地址
        失败返回NULL

    2.free


      void free(void *ptr);
      功能:
        释放堆区空间

      注意:
        1.free只能释放堆区空间
        2.一个空间只能被free一次,多次free程序会崩溃
        3.malloc需要和free搭配使用,如果只有malloc没有free会内存泄露

malloc和free的使用参考如下:

#include
#include

int main(void)
{
	int *p = NULL;

	p = malloc(4);
	if(NULL == p)
	{
		printf("malloc faild!\n");
		return -1;
	}

	*p = 100;

	printf("*p = %d\n",*p);

	free(p);

	return 0;
}

    练习:要求申请堆区空间,将"hello world"存放到堆区空间,完成打印

参考如下:

#include
#include
#include

int main(void)
{
	char *p = NULL;

	p = malloc(12);

	if(NULL == p)
	{
		printf("fall");
		return -1;
	}

	strcpy(p,"hello world");

	printf("p = %s\n",p);

	free(p);

	return 0;
}

函数间传参时,利用使用malloc和free函数创造出来的空间来传递也是一个方便的新方法

参考如下:

#include
#include
#include

char *fun(void)
{
	char *pa = NULL;

	pa = malloc(12);
	if(pa == NULL)
	{
		return NULL;
	}

	strcpy(pa,"hello world");
	
	return pa;
}

int main(void)
{
	char *p = NULL;
	
	p = fun();

	printf("%s\n",p);

	return 0;
}

2.内存溢出:


    内存溢出也称为内存越界

3.内存泄露:


    程序中malloc的空间没有被释放

4.内存碎片:


    由于频繁申请和释放,导致连续的空间分散成一些小的碎片空间,当malloc超过碎片空间时,则无法获得该空间(空间不连续),将这样的空间称为内存碎片


======================================================================================================================================================


链表:

区别于数组中每个元素只储存数据

链表的构成中每个元素都由两部分组成包括:

元素储存的数据和指向下一个链表的地址

——————————

   数据       |     地址         

——————————

链表分为:

有头链表无头链表

1,为什么要使用链表:

1,对比于数组它的数据处理速度快

2,由于链表所占空间不连续,能更有效地利用零碎空间

2,链表类型的定义:

先介绍一个函数

typedef函数

作用:

主要用于给用户自主构造的数据类型例如构造体赋予简单的类型名

定义形式:

typedef   数据类型   新类型名;

参考:

#include
#include
#include

typedef int DataType;

int main(void)
{
    return 0;
}

那么利用typedef函数和构造体的知识我们就可以构造出一个链表类型LinkNode

参考如下:

#include
#include
#include

typedef struct node
{
	DataType Data;
	struct node *pNext;
}LinkNode;

3,头链表的创建:

这里我们采用封装函数的方法创建新的头链表

因为我们要返回一个链表形式的返回值,所以函数类型我们定义为上面构造的链表类型

参考如下:


LinkNode *CreateLinkList(void)
{
	LinkNode *pTmpNode = NULL;

	pTmpNode = malloc(sizeof(LinkNode));
	if(pTmpNode == NULL)
	{
		return NULL;
	}

	pTmpNode->pNext = NULL;

	return pTmpNode;
}

int main(void)
{

    LinkNode *LinkList = NULL;

    LinkList = CreatLinkList();

    return 0;
}

4,新链表的写入:

(这里的写入方法是头插法)

这里的实参传的是上面定义的头链表

参考如下:

int InsertLinkList(LinkNode *pHead,DataType TmpData)
{
	LinkNode *pTmpNode = NULL;
	
	pTmpNode = malloc(sizeof(LinkNode));

	if(pTmpNode == NULL)
	{
		return -1;
	}

	pTmpNode->Data = TmpData;
	pTmpNode->pNext = pHead->pNext;
	pHead->pNext = pTmpNode;

	return 0;
}

int main(void)
{
    InsertLinkList(LinkList,新数据);

    return 0;
}

5,链表的输出:

将头链表传入函数,然后遍历输出即可

参考如下:

int ShowLinkList(LinkNode *pHead)
{
	LinkNode *pTmpNode = NULL;

	pTmpNode = pHead->pNext;
	while(pTmpNode != NULL)
	{
		printf("%d ",pTmpNode->Data);
		pTmpNode = pTmpNode->pNext;
	}
	printf("\n");

	return 0;
}

int main(void)
{
    ShowLinkList(Linklist);

    return 0;
}

6,链表内容的替换:

参考如下:

int ReplaceLinkList(LinkNode *pHead,DataType OldData,DataType NewData)
{
	LinkNode *pTmpNode = NULL;
	pTmpNode = pHead->pNext;
	while(pTmpNode != NULL)
	{
		if(pTmpNode->Data == OldData)
		{
			pTmpNode->Data = NewData;
		}
		pTmpNode = pTmpNode->pNext;
	}

	return 0;
}

int main(void)
{
    ReplaceLinkList(LinkList,被替换数据,新数据);

    return 0;
}

7,链表数据的删除:

数据的删除也就代表着相应链表空间的删除,所以我们在遍历到需删除的数据时,也要将对应空间释放,并注意在本次循环中只需要将靠近尾部的指针后移即可

参考如下:

int DeleteLinkList(LinkNode *pHead,DataType DeleteData)
{
	LinkNode *pTmpNode = NULL;
	LinkNode *pPreNode = NULL;

	pTmpNode = pHead->pNext;
	pPreNode = pHead;

	while(pTmpNode != NULL)
	{
		if(pTmpNode->Data == DeleteData)
		{
			pPreNode->pNext = pTmpNode->pNext;
			free(pTmpNode);
			pTmpNode = pTmpNode->pNext;
		}
		else
		{
			pTmpNode = pTmpNode->pNext;
			pPreNode = pPreNode->pNext;
		}
	
	}

	return 0;
}

int main(void)
{
    DeleteLinkList(LinkList,要删除的数据);

    return 0;
}

8,链表空间的释放:

这里需要注意的是头链表指针还指向着已经被回收的头链表空间,该空间在被回收后内容为乱码,为了避免出现bug,函数里采用二级指针将头链表指针的内容更改为NULL

参考如下:

int DestroyLinkList(LinkNode **pHead)
{
	LinkNode *pTmpNode = NULL;
	LinkNode *pFreeNode = NULL;

	pFreeNode = *pHead;
	pTmpNode = pFreeNode->pNext;
	while(pTmpNode != NULL)
	{
		pTmpNode = pTmpNode->pNext;
		free(pFreeNode);
		pFreeNode = pTmpNode;
	}
	*pHead = NULL;

	return 0;
}

int main(void)
{
    DestroyLinkList(&LinkList);

    return 0;
}


作业:


    1.封装函数在链表中实现尾插法
        int InsertTailLinkList(LinkNode *pHead, DataType TmpData);

    2.从终端接收一个字符串,将字符串倒置后输出
        "how are you"

        "you are how"

1,参考答案:

#include
#include
#include

typedef struct node
{
	int Data;
	struct node *pNext;
}LinkNode;

LinkNode *CreatLinkList(void)
{
	LinkNode *pTmpNode =NULL;

	pTmpNode = malloc(sizeof(LinkNode));
	if(pTmpNode == NULL)
	{
		return NULL;
	}

	pTmpNode->pNext = NULL;

	return pTmpNode;
}

int InsertHeadLinkList(LinkNode *pHead,int TmpData)
{
	LinkNode *pTmpNode = NULL;
	LinkNode *pInserNode = NULL;

	pInserNode = malloc(sizeof(LinkNode));
	if(pInserNode == NULL)
	{
		return -1;
	}

	pTmpNode = pHead;
	while(pTmpNode->pNext != NULL)
	{
		pTmpNode = pTmpNode->pNext;
	}
	pInserNode->pNext = NULL;
	pInserNode->Data = TmpData;
	pTmpNode->pNext = pInserNode;
	
	return 0;
}

int ShowLinkList(LinkNode *pHead)
{
	LinkNode *pTmpNode = NULL;

	pTmpNode = pHead->pNext;
	while(pTmpNode != NULL)
	{
		printf("%d ",pTmpNode->Data);
		pTmpNode = pTmpNode->pNext;
	}
	printf("\n");

	return 0;
}

int DestroyLinkList(LinkNode **ppHead)
{
	LinkNode *pTmpNode = NULL;
	LinkNode *pFreeNode = NULL;

	pTmpNode = pFreeNode = *ppHead;
	while (pTmpNode != NULL)
	{
		pTmpNode = pTmpNode->pNext;
		free(pFreeNode);
		pFreeNode = pTmpNode;
	}
	*ppHead = NULL;

	return 0;
}

int main(void)
{
	LinkNode *LinkList = NULL;

	LinkList = CreatLinkList();

	InsertHeadLinkList(LinkList,1);
	InsertHeadLinkList(LinkList,2);
	InsertHeadLinkList(LinkList,3);
	InsertHeadLinkList(LinkList,4);
	InsertHeadLinkList(LinkList,5);
	ShowLinkList(LinkList);
	DestroyLinkList(&LinkList);

	return 0;
}

2,参考答案:

#include
#include

int InverFun(char *pa,int len,int lin)
{
	int i = lin;
	char tmp = 0;
	while(i < len-1)
	{
		tmp = pa[i];
		pa[i] = pa[len-1];
		pa[len-1] = tmp;
		i++;
		len--;
	}
	return 0;
}

int SmartInverFun(char *pa,int len)
{	
	int i = 0;
	int j = 0;
	InverFun(pa,len,j);
	while(pa[i] != '\0')
	{
		if(pa[i] == ' ')
		{
			InverFun(pa,i,j);
			j = i + 1;
		}
		
		i++;
	}
	InverFun(pa,len,j);


	return 0;
}

int main(void)
{
	char a[32] = {0};
	int len = 0;

	gets(a);
	len = strlen(a);
	
	SmartInverFun(a,len);

	puts(a);

	return 0;
}

C语言阶段学习结束

你可能感兴趣的:(学习,c语言,linux,嵌入式硬件)