帶有詳細(xì)注釋的操作系統(tǒng)首次適應(yīng)法C++程序-創(chuàng)新互聯(lián)

文章目錄
    • 內(nèi)容簡介
    • 程序代碼
    • 運(yùn)行效果

站在用戶的角度思考問題,與客戶深入溝通,找到威信網(wǎng)站設(shè)計(jì)與威信網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗(yàn)好的作品,建站類型包括:網(wǎng)站設(shè)計(jì)制作、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、國際域名空間、雅安服務(wù)器托管、企業(yè)郵箱。業(yè)務(wù)覆蓋威信地區(qū)。內(nèi)容簡介

操作系統(tǒng)實(shí)驗(yàn)課程的任務(wù),使用首次適應(yīng)算法完成內(nèi)存的分配與回收。
下面的代碼可以實(shí)現(xiàn)用戶指定的內(nèi)存初始化、內(nèi)存分配、內(nèi)存回收和連續(xù)隨機(jī)回收內(nèi)存直到得到一個完整內(nèi)存空間的操作。

程序代碼
#include#include#include#include#include#includeusing namespace std;

//前向引用聲明
struct AllocMem;                      
struct FreeMem;

static unsigned Memspace;             //定義內(nèi)存空間的總大?。ㄒ訩B為單位)
static string errorMessage;           //記錄創(chuàng)建內(nèi)存分區(qū)時的錯誤信息的字符串
static listAllocted_List;  //借助C++STL的鏈表結(jié)構(gòu)定義已分配分區(qū)鏈
static listFree_List;        //借助STL鏈表結(jié)構(gòu)定義的空閑分區(qū)鏈

//以結(jié)構(gòu)體的形式定義每一個已分配內(nèi)存分區(qū),內(nèi)容包括起始地址、分區(qū)大小和程序號
struct AllocMem
{unsigned Start_Address;  //內(nèi)存分區(qū)的開始地址(之所以用unsigned類型表示是為了突出地址只能為非負(fù)數(shù)),以KB為單位
	unsigned size;           //內(nèi)存分區(qū)的大?。ㄖ杂胾nsigned類型是為了表示分區(qū)大小只能為非負(fù)數(shù))
	unsigned processID;      //內(nèi)存分區(qū)對應(yīng)的程序號,基于類似的原因仍然使用unsigned類型定義

	//結(jié)構(gòu)體的顯式構(gòu)造函數(shù),參數(shù)為起始地址、分區(qū)大小和程序號,采用內(nèi)聯(lián)形式以進(jìn)一步提高執(zhí)行效率
	explicit inline AllocMem(const unsigned& Start_Address, const unsigned& size, const unsigned& processID) :\
		                     Start_Address(Start_Address), size(size), processID(processID) {}
};

//同樣以結(jié)構(gòu)體的形式定義未分配內(nèi)存分區(qū),內(nèi)容包括起始地址和大小
struct FreeMem
{unsigned Start_Address;  //內(nèi)存分區(qū)的開始地址(之所以用unsigned類型表示是為了突出地址只能為非負(fù)數(shù)),以KB為單位
	unsigned size;           //內(nèi)存分區(qū)的大?。ㄖ杂胾nsigned類型是為了表示分區(qū)大小只能為非負(fù)數(shù))

	//與已分配內(nèi)存分區(qū)類似的顯式構(gòu)造函數(shù)
	explicit inline FreeMem(const unsigned& Start_Address, const unsigned& size) :Start_Address(Start_Address), size(size) {}
};

//用于判斷新加入的內(nèi)存分區(qū)是否有效的函數(shù),根據(jù)已有的內(nèi)存分區(qū)表和新加入的內(nèi)存分區(qū)信息作為參數(shù),返回布爾值
bool isValid(const list& Allocted_List, const unsigned& Start_Address, const unsigned& size, const unsigned& processID,const unsigned& Memspace)
{//通過C++STL的增強(qiáng)型for循環(huán)逐一檢查新增加的內(nèi)存分區(qū)是否與之前的內(nèi)存分區(qū)存在矛盾
	for (auto& element : Allocted_List)
	{//第一種矛盾情況:發(fā)生進(jìn)程號重復(fù)
		if (element.processID == processID)
		{	errorMessage = "進(jìn)程號重復(fù)!";
			return false;
		}
		//第二種矛盾情況:發(fā)生內(nèi)存分區(qū)空間重合
		if (!(Start_Address >= element.Start_Address + element.size || Start_Address + size<= element.Start_Address))
		{	errorMessage = "內(nèi)存空間重合!";
			return false;
		}
		//第三種矛盾情況:分配空間高地址大于內(nèi)存空間大地址
		if (Start_Address + size >Memspace)
		{	errorMessage = "超過內(nèi)存空間大?。?;
			return false;
		}
	}
	//不存在矛盾,因此返回true值
	return true;
}

