最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言實現(xiàn)可增容動態(tài)通訊錄詳細過程

 更新時間:2022年05月12日 10:18:08   作者:Iceevov  
這篇文章主要為大家介紹了C語言實現(xiàn)簡易通訊錄的完整流程,此通訊錄還可以增容,并且每個環(huán)節(jié)都有完整代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助

創(chuàng)建可自動擴容的通訊錄

這里我們想實現(xiàn)通訊錄自動擴容,不夠了能擴大內存,變得稍微有點智能,就不得不用到開辟內存的函數(shù)malloc和realloc,這兩個函數(shù)又和free離不開關系

所以這里我給大家簡單的介紹一下這三個庫函數(shù)

malloc:這個函數(shù)向內存申請一塊連續(xù)可用的空間,并返回指向這塊空間的指針

void *malloc( size_t size );

如果開辟成功,則返回一個指向開辟好空間的指針。

如果開辟失敗,則返回一個NULL指針,因此malloc的返回值一定要做檢查。

返回值的類型是 void* ,所以malloc函數(shù)并不知道開辟空間的類型,具體在使用的時候使用者自己

來決定。

如果參數(shù) size 為0,malloc的行為是標準是未定義的,取決于編譯器

這里給大家簡單的演示一下:

int main()
{
	int arr[5] = { 0 };
	int* ptr = NULL;
	ptr = (int*)malloc(5 * sizeof(int));//開辟5個大小為int整型的空間給ptr
	//判斷是否開辟成功
	if (ptr == NULL)
	{
		perror(malloc);//打印錯誤信息
		return;
	}
	free(ptr);//釋放內存
    ptr = NULL;//消除野指針問題
	return 0;
}

realloc:realloc函數(shù)的出現(xiàn)讓動態(tài)內存管理更加靈活。

有時會我們發(fā)現(xiàn)過去申請的空間太小了,有時我們又會覺得申請的空間過大了,那為了合理的時使用內存,我們一定會對內存的大小做靈活的調整。那 realloc 函數(shù)就可以做到對動態(tài)開辟內存大小的調整

void* realloc (void* ptr, size_t size);

ptr 是要調整的內存地址

size 調整之后新大小

返回值為調整之后的內存起始位置。

這個函數(shù)調整原內存空間大小的基礎上,還會將原來內存中的數(shù)據移動到新的空間

值得我們注意的是這個函數(shù)的開辟內存有兩種情況:

情況1

當原有空間之后有足夠大的空間的時候,要擴展內存就直接原有內存之后直接追加空間,原來空間的數(shù)據不發(fā)生變化。

情況2

當原有空間之后沒有足夠大的空間時候,原有空間之后沒有足夠多的空間時,擴展的方法是:在堆空間上另找一個合適大小

的連續(xù)空間來使用。這樣函數(shù)返回的是一個新的內存地址

free:用來釋放內存的,這個函數(shù)是搭配開辟內存的函數(shù)使用且非常關鍵,如果開辟了內存不及時釋放的話會造成內存釋放等嚴重后果,若重復釋放也會有不良影響,所以需要我們注意。

當我們了解了上面三個函數(shù)過后我們來試著建立一個可擴容的通訊錄

這里我們先創(chuàng)建一個結構體用來存放用戶的信息

//在這里進行初始化賦值,若以后有變只需在這一個地方改變
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
typedef struct PeoInfo
{
	char name[NAME_MAX];//姓名
	char sex[SEX_MAX];//性別
	int age;//年齡
	char tele[TELE_MAX];//電話號碼
	char addr[ADDR_MAX];//地址
} PeoInfo;

當我們的用戶變多,我們所需要的這樣的結構體也需要增加,我們可以在創(chuàng)建一個包含這個結構體的結構體,里面記錄用戶個數(shù)和記錄當前通訊錄的最大容量

typedef struct Contact
{
	PeoInfo* data;//可以存放人的信息(可增長)
	int sz;//記錄通訊中已經保存的信息個數(shù)
	int capacity;//記錄通訊錄當前的最大容量
}Contact;

當數(shù)量大于3時我們就應該擴容并初始化,具體實現(xiàn)

