欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言鏈表案例學習之通訊錄的實現(xiàn)

 更新時間:2022年10月28日 09:54:04   作者:EMCred  
為了將所學到的鏈表的知識進行鞏固學習,做到學以致用,本文將利用鏈表制作一個簡單的通訊錄。文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下

一、通訊錄需要實現(xiàn)的功能

1,通訊錄可以存儲編號,聯(lián)系人的姓名,電話號碼和家庭住址。

2,通訊錄最基本的功能是添加聯(lián)系人,用戶可以隨時添加聯(lián)系人。

3,通訊錄可以展示已經(jīng)添加的所有聯(lián)系人。

4,通訊錄中用戶可以根據(jù)聯(lián)系人的姓名刪除對應(yīng)通訊錄中的信息。

5,通訊錄中姓名可以重復,所以為了刪除準確的信息,需要實現(xiàn)按位置刪除的功能。

6,通訊錄中用戶可以根據(jù)聯(lián)系人的姓名找到聯(lián)系人在通訊錄中的信息,因為聯(lián)系人可以重名,所以如果有重名的聯(lián)系人的時候就需要返回兩個或兩個以上的聯(lián)系人信息到一個查找表單中。

7,通訊錄中用戶可以根據(jù)通訊錄的位置修改該位置的聯(lián)系人信息,而修改這樣的功能就只需要按照位置來進行修改,不需要再按照姓名進行修改,因為存在重名的情況,并且可以根據(jù)返回的表單看到具體的聯(lián)系人位置,所以就不需要再 設(shè)計像按照名字進行修改這樣冗余的功能了。

8,通訊錄可以按照位置插入聯(lián)系人

二、項目目的

制作本項目是為了將所學到的鏈表的知識進行鞏固學習,做到學以致用,并通過做這樣的小項目來增強理解開發(fā),算法和C語言的指針,結(jié)構(gòu)體等知識,同時收獲開發(fā)經(jīng)驗,項目重點是能夠使用鏈表的知識做出的小項目,所以該項目不會考慮到實現(xiàn)數(shù)據(jù)持久化的操作和GUI編程,只是基于DOS的命令行程序。

三、項目開發(fā)

開發(fā)IDE:Visual Studio 2019

IDE注意:

1,在該IDE中不能夠直接使用scanf()函數(shù),因為它可能會存在一些不安全的因素,所以在該IDE中使用的是scanf_s()函數(shù),但是scanf和scanf_s函數(shù)具有本質(zhì)的區(qū)別,并且scanf_s函數(shù)只能在該IDE中使用,不廣泛,所以還是推薦使用scanf()函數(shù),為了能正常使用scanf()函數(shù),需要將聲明#define _CRT_SECURE_NO_WARNINGS放在項目的最頂部。

2,為了更方便的開發(fā)該項目,所以使用了一些c++的庫函數(shù),所以為了能夠正確運行程序,建議將后綴改為.cpp,其實c++是c的升級版本,解決了c不能面向?qū)ο箝_發(fā)的模式,它的編譯器既可以運行.c的程序也可以運行.cpp的程序,但是.c的編譯器是不能夠運行.cpp的程序的,它并不能識別一些.cpp的源碼。

首先,根據(jù)需求,選擇合適的數(shù)據(jù)結(jié)構(gòu),這里選擇的數(shù)據(jù)結(jié)構(gòu)是鏈表為主體,采用帶有頭結(jié)點的單鏈表的形式,通過傳入指向頭結(jié)點的指針進行添加結(jié)點,遍歷結(jié)點,刪除結(jié)點,插入結(jié)點等對結(jié)點的操作,這樣每次對鏈表進行操作就只需要傳入指向頭結(jié)點的指針就可以了,可以這樣理解:

當程序運行在內(nèi)存中的時候,首先先使用一個指針指向一個頭結(jié)點

將該指針傳入到添加結(jié)點的函數(shù)中,在該函數(shù)中通過指針從頭結(jié)點開始遍歷,使用頭插法或尾插法,將生成的結(jié)點插入到頭結(jié)點之后

