首页 > 其他分享 >c语言动态通讯录

c语言动态通讯录

时间:2024-11-29 23:00:40浏览次数:13  
标签:sz 语言 pc Contact 通讯录 printf 动态 data name

首先我们得明确它的基本功能,信息:

1.人的信息:姓名+年龄+性别+地址+电话
2.通讯录的可以存放100个人的信息
3.功能:
1>增加联系人
2>删除指定联系人
3>查找指定联系人的信息
4>修改指定联系人的信息
5>显示所有联系人的信息
6>排序(姓名,年龄)

test.c  测试通讯录
contact.c  通讯录的实现
contact.h  函数的声明

为了一步一步的引进?我们先写静态版本的吧!

第一步,我们是先写个框架(怎么进去,怎么选择的)

其实这个是非常简单的,也是相当固定的,跟之前写过的扫雷,三子棋,等游戏写法差不多

创建了test.c文件后开始

void menu()
{

	printf("###########################\n");
	printf("######1.Add    2.del   ####\n");
	printf("######3.search 4.modify####\n");
	printf("######5.show   6.sort  ####\n");
	printf("######0.exit           ####\n");
	printf("###########################\n");
}
//枚举方式
enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT
};
int main()
{
	
	int input = 0;
	do
	{
		menu();
		printf("请输入你想实现的业务数字:");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			
			break;
		case DEL:
			
			break;
		case SEARCH:
			
			break;
		case MODIFY:
			
			break;
		case SHOW:
			
			break;
		case SORT:
			
			break;

		case EXIT:
			
			
			printf("退出游戏");
			break;
		default:
			printf("输入错误,请重新选择");
			break;
		}

	} while (input);

	return 0;
}

出来的效果是这样的: 

其中上面用了枚举的便利方法:为什么?

因为如果了解过枚举的原理,我们知道,枚举的成员正常情况下第一个默认为0,接着下去

 

enum Option
{
	EXIT,  --0  退出
	ADD,   --1   增加
	DEL,   --2   删除
	SEARCH,  --3  查找
	MODIFY,  --4  修改
	SHOW,    --5  展示
	SORT     --6  排序
};

 这就很好的对应了我们的菜单数字,且在case那里可以更直观明了的看清楚我们想实现的代码,更方便我们后续写代码。

接着,我们先进行写人的信息的代码,想想,这是不是得用我们所学的结构体的知识

这个代码我们在Contact.h文件中写,可以方便我们在.c文件中任意调用。

//人的信息
typedef struct PeoInfo
{
	char name[20];
	int age;
	char sex[4];
	char addr[40];
	char tele[4];

}PeoInfo;

这样子就写好了人的信息了,可我们试想一下,这给定一个数字的,是不是就固定死了。

想要更加灵活的话,我们可以自定义一下,如下:

#define NameMax 20 
#define SexMax 4
#define AddrMax  40
#define TeleMax  12
//人的信息
typedef struct PeoInfo
{
	char name[NameMax];
	int age;
	char sex[SexMax];
	char addr[AddrMax];
	char tele[TeleMax];

}PeoInfo;

这样是不是就更加灵活了,后续想要改的话,就直接在上面改个数字就行,不用在具体代码中一个一个的改。

初始化部分

接着,到我们的初始化部分了。想想,我们在什么时候应该初始化呢?是不是在每次进入菜单选择之前,就把初始化搞好?

所以把初始化在菜单的前面声明了先,又因为它属于通讯录部分,为了更加清晰它的分工,我们把它放在Contact.c文件那里

静态的
typedef struct Contact
{
	PeoInfo data[Max];  //存放人的信息的
	int sz;  //当前已经存放的信息个数

两者必然是一起的?
因为data无论增加还是减少,sz都会随着改变的!
}Contact;
test.c文件中
   
    Contact con;
	InitContact(&con);
在Contact.h头文件中声明
#define MAX  100

void InitContact(Contact* pc);
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));

memset这个函数我们之前讲过了,作用就把它全初始化为0。

}

 写完初始化之后,我们就可以走向功能区的部分了

先Add增加部分吧!

void AddContact(Contact* pc)
{
	assert(pc);    这里断言是一个好习惯,遇到指针就应该加上断言,防止空指针
	if (pc->sz == Max)        判断是否已经满了通讯录
	{
		printf("通讯录已满,无法添加\n");
		return;
	}
	//增加一个人的信息                     这里由于是数组,scanf不用加&
                                          但是age不是数组,必须&!!!!! 
	printf("请输入一个人的姓名:");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入一个人的年龄:");
	scanf("%d", &(pc->data.age));
	printf("请输入一个人的性别:");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入一个人的地址:");
	scanf("%s", pc->data[pc->sz].addr);
	printf("请输入一个人的电话:");
	scanf("%s", pc->data[pc->sz].tele);

	pc->sz++;        一个人增加完后,开始下一个空间大小
}

 显示部分:

void ShowContact(const Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%-20s\t %-4s\t %-4s\t %-40s\t %-12s\n ", "名字", "年龄", "性别", "地址", "电话");
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t %-4d\t %-4s\t %-40s\t %-12s\n", pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].addr,
			pc->data[i].tele);
	}
}

 

删除部分:

我们要删除之前,是不是得找到你要删的那个名字?

所以得创建一个函数,找出来,删除它

int Find(const Contact* pc, char name[])
{
	assert(pc);
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void DelContact(Contact* pc)
{
	assert(pc);
	char name[NameMax] = { 0 };
	if (pc->sz == 0)
	{
		printf("不好意思,没有可以删除的人");
		return;
	}
	printf("请选择你要删除的人:");
	scanf("%s", name);
	int ret = Find(pc, name);
	if (-1 == ret)
	{
		printf("没有这个人,请再次查看是否输入正确?\n");
		return;
	}
	int i = 0;
	for (i = ret; i < pc->sz - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];

	}
	pc->sz--;
	printf("删除成功\n");
}

查找部分: 

void SearchContact(const Contact* pc)
{
	assert(pc);
	char name[NameMax] = { 0 };

	printf("请输入你要查找的名字");
	scanf("%s", name);
	int pos = Find(pc, name);    这里也使用到了找的函数,说明我们单独去创建是明智的
	if (-1 == pos)
	{
		printf("不好意思,没有这个人的信息");
		return;
	}
	//打印信息
	printf("%-20s\t %-4s\t %-4s\t %-40s\t %-12s\n ",
		"名字", "年龄", "性别", "地址", "电话");
	printf("%-20s\t %-4d\t %-4s\t %-40s\t %-12s\n",
		pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].addr,
		pc->data[pos].tele);
}

修改部分:

void ModifyContact(Contact* pc)
{
	assert(pc);
	char name[NameMax] = { 0 };
	printf("请输入你要修改的人的名字");
	scanf("%s", name);
	int ret = Find(pc, name);
	if (-1 == ret)
	{
		printf("对不起,没有这个人的信息");
		return;
	}
	//修改就是重新录一遍进去
	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].addr);
	printf("请输入一个人的电话:");
	scanf("%s", pc->data[pc->sz].tele);

	printf("修改完成");

可能有人会问?

我写这个时的疑问?这里有点想不通,为啥直接录进去就可以修改了呢?

原来的数又怎么处理呢?

解答:我这样跟你说一下吧,它这块儿是一个结构体,是数组嘛,对吗?

每个数组,每个下边里面存的是一个一个的结构体,这个你能理解吧。

如果我在就是VS里面,我定义一个结构体

然后我给这个结构体里面就是先进行一个一个初始化,初始了一个值,对吧?

然后我在后面再给它这里面的每一个成员变量再重新输入了一遍值,

你说它里面的值是不是会修改?那原来的值就被覆盖了嘛,对吧

你初始化的这肯定算你的初始化呀,对吧?我我为什么要初始化这个东西?

因为我害怕。我如果没有就是在后面修改的话,我用我这个初始化的东西,

它是不是就是一个随机的东西了?我就不可控制了对吧?

那我是不是得初始化一下?这块儿和你这个初始化没有啥关系。

就相当于你用一个int a=1,再然后让这个 a=2,

你说你这个a=in a=1,这个A=1,

还算不算初始化?它当然算初始化呀。

排序部分:

这里用到了qsort函数。看不懂的话,可以去前面几篇有讲到过哦~

cmp_by_name(void* e1, void* e2)
{
	return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_by_name);
}

好了,写完了静态部分的通讯录。我们是不是觉得这种有些小缺陷呢?就是它目前是设定了100个人的,但是当我们填完100人之后,我们就不可以再填了,这样,我们又不知道我们以后有多少个人要记录,满了之后再改,就显得十分麻烦。又我们在上一篇文章中写到了动态内存的开辟的文章了,我们是不是就可以使用一下,又节省空间。

现在我们先说明一下动态通讯录要改静态的什么内容?

首先是不是得改变一下初始化内容,增加部分,