//用于輸出某一時刻的分區(qū)信息的函數(shù)
void print(void)
{cout<<"分區(qū)號      "<<  "起始地址    "<<  "分區(qū)大小    "<<  "進(jìn)程號      "<< endl;

	list::iterator it1(Allocted_List.begin());  //記錄已分配分區(qū)鏈的遍歷位置的迭代器
	list::iterator it2 (Free_List.begin());      //記錄空閑分區(qū)鏈的遍歷位置的迭代器
	unsigned pos(1);                                      //記錄當(dāng)前的分區(qū)號

	//當(dāng)兩個鏈表都還未遍歷完成時持續(xù)進(jìn)行循環(huán)
	while (it1 != Allocted_List.end() && it2 != Free_List.end())
	{//通過比較兩個鏈表中當(dāng)前節(jié)點(diǎn)的起始地址屬性,可以得知需要先按順序輸出哪一個節(jié)點(diǎn)的信息
		if (it1->Start_Address< it2->Start_Address)
		{	cout<< setw(6)<< setiosflags(ios::right)<< pos++<< setw(14)<< setiosflags(ios::right)<< it1->Start_Address \
				<< setw(12)<< setiosflags(ios::right)<< it1->size<< setw(10)<< setiosflags(ios::right)<< it1->processID<< endl;
			it1++;
		}
		else
		{	cout<< setw(6)<< setiosflags(ios::right)<< pos++<< setw(14)<< setiosflags(ios::right)<< it2->Start_Address \
				<< setw(12)<< setiosflags(ios::right)<< it2->size<< setw(10)<< setiosflags(ios::right)<< "無進(jìn)程"<< endl;
			it2++;
		}
	}
	//循環(huán)結(jié)束時,已經(jīng)完成遍歷了一個鏈表,那么就繼續(xù)將另一個鏈表中的信息輸出(類似于數(shù)據(jù)結(jié)構(gòu)中的歸并排序中的歸并過程)
	//第一種情況:已分配內(nèi)存分區(qū)鏈表先完成遍歷
	if (it1 == Allocted_List.end())
	{while (it2 != Free_List.end())
		{	cout<< setw(6)<< setiosflags(ios::right)<< pos++<< setw(14)<< setiosflags(ios::right)<< it2->Start_Address \
				<< setw(12)<< setiosflags(ios::right)<< it2->size<< setw(10)<< setiosflags(ios::right)<< "無進(jìn)程"<< endl;
			it2++;
		}
	}
	//第二種情況:空閑分區(qū)鏈表先完成遍歷
	else
	{while (it1 != Allocted_List.end())
		{	cout<< setw(6)<Start_Address \
				<< setw(12)<size<< setw(10)<< setiosflags(ios::right)<< it1->processID<< endl;
			it1++;
		}
	}
	cout<< endl;
}