然后再次傳入指向頭結(jié)點的指針到添加結(jié)點的函數(shù),此時該鏈表已經(jīng)有兩個結(jié)點,頭結(jié)點和一個結(jié)點,內(nèi)部函數(shù)使用指針進行遍歷,然后添加結(jié)點,形成頭結(jié)點為起點的后面帶有兩個結(jié)點的單向鏈表

依次如此....

理解這里最重要的是對于指針的理解

然后我們根據(jù)需要在通訊錄中的內(nèi)容可以存儲編號,聯(lián)系人的姓名,電話號碼和家庭住址定義一個結(jié)構(gòu)體,如下:

typedef struct Node {
    Number num;//編號
    Name name[23];//聯(lián)系人姓名
    Phone phone[33];//聯(lián)系人電話
    Addr addr[50];//聯(lián)系人地址
    struct Node* next;//next指針
}LNode;

在這里需要考慮到的問題是對于編號的實現(xiàn),編號可以在程序中由程序自主的實現(xiàn),也就是在程序中可以定義一個全局變量number,并且賦初值為0,當調(diào)用添加結(jié)點的函數(shù)時,number自增并將number的值的賦給結(jié)構(gòu)體成員num,但是它只能夠不斷的自增,當調(diào)用刪除功能時,它的序號就會變得混亂,比如,現(xiàn)在已經(jīng)添加了5個聯(lián)系人,編號分別為1,2,3,4,5,如果刪除編號為3的聯(lián)系人的話,那么此時通訊錄中的編號只剩下1,2,4,5,這樣就會造成編號無序的情況,就沒有意義也不便于管理操作。

如果編號在添加結(jié)點的時候由用戶輸入實現(xiàn)的話,對于用戶來說可能會增加操作的負擔,同時也不便于管理,可能它會無序甚至是重復。

所以最后可以解決的方式就是將編號不作為結(jié)構(gòu)體成員的變量而是作為功能函數(shù)體中的一部分,也就是說我們傳入頭結(jié)點之后添加結(jié)點形成的單鏈表,如果要將信息輸出到屏幕上時,可以定義一個指針指向單鏈表的首元結(jié)點并定義一個num為1的計數(shù)器,指針遍歷到的個數(shù)就是計數(shù)器上的數(shù)字,這樣如果刪除了某個結(jié)點,它都會重新遍歷一次,這樣編號就是有序的,也就是說在打印聯(lián)系人名單的函數(shù)中每次傳入頭結(jié)點都需要重新遍歷一下,編號由函數(shù)中的num給出,所以此時重新修改結(jié)構(gòu)體為:

typedef struct Node {
    Name name[23];//聯(lián)系人姓名
    Phone phone[33];//聯(lián)系人電話
    Addr addr[50];//聯(lián)系人地址
    struct Node* next;//next指針
}LNode;

然后定義函數(shù)printNode(Node* head)用來打印通訊錄的名單,這里可以更好的理解如何解決編號的問題

void printNode(Node* head)
{
    Node* move;
    move = head->next;
    int num = 1;
    printf("================================通訊錄頁面=============================\n");
    while (move)
    {
        printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
        printf("編號:%d 姓名:%s 電話:%s 住址:%s\n", num, move->name, move->phone, move->addr);
        printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
        move = move->next;
        num++;
    }
    printf("================================通訊錄頁面=============================\n");
}

接下來,我們來定義完整的鏈表實現(xiàn):

首先,可以定義一個函數(shù)Node* initList()用來初始化鏈表,也就是創(chuàng)建一個頭結(jié)點并讓它的指針域指向NULL,定義一個指針函數(shù),該指針函數(shù)返回一個指向頭結(jié)點的指針。

Node* initList()
{
    Node* head;
    head = (Node*)malloc(sizeof(Node));
    head->next = NULL;
    return head;
}