//静态的
//typedef struct Contact
//{
//	PeoInfo data[Max];  //存放人的信息的
//	int sz;  //当前已经存放的信息个数
//
//}Contact;

//动态的
typedef struct Contact
{
	PeoInfo* data;  存放人的信息的  ,这里就不能使用数组了,直接用指针传地址过去
	int sz;    当前已经存放的信息个数
	int capacity;    当前通讯录的最大容量
}Contact;

利用扩容方式初始化通讯录 

void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	PeoInfo* str = (PeoInfo*)calloc(DEFFAULT_SZ, sizeof(PeoInfo));
	if (str == NULL)
	{
		perror("calloc");
		return;
	}
	pc->data = str;
	pc->capacity = DEFFAULT_SZ;
	//加载文件信息到通讯录
	LoadContact(pc);
}

 检查是否扩容成功?

void CheckContact(Contact* pc)
{
	//判断是否满
	if (pc->sz == pc->capacity)
	{
		//增容
		PeoInfo* str = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (NULL==STR)
		{
			perror("calloc");
			return;
		}
		pc->data = str;
		pc->capacity += INC_SZ;
		printf("增容成功\n");
	}
}

增加部分:

void AddContact(Contact* pc)
{
	assert(pc);
	//判断增容是否需要
	CheckContact(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].addr);
	printf("请输入一个人的电话:");
	scanf("%s", pc->data[pc->sz].tele);

	pc->sz++;
}

 排序部分:

void SortContact(Contact* pc)
{
	int i = 0;

	for (i = 0; i < pc->sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < pc->sz - 1 - i; j++)
		{
			int temp = { 0 };
			if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
			{
				memcpy(&temp, &(pc->data[j].name), sizeof(struct PeoInfo*));
				memcpy(&(pc->data[j].name), &(pc->data[j + 1].name), sizeof(struct PeoInfo*));
				memcpy(&(pc->data[j + 1].name), &temp, sizeof(struct PeoInfo*));
			}
		}
	}
	printf("排序成功!");
}

 解释:

解释下面代码:
memcpy(&temp, &(pc->data[j].name), sizeof(struct PeoInfo*))
memcpy(&(pc->data[j].name), &(pc->data[j + 1].name), sizeof(struct PeoInfo*));
memcpy(&(pc->data[j + 1].name), &temp, sizeof(struct PeoInfo*));

这里相当于加一个临时变量转换
eg:原理相当于
   int temp=arr[i];
   arr[i]=arr[i+1];
   arr[i+1]=temp;

结束后要释放函数:

//退出后需要释放
void DestoryContact(Contact* pc)
{
	assert(pc);
	free(pc->data);
	pc->data = NULL;


}

好了,结束了,下面我们各部分完整代码放下面:

Contact.h:

#pragma once
#include<assert.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
//#define Max 100
#define NameMax 20 
//#define AgeMax  4
#define SexMax 4
#define AddrMax  40
#define TeleMax  12
#define DEFFAULT_SZ 3  //默认
#define INC_SZ 2       //加
//人的信息
typedef struct PeoInfo
{
	char name[NameMax];
	int age;
	char sex[SexMax];
	char addr[AddrMax];
	char tele[TeleMax];

}PeoInfo;
//静态的
//typedef struct Contact
//{
//	PeoInfo data[Max];  //存放人的信息的
//	int sz;  //当前已经存放的信息个数
//
//}Contact;

//动态的
typedef struct Contact
{
	PeoInfo* data;  //存放人的信息的
	int sz;  //当前已经存放的信息个数
	int capacity; //当前通讯录的最大容量
}Contact;

void InitContact(Contact* pc);
void AddContact(Contact* pc);
void ShowContact(Contact* pc);
void DelContact(Contact* pc);

void SearchContact(Contact* pc);
void ModifyContact(Contact* pc);

void SortContact(Contact* pc);
void DestoryContact(Contact* pc);
void SaveContact(Contact *pc);
void LoadContact(Contact* pc);

Contact.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"

