⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os5.c

📁 这个程序实现了内存空间的动态管理和分配
💻 C
字号:
#include<stdio.h>
#include<stdlib.h>
#define NULL 0
#define getjcb(type) (type*)malloc(sizeof(type))
#define getsub(type)  (type*)malloc(sizeof(type))

int num,num2;  //要调度的作业数和要回收的区域数
int m=0;     //已分配作业数
int flag;     //分配成功标志
int isup,isdown;   //回收区域存在上邻和下邻的标志
int is=0;

struct jcb{
		char name[10];
		char state;
		int ntime; //所需时间
	    int size;  //所需空间大小
        int addr;  //所分配分区的首地址
		struct jcb *link;
	} *ready =NULL, *p,*q,*as=NULL;//作业队列ready,已分配作业队列as
		typedef struct jcb JCB;
struct subarea{         //分区块
	    char name[10];
	    int addr;    //分区首地址
		int size;    //分区大小
		char state;
		struct subarea *link;
  } *sub=NULL,*r,*s,*cur; //空闲分区队列sub,当前分区指针cur
        typedef struct subarea SUB;


void sort() /* 建立对作业按到达时间进行排列的函数,直接插在队列之尾*/
{
 JCB *first;
 if(ready==NULL)  ready=p;
 else{
   first=ready;
   while(first->link!=NULL)
       first=first->link;
   first->link=p;
   p->link=NULL;
  }
}

void sort3()      /*建立对已分配作业队列的排列函数,直接插在队列之尾*/
{
 JCB *fir;
 if(as==NULL) as=q;
 else{
   fir=as;
   while(fir->link!=NULL)
     fir=fir->link;
   fir->link=q;
   q->link=NULL;
  }
  m++;
}

void input() /* 建立作业控制块函数*/
{
 int i;
 printf("\n请输入要调度的总作业数:");
 scanf("%d",&num);
 for(i=0;i<num;i++)
  {
   printf("\n作业号No.%d:\n",i);
   p=getjcb(JCB);
   printf("\n输入作业名:");
   scanf("%s",&p->name);
   printf("\n输入作业的大小:");
   scanf("%d",&p->size);
   printf("\n输入作业所需运行时间:");
   scanf("%d",&p->ntime);
   p->state='w';
   p->link=NULL;
   sort(); /* 调用sort函数*/
  }
 printf("\n 按任一键继续......\n");
 getch();
}





void input2()     /*建立要回收区域的函数*/
{
 JCB *k;
 int has;
 q=getjcb(JCB);
 printf("\n输入区域名(作业名):");
 scanf("%s",&q->name);
 p=as;
 while(p!=NULL)
  {if(strcmp(p->name,q->name)==0)  /*在已分配作业队列中寻找*/
       {
        q->addr=p->addr;
        q->size=p->size;
        has=1;    /*输入作业名存在标志位*/
        if(p==as)  as=p->link;    /*在已分配作业队列中删除该作业*/
        else
          {k=as;
	       while(k->link!=p)  k=k->link;
	       k->link=k->link->link;      /*删除*/
	      }
	    printf("输出该作业首地址:%d\n",q->addr);
        printf("输出该作业大小:%d\n\n",q->size);
        q->link=NULL;
        break;
       }
   else
       {p=p->link; has=0;}   /*输入作业名不存在标志*/
  }
 if(has==0)
  {printf("\n输入作业名错误!请重新输入!\n");
   input2();
  }  
}



void print()
{printf("\n\n\n\n");
 printf("\t\t**************************************\n");
 printf("\t\t\t三.存储管理实验演示\n");
 printf("\t\t**************************************\n\n\n");
 printf("\t\t\t\t蓝小花\n");
 printf("\t\t\t\t计算机学院\n");
 printf("\t\t\t\t软件4班\n");
 printf("\t\t\t\t3204007102\n");
 printf("\t\t\t\t2006年12月\n");
 printf("\n\n\n");
 printf("\t\t\t按任意键进入演示");
 getch();
 system("cls");
}