然后,定義一個函數(shù)用來添加聯(lián)系人也就是創(chuàng)建結(jié)點并使用頭插法添加到單向鏈表中,此時我們需要傳入指向頭結(jié)點的指針。

void addListNode(Node* head)
{
    Node* node;
    node = (Node*)malloc(sizeof(Node));
    printf("請輸入聯(lián)系人信息:\n");
    printf("姓名:");
    scanf("%s", &node->name);
    printf("電話號碼:");
    scanf("%s", &node->phone);
    printf("家庭地址:");
    scanf("%s", &node->addr);
    //使用頭插法將結(jié)點鏈接到頭結(jié)點之后
    node->next = head->next;
    head->next = node;
    if (head->next != NULL) {
        printf("添加聯(lián)系人成功\n");
    }
    else {
        printf("添加聯(lián)系人失敗\n");
    }
}

此時,可以在主方法中進行測試,此時已經(jīng)能夠打印出三個聯(lián)系人了

int main()
{
    Node* head;
    head=initList();
    addListNode(head);
    addListNode(head);
    printNode(head);
    return 0;
}

我們已經(jīng)實現(xiàn)了通訊錄的存儲要求,添加聯(lián)系人和打印出通訊錄的聯(lián)系人信息了。

此時我們會考慮到如果該通訊錄為空的話,我們直接進行打印可能會造成nullptr,所以需要實現(xiàn)一個判斷表空的函數(shù),該函數(shù)返回bool值便于調(diào)用判斷布爾類型。

bool isempty(Node* head)
{
    if (head->next == NULL) {
        return false;
    }
    else {
        return true;
    }
}

此時在打印聯(lián)系人目錄的函數(shù)中使用該函數(shù)在函數(shù)的最開始進行判斷,并在main中進行測試

if (!isempty(head)) {
    printf("檢測到通訊錄為空,請先添加聯(lián)系人再進行操作\n");
    return;
}

接下來需要實現(xiàn)的是通訊錄的其他功能。

首先實現(xiàn)用戶可以根據(jù)聯(lián)系人的姓名刪除對應(yīng)通訊錄中的信息,根據(jù)聯(lián)系人的姓名刪除對應(yīng)通訊錄中的信息,我們可以想到,聯(lián)系人的姓名是可以重復的,所以在刪除時需要判斷是否有重名的情況,所以可以先實現(xiàn)第6個需求,也就是通訊錄中用戶可以根據(jù)聯(lián)系人的姓名找到聯(lián)系人在通訊錄中的信息,因為聯(lián)系人可以重名,所以如果有重名的聯(lián)系人的時候就需要返回兩個或兩個以上的聯(lián)系人信息到一個查找表單中。

首先我們知道該功能是通過用戶輸入聯(lián)系人的姓名也就是字符串然后在鏈表中找到相應(yīng)字符串的位置進行返回,那么我們就需要實現(xiàn)一個字符串匹配的函數(shù),它應(yīng)當返回一個bool類型的值,當指針在鏈表中不斷遍歷并取出聯(lián)系人的姓名進行比較直到找到這個聯(lián)系人為止也就是該函數(shù)返回false的時候循環(huán)結(jié)束,所以可以定義一個字符匹配函數(shù)bool isBatch(Name n1[], Name n2[]);它的具體實現(xiàn)如下:

bool isBatch(Name n1[], Name n2[])
{
	Name* n11, * n22;//定義兩個char類型的指針
	n11 = n1;//讓n11指向字符串n1的首地址
	n22 = n2;//讓n22指向字符串n2的首地址
	int num1 = 1;//定義長度器用來計量n1的長度
	int num2 = 1;//定義長度器用來計量n2的長度
	//定義兩個長度器的原因是如果是n1:NUM,n2:NUM2的話,沒有計數(shù)器的情況下當跳出循環(huán)后它依然是返回true的
	while (1)
	{
		if (*n11 == *n22)
		{
			n11++;
			n22++;
			num1++;
			num2++;
			if (*n11 == '\0' && *n22 == '\0') {
				break;
			}
		}
		else {
			return false;
		}
	}
	if (num1 != num2) {
		return false;
	}
	return true;
}

