C语言简单企业链表实现

 my_print中的强转:

在 C 语言中,结构体的第一个成员会放置在结构体的开始位置,而且结构体的布局是按照成员定义的顺序进行的。因此,在你的代码中,Student 结构体的第一个成员变量就是 LinkNode 类型的 node

通过将 LinkNode *data 强制转换为 Student *student,可以将 Student 结构体的地址赋给指针 student,从而正确地访问和操作 Student 结构体中的字段。

请注意,强制类型转换只是告诉编译器将某个指针视为另一种类型的指针,但它并不改变实际的内存布局或数据类型。因此,当你确保 LinkNode 结构体是作为 Student 结构体的第一个成员时,并且两者的大小和布局相同,强制类型转换是合法的。

然而,在进行强制类型转换时,请务必确保 LinkNode 指针指向的实际数据类型是 Student,否则会导致访问错误的内存位置。如果无法确定类型或存在不确定性,最好使用更通用的方式来处理节点的内容。

LinkNode* pCurrent = &(list->head);与LinkNode* tmp = list->head.next;的区别:

第一个取得的是链表头节点指针 LinkNode* 的地址,并把它赋给了pCurrent 指针,然后通过pCurrent->next可以访问到下一个结点

在删除操作里要操作的是结点,在插入操作里操作的也是结点,所以用这个。而且注意传入的参数是LinkNode*类型的,要传入Student的Student.node。

第二个取得的是链表中第一个数据节点的指针 LinkNode*

最大的区别就是第一个取得就是头结点,让指针就从头结点开始,第二个就是直接从头结点的下一个数据结点开始。因为.next对应的就是LinkNode*类型的,所以从视觉效果上来看&(list->head)这俩有区别,但实质上都是一样的。

 

#include<stdio.h>
#include<stdlib.h>
#include <string.h>
typedef struct LinkNode {//链表结点
	struct LinkNode* next;
}LinkNode;
typedef struct LinkList {//链表结构体
	struct LinkNode head;
	int size;
}LinkList;
typedef struct Student {
	LinkNode node;
	int age;
	char name[64];
}Student;
LinkList* Init_Linklist() {//初始化链表
	LinkList* list = (LinkList*)malloc(sizeof(LinkList));//分配内存空间
	list->head.next = NULL;//头结点默认指向NULL
	list->size = 0;
	return list;
}

void insert_list_by_position(LinkList* list, int position, LinkNode* data){
	if (list == NULL) {
		return;
	}
	if (data == NULL) {
		return;
	}
	if (position<0|| position>list->size) {
		position = list->size;
	}
	LinkNode* tmp = &(list->head);
	for (int i = 0; i < position - 1;i++) {
		tmp = tmp->next;
	}
	data->next = tmp->next;
	tmp->next = data;
	list->size++;
}
void insert_list(LinkList* list,LinkNode* data) {//尾插法
	if (list == NULL) {
		return;
	}
	if (data == NULL) {
		return;
	}
	LinkNode* tmp = &(list->head);
	while (tmp->next != NULL) {
		tmp = tmp->next;
	}
	data->next = NULL;
	tmp->next = data;
	list->size++;
}
void remove_linklist(LinkList* list, int pos)
{
	if (pos < 0 || pos >= list->size)
	{
		return;
	}
	if (list != NULL)
	{
		LinkNode* pCurrent = &(list->head);//得到了头结点的指针

		for (int i = 0; i < pos; i++)
		{
			pCurrent = pCurrent->next; // 找到当前下标的指针
		}
		// pCurrent 是pos位置的前驱节点,将pos位置的指针删除掉,就相当于是
		// pos的前驱节点指向pos的下一个节点,因为不是自己开辟的内存,不需要释放内存
		pCurrent->next = pCurrent->next->next;
		list->size--;
	}
	return;
}

void my_print(LinkList* list) {
	LinkNode* tmp = list->head.next;
	while (tmp!=NULL) {
		Student* p = (Student*)tmp;
		printf("age = %d,name = %s\n",p->age,p->name);
		tmp = tmp->next;
	}



}
int main() {
	LinkList* a = Init_Linklist();
	Student s1, s2, s3, s4, s5,s6;
	s6.age = 0;
	strcpy_s(s6.name, "666");
	s1.age = 10;
	strcpy_s(s1.name,"aaa");
	s2.age = 20;
	strcpy_s(s2.name, "bbb");
	s3.age = 30;
	strcpy_s(s3.name, "ccc");
	s4.age = 40;
	strcpy_s(s4.name, "ddd");
	s5.age = 50;
	strcpy_s(s5.name, "eee");
	
	insert_list(a,&(s1.node));
	insert_list(a, &(s2.node));
	insert_list(a, &(s3.node));
	insert_list(a, &(s4.node));
	insert_list(a, &(s5.node));
	my_print(a);
	printf("------------------\n");
	insert_list_by_position(a,3, &(s6.node));
	my_print(a);
	printf("------------------\n");
	remove_linklist(a,2);
	my_print(a);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值