数据结构学习(1)——指针、结构体、链表(C语言)

算法题的对数据结构相关知识的要求较高,接下来将学习一段时间的数据结构,今天来介绍一下C语言中的指针、结构体和链表的知识。

指针

定义

指针是C语言中一个非常重要的知识点。首先需要明确的一点是:指针本身是一种数据类型,该变量保存的是对应类型变量的一个地址。保存了这个地址后,我们就可以通过这个地址访问到变量,操作该变量所在的内存空间(可以修改该变量)。

形象解释

小明在A地点放了1kg黄金 ,小明将A地址的地址写在一张纸Z1上,这张纸就相当于是一个指针变量指向黄金。小明将这张纸放在了B地点 ,又写了一张纸Z2,将Z1这张纸存放的地址 B地点 写在Z2这张纸上,那么Z2就相当于一个指针变量指向Z1。这样下来,小明就可以通过Z1找到黄金,也可以通过Z2找到Z1,从而找到黄金。这种方式就是通过指针访问变量的形象解释。

定义格式

数据类型 *指针变量名= 某个变量的地址/一段内存的地址;

同时,指针可以是多层的,例如要保存一个单层指针的地址,则可以加多一个*,然后对要保存的单层指针取址。(以此类推)

示例代码

cs 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() {
	int a = 10;
	//定义一个指针变量存储变量a的地址
	int *z1 = &a;
	//直接打印z1
	printf("z1=%d\n", z1);
	//打印z1地址下对应的变量
	printf("*z1=%d\n", *z1);
	//改变z1保存的地址对应的数据
	*z1 = *z1 + 10;
	printf("*z1=%d\n", *z1);
	int **z2 = &z1;
	printf("*z2=%d\n", *z2);
	printf("**z2=%d\n", **z2);
}

结构体

定义

结构体是C语言中一种重要的用户自定义复合数据类型,它允许将多个不同类型的数据元素(称为成员)组织在一起,形成一个整体。结构体的主要作用是封装数据,便于管理和操作复杂的数据集合。其作用和地位相当于Java中的对象,可以通过名字调用里面的成员并进行操作。

定义格式

①使用结构体变量

创建:struct 结构体名{ }; 大括号中可以书写不同类型的数据(属性)

调用:struct 结构体名 调用时的名 ; 相当于Java中的创建类的对象,然后通过对象调用属性

注意:使用结构体变量是调用使用的符号是" . "!

示例代码
cs 复制代码
#include <stdio.h>
#include <stdlib.h>

struct Student {
	int id;
	int age;
	char name;
};
int main() {
	struct Student s;
	s.name = 'M';
	s.age = 18;
	s.id = 27;
	printf("name=%c\n", s.name);
	printf("age=%d\n", s.age);
	printf("id=%d\n", s.id);
	return 0;
}

②使用结构体指针

创建:struct 结构体名{ };

调用:struct 结构体名 *调用时使用的名=(结构体名 *)malloc(sizeof(结构体名))

注意:使用结构体指针需要使用malloc函数分配内存地址,并且需要用小括号转换成"结构体类型的指针"的数据类型。并且,与使用结构体变量不同的还有在调用的时候需要用符号 "->" 调用结构体中的属性。

示例代码

cs 复制代码
#include <stdio.h>
#include <stdlib.h>

struct Student {
	int id;
	int age;
	char name;
};

int main() {
	struct Student *s = (Student *)malloc(sizeof(Student));
	s->age = 18;
	s->id = 27;
	s->name = 'm';
	printf("age=%d\n", s->age);
	printf("id=%d\n", s->id);
	printf("name=%c\n", s->name);
	return 0;
}

输出结果与上面"使用结构体变量"一致!

链表

定义

链表是通过指针相连保存数据的一种数据结构,其存储单元为节点。链表的特点是节点在内存中不必连续存储,节点的逻辑顺序是通过每个节点中的指针链接实现的,可以只通过头节点访问到链表不同位置的数据。

一个节点需要包括两个变量:一个用来存储数据,另一个变量是一个指针变量,用来存储下一个节点的地址。由于两个变量类型不一致,就需要用到结构体指针。

定义方法(先介绍不用循环的)

我们要书写一个结构体指针,在里面定义两个变量data和*next,然后在主函数中创建多个节点,并分配内存,最后通过调用data和*next并对其赋值,就可以建立起各个节点的联系。注意,创建完链表之后只需要使用头节点操作链表中的数据!

如果想要在链表中添加数据,只需要创建一个新的节点,赋上对应的data和*next即可。以添加到链表最后为例,data可以是键盘输入的,*next为NULL。

示例代码

cs 复制代码
#include <stdio.h>
#include <stdlib.h>

//定义一个结构体
struct ListNode {
	int data;
	ListNode *next;
};

int main() {
	//先创建多个节点,并分配内存
	ListNode *node1 = (ListNode *)malloc(sizeof(ListNode));
	ListNode *node2 = (ListNode *)malloc(sizeof(ListNode));
	ListNode *node3 = (ListNode *)malloc(sizeof(ListNode));
	ListNode *node4 = (ListNode *)malloc(sizeof(ListNode));
	ListNode *node5 = (ListNode *)malloc(sizeof(ListNode));
	node1->data = 100;
	node2->data = 200;
	node3->data = 300;
	node4->data = 400;
	node5->data = 500;

	//接下来将所有的节点连接
	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = node5;

	//接下来只能借助头节点进行链表的相关操作
	printf("1:%d\n", node1->data);
	printf("2:%d\n", node1->next->data);
	printf("3:%d\n", node1->next->next->data);
	printf("4:%d\n", node1->next->next->next->data);
	printf("5:%d\n", node1->next->next->next->next->data);

	//添加一个新的节点

	ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));
	node5->next = newNode;
	//将输入的数字添加到下一个节点上
	int n;
	printf("请输入一个数据添加到下一个节点:");
	scanf("%d", &n);
	newNode->data = n;
	newNode->next = NULL;
	printf("6:%d\n", node1->next->next->next->next->next->data);
	return 0;
}
相关推荐
蒙奇D索大3 小时前
【数据结构】考研算法精讲:分块查找的深度剖析 | 从“块内无序、块间有序”思想到ASL性能最优解
数据结构·笔记·学习·考研·改行学it
不太可爱的叶某人3 小时前
【学习笔记】kafka权威指南——第1章 初识kafka
笔记·学习·kafka
正经人_x3 小时前
学习日记20:GraphGPT
学习
v_for_van3 小时前
STM32简单的串口Bootloader入门
笔记·stm32·单片机·嵌入式硬件·物联网·学习
东木君_3 小时前
RK3588:MIPI底层驱动学习——入门第四篇(驱动精华:OV13855驱动加载时究竟发生了什么?)
单片机·嵌入式硬件·学习
悠哉悠哉愿意4 小时前
【ROS2学习笔记】分布式通信
笔记·学习·ros2
丰锋ff4 小时前
2010 年真题配套词汇单词笔记(考研真相)
笔记·学习·考研
驱动探索者5 小时前
linux 学习平台 arm+x86 搭建
linux·arm开发·学习
lingchen19065 小时前
b = [1 2 3;4 5 6;7 8 9]>> b(2,2)=[ ]??? Subscripted assignme
数据结构·算法