//使用首次適應(yīng)法進(jìn)行內(nèi)存分區(qū)分配的函數(shù)
void FF_Allocate(void)
{unsigned pid;   //記錄進(jìn)程號
	unsigned space; //記錄空間大小

	//獲取用戶輸入的進(jìn)程號和空間大小
	cout<< "請輸入所需分配內(nèi)存的進(jìn)程的進(jìn)程號:";
	cin >>pid;
	cout<< "請輸入分配空間的大?。?;
	cin >>space;

	//遍歷已分配進(jìn)程表,判讀進(jìn)程號是否重復(fù)
	for (auto& e : Allocted_List)
	{if (e.processID == pid)
		{	cout<< "進(jìn)程號重復(fù),本次分配內(nèi)存空間結(jié)束!"<< endl;
			return;
		}
	}

	//循環(huán)遍歷空閑分區(qū)鏈,找到第一個可以容納當(dāng)前進(jìn)程的內(nèi)存分區(qū)
	list::iterator it = Free_List.begin();
	while (true)
	{//當(dāng)前內(nèi)存分區(qū)的容量足夠容納用戶進(jìn)程的情況
		if (it->size >= space)
		{	//記錄分區(qū)的起始位置
			unsigned start = it->Start_Address;
			//首先修改空閑分區(qū)鏈中的相應(yīng)內(nèi)容
			//情況1:該內(nèi)存分區(qū)的容量剛好與用戶進(jìn)程所需內(nèi)存容量相同
			if (it->size == space)
			{		//從空閑分區(qū)表中刪除當(dāng)前的空閑分區(qū),表示該分區(qū)已經(jīng)被分配
				auto it2 = it;
				Free_List.erase(it2);
			}
			//情況2:該內(nèi)存分區(qū)的容量大于用戶,則將該分區(qū)的一部分分配給用戶進(jìn)程
			else
			{		it->Start_Address += space;  //修改分區(qū)的起始地址
				it->size -= space;           //修改分區(qū)的容量大小
			}

			//接下來修改已分配分區(qū)鏈中的相應(yīng)內(nèi)容,那么就需要找到插入節(jié)點(diǎn)的位置,通過遍歷的方式進(jìn)行
			auto pos = Allocted_List.begin();
			while (pos!=Allocted_List.end())
			{		//如果當(dāng)前所遍歷到的內(nèi)存分區(qū)的起始地址小于插入新分區(qū)的起始地址,則繼續(xù)向后遍歷
				if (pos->Start_Address< start)
				{pos++;
				}
				//找到了一個合適的添加位置的情況,操作完成后函數(shù)直接返回
				else
				{//第一種情況:之前所有已分配分區(qū)的起始地址都小于當(dāng)前分區(qū)的起始地址,則直接在尾部添加
					if (pos == Allocted_List.end())
					{AllocMem* tempSpace = new AllocMem(start, space, pid);
						Allocted_List.push_back(*tempSpace);
					}
					//第二種情況:新分配分區(qū)的位置在兩個已有分配區(qū)域的中間,則從中間插入
					else
					{AllocMem* tempSpace = new AllocMem(start, space, pid);
						Allocted_List.insert(pos, *tempSpace);
					}
					cout<< "已經(jīng)成功為新進(jìn)程分配分區(qū)!"<< endl;
					cout<< endl;
					return;
				}
			}
			//迭代完成后如果沒有找到插入位置,則在鏈表尾部進(jìn)行添加
			if (pos == Allocted_List.end())
			{		AllocMem* tempSpace = new AllocMem(start, space, pid);
				Allocted_List.push_back(*tempSpace);
				cout<< "已經(jīng)成功為新進(jìn)程分配分區(qū)!"<< endl;
				cout<< endl;
				return;
			}
		}
		//當(dāng)前內(nèi)存分區(qū)不足以容納用戶進(jìn)程,則繼續(xù)考察下一個內(nèi)存分區(qū)
		else
		{	it++;
		}
	}
	//循環(huán)退出,表示經(jīng)過遍歷后仍然沒有找到足夠用戶進(jìn)程的內(nèi)存分區(qū),則輸出提示信息
	cout<< "沒有找到滿足大小的空閑分區(qū),分區(qū)分配失??!"<< endl;
	return;
}