然后我們需要返回聯(lián)系人在鏈表中的位置通過再打印查找單的函數(shù)中遍歷打印出信息,聯(lián)系人可能重名,所以位置可能會返回多個,一個或者是無聯(lián)系人的情況,因此這個返回位置的函數(shù)可以想到使用返回一個int數(shù)組的方式來操作,在C語言中如果想要返回數(shù)組的話需要返回的是指向這個數(shù)組的指針,也就是說C語言不能夠直接就返回一個數(shù)組類型的數(shù)據(jù),所以可以定義一個函數(shù)int* lookupByname(Node* head, Name name[]);傳入頭結(jié)點和輸入的名字,它的具體實現(xiàn)如下:

int* lookupByname(Node* head, Name name[])
{
	Node* target;//定義一個目標指針,該目標指針是用來獲取每一個結(jié)點中的name并與輸入的name進行比較
	target = head->next;//讓其指向第一個結(jié)點
	int* summary = NULL;//定義一個指向返回數(shù)組的指針
	summary = (int*)calloc(NUM, sizeof(int));//該指針指向一片大小為NUM的int類型的數(shù)組,該數(shù)組中所有值為0
	int loc = 1;//獲取位置從1開始,放在所申請的數(shù)組中
	int numd = 0;//數(shù)組的下標
	while (target)//遍歷完整個鏈表
	{
		if (isBatch(target->name, name))//如果匹配
		{
		summary[numd] = loc;//位置放入數(shù)組
		numd++;//只要放入numd就會加1,所以只要有一個聯(lián)系人numd是1不是0
		}
		target = target->next;
		loc++;
	}
	if (numd == 0) {//如果最后遍歷完整個鏈表numd還是0就說明沒有這個人
		loc = -1;//讓位置為-1
		summary[0] = loc;
	}
	return summary;//返回指向整型數(shù)組的指針
}

最后,我們來實現(xiàn)遍歷打印出查找單的函數(shù)void printsMenu(Node* head, int* loc);傳入鏈表的頭結(jié)點和指向整型數(shù)組的指針,它的具體實現(xiàn)如下:

void printsMenu(Node* head, int* loc) {
	if (!isempty(head)) {
		printf("檢測到通訊錄為空,請先添加聯(lián)系人再進行操作\n");
		return;
	}
	Node* ptr;//定義一個指針用來獲取位置并打印信息
	ptr = head->next;
	int num = 1;//定義位置尋找器用來找到指定的位置
	printf("================================查找人匯總=============================\n");
	for (int i = 0; i < NUM; i++)//遍歷返回的數(shù)組,數(shù)組最大值為NUM其實不必要遍歷到NUM,找到0的時候就可以跳出循環(huán)
	{
		if (loc[i] == -1) {//如果位置返回的是-1的話就表明無此人
			printf("                  未查詢到此人\n");
			break;
		}
		while (num!=loc[i]) {//指針指到相應(yīng)位置的結(jié)點
			num++;
			ptr = ptr->next;
		}
		//打印信息
		printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
		printf("編號:%d 姓名:%s 電話:%s 住址:%s\n", num, ptr->name, ptr->phone, ptr->addr);
		printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
		if (ptr->next == NULL) {//如果指針指到結(jié)尾就結(jié)束方法
			return;
		}
	}
	return;
}

此時我們可以來測試一下這個功能,在main方法中:

int main()
{
    Node* head;
    Name name[23]="李白";
    //添加兩個李白,一個李白,沒有李白和一個叫李白一個叫李白1進行測試
    head=initList();
    addListNode(head);
    addListNode(head);
    addListNode(head);
    addListNode(head);
    int* loc;
    loc=lookupByname(head,name);
    printsMenu(head, loc)
    return 0;
}

