指针与链表:C语言核心数据结构解析

        指针,是一个存储变量地址的变量。链表是一种线性数据结构,由一系列节点(Node)组成,每个节点包含数据域(存储数据)和指针域(指向下一个节点的地址)。今天,我们就来了解指针和链表的相关知识。

指针

       指针本身是一种数据类型,由它创建的变量可以存储其他变量的地址。定义的格式为:

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

例如: int g=10;int *z1=&g;这样就将g变量存储数据的地址存入了z1变量中。

会存储同样要会取指针存储的地址的值:int n=*z1;  这样就将g的值赋给了n。

如图

将g的地址赋给z1,打印出的z1就是z1变量变量的值,&z1,则是z1变量的地址,这里不能直接:int m=z1;因为指针类型的变量不能直接赋值给基本数据变量类型,类型不匹配。我们如果想继续存储指针z1的地址,则需要使用双指针:int **z2=&z1;不能使用单指针赋值单指针。

如图,通过输出的可以看出,可以通过**z2来访问g的值,并且z2所存储的值是z1的地址。

       然后,我们就会有一个疑问,改变数据的存储地址,例如写个n++,会不会改变存储的值,也就是g的值。显然是不会的,因为这里的赋值运算,是将原来的拷贝一份再给n,所以n发生变化,是不会去影响到原来的值。所以,要想改变变量的值,只有通过地址来改变:**z2=100;这样,g的之就会变为100。

       在函数参数中,如果不是指针或者数组,传递的参数都是拷贝的值,继续修改,不会影响原来的变量。赋值运算不等于传递。

        咱们定义变量的时候,还有一种情况,提前准备好一段内存空间,但是我不知道它的值是多少,我就可不先不赋值,然后这段内存空间,用来以后存储数据。所以要学习一下库函数当中的动态分配内存。动态分配内存,这个动态指的是程序运行过程当中,我们通过代码去分配,而不是指它可以自己动态调节内存大。我们需要再导入一个库:Include<stdlib.h>.然后使用 int *p=malloc(4);来定义变量,

if(p1==NULL){
printf("内存分配失败\n");
free(p1);
}

可以用这个if语句来判断是否内存不足,如果不足,就是用free,来释放p1的内存。

链表

       链表结构的存储单元为节点,一个节点变量中需要包含两个变量,其中一个是用来存储值的,另一个变量是一个指针变量,用来存储另一个节点的地址,而像这样需要使用一个变量,存储多个不同类型变量的结构,在C语言中叫做结构体。这里我们自己创建节点,然后将节点相连,组成一个链表,对于链表的操作,则是从头节点开始操作。

typedef struct ListNode {
 int data;
 struct ListNode *next;
} ListNode;

链表节点定义 ListNode结构体的名称,typedef是重命名的意思。

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);

首先,创建存储空间,然后存入数据,接着将节点相连,其中使用node,而不是用它的地址,因为node本身,就是存储数据的地址。相连后,在打印链表的值时,不能使用node1以外的节点名,node1是头节点。

 int n = 0;
 printf("请输入一个数据:\n");
 scanf("%d",&n);
 ListNode *newNode = (ListNode*)malloc(sizeof(ListNode)); 
 newNode->data=n;
 node1->next->next->next->next->next=newNode;
 newNode->next = NULL;

如果想要添加元素,首先我们要给出内存,然后将数据存入链表,记住要以node1开头,然后,将新节点的下一个指向NULL。

ListNode *tempNode = node1;
 while(tempNode->next == NULL){
 printf("%d >> ",tempNode->data);
 tempNode = tempNode->next;
 }

此外,我们也可以用循环来代替链表达到所需要的效果。

结构体

格式:typedef struct 结构变量名{//结构体的成员变量名}结构体别名;

结构体以及指针初始化,都需要malloc函数,来分配内存地址。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值