//void InitContact(Contact* pc)
//{
//	assert(pc);
//	pc->sz = 0;
//	memset(pc->data, 0, sizeof(pc->data));
//}
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	PeoInfo* str = (PeoInfo*)calloc(DEFFAULT_SZ, sizeof(PeoInfo));
	if (str == NULL)
	{
		perror("calloc");
		return;
	}
	pc->data = str;
	pc->capacity = DEFFAULT_SZ;
	
	
}
//void AddContact(Contact* pc)
//{
//	assert(pc);
//	if (pc->sz == Max)
//	{
//		printf("通讯录已满,无法添加\n");
//		return;
//	}
//	//增加一个人的信息
//	printf("请输入一个人的姓名:");
//	scanf("%s", pc->data[pc->sz].name);
//	printf("请输入一个人的年龄:");
//	scanf("%s", pc->data[pc->sz].age);
//	printf("请输入一个人的性别:");
//	scanf("%s", pc->data[pc->sz].sex);
//	printf("请输入一个人的地址:");
//	scanf("%s", pc->data[pc->sz].addr);
//	printf("请输入一个人的电话:");
//	scanf("%s", pc->data[pc->sz].tele);
//
//	pc->sz++;
//}
void CheckContact(Contact* pc)
{
	//判断是否满
	if (pc->sz == pc->capacity)
	{
		//增容
		PeoInfo* str = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (str == NULL)
		{
			perror("calloc");
			return;
		}
		pc->data = str;
		pc->capacity += INC_SZ;
		printf("增容成功\n");
	}
}
void AddContact(Contact* pc)
{
	assert(pc);
	//判断增容是否需要
	CheckContact(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].addr);
	printf("请输入一个人的电话:");
	scanf("%s", pc->data[pc->sz].tele);

	pc->sz++;
}
void ShowContact(const Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%-20s\t %-4s\t %-4s\t %-40s\t %-12s\n ", "名字", "年龄", "性别", "地址", "电话");
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t %-4d\t %-4s\t %-40s\t %-12s\n", pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].addr,
			pc->data[i].tele);
	}
}

int Find(const Contact* pc, char name[])
{
	assert(pc);
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void DelContact(Contact* pc)
{
	assert(pc);
	char name[NameMax] = { 0 };
	if (pc->sz == 0)
	{
		printf("不好意思,没有可以删除的人");
		return;
	}
	printf("请选择你要删除的人:");
	scanf("%s", name);
	int ret = Find(pc, name);
	if (-1 == ret)
	{
		printf("没有这个人,请再次查看是否输入正确?\n");
		return;
	}
	int i = 0;
	for (i = ret; i < pc->sz - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];

	}
	pc->sz--;
	printf("删除成功\n");
}

void SearchContact(const Contact* pc)
{
	assert(pc);
	char name[NameMax] = { 0 };

	printf("请输入你要查找的名字");
	scanf("%s", name);
	int pos = Find(pc, name);
	if (-1 == pos)
	{
		printf("不好意思,没有这个人的信息");
		return;
	}
	//打印信息
	printf("%-20s\t %-4s\t %-4s\t %-40s\t %-12s\n ",
		"名字", "年龄", "性别", "地址", "电话");
	printf("%-20s\t %-4d\t %-4s\t %-40s\t %-12s\n",
		pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].addr,
		pc->data[pos].tele);
}
void ModifyContact(Contact* pc)
{
	assert(pc);
	char name[NameMax] = { 0 };
	printf("请输入你要修改的人的名字");
	scanf("%s", name);
	int ret = Find(pc, name);
	if (-1 == ret)
	{
		printf("对不起,没有这个人的信息");
		return;
	}
	//修改就是重新录一遍进去
	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].addr);
	printf("请输入一个人的电话:");
	scanf("%s", pc->data[pc->sz].tele);

	printf("修改完成");
	
}
//cmp_by_name(void* e1, void* e2)
//{
//	return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
//}
//void SortContact(Contact* pc)
//{
//	qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_by_name);
//}
void SortContact(Contact* pc)
{
	int i = 0;

	for (i = 0; i < pc->sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < pc->sz - 1 - i; j++)
		{
			int temp = { 0 };
			if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
			{
				memcpy(&temp, &(pc->data[j].name), sizeof(struct PeoInfo*));
				memcpy(&(pc->data[j].name), &(pc->data[j + 1].name), sizeof(struct PeoInfo*));
				memcpy(&(pc->data[j + 1].name), &temp, sizeof(struct PeoInfo*));
			}
		}
	}
	printf("排序成功!");
}
//退出后需要释放
void DestoryContact(Contact* pc)
{
	assert(pc);
	free(pc->data);
	pc->data = NULL;


}