void init_sub()       /*初始化空闲分区表*/
{
 r=getsub(SUB);
 strcpy(r->name,"one"); r->addr=5; r->size=10; r->state='n';
 sub=r;
 s=getsub(SUB);
 strcpy(s->name,"two"); s->addr=20; s->size=120; s->state='n';
 sub->link=s;r=s;
 s=getsub(SUB);
 strcpy(s->name,"three"); s->addr=160; s->size=40; s->state='n'; 
 r->link=s;r=s;
 s=getsub(SUB);
 strcpy(s->name,"four"); s->addr=220; s->size=10; s->state='n'; 
 r->link=s;r=s;
 s=getsub(SUB);
 strcpy(s->name,"five"); s->addr=250; s->size=20; s->state='n'; 
 r->link=s;r=s;
 s=getsub(SUB);
 strcpy(s->name,"six"); s->addr=300; s->size=80; s->state='n'; 
 r->link=s;r=s;
 s=getsub(SUB);
 strcpy(s->name,"seven"); s->addr=400; s->size=60; s->state='n'; 
 r->link=s;r=s;
 s=getsub(SUB);
 strcpy(s->name,"eight"); s->addr=480; s->size=300; s->state='n'; 
 r->link=s;r=s;
 s=getsub(SUB);
 strcpy(s->name,"nine"); s->addr=850; s->size=150; s->state='n'; 
 r->link=s;r=s;
 s=getsub(SUB);
 strcpy(s->name,"ten"); s->addr=1200; s->size=60; s->state='n'; 
 r->link=s;
}
//--------------------------------------------------------------------------
void disp()    /*空闲分区表的显示函数*/
{
 printf("\n\n");
 printf("\t\t 分区          首地址           长度          状态 \n");
 r=sub;
 while(r!=NULL)
   {
    printf("\t\t %s\t\t%d\t\t%d\t\t%c\n",r->name,r->addr,r->size,r->state);
    r=r->link;
   }
 printf("\n");
}

//--------------------------------------------------------------------------
void disp2()   /*显示已分配内存的作业表函数*/
{
 printf("\n\n");
 printf("\t\t 作业名         首地址          长度          状态 \n");
 p=as;
 while(p!=NULL)
   {
    printf("\t\t %s\t\t%d\t\t%d\t\t%c\n",p->name,p->addr,p->size,p->state);
    p=p->link;
   }
 printf("\n\n");
}


//--------------------------------------------------------------------------
void assign2(JCB *pr) /*首次适应作业分区*/
{
 SUB *k;
 r=sub;   /*从空闲表头开始寻找*/
 while(r!=NULL)
  {
   if(((r->size)>(pr->size))&&(r->state=='n'))   /*有空闲分区大于作业大小的情况*/
	  {
	   pr->addr=r->addr;
	   r->size-=pr->size;
	   r->addr+=pr->size;
	   flag=1;       /*分配成功标志位置1*/
	   q=pr;
	   q->state='r';
	   sort3();     /*插入已分配作业队列*/
	   printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr);
	   break;
	  }
   else if(((r->size)==(pr->size))&&(r->state=='n'))    /*有空闲分区等于作业大小的情况*/
	  {
	   pr->addr=r->addr;
	   flag=1;    /*分配成功标志位置1*/
	   q=pr;
	   sort3();	    /*插入已分配作业队列*/
	   s=sub;       /*空闲分区已完成分配,应删除*/
	   while(s->link!=r)  s=s->link;
	   s->link=s->link->link;	 /*删除空闲分区*/
	   printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr);
	   break;
	 }
   else
         {r=r->link;  flag=0;}
}
 if(flag==0)           /*作业过大的情况*/
 {
  printf("作业%s长度过大,内存不足,分区分配出错!\n",p->name);
  is=1;
 }
}