接下來,既然現(xiàn)在已經(jīng)能夠按照姓名查到位置并輸出了,那么實現(xiàn)用戶可以根據(jù)聯(lián)系人的姓名刪除對應(yīng)通訊錄中的信息,這里可以考慮到姓名重名的話我們可以再設(shè)計一個按照位置刪除聯(lián)系人的函數(shù),這樣在按姓名刪除的函數(shù)中需要通過返回的數(shù)組的大小提醒用戶是否有重名的聯(lián)系人,并提供建議如果有則建議結(jié)束函數(shù)然后采用按位置刪除聯(lián)系人的方式解決,沒有就可以直接刪除還有就是沒有此聯(lián)系人的情況,所以定義函數(shù)void deleteByname(Node* head, Name name[]),依然傳入頭結(jié)點和要刪除的名字

void deleteByname(Node* head, Name name[])
{
	if (!isempty(head)) {
		printf("檢測到通訊錄為空,請先添加聯(lián)系人再進行操作\n");
		return;
	}
	Node* p, * q;//定義兩個指針,p指針指向的是頭結(jié)點,q指針指向的是首元結(jié)點
	p = head;
	q = head->next;
	//當q查詢到名字時就將q所指結(jié)點進行釋放,然后將p所指結(jié)點也就是q所指結(jié)點的前一個結(jié)點連接到q所指結(jié)點的后一個結(jié)點
	while (q)
	{
		if (q->next == NULL && !isBatch(q->name, name)) {//當遍歷完整個鏈表并且最后一個結(jié)點的名字與輸入的名字不符合的情況下結(jié)束遍歷
			printf("刪除失敗,未找到該聯(lián)系人\n");
			return;
		}
		if (isBatch(q->name, name))//如果遍歷的過程中找到與輸入的名字相對于的名字時
		{
			int* ptr = lookupByname(head, name);//調(diào)用查找名字位置的函數(shù)用于查找該名稱是否有重名的情況
			int li=1;//定義計數(shù)器記錄有無重名的情況
			for (int i = 0; i < NUM; i++) {
				if (ptr[i] == 0) {
					break;
				}
				li++;
			}
			if (li-1 == 1) {//計數(shù)器為1,也就是說只有一個名字無重名
				printf("沒有重名的聯(lián)系人\n");
			}
			else {
				printf("有%d個重名的聯(lián)系人,建議查詢后使用位置刪除\n",li-1);
				printf("按1選擇繼續(xù)刪除,按2選擇結(jié)束本次刪除:");
				int input;
				scanf("%d", &input);
				if (input == 1) {
					goto loop;
				}
				else {
					return;
				}
			}
			break;
		}
		p = p->next;
		q = q->next;
		
	}
loop:
	//刪除結(jié)點的過程
	p->next = q->next;
	q->next = NULL;
	free(q);
	printf("刪除聯(lián)系人成功\n");
}

然后在main方法寫測試的用例:

int main()
{
    Node* head;
    Name deletename[23]="李白";
    //添加兩個李白,一個李白,沒有李白和一個叫李白一個叫李白1進行測試
    head=initList();
    addListNode(head);
    addListNode(head);
    addListNode(head);
    addListNode(head);
    deleteByName(head,deletename);
    return 0;
}

添加兩個李白的情況:

添加一個李白的情況:

沒有李白的情況:

接下來,既然能夠按照聯(lián)系人的名稱進行刪除了,那么在重名的情況下,還需要一種刪除的方法,也就是按照位置的刪除方法,所以可以定義函數(shù)void deleteByLoc(Node* head, int loc),按照位置刪除聯(lián)系人,它的具體實現(xiàn)如下:

void deleteByLoc(Node* head, int loc)
{
	if (!isempty(head)) {
		printf("檢測到通訊錄為空,請先添加聯(lián)系人再進行操作\n");
		return;
	}
	Node* move,*q,*choic;
	choic = head->next;//choic指向首元結(jié)點,用來判斷鏈表中結(jié)點的數(shù)量,避免程序出現(xiàn)nullptr
	//刪除操作的兩個指針
	q = head;
	move = head->next;
	int num = 1;//位置計數(shù)器,一直自增到對應(yīng)的位置loc
	int t = 1;//鏈表數(shù)量器,用來遍歷獲取鏈表的結(jié)點數(shù)量
	while (choic) {//獲取鏈表的實際長度
		if (choic->next == NULL) {
			break;
		}
		choic = choic->next;
		t++;
	}
	while (num!=loc&&move) {//尋找到要刪除的位置
		q = q->next;
		move = move->next;
		num++;
	}	
	if (num >= t) {//如果要刪除的位置比鏈表的長度都長就說明刪除錯誤
		printf("查詢錯誤,已經(jīng)超出已有人數(shù)上限,會造成程序異常\n");
		return;
	}
	else {
		q->next = move->next;
		move->next = NULL;
		free(move);
		printf("刪除成功\n");
	}
}

再次使用main方法進行測試:

int main()
{
    Node* head;
    int loc=1;
    head=initList();
    addListNode(head);
    deleteByLoc(head,1);
    return 0;
}

到目前位置,整個通訊錄的功能已經(jīng)完成了,接下來完成修改聯(lián)系人的信息和插入新的聯(lián)系人的功能,先完成修改聯(lián)系人信息的功能,既然可以查找到重名的聯(lián)系人,所以此時需要按照位置修改聯(lián)系人信息,所以定義函數(shù)void modifyByName(Node* head, int loc),闖入頭結(jié)點和需要修改的位置,在修改的時候,我們希望可以展示修改人原先的信息,有些算法的思想和按位刪除聯(lián)系人的思想一致,具體實現(xiàn)如下:

void modifyByName(Node* head, int loc)
{
	if (!isempty(head)) {
		printf("檢測到通訊錄為空,請先添加聯(lián)系人再進行操作\n");
		return;
	}
	Node* move, * choic;
	choic = head->next;
	move = head->next;
	int num = 1;
	int t = 1;
	while (choic) {
		choic = choic->next;
		t++;
		if (choic->next == NULL) {
			break;
		}
	}
	while (num != loc && move) {
		move = move->next;
		num++;
	}
	if (num > t) {
		printf("位置錯誤,已經(jīng)超出已有人數(shù)上限,會造成程序異常\n");
		return;
	}
	else {
		printf("找到聯(lián)系人信息\n");
		printf("正在檢測聯(lián)系人信息...........\n");
		printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
		printf("編號:%d 姓名:%s 電話:%s 住址:%s\n", num, move->name, move->phone, move->addr);
		printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
		printf("按1鍵更改聯(lián)系人信息,按2鍵不更改聯(lián)系人信息并結(jié)束:");
		int inputs;
		scanf("%d", &inputs);
		if (inputs==1)
		{
			int istrue;
			do {
				printf("請輸入聯(lián)系人信息:\n");
				printf("姓名:");
				scanf("%s", &move->name);
				printf("電話號碼:");
				scanf("%s", &move->phone);
				printf("家庭地址:");
				scanf("%s", &move->addr);
				printf("按1鍵確認更改,按2鍵重新更改:");
				scanf("%d", &istrue);
			} while (istrue!=1);
			printf("修改聯(lián)系人信息成功\n");
		}
		else {
			printf("ERROR");
			return;
		}
	}
}

同樣在main函數(shù)中進行測試

最后完成最后一個功能,按位置插入聯(lián)系人,這個函數(shù)的意義不大,但是為了鞏固鏈表的插入而設(shè)計的,定義一個函數(shù)void insertNodeByLoc(Node* head, int loc)算法的實現(xiàn)思路與按位刪除的一致,只是找到后是將新的結(jié)點插入而已,具體實現(xiàn)如下:

void insertNodeByLoc(Node* head, int loc)
{
	if (!isempty(head)) {
		printf("檢測到通訊錄為空,請先添加聯(lián)系人再進行操作\n");
		return;
	}
	Node* p, * q,*m;
	m = head->next;
	p = head->next;
	q = head;
	int num=1;
	int i=1;
	while (m)
	{
		i++;
		if (m->next == NULL) {
			break;
		}
	}
	while (num!=loc&&p) {
		p = p->next;
		q = q->next;
		num++;
	}
	if (num >= i) {
		printf("插入位置錯誤,已經(jīng)超出已有數(shù)量上限,會造成程序異常\n");
		return;
	}
	else {
		Node* node;
		node = (Node*)malloc(sizeof(Node));
		printf("請輸入聯(lián)系人信息:\n");
		printf("姓名:");
		scanf("%s", &node->name);
		printf("電話號碼:");
		scanf("%s", &node->phone);
		printf("家庭地址:");
		scanf("%s", &node->addr);
		node->next = p->next;
		p->next = node;
		printf("插入成功\n");
	}
}

同樣進行測試:

以上就是C語言鏈表案例學習之通訊錄的實現(xiàn)的詳細內(nèi)容,更多關(guān)于C語言鏈表實現(xiàn)通訊錄的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++實現(xiàn)一個簡易版的事件(Event)的示例代碼

    C++實現(xiàn)一個簡易版的事件(Event)的示例代碼

    之前在?windows系統(tǒng)中開發(fā)應(yīng)用時,?遇到需要進行線程同步的時候幾乎都是使用的事件內(nèi)核對象?Event。本文為大家整理了C++實現(xiàn)一個簡易版的事件(Event)的相關(guān)資料,需要的可以參考一下
    2022-11-11
  • 基于C中一個行壓縮圖的簡單實現(xiàn)代碼

    基于C中一個行壓縮圖的簡單實現(xiàn)代碼

    首先簡單說一下什么是行壓縮圖,其實嚴格意義上應(yīng)該是行壓縮矩陣
    2013-05-05
  • FFmpeg中AVIOContext的使用方法詳解

    FFmpeg中AVIOContext的使用方法詳解

    AVIOContext是FFMPEG管理輸入輸出數(shù)據(jù)的結(jié)構(gòu)體,這篇文章主要為大家詳細介紹了這個結(jié)構(gòu)體的具體使用,文中的示例代碼講解詳細,需要的可以參考一下
    2023-08-08
  • C++實現(xiàn)景區(qū)信息管理系統(tǒng)

    C++實現(xiàn)景區(qū)信息管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C++實現(xiàn)景區(qū)信息管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C語言實現(xiàn)學生成績管理系統(tǒng)

    C語言實現(xiàn)學生成績管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)學生成績管理系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C++內(nèi)存池的簡單實現(xiàn)

    C++內(nèi)存池的簡單實現(xiàn)

    內(nèi)存池是一種動態(tài)內(nèi)存分配與管理技術(shù)。本文主要介紹了C++內(nèi)存池的簡單實現(xiàn),文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2021-07-07
  • 使用C++實現(xiàn)給PDF文檔添加文字水印

    使用C++實現(xiàn)給PDF文檔添加文字水印

    這篇文章主要為大家詳細介紹了如何通過第三方國產(chǎn)庫Spire.PDF?for?C++來實現(xiàn)給PDF文檔添加文字水印,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-11-11
  • 深入解析C++中的函數(shù)模板和函數(shù)的默認參數(shù)

    深入解析C++中的函數(shù)模板和函數(shù)的默認參數(shù)

    這篇文章主要介紹了深入解析C++中的函數(shù)模板和函數(shù)的默認參數(shù),是C++入門學習中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • C語言版三子棋游戲?qū)崿F(xiàn)代碼

    C語言版三子棋游戲?qū)崿F(xiàn)代碼

    這篇文章主要為大家詳細介紹了C語言版三子棋游戲的實現(xiàn)代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 一文徹底搞懂IO底層原理

    一文徹底搞懂IO底層原理

    我們今天要給大家講的底層的IO看上去簡單,實則抽象。并且在它之上衍生出了語言層面用于實戰(zhàn)的技術(shù),比如我們熟悉的java語言中的NIO或者像Netty這樣的框架
    2021-06-06

最新評論