学过数据结构的不妨来看一看!

wmzlq wmzlq 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
想把一个链表保存在文件中,但是保存后再输出时出现了问题.(问题就出现在文件尾eof上面),跟踪调试,发现保存的是有两个节点的链表,但读出的是有三个节点的链表(最后多出的一个节点不符合),想问一下各位大虾,有没有一个好的方法来重载"<<"运算符才能避免这种失误....
#include<fstream.h>

struct Person //一个简单的结构体
{
int id;
char name[20];
Person* next;
};

void save(Person* &); //保存
void getout(Person* &); //从文件中读出重建链表

ostream& operator <<(ostream& oo,Person& d)
{
oo<<d.id<<" "<<d.name<<" "; //估计是这里出现了问题因导致对文件尾的判断出错
return oo;
}

istream& operator >>(istream& oo,Person& d)
{
oo>>d.id>>d.name;
return oo;
}

void main()
{
Person* List;
Person* &head=List;
Person* pS;
pS=new Person;

cout<<"请输入身份证号码:"<<endl;
cin>>pS->id;
cout<<"请输入姓名:"<<endl;
cin>>pS->name;

head=pS;
pS=new Person;

cout<<"请输入身份证号码:"<<endl;
cin>>pS->id;
cout<<"请输入姓名:"<<endl;
cin>>pS->name;

head->next=pS;
pS->next=NULL; //简单起见链表只有两个节点

save(head);

head=NULL; //为了验证getout函数,特意将head置为NULL

getout(head);
}

void save(Person* &head)
{
Person* pGuard;
fstream outfile("d:\\myprogram.txt",ios::out|ios::ate);

for(pGuard=head;pGuard!=NULL;pGuard=pGuard->next)
{
outfile<<*pGuard;
}
cout<<"已经被保存!"<<endl;
}

void getout(Person* &head)
{
fstream infile("d:\\myprogram.txt",ios::in);
Person* pGuard;
Person* pS;
pGuard=pS;
pS=new Person;

while(!infile.eof())
{
infile>>*pS;

if(head==NULL)
head=pS;
else
{
pGuard->next=pS;
}

pGuard=pS;
pS=new Person;
}
pGuard->next=NULL;
}
...全文

相关推荐

Java concurrency之公平锁(一)_动力节点Java学院整理

主要为大家详细介绍了Java concurrency之公平锁的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

weixin_38727928

浅谈Java并发 J.U.C之AQS:CLH同步队列

AQS内部维护着一个FIFO队列,该队列就是CLH同步队列。下面小编来简单介绍下这个队列

weixin_38694336

【Java并发编程】基于AQS的ReentrantLock加锁机制解析:CLH队列与CAS无锁算法在多线程同步控制中的应用研究

内容概要:本文详细解析了Java并发编程中的核心组件AbstractQueuedSynchronizer(AQS)的工作原理,重点围绕ReentrantLock的底层实现机制展开。文章首先介绍AQS如何通过构建CLH虚拟队列管理线程竞争,利用CAS操作实现无锁化同步,并结合LockSupport.park()与unpark()实现线程的阻塞与唤醒。随后深入分析加锁全过程,包括nonfairTryAcquire尝试获取锁、addWaiter将竞争失败的线程加入队列尾部、acquireQueued进行阻塞前重试及parkAndCheckInterrupt挂起线程,以及shouldParkAfterFailedAcquire根据前驱节点状态决定是否阻塞等关键步骤。最后概括了整个加锁流程,揭示了AQS如何高效处理线程争用与调度。; 适合人群:具备一定Java多线程基础,对并发编程感兴趣的研发人员,尤其是工作1-3年希望深入理解JUC底层原理的开发者;准备应对高并发面试的技术人员。; 使用场景及目标:①深入掌握ReentrantLock与AQS的关系及其加锁机制;②理解非公平锁、可重入性、线程阻塞唤醒、队列管理等核心概念的实现原理;③提升对JUC包下同步器设计思想的理解,助力面试中应对“AQS原理”类高频问题。; 阅读建议:建议结合源码边读边实践,重点关注CAS、Node节点状态变更、队列维护逻辑,同时可通过调试ReentrantLock的加锁解锁过程加深理解。配合文中提到的技术讲座学习效果更佳。

Poulyield

面试必问之AQS原理详解.pdf

AQS 原理 lock 最 常 用 的 类 就 是 ReentrantLock , 其 底 层 实 现 使 用 的 是 AbstractQueuedSynchronizer(AQS) 简单来说 AQS 会把所有的请求线程构成一个 CLH 队列,当一个线程执行完毕 (lock.unlock())时会激活自己的后继节点,但正在执行的线程并不在队列中, 而那些等待执行的线程全部处于阻塞状态,经过调查线程的显式阻塞是通过调用 LockSupport.park() 完成,而 LockSupport.park() 则调用 sun.misc.Unsafe.park()本地方法,再进一步,HotSpot 在 Linux 中中通过调用 pthread_mutex_lock 函数把线程交给系统内核进行阻塞。

ゞ浪人与酒丶0

AQS原理解析[项目代码]

AQS(AbstractQueuedSynchronizer)是Java中用于构建锁和同步器的抽象类,位于java.util.concurrent.locks包下。其核心思想是通过CLH队列管理线程的阻塞与唤醒,实现共享资源的独占或共享访问。AQS使用state变量表示同步状态,并提供原子操作方法。文章详细解析了AQS的工作原理,包括CLH队列结构、资源共享方式(独占与共享),以及如何通过重写钩子方法来自定义同步器。此外,还以ReentrantLock和CountDownLatch为例,展示了AQS在实际同步器中的应用。

blue
评论 2
收藏 已收藏
分享
返回顶部
wmzlq
C语言 70,039 成员 243,237 内容