//用于釋放進(jìn)程的函數(shù)
void SetFree(const unsigned& pid)
{//通過遍歷的方式來找到指定進(jìn)程號的已分配分區(qū)
	auto it1 = Allocted_List.begin();
	while (it1 != Allocted_List.end())
	{//第一種情況:當(dāng)前遍歷到的進(jìn)程對應(yīng)的進(jìn)程號和用戶輸入的不同,則繼續(xù)考察下一個進(jìn)程
		if (it1->processID != pid)
		{	it1++;
		}
		//第二種情況:當(dāng)前遍歷到的進(jìn)程對應(yīng)的進(jìn)程號就是用戶所輸入的進(jìn)程號,那么就處理這個進(jìn)程
		else
		{	//首先記錄當(dāng)前分區(qū)的起始地址和大小
			unsigned start = it1->Start_Address;
			unsigned size = it1->size;
			//從已分配分區(qū)鏈表中將這個分區(qū)刪除
			Allocted_List.erase(it1);

			//接下來處理空閑分區(qū)鏈表,找到將這塊分區(qū)歸還所應(yīng)該存放的位置

			//首先考慮空閑分區(qū)鏈表為空的情況
			if (Free_List.size() == 0)
			{		FreeMem* tempSpace = new FreeMem(start, size);
				Free_List.push_back(*tempSpace);
				cout<< "已經(jīng)成功刪除指定進(jìn)程的內(nèi)容!"<< endl;
				cout<< endl;
				return;
			}
			auto it2 = Free_List.begin();
			while (it2!=Free_List.end())
			{		//對于當(dāng)前迭代器所指示的內(nèi)存分區(qū)首地址小于當(dāng)前分區(qū)起始地址的情況,則繼續(xù)向后遍歷
				if (it2->Start_Address< start)
				{it2++;
				}
				//對于找到了合適的位置的情況,則需要分情況進(jìn)行討論(共有4種情況)
				else
				{//首先考慮從鏈表頭部進(jìn)行添加的情況
					if (it2 == Free_List.begin())
					{//第一種情況:歸還分區(qū)與下一個分區(qū)右相鄰,則修改下一個分區(qū)的起始地址和大小即可
						if (start + size == it2->Start_Address)
						{	it2->Start_Address = start;
							it2->size += size;
						}
						//第二種情況:歸還分區(qū)與下一個分區(qū)不相鄰,則需要創(chuàng)建一個新的節(jié)點(diǎn)從空閑分區(qū)鏈的頭部插入
						else
						{	FreeMem* tempSpace = new FreeMem(start, size);
							Free_List.push_front(*tempSpace);
						}

						cout<< "已經(jīng)成功刪除指定進(jìn)程的內(nèi)容!"<< endl;
						cout<< endl;
						return;
					}

					//找到當(dāng)前遍歷位置的前一個位置進(jìn)行分析
					auto temp0 = it2;
					auto temp1 = (--temp0);

					//第一種情況:當(dāng)前新插入的分區(qū)與前后兩個分區(qū)都不是緊鄰的,則直接插入即可
					if (temp1->Start_Address + temp1->size< start&&it2->Start_Address>(start+size))
					{FreeMem* tempSpace = new FreeMem(start, size);
						Free_List.insert(it2,*tempSpace);
					}
					//第二種情況:當(dāng)前新插入的分區(qū)與前一個分區(qū)緊鄰,與后一個分區(qū)存在間隔,則修改前一個分區(qū)的大小即可
					else if(temp1->Start_Address+temp1->size==start&& start && it2->Start_Address >(start + size))
					{temp1->size += size;
					}
					//第三種情況:當(dāng)前新插入的分區(qū)與后一個分區(qū)緊鄰,與前一個分區(qū)存在間隔,則修改后一個分區(qū)的起始地址和大小即可
					else if (temp1->Start_Address + temp1->sizeStart_Address ==(start + size))
					{it2->Start_Address = start;
						it2->size += size;
					}
					//第四種情況:當(dāng)前新插入的分區(qū)與前后兩個分區(qū)都緊鄰,則將三個分區(qū)進(jìn)行合并
					else
					{temp1->size = temp1->size + size + it2->size;
						Free_List.erase(it2);
					}
					
					//操作完成,向用戶輸出提示信息
					cout<< "已經(jīng)成功刪除指定進(jìn)程的內(nèi)容!"<< endl;
					cout<< endl;
					return;
				}
			}
			//遍歷完成后沒有找到可以插入的地方,說明歸還的內(nèi)存分區(qū)位于內(nèi)存空間的末尾,此時有兩種情況
			it2--;
			//第一種情況:該內(nèi)存分區(qū)與前一個內(nèi)存分區(qū)緊鄰,則修改前一個空閑內(nèi)存分區(qū)的大小即可
			if (it2->Start_Address + it2->size == start)
			{		it2->size += size;
			}
			//第二種情況:該內(nèi)存分區(qū)與前一個內(nèi)存分區(qū)不緊鄰,則向空閑分區(qū)鏈表中新增加一個節(jié)點(diǎn)
			else
			{		FreeMem* tempSpace = new FreeMem(start, size);
				Free_List.push_back(*tempSpace);
			}
			//輸出結(jié)束提示信息
			cout<< "已經(jīng)成功刪除指定進(jìn)程的內(nèi)容!"<< endl;
			cout<< endl;
			return;
		}
	}
	//遍歷完所有現(xiàn)存進(jìn)程都沒有找到指定進(jìn)程號的進(jìn)程,那么輸出提示信息
	cout<< "不存在指定進(jìn)程號的內(nèi)存分區(qū),本次釋放進(jìn)程過程結(jié)束!"<< endl;
	return;
}