//通訊錄初始狀態(tài)的容量大小
#define DEFAULT_SZ 3
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
	pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));
	if (pc->data == NULL)
	{
		perror("InitContact::malloc");
		return;
	}
	memset(pc->data, 0, pc->capacity * sizeof(PeoInfo));
}
void CheckCapacity(Contact* pc)
{
	//增容(當用戶等于最大容量時)
	if (pc->sz == pc->capacity)
	{
        //開辟兩個大小為PeoInfo的內存并且強制類型轉換為PeoInfo*類型放在tmp地址處
		PeoInfo* tmp = (PeoInfo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoInfo));
		if (tmp != NULL)
		{
			pc->data = tmp;//將tmp地址給到pc->data達到連續(xù)存放的目的
		}
		else
		{
			perror("CheckCapacity::realloc");//開辟失敗打印錯誤信息
			return;
		}
		pc->capacity += 2;//開辟成功后及時更新最大容量
		printf("增容成功\n");
	}
}

添加用戶信息

實現(xiàn):

void AddContact(Contact* pc)
{
	assert(pc);
    //動態(tài)的版本
	CheckCapacity(pc);//輸入前看是否需要擴容
	//錄入信息
	printf("請輸入名字:>");
	scanf("%s", pc->data[pc->sz].name);
	printf("請輸入年齡:>");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("請輸入性別:>");
	scanf("%s", pc->data[pc->sz].sex);
	printf("請輸入電話:>");
	scanf("%s", pc->data[pc->sz].tele);
	printf("請輸入地址:>");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;
	printf("添加成功\n");
}

刪除用戶信息

//找到了返回下標
//找不到返回-1
int FindByName(const Contact* pc, char name[])
{
	assert(pc);
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (0 == strcmp(pc->data[i].name, name))
		{
			return i;
		}
	}
	return -1;
}
//刪之前需要先查找是否有這個用戶
void DelContact(Contact* pc)
{
	assert(pc);
 
	if (pc->sz == 0)
	{
		printf("通訊錄已空,無法刪除\n");
		return;
	}
	//刪除
	//1. 找到
	char name[NAME_MAX] = { 0 };
	printf("請輸入要刪除人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);//通過函數(shù)查找
	if (pos == -1)
	{
		printf("要刪除的人不存在\n");
		return;
	}
	//2. 刪除
	int j = 0;
	for (j = pos; j < pc->sz - 1; j++)
	{
		pc->data[j] = pc->data[j + 1];
	}
	pc->sz--;
	printf("刪除成功\n");
}

查找聯(lián)系人

int FindByName(const Contact* pc, char name[])
{
	assert(pc);
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (0 == strcmp(pc->data[i].name, name))
		{
			return i;
		}
	}
	return -1;
}
void SearchContact(const Contact* pc)
{
	char name[NAME_MAX] = { 0 };
	printf("請輸入要查找人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年齡", "性別", "電話", "地址");
	printf("%-20s %-5d %-5s %-12s %-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex,
		pc->data[pos].tele, pc->data[pos].addr);
}

修改用戶信息

//修改信息
void ModifyContact(Contact* pc)
{
	//首先先找到要修改的人
	int input = 0;
	char name[NAME_MAX] = { 0 };
	printf("請輸入要查找人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年齡", "性別", "電話", "地址");
	printf("%-20s %-5d %-5s %-12s %-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex,
		pc->data[pos].tele, pc->data[pos].addr);
	printf("請選擇你要修改的信息:\n");
    //用switch語句可以實現(xiàn)只改某一項的信息
	do
	{
		printf("0.修改完畢  1.姓名  2.年齡  3.性別  4.電話  5.地址\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("請輸入修改的名字:>");
			scanf("%s", pc->data[pos].name);
			break;
		case 2:
			printf("請輸入修改的年齡:>");
			scanf("%d", &(pc->data[pos].age));//注意取地址
			break;
		case 3:
			printf("請輸入修改的性別:>");
			scanf("%s", pc->data[pos].sex);
			break;
		case 4:
			printf("請輸入修改的電話:>");
			scanf("%s", pc->data[pos].tele);
			break;
		case 5:
			printf("請輸入修改的地址:>");
			scanf("%s", pc->data[pos].addr);
			break;
		}
	} while (input);
	printf("修改成功\n");
}

以名字將用戶排序

//以姓名排序(A~Z的順序)
void SortContact(Contact* pc)
{
	int i = 0;
	for (i = 0; i < pc->sz-1; i++)
	{
		int ret = strcmp(pc->data[i].name, pc->data[i + 1].name);
		if (ret > 0)
		{
			PeoInfo tmp;
			tmp = pc->data[i];
			pc->data[i] = pc->data[i + 1];
			pc->data[i + 1] = tmp;
		}
	}
	printf("排序成功\n");
}

