本文主要为mooc课程上北京理工大学C语言程序设计相关知识点的笔记与整理。
关于指针数组与数组指针的说明:https://www.cnblogs.com/mq0036/p/3382732.html
关于运算符优先级的说明:http://c.biancheng.net/view/161.html
1 typedef自定义类型
之前的内容中,结构和联合可以定义全新的自定义类型,而typedef则不产生全新的自定义类型,它是来说明一个数据类型,替代已有的数据类型。例如,我们可以使用一个有意义的名字,来替代已有的类型,提高程序的可读性;可以给一个复杂的数据类型起一个简单的名字,提高程序的应用性;也可以定义一个其他语言中的关键字来说明c语言的数据类型,提高程序的可移植性。
可以利用typedef来定义c语言中没有的数据类型
没有typedef ,OLD是一个结构体变量;有typedef,OLD是一个结构体类型,即DATA的别名。
2 枚举类型
系统会自动给数据列表中的数据从0开始赋值。
大括号中的值作为常量不可以被赋值,但可以被直接引用。
通过枚举类型可以定义一个取值有限的变量;取值是通过常量来进行描述的。
3 链表的概念
动态数据类型代表——链表
顺序存取单元是一次性分配,所以要按最大需要的空间来分配存储空间,可能存在空间分配的效率问题。
定义结点最重要是要在其指针域定义一个指向该种结构的指针。
4 链表的基本操作
如何开辟存储空间:
在内存分配与释放的过程中要求malloc与free配对使用。若未使用free()的话,会导致malloc分配的内存空间泄露。
表头结点不存储基本信息。p指向表头结点的首地址,而表头指针也需要指向表头结点的首地址,等效于将p赋给head。
表头结点在环链表中可以提示当前访问的结点是第几个数据结点。
相关知识点代码实现如下:
#include<stdio.h>
#include<stdlib.h>
struct node
{
char name[20], address[20], phone[15];
struct node* link;
};
typedef struct node NODE;
main()
{
int len;
NODE* head;
NODE* p;
p = (NODE*)malloc(sizeof(NODE));//开辟新存储区,申请表头结点
p->link = NULL;
head = p;//表头指针指向表头结点
int create(NODE* head,int n);//创建链表
int length(NODE * head);//求链表长度
int insert_node(NODE * head, NODE * p, int i);//在第i个数据结点之后插入新结点
int output(NODE * head);//输出链表内容
int delete_node(NODE * head, int i);//删除第i个结点
create(head, 3);//创建一个有三个数据结点的链表
len = length(head);
printf("%d\n", len);//打印链表长度
p = (NODE*)malloc(sizeof(NODE));
gets(p->name);
insert_node(head, p, 1);//在第一个数据结点后插入新结点
len = length(head);
printf("%d\n", len);//输出插入新结点后的链表长度
output(head);//输出链表内容
delete_node(head, 2);//删除第二个结点
len = length(head);
printf("%d\n", len);//输出删除结点之后的链表长度
output(head);
getchar();
}
int create(NODE* head, int n)//创建结点需要表头指针和创建结点个数作为参数
{
NODE* p;
for (; n > 0; n--)
{
p = (NODE*)malloc(sizeof(NODE));
gets(p->name);
p->link = head->link;
head->link = p;//表头结点后插入新结点
}
return 0;
}
int output(NODE* head)
{
NODE* p;
p = head->link;
while (p != NULL)
{
puts(p->name);
p = p->link;
}
return 0;
}
int insert_node(NODE* head, NODE* p, int i)//表头指针,待插入的结点,插入结点的位置(插在第几个数据结点之后)
{
NODE* q;
int n = 0;
for (q = head; n < i && q->link != NULL; ++n)
q = q->link; //定位
p->link = q->link;
q->link = p;
return 0;
}
int delete_node(NODE* head, int i)
{
NODE* p, * q;
int n;
for (n = 0, q = head; n < i - 1 && q->link != NULL; ++n)
q = q->link; //定位
if (i > 0 && q->link != NULL)
{
p = q->link;
q->link = p->link;
free(p);
}
}
int length(NODE* head)
{
int len;
NODE* p;
for (len = 0, p = head; p->link != NULL; ++len)
p = p->link;
return(len);
}
输出结果展示如下:
先创建具有三个数据结点的链表,然后打印链表的长度;然后输入插入结点的name,然后打印链表长度并打印链表内容,接着删除第二个结点,打印此时的链表数据结点长度和链表内容。、