//隨機(jī)刪除且進(jìn)行過程展示的函數(shù)
void Multiple_Random_Delete(void)
{//首先記錄鏈表長度
	size_t length = Allocted_List.size();
	for (; length >0; length--)
	{//記錄隨機(jī)刪除的位置
		int randNum = rand() % length;

		list::iterator it = Allocted_List.begin();
		for (unsigned pos (0); pos< length - 1; ++pos)
		{	it++;
		}
		//將指定位置的元素刪除
		cout<< "本次隨機(jī)刪除的進(jìn)程的進(jìn)程號為為:"<< it->processID<< endl;
		SetFree(it->processID);
		
		//顯式刪除后的效果
		print();
	}
}

int main(void)
{//定義初始狀態(tài)下內(nèi)存分區(qū)的個數(shù)
	unsigned AllocMem_Num;         

	//獲取用戶輸入的內(nèi)存空間的總大小,此處為方便起見并考慮實(shí)際情況,選擇使用KB作為單位
	cout<< "請輸入內(nèi)存空間的大小(單位為KB):";
	cin >>Memspace;
	cout<< endl;

	//獲取用戶輸入的初始狀態(tài)下進(jìn)程個數(shù),接下來獲取初始狀態(tài)下每一個進(jìn)程內(nèi)存分區(qū)的信息
	cout<< "請輸入初始狀態(tài)下的進(jìn)程個數(shù):";
	cin >>AllocMem_Num;
	cout<< "接下來請按照起始地址的遞增順序逐一輸入初始狀態(tài)下每個內(nèi)存分區(qū)的信息:"<< endl;
	cout<< endl;
	for (unsigned i(0); i< AllocMem_Num; ++i)
	{unsigned startAddress;
		unsigned size;
		unsigned processID;

		//獲取當(dāng)前內(nèi)存分區(qū)的起始地址
		cout<< "請輸入第"<< (i + 1)<< "個內(nèi)存分區(qū)的起始地址(以KB為單位):";
		cin >>startAddress;
		//獲取當(dāng)前內(nèi)存分區(qū)的分區(qū)大小
		cout<< "請輸入第"<< (i + 1)<< "個內(nèi)存分區(qū)的分區(qū)大?。?;
		cin >>size;
		//獲取當(dāng)前內(nèi)存分區(qū)的進(jìn)程號
		cout<< "請輸入第"<< (i + 1)<< "個內(nèi)存分區(qū)對應(yīng)的進(jìn)程號:";
		cin >>processID;

		//首先通過自定義的函數(shù)判斷輸入的內(nèi)存分區(qū)是否有效,即不存在分區(qū)重疊、進(jìn)程號重名和超過空間大小
		if (isValid(Allocted_List,startAddress, size, processID,Memspace) == true)
		{	//以結(jié)構(gòu)體的形式創(chuàng)建一個新的已分配內(nèi)存分區(qū)
			AllocMem* tempSpace = new AllocMem(startAddress, size, processID);
			//將新創(chuàng)建的內(nèi)存分區(qū)從尾部插入已分配內(nèi)存分區(qū)鏈中
			Allocted_List.push_back(*tempSpace);
		}
		//如果內(nèi)存分區(qū)無效,則輸出無效原因的提示信息,同時程序終止
		else
		{	cout<< "程序錯誤信息:"<< errorMessage<< endl;
			return 0;
		}
		cout<< endl;
	}

	//接下來對空閑分區(qū)鏈表進(jìn)行初始化
	list::iterator it1 = Allocted_List.begin();
	//首先判斷首地址為0的一段地址空間是否已經(jīng)被分配
	if (it1->Start_Address != 0)
	{FreeMem* tempSpace = new FreeMem(0, it1->size);
		Free_List.push_back(*tempSpace);
	}
	//通過遍歷的方式逐一獲取每一段空閑分區(qū)的起始地址和大小
	list::iterator it2 = (--Allocted_List.end());
	for(; it1 != it2; it1++)
	{//上一個已分配內(nèi)存分區(qū)的終止位置就是該空閑分區(qū)的起始位置
		unsigned start = it1->Start_Address + it1->size;
		//空閑分區(qū)的大小即下一個已分配內(nèi)存分區(qū)的起始地址和該空閑分區(qū)的起始位置的差值
		list::iterator it3 = (++it1);
		it1--;
		unsigned size = it3->Start_Address-start;
		//如果差值為零則說明兩個已分配的內(nèi)存分區(qū)緊鄰,此時兩者之間不存在空閑分區(qū),因此跳過本次循環(huán)
		if (size == 0)continue;
		//大小不為零時,創(chuàng)建一個新的未分配內(nèi)存分區(qū)并將其放入空閑分區(qū)表中
		FreeMem* tempSpace = new FreeMem(start, size);
		Free_List.push_back(*tempSpace);
	}
	//判斷最后一個已分配分區(qū)是否與內(nèi)存大小的上界緊鄰,如果不緊鄰則再增加一個空閑分區(qū)進(jìn)入空閑分區(qū)鏈中
	unsigned lastPos = it2->Start_Address + it2->size;
	if (lastPos< Memspace)
	{FreeMem* tempSpace = new FreeMem(lastPos, Memspace - lastPos);
		Free_List.push_back(*tempSpace);
	}

	//初始化工作完成,輸出內(nèi)存分區(qū)結(jié)果
	cout<< "初始化工作完成,下面輸出內(nèi)存分區(qū)的結(jié)果:"<< endl;
	//通過調(diào)用自定義的print函數(shù)輸出結(jié)果
	print();
	char ch = getchar();

	//接下來由用戶通過鍵盤輸入指定操作類型來完成對應(yīng)類型的操作(包括進(jìn)程的創(chuàng)建、刪除、多次隨機(jī)刪除過程展示和退出程序)
	while (true)
	{char cmd; //記錄用戶的操作類型
		cout<< "請輸入您需要進(jìn)行的操作(C創(chuàng)建進(jìn)程,D刪除進(jìn)程,M多次隨機(jī)刪除過程展示,P當(dāng)前內(nèi)存分區(qū)展示,Q退出程序):";
		cmd = getchar();

		//根據(jù)用戶的操作類型調(diào)用不同的函數(shù)處理
		switch (cmd)
		{//創(chuàng)建進(jìn)程操作
		case 'C': {FF_Allocate(); break; }
		//刪除進(jìn)程操作
		case 'D': 
		{	unsigned pid;
			//獲取用戶輸入的需要釋放空間的進(jìn)程號
			cout<< "請輸入需要釋放內(nèi)存空間的進(jìn)程號:";
			cin >>pid;

			SetFree(pid); 
			break; 
		}
		//多次隨機(jī)刪除過程展示
		case 'M': {Multiple_Random_Delete(); break; }
		//當(dāng)前內(nèi)存分區(qū)展示
		case 'P': {print(); break; }
		//退出程序
		case 'Q': {cout<< "程序退出!"<< endl; return 0; break; }
		//其余情況處理(充分考慮程序的魯棒性)
		default: {cout<< "無法識別您的命令,請重新輸入。"<< endl; cout<< endl; break; }
		}
		cmd = getchar();
	}
	return 0;
}
運(yùn)行效果

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)站名稱:帶有詳細(xì)注釋的操作系統(tǒng)首次適應(yīng)法C++程序-創(chuàng)新互聯(lián)
標(biāo)題網(wǎng)址:http://bm7419.com/article22/gjccc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、網(wǎng)站導(dǎo)航、動態(tài)網(wǎng)站、面包屑導(dǎo)航、網(wǎng)站策劃、移動網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化