銷毀通訊錄

當結束時銷毀通訊錄,釋放內存,避免出現(xiàn)內存泄漏等問題

void DestroyContact(Contact* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	printf("銷毀成功\n");
}

這里只展示了功能函數(shù)以及我認為一些需要注意的地方,若想看完整版可以去下面的鏈接看看哦

gitee

到此這篇關于C語言實現(xiàn)可增容動態(tài)通訊錄詳細過程的文章就介紹到這了,更多相關C語言動態(tài)通訊錄內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C語言制作簡易金山打字通功能的代碼

    C語言制作簡易金山打字通功能的代碼

    今天小編就為大家分享一篇關于C語言制作簡易金山打字通功能的代碼,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • 區(qū)分C++中的&和&&

    區(qū)分C++中的&和&&

    這篇文章主要介紹了如何區(qū)分C++的&和&&,幫助大家更好的理解和學習c++,感興趣的朋友可以了解下
    2020-09-09
  • c語言實現(xiàn)奇偶排序算法

    c語言實現(xiàn)奇偶排序算法

    這篇文章主要介紹了c語言實現(xiàn)奇偶排序算法,有需要的朋友可以參考一下
    2013-12-12
  • C++Vector容器常用函數(shù)接口詳解

    C++Vector容器常用函數(shù)接口詳解

    最近我學習了C++中的STL庫中的vector容器,對于常用容器,我們不僅要會使用其常用的函數(shù)接口,我們還有明白這些接口在其底層是如何實現(xiàn)的。所以特意整理出來一篇博客供我們學習
    2022-08-08
  • 關于C++地址交換的實現(xiàn)

    關于C++地址交換的實現(xiàn)

    在C++中,地址交換通常是指通過指針操作改變兩個變量之間的內存地址引用,當你有兩個指針分別指向兩個變量時,你可以通過某種機制交換這兩個指針的內容,使得它們各自指向對方原來的位置,本介紹了關于C++地址交換的實現(xiàn),需要的朋友可以參考下
    2024-11-11
  • 淺談C語言中的強符號、弱符號、強引用和弱引用

    淺談C語言中的強符號、弱符號、強引用和弱引用

    這篇文章主要介紹了C語言中的強符號、弱符號、強引用和弱引用的定義及相關內容,非常的簡單易懂,有需要的朋友可以參考下
    2014-10-10
  • C++示例講解初始化列表方法

    C++示例講解初始化列表方法

    這篇文章主要介紹了C++成員初始化列表,除了可以使用構造函數(shù)對類成員進行初始化之外,C++還提供了另外一種初始化的方法,叫做成員初始化列表。下面來看看文章的詳細吧,需要的朋友可以參考一下
    2022-07-07
  • 動態(tài)數(shù)組C++實現(xiàn)方法(分享)

    動態(tài)數(shù)組C++實現(xiàn)方法(分享)

    下面小編就為大家?guī)硪黄獎討B(tài)數(shù)組C++實現(xiàn)方法(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • 詳解C++虛函數(shù)中多態(tài)性的實現(xiàn)原理

    詳解C++虛函數(shù)中多態(tài)性的實現(xiàn)原理

    C++是一種面向對象的編程語言,在C++中,虛函數(shù)是實現(xiàn)多態(tài)性的關鍵。本文就來探討一下C++虛函數(shù)中多態(tài)性的實現(xiàn)原理及其在面向對象編程中的應用吧
    2023-05-05
  • C語言中反斜杠的作用及說明

    C語言中反斜杠的作用及說明

    這篇文章主要介紹了C語言中反斜杠的作用及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07

最新評論

罗江县| 宿松县| 益阳市| 贵南县| 南投市| 宽城| 桂林市| 芦溪县| 如东县| 桑植县| 三门县| 盘山县| 哈密市| 洪泽县| 河北区| 陇西县| 固始县| 长垣县| 肇源县| 奉新县| 方正县| 云南省| 曲水县| 黎平县| 凤阳县| 平利县| 巴塘县| 拉萨市| 怀安县| 汕头市| 古浪县| 涟水县| 漳州市| 沙洋县| 犍为县| 绍兴县| 应城市| 大田县| 资溪县| 云梦县| 庆云县|