目录
前言
这一篇博客解决你结构体中.和->的疑惑。关于C语言结构体中
& * -> . 在结构体中的应用
这一关,你写的代码也在一直报错吗?我猜测,应该和我一样,使用的HNode或者HNode*一直各种报错。
由于这关同时定义了结构体类型和结构体类型的指针【之前遇到的关卡一般都是定义成指针或者都定义成结构体类型,第一次见这种,如果不能改声明,这就涉及两者间用&和*的相互转换了】,散列查找没啥好说的,很好想明白。但我写完后,测评时一直提示我的代码中包含.和->所在的行是存在问题的,我检查逻辑,并未发现错误,猜测是结构体没用正确,之前对.和->也确实理解的不够透彻。
struct HNode {
int key; //假设关键码为整数
HNode* next;
};
struct LHTable {
HNode* pn; //指向散列表,每个表结点是独立链表的表头结点.【个人注释:这里是将pn当做一个HNode的结构体数组来用了,并非一个HNode*的指针】
int n; //散列表的长度,一般取(小于等于数据个数的最大)质数
};
最终看了多篇关于这方面的博客终于弄明白了,我将用简单明了的方式给也对这个知识点抱有疑惑的各位解释清楚【听不明白来线下真实我】
正文
用. 需要声明结构体。格式是,结构体类型名+结构体名【HNode Dome】,则直接用.就能访问到结构体Dome中的数据域和指针域。
【int a = Dome.key;
HNode* node = Dome.next; 】
用-> 需要声明结构体类型的指针。【HNode* Dome】,则直接用->来访问指针所指向的相应地址的结构体的数据域和指针域。
【int a = Dome->key;
HNode* node = Dome->next; 】
再通俗的总结一下: .前面的是一个具体结构体,而->前面是一个指针(你应该知道,指针也就是地址)
铺垫了些知识点,重头戏来了!!!!
在一行语句中即有结构体,又有结构体类型的指针,如何赋值或正常引用:[记住&取地址符,和*是一对逆运算符]
在结构体前加上&,就成了指针了,也就可以用->了,在指针前加上*,就变成结构体了,用.来访问域
但要注意一下优先级,不放心就加个括号。且要让等式左右两边输出类型一致【检查一下,不能一边指针,一边不是指针】
【HNode H1; HNode* H2;】
HNode* H3=(&H1)->next;
HNode H4=(*H2).next;
---------------------------------------------------------------------------------
下面代码中的应用:
pt->pn[i]=*(pt->pn[i].next); 代码第97行 //pt->pn[i]是一个结构体,
pre=&(pt->pn[i]); 代码第103行 //pre的声明: HNode* pre;
作者的话
对于那些直接找代码的同学,我真心劝诫你,数据结构是很重要的课程,这代码逻辑并不难,学校讲的不会?只会理论,不会代码?推荐去看这个宝藏视频【别问为什么】:UP从0到1带你手撕数据结构全集(C语言版)_哔哩哔哩_bilibili
如果确实很急,把我的先借给你用用,但希望你会重新写一遍【没看答案,自己写的,写的不好 请谅解!!】你应该早听说过数据结构真的真的真的很重要,你也该想想,如果学了这门课不能实践,写不出代码,这不和现实所需,社会所求脱轨吗?找工作呢?【打住,我也是学生,对找工作的要求不太清楚,只是个人主观觉得有问题】
代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "indLnkHash.h"
LHTable* ILH_Create(int n)
//创建散列表, n为表长度,最佳取值:n取小于等于数据个数的最大质数
{
HNode* pn=(HNode*)malloc(sizeof(HNode)*n);
for (int i=0; i<n; i++) {
pn[i].key=0;
pn[i].next=NULL;
}
LHTable* pt=(LHTable*)malloc(sizeof(LHTable));
pt-> pn=pn;
pt->n=n;
return pt;
}
void ILH_Free(LHTable* pt)
//释放散列表
{
if (pt==NULL) return;
for (int i=0; i<pt->n; i++) {
HNode* curr=pt->pn[i].next;
while (curr) {
HNode* next=curr->next;
free(curr);
curr=next;
}
}
free(pt->pn);
free(pt);
}
bool ILH_InsKey(LHTable* pt, int x)
//插入关键码x
//返回true,表示插入成功
//返回false,表示插入失败(关键码已经存在)
{
/*请在BEGIN和END之间实现你的代码*/
/*****BEGIN*****/
if(ILH_FindKey(pt,x))
return false;
int i=x%(pt->n);
if(pt->pn[i].key==0)
pt->pn[i].key=x;
else
{
HNode* temp=&(pt->pn[i]);
HNode* p=(HNode*)malloc(sizeof(HNode));
while(temp->next)
temp=temp->next;
temp->next=p;
p->key=x;
p->next=NULL;
}
return true;
/******END******/
/*请不要修改[BEGIN,END]区域外的代码*/
}
bool ILH_FindKey(LHTable* pt, int x)
//查找关键码x
//返回true表示找到
//返回false表示没找到
{
int d=x%pt->n;
if (pt->pn[d].key==0) {
return false;
}
else if (pt->pn[d].key==x)
return true;
HNode* curr=pt->pn[d].next;
while (curr && curr->key!=x) curr=curr->next;
if (curr) return true;
else return false;
}
bool ILH_DelKey(LHTable* pt, int x)
//删除关键码
//返回true表示该关键码存在,且成功删除
//返回false表示该关键码不存在
{
/*请在BEGIN和END之间实现你的代码*/
/*****BEGIN*****/
if(!ILH_FindKey(pt,x))
return false;
int i=x%(pt->n);
if(pt->pn[i].key==x)
{
if(pt->pn[i].next==NULL)
pt->pn[i].key=0;
else
pt->pn[i]=*(pt->pn[i].next);
}
else
{
HNode* pre;
HNode* del;
pre=&(pt->pn[i]);
del=pre->next;
while(del->key!=x)
{
pre=pre->next;
del=del->next;
}
pre->next=del->next;
free(del);
}
return true;
/******END******/
/*请不要修改[BEGIN,END]区域外的代码*/
}
void ILH_Print(LHTable *pt)
{
for (int i=0; i<pt->n; i++) {
printf("%5d:", i);
if (pt->pn[i].key) {
printf("%d", pt->pn[i].key);
HNode* curr=pt->pn[i].next;
while (curr) {
printf("->%d", curr->key);
curr=curr->next;
}
printf("\n");
}
else
printf("-\n");
}
}