test.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
void menu()
{

	printf("###########################\n");
	printf("######1.Add    2.del   ####\n");
	printf("######3.search 4.modify####\n");
	printf("######5.show   6.sort  ####\n");
	printf("######0.exit           ####\n");
	printf("###########################\n");
}
//枚举方式
enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT
};
int main()
{
	Contact con;
	InitContact(&con);

	int input = 0;
	do
	{
		menu();
		printf("请输入你想实现的业务数字:");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DelContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case SORT:
			SortContact(&con);
			break;

		case EXIT:
			
			
			DestoryContact(&con);
			
			printf("退出游戏");
			break;
		default:
			printf("输入错误,请重新选择");
			break;
		}

	} while (input);

	return 0;
}

 最后的最后,我希望小伙伴们,能够在学习中收获满满,生活上也是顺顺利利,开开心心

事事如意,保持好那份初心!

 

标签:sz,语言,pc,Contact,通讯录,printf,动态,data,name
From: https://blog.csdn.net/go_bai/article/details/144129103

相关文章

  • 动态内存管理的知识点笔记总结
    开始之前,我们解释一为什么存在动态内存分配?在我们之前写的:intarr[10]={0};连续开辟40个字节的空间inta=10;在内存开辟4个字节但是,1.这种大小是固定死的,我们是无法改变的。2.数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。但是对于空间的需求......
  • 16-20动态规划
    动态规划动态规划基本概念17矩阵连乘问题18n阶级楼梯上楼问题19-20最长公共子序列#include<iostream>usingnamespacestd;constintN=1010;intn,m;chara[N],b[N];intf[N][N];intmain(){cin>>n>>m>>a+1>>b+1;for(inti=1;i<=n;i++){......
  • 30天学会GO–第2天 GO语言语法和数据类型
    30天学会GO–第2天GO语言语法和数据类型文章目录30天学会GO--第2天GO语言语法和数据类型前言一、基础数据类型1.1数字类型1.2浮点类型1.3var声明一个或者多个变量:二、流程控制语法2.1ifelse2.2for/range2.3switch2.4goto2.5break/continue三、总结......
  • C语言 - 指针,数组
    指针指针入门创建变量intage=10;创建指针,指向变量指针类型*指针变量=&变量int*p=&age;当有了指针之后,就可以通过指针操作他指向的数据了通过指针获取指向的位置的数据,在指针前面加一个*为解引用指针前加*修改,改的是指针指向的位置的值指针的作用:游......
  • JAVA基础教程---(一)JAVA语言概述
    JAVA基础教程JAVA语言概述前言JAVA之父JamesGosling团队在开发”Green”项目时,发现C缺少垃圾回收系统,还有可移植的安全性、分布程序设计和多线程功能。最后,他们想要一种易于移植到各种设备上的平台。Java确实是从C语言和C++语言继承了许多成份,甚至可以将Java看成是类......
  • 使用 Intersection Observer API以及动态加载内容细节
    1使用IntersectionObserverAPI什么是IntersectionObserver?IntersectionObserverAPI是现代浏览器提供的一种接口,用于检测一个元素(目标元素)是否与视口(用户可见区域)或某个特定父容器交叉。优点不需要手动监听滚动事件,性能更优。在用户接近目标区域时触发,比滚动事件......
  • C语言笔记--函数
    C语言中函数的分类1.库函数2.自定义函数库函数那怎么学习库函数呢?简单看看:www.cplusplus.com简单的总结,C语言常用的库函数都有:IO函数字符串操作函数字符操作函数内存操作函数时间/日期函数数学函数其他库函数注:但是库函数必须知道的一个秘密就是:使用库函数,必须......
  • C语言--变量
    变量1.变量的创建1.1变量的概念在这一篇博客【https://editor.csdn.net/md/?articleId=143997006】中,我们讲述了数据类型,那么数据类型是来做什么的呢?数据类型是用来创建变量的。变量是什么呢?顾名思义,C语言中把经常变化的值称为变量,不变的值成为常量。1.2如何创建一个变......
  • 【嵌入式C语言】常用关键字及运算符操作
    常用关键字及运算符操作关键字杂项sizeofreturn数据类型charint进制表示long、shortunsigned,signedfloat、doublevoid自定义数据类型structunionenumtypedef逻辑结构类型修饰符【重点】掌握C语言的常用关键字及其应用场景,使用技巧掌握位运算的典型操作掌握常用......
  • 这可能是交互性最强的数据分析编程语言
    强计算和交互性的两难Excel和BI是常用的数据分析工具,很适合完成初级的数据分析任务,比如统计各月销售总额,计算各组的平均订单金额和购买频次等。但随着业务需求升级,更复杂的任务用Excel或BI就很难完成了,比如要找出股票连续上涨5天以上的区间;求每7天中连续3天活跃......