链表就是多个结构体变量连接在一起形成的链式结构
有头链表是第一个节点里面不存数据
无头链表是第一个节点里面存数据
有头链表
创建表头,表头数据不做初始化,只需要初始化指针就行
一个指针要想变成一个变量,需要用动态内存申请,
struct Node* creatHead()
{
struct* Node headNode = (struct Node* )malloc(sizeof(struct Node));
assert(headNode);
headNode->next=NULL;
return headNode;
}
申请可能失败,可用assert()
一、assert定义
我一直以为 assert 仅仅是个报错函数,事实上,它居然是个宏,并且作用并非"报错"。
在经过对其进行一定了解之后,对其作用及用法有了一定的了解,assert() 的用法像是一种"契约式编程",在我的理解中,其表达的意思就是,程序在我的假设条件下,能够正常良好的运作,其实就相当于一个 if 语句:
if(假设成立)
{
程序正常运行;
}
else
{
报错&&终止程序!(避免由程序运行引起更大的错误)
}
但是这样写的话,就会有无数个 if 语句,甚至会出现,一个 if 语句的括号从文件头到文件尾,并且大多数情况下,我们要进行验证的假设,只是属于偶然性事件,又或者我们仅仅想测试一下,一些最坏情况是否发生,所以这里有了 assert()。
assert 宏的原型定义在 assert.h 中,其作用是如果它的条件返回错误,则终止程序执行。
#include “assert.h”
void assert( int expression );
assert 的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向 stderr 打印一条出错信息,然后通过调用 abort 来终止程序运行。
使用 assert 的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。
在调试结束后,可以通过在包含 #include 的语句之前插入 #define NDEBUG 来禁用 assert 调用,示例代码如下:
#include
#define NDEBUG
#include
malloc函数使用形式
关于malloc所开辟空间类型:malloc只开辟空间,不进行类型检查,只是在使用的时候进行类型的强转。
举个例子:‘我’开辟你所需要大小的字节大小空间,至于怎么使用是你的事
mallo函数返回的实际是一个无类型指针,必须在其前面加上指针类型强制转换才可以使用
指针自身 = (指针类型*)malloc(sizeof(指针类型)*数据数量)
int *p = NULL;
int n = 10;
p = (int *)malloc(sizeof(int)*n);
1
2
3
在使用malloc函数之前我们一定要计算字节数,malloc开辟的是用户所需求的字节数大小的空间。
如果多次申请空间那么系统是如何做到空间的不重复使用呢?
在使用malloc开辟一段空间之后,系统会在这段空间之前做一个标记(0或1),当malloc函数开辟空间如果遇到标记为0就在此开辟,如果为1说明此空间正在被使用。
free函数
作用:释放malloc(或calloc、realloc)函数给指针变量分配的内存空间。
注意:使用后该指针变量一定要重新指向NULL,防止悬空指针(失效指针)出现,有效规避错误操作。
int main()
{
int *p = (int *)malloc(sizeof(int));
*p = 100;
free§;
p = NULL;
return 0;
1
2
3
4
5
6
7
free函数在释放空间之后,把内存前的标志变为0,且为了防止数据泄露,它会把所释放的空间用cd进行填充。
memset(数组,赋值,内存大小)函数的头文件在C语言中string.h
在C++中是cstring.h
#include<string.h>//C语言
#include//c++