//--------------------------------------------------------------------------
void reclaim2(JCB *pr)       /*首次适应与循环首次适应区域回收*/
{
 SUB *k;
 r=sub;
 while(r!=NULL)
 {
  if(r->addr==((pr->addr)+(pr->size)))     /*回收区域有下邻*/
    {
	  pr->size+=r->size;
	  s=sub;
	  isdown=1;     /*下邻标志位置1*/
	  while(s!=NULL)
	  {
	   if(((s->addr)+(s->size))==(pr->addr))   /*有下邻又有上邻*/
	    {
	     s->size+=pr->size;
	     k=sub;
	     while(k->link!=r)  k=k->link;
	     k->link=k->link->link;
	     isup=1;      /*上邻标志位置1*/
	     break;
	    }
	   else
	    {s=s->link; isup=0;}    /*上邻标志位置0*/  
	  }
 	  if(isup==0)               /*有下邻无上邻*/
	   { 
	     r->addr=pr->addr;
	     r->size=pr->size;
	   }
	 break;	   
    }
 else 
   {r=r->link; isdown=0;}     /*下邻标志位置0*/
 }  
 if(isdown==0)              /*区域无下邻*/
    { 
      s=sub;
      while(s!=NULL) 
	  {
	   if(((s->addr)+(s->size))==(pr->addr))   /*无下邻但有上邻*/
	     {
	      s->size+=pr->size; 
	      isup=1;        /*上邻标志位置1*/
	      break;
	     }
	   else 
	     { s=s->link; isup=0;}     /*上邻标志位置0*/
	  }
	  if(isup==0)           /*无下邻且无上邻*/
	       { 
	         k=getsub(SUB);   /*重新生成一个新的分区结点*/
	         strcpy(k->name,pr->name);
	         k->addr=pr->addr;
	         k->size=pr->size;
	         k->state='n';
	         r=sub;
	         while(r!=NULL)
	         {
	          if((r->addr)>(k->addr))   /*按分区首地址排列,回收区域插在合适的位置*/
	            {
	              if(r==sub)       /*第一个空闲分区首址大于回收区域的情况*/
	                  { k->link=r; sub->link=k; }
	              else
	                 {
	                  s=sub;
	                  while(s->link!=r)  s=s->link;    
	                  k->link=r;
	                  s->link=k;
	                 }
	              break;
	            }
	          else r=r->link;
	         }
	        if(r==NULL)     /*所有空闲分区的首址都大于回收区域首址的情况*/
	           {
	             s=sub;
	             while(s->link!=NULL)  s=s->link;
	             s->link=k;
	             k->link=NULL;
	           }
	       }    
    }
 printf("\n区域%s己回收.",pr->name);
}

menu()
{
  printf("\n\n\n\t\t**************************************\n");
 printf("\t\t\t存储管理实验演示\n");
 printf("\t\t**************************************\n\n\n");
 printf("\t\t\t 1. 显示空闲分区                  \n");
 printf("\t\t\t 2. 分配和回收作业                    \n");
 printf("\t\t\t 0. 退出                    \n");
 printf("\t\t\t请选择你要的操作:");
 switch(getchar())
{
    case '1':
       system("cls");
        disp();
        getch();
        system("cls");
         menu();
        break;
 case '2':
            system("cls");
            printf("\n首次适应算法");
            input();
            printf("\n");
            while(num!=0)
              {
                p=ready;
                ready=p->link;
                p->link=NULL;
                assign2(p);
                num--;
              }
            printf("\n显示回收后的空闲分区表和已分配作业表...");
            getch();
            printf("\n\t\t              完成分配后的空闲分区表             \n");
            disp();
            printf("\n\t\t                  已分配作业表                   \n");
            disp2();
            if(is==0)
               printf("\n 全部作业已经被分配内存.");
            else printf("\n 作业没有全部被分配内存.\n");

            printf("\n\n按任意键进行区域回收.");
            printf("\n");

            while(as!=NULL)
              {getch();
               input2();
               printf("按任意键继续...");
               getch();
               printf("\n");
               reclaim2(q);
               printf("\n显示回收后的空闲分区表和已分配作业表...");
               getch();
               printf("\n\t\t              回收后的空闲分区表             \n");
               disp();
               printf("\n\t\t                已分配作业表                 \n");
               disp2();
               printf("\n继续回收...(Enter)");
              }
            printf("\n所有已分配作业已完成!");
            printf("\nPress any key to return...");
            getch();
            system("cls");
            menu();
            break;

    case '0':
           system("cls");
           break;
           
    default:
           system("cls");
           menu();
           
}
}




void main()     /*主函数*/
{
 init_sub();
 print();
 menu();
} 	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -