第 2 章 线性表(学生健康登记表实现)

news2025/1/11 0:30:57

1. 示例代码

1) status.h

/* DataStructure 预定义常量和类型头文件 */

#ifndef STATUS_H
#define STATUS_H

/* 函数结果状态码 */
#define TRUE 					1			/* 返回值为真 */
#define FALSE 					0			/* 返回值为假 */
#define RET_OK 					0			/* 返回值正确 */
#define INFEASIABLE    		   	2			/* 返回值未知 */
#define ERR_MEMORY     		   	3			/* 访问内存错 */
#define ERR_NULL_PTR   			4			/* 空指针错误 */
#define ERR_MEMORY_ALLOCATE		5			/* 内存分配错 */
#define ERR_NULL_STACK			6			/* 栈元素为空 */
#define ERR_PARA				7			/* 函数参数错 */
#define ERR_OPEN_FILE			8			/* 打开文件错 */
#define ERR_NULL_QUEUE			9			/* 队列为空错 */
#define ERR_FULL_QUEUE			10			/* 队列为满错 */
typedef int Status;							/* Status 是函数的类型,其值是函数结果状态代码,如 RET_OK 等 */
typedef int Bollean;						/* Boolean 是布尔类型,其值是 TRUE 或 FALSE */

#endif // !STATUS_H

2) singleLinkList.h

/* 线性表的单链表存储结构头文件 */

#ifndef SINGLELINKLIST_H
#define SINGLELINKLIST_H

#include "status.h"

#define NAMELEN 20		/* 姓名最大长度 */
#define CLASSLEN 10		/* 班级名最大长度 */
#define HEALTHLEN 10	/* 健康状态字符长度 */
#define N 4		 		/* 学生个数 */

typedef struct {
	char name[NAMELEN];
	long studentId;
	char sex;
	int age;
	char className[CLASSLEN];
	int healthState;
} StudentInfo;

typedef StudentInfo ElemType;

typedef struct LNode {
	ElemType data;
	struct LNode *next;
} *LinkList;

/* 辅助函数,创建一个新的节点 */
LinkList MakeNewLNode(ElemType e);

/* 操作结果:构造一个空的线性表 L */
Status InitList(LinkList *L);

/* 初始条件:线性表 L 已存在。操作结果:销毁线性表 L */
Status DestroyList(LinkList *L);

/* 初始条件:线性表 L 已存在。操作结果:将 L 重置为空表 */
Status ClearList(LinkList L);

/* 初始条件:线性表 L 已存在。操作结果:若 L 为空表,则返回 TRUE,否则返回 FALSE */
Status ListEmpty(LinkList L);

/* 初始条件:线性表 L 已存在。操作结果:返回 L 中数据元素个数 */
int ListLength(LinkList L);

/* 算法 2.8,L 为带头结点的单链表的头指针。当第 i 个元素存在时, 其值赋给 e 并返回 OK,否则返回 ERROR */
Status GetElem(LinkList L, int i, ElemType *e);

/* 初始条件: 线性表 L 已存在, compare() 是数据元素判定函数(满足为 1,否则为 0)
   操作结果: 返回 L 中第 1 个与 e 满足关系 compare() 的数据元素的位序。
   若这样的数据元素不存在,则返回值为 0 */
int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType));

/* 算法 2.9,在带头结点的单链线性表 L 中第 i 个位置之前插入元素 e */
Status ListInsert(LinkList L, int i, ElemType e);

/* 算法 2.10,在带头结点的单链线性表 L 中,删除第 i 个元素,并由 e 返回其值 */
Status ListDelete(LinkList L, int i, ElemType* e);

/* 按学号非降序插入 */
void InsertAscend(LinkList L, ElemType e);

#endif

3) singleLinkList.c

/* 线性表的单链表存储结构源文件实现 */

#include "singleLinkList.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

/* 辅助函数,创建一个新的节点 */
LinkList MakeNewLNode(ElemType e)
{
	LinkList newLNode = (LinkList)malloc(sizeof(struct LNode));
	if (!newLNode) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);
		return NULL;
	}

	newLNode->data = e;
	newLNode->next = NULL;

	return newLNode;
}

/* 操作结果:构造一个空的线性表 L */
Status InitList(LinkList *L)
{
	*L = (LinkList)malloc(sizeof(struct LNode));
	if (!(*L)) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);
		return ERR_MEMORY_ALLOCATE;
	}

	(*L)->next = NULL;

	return RET_OK;
}

/* 初始条件:线性表 L 已存在。操作结果:销毁线性表 L */
Status DestroyList(LinkList *L)
{
	LinkList q;
	while (*L) {
		q = (*L)->next;
		free(*L);
		*L = q;
	}

	return RET_OK;
}

/* 初始条件:线性表 L 已存在。操作结果:将 L 重置为空表 */
Status ClearList(LinkList L)
{
	LinkList p, q;
	p = L->next;
	while (p) {
		q = p->next;
		free(p);
		p = q;
	}

	L->next = NULL;

	return RET_OK;
}

/* 初始条件:线性表 L 已存在。操作结果:若 L 为空表,则返回 TRUE,否则返回 FALSE */
Status ListEmpty(LinkList L)
{
	if (L->next) {
		return FALSE;
	}

	return TRUE;
}

/* 初始条件:线性表 L 已存在。操作结果:返回 L 中数据元素个数 */
int ListLength(LinkList L)
{
	int count = 0;
	LinkList p = L->next;
	while (p) {
		++count;
		p = p->next;
	}

	return count;
}

/* 算法 2.8,L 为带头结点的单链表的头指针。当第 i 个元素存在时, 其值赋给 e 并返回 RET_OK,否则返回 ERROR */
Status GetElem(LinkList L, int i, ElemType *e)
{
	int j = 1;
	LinkList p = L->next;
	while (p && j < i) {
		p = p->next;
		++j;
	}

	if (!p || j > i) {			/* j > i 适用于 i < 1 时,如 i = 0 */
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_PARA);
		return ERR_PARA;
	}

	*e = p->data;

	return RET_OK;
}

/* 初始条件: 线性表 L 已存在, compare() 是数据元素判定函数(满足为 1,否则为 0)
   操作结果: 返回 L 中第 1 个与 e 满足关系 compare() 的数据元素的位序。
   若这样的数据元素不存在,则返回值为 0 */
int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType))
{
	int i = 0;
	LinkList p = L->next;
	while (p) {
		++i;
		if (compare(p->data, e)) {
			return i;
		}

		p = p->next;
	}

	return 0;
}

/* 算法 2.9,在带头结点的单链线性表 L 中第 i 个位置之前插入元素 e */
Status ListInsert(LinkList L, int i, ElemType e)
{
	int j = 0;
	LinkList p = L;
	while (p && j < i - 1) {
		++j;
		p = p->next;
	}

	if (!p || j > i - 1) {				/* 超出表长或者 i < 1 */
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_PARA);
		return ERR_PARA;
	}

	LinkList newLNode = MakeNewLNode(e);
	if (!newLNode) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);
		return ERR_MEMORY_ALLOCATE;
	}

	newLNode->next = p->next;
	p->next = newLNode;

	return RET_OK;
}

/* 算法 2.10,在带头结点的单链线性表 L 中,删除第 i 个元素,并由 e 返回其值 */
Status ListDelete(LinkList L, int i, ElemType *e)
{
	int j = 0;
	LinkList p = L;
	while (p->next && j < i - 1) {
		++j;
		p = p->next;
	}

	if (!p->next || j > i - 1) {	/* 理论上 j 最多只能等于 i - 1, 但此处当参数不合法时可用, 建议单独判断参数合法性 */
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_PARA);
		return ERR_PARA;
	}

	LinkList q = p->next;
	p->next = q->next;
	*e = q->data;
	free(q);

	return RET_OK;
}

/* 初始条件:线性表 L 已存在
   操作结果:依次对 L 的每个数据元素调用函数 vi()。一旦 vi() 失败,则操作失败 */
Status ListTraverse(LinkList L, void(*vi)(ElemType))
{
	LinkList p = L->next;
	while (p) {
		vi(p->data);
		p = p->next;
	}

	return RET_OK;
}

/* 按学号非降序插入 */
void InsertAscend(LinkList L, ElemType e)
{
	LinkList q = L, p = L->next;
	while (p && e.studentId > p->data.studentId) {
		q = p;
		p = p->next;
	}

	q->next = MakeNewLNode(e);
	q->next->next = p;
}

4) studentHealthRecord.h

/* 学生健康登记表定义头文件 */

#ifndef STUDENTSHEALTHRECORD_H
#define STUDENTSHEALTHRECORD_H

#include "status.h"
#include "singleLinkList.h"
#include <stdio.h>

/* 打印学生信息 */
void PrintStuentInfo(char healthState[][HEALTHLEN], int arrayLen, ElemType e);

/* 读入学生信息 */
void ReadIn(char healthState[][HEALTHLEN], int arrayLen, ElemType *e);

/* 将学生信息写入指定文件 */
void WriteToFile(ElemType e, FILE *fp);

/* 由 fp 指定文件读取学生信息到 e */
Status ReadFromFile(ElemType *e, FILE *fp);

/* 查找表中学号为 studentId 的结点,如找到,q 指向此结点, p 指向 q 的前驱
   并返回 TRUE; 如无此元素,则返回 FALSE */
Status FindByStudentId(LinkList L, long studentId, LinkList *p, LinkList *q);

/* 查找表中姓名为 name 的结点,如找到,q 指向此结点, p 指向 q 的前驱
   并返回 TRUE; 如无此元素,则返回 FALSE */
Status FindByName(LinkList L, char name[], LinkList *p, LinkList *q);

/* 删除表中学号为 studentId 的元素,并返回 TRUE;如无此元素,则返回 FALSE */
Status DeleteByStudentId(LinkList L, long studentId);

/* 删除表中姓名为 name 的元素,并返回 TRUE;如无此元素,则返回 FALSE */
Status DeleteByName(LinkList L, char name[]);

/* 修改学生信息 */
void ModifyStudentInfo(char healthState[][HEALTHLEN], int arrayLen, ElemType *e);

/* 显示操作选项 */
void ShowMenu(void);

#endif // !STUDENTSHEALTHRECORD_H

5) studentHealthRecord.c

/* 学生健康登记表实现源文件 */

#include "studentHealthRecord.h"
#include <string.h>
#include <stdlib.h>

/* 打印学生信息 */
void PrintStuentInfo(char healthState[][HEALTHLEN], int arrayLen, ElemType e)
{
	if (e.healthState > arrayLen - 1) {
		printf("Error: Parameter out of bounds!\n");
		return;
	}

	printf("%-10s%-10ld", e.name, e.studentId);
	if (e.sex == 'm') {
		printf(" Man");
	}
	else {
		printf(" Female");
	}

	printf("%10d%10s%10s\n", e.age, e.className, healthState[e.healthState]);
}

/* 读入学生信息 */
void ReadIn(char healthState[][HEALTHLEN], int arrayLen, ElemType *e)
{
	printf("Please input name(No more than %d characters): ", NAMELEN);
	scanf_s("%s", e->name, (unsigned int)sizeof(e->name));
	getchar();
	printf("Please input the student ID: ");
	scanf_s("%ld", &e->studentId);
	getchar();
	printf("Please input the gender: ");
	scanf_s("%c", &e->sex, 1);
	getchar();
	printf("Please input the age: ");
	scanf_s("%d", &e->age);
	getchar();
	printf("Please input the class name: ");
	scanf_s("%s", e->className, (unsigned int)sizeof(e->className));
	getchar();
	printf("Please input the health state(");
	for (int i = 0; i < arrayLen; ++i) {
		printf("%d: %s ", i, healthState[i]);
	}
	
	printf("): ");
	scanf_s("%d", &e->healthState);
	getchar();
}

/* 将学生信息写入指定文件 */
void WriteToFile(ElemType e, FILE *fp)
{
	fwrite(&e, sizeof(StudentInfo), 1, fp);
}

/* 由 fp 指定文件读取学生信息到 e */
Status ReadFromFile(ElemType *e, FILE *fp)
{
	size_t ret = fread(e, sizeof(StudentInfo), 1, fp);

	return (ret == 1) ? 1 : 0;
}

/* 查找表中学号为 studentId 的结点,如找到,q 指向此结点, p 指向 q 的前驱
   并返回 TRUE; 如无此元素,则返回 FALSE */
Status FindByStudentId(LinkList L, long studentId, LinkList *p, LinkList *q)
{
	*p = L;
	while (*p) {
		*q = (*p)->next;
		if (*q && (*q)->data.studentId > studentId) {
			break;
		}

		if (*q && (*q)->data.studentId == studentId) {
			return TRUE;
		}

		*p = *q;
	}

	return FALSE;
}

/* 查找表中姓名为 name 的结点,如找到,q 指向此结点, p 指向 q 的前驱
   并返回 TRUE; 如无此元素,则返回 FALSE */
Status FindByName(LinkList L, char name[], LinkList *p, LinkList *q)
{
	*p = L;
	while (*p) {
		*q = (*p)->next;
		if (*q && !strcmp((*q)->data.name, name)) {
			return TRUE;
		}

		*p = *q;
	}

	return FALSE;
}

/* 删除表中学号为 studentId 的元素,并返回 TRUE;如无此元素,则返回 FALSE */
Status DeleteByStudentId(LinkList L, long studentId)
{
	LinkList p, q;
	if (FindByStudentId(L, studentId, &p, &q)) {
		p->next = q->next;
		free(q);
		return TRUE;
	}

	return FALSE;
}

/* 删除表中姓名为 name 的元素,并返回 TRUE;如无此元素,则返回 FALSE */
Status DeleteByName(LinkList L, char name[])
{
	LinkList p, q;
	if (FindByName(L, name, &p, &q)) {
		p->next = q->next;
		free(q);
		return TRUE;
	}

	return FALSE;
}

/* 修改学生信息 */
void ModifyStudentInfo(char healthState[][HEALTHLEN], int arrayLen, ElemType *e)
{
	PrintStuentInfo(healthState, arrayLen, *e);
	printf("Please input the content you want to modify, or click Enter to cancel\n");
	char str[100];
	printf("Please input name(No more than %d characters): ", NAMELEN);
	if (gets_s(str, sizeof(str)) == NULL) {
		printf("%s, line: %d: Error: Get string failed!\n", __func__, __LINE__);
	}

	if (strlen(str)) {
		strcpy_s(e->name, sizeof(e->name), str);	/* 第二个参数为目标缓冲区大小 */
	}

	printf("Please input student ID: ");
	if (gets_s(str, sizeof(str)) == NULL) {
		printf("%s, line: %d: Error: Get string failed!\n", __func__, __LINE__);
	}

	if (strlen(str)) {
		e->studentId = atol(str);
	}

	printf("Please input gender(m: Man f: Female): ");
	if (gets_s(str, sizeof(str)) == NULL) {
		printf("%s, line: %d: Error: Get string failed!\n", __func__, __LINE__);
	}

	if (strlen(str)) {
		e->sex = str[0];
	}

	printf("Please input age: ");
	if (gets_s(str, sizeof(str)) == NULL) {
		printf("%s, line: %d: Error: Get string failed!\n", __func__, __LINE__);
	}

	if (strlen(str)) {
		e->age = atoi(str);
	}

	printf("Please input class name(No more than %d characters): ", CLASSLEN);
	if (gets_s(str, sizeof(str)) == NULL) {
		printf("%s, line: %d: Error: Get string failed!\n", __func__, __LINE__);
	}

	if (strlen(str)) {
		strcpy_s(e->className, sizeof(e->className), str);
	}

	printf("Please input the health state(");
	for (int i = 0; i < arrayLen; ++i) {
		printf("%d: %s ", i, healthState[i]);
	}

	printf("): ");
	if (gets_s(str, sizeof(str)) == NULL) {
		printf("%s, line: %d: Error: Get string failed!\n", __func__, __LINE__);
	}

	if (strlen(str)) {
		e->healthState = atoi(str);
	}
}

void ShowMenu(void)
{
	printf("1:  将结构体数组 student 中的记录按学号非降序插入链表\n");
	printf("2:  将文件中的记录按学号非降序插入链表\n");
	printf("3:  键盘输入新记录,并将其按学号非降序插入链表\n");
	printf("4:  删除链表中第一个有给定学号的记录\n");
	printf("5:  删除链表中第一个有给定姓名的记录\n");
	printf("6:  修改链表中第一个有给定学号的记录\n");
	printf("7:  修改链表中第一个有给定姓名的记录\n");
	printf("8:  查找链表中第一个有给定学号的记录\n");
	printf("9:  查找链表中第一个有给定姓名的记录\n");
	printf("10: 显示所有记录\n");
	printf("11: 将链表中的所有记录存入文件\n");
	printf("12: 结束\n");
	printf("    请选择操作命令: ");
}

6) main.c

/* 入口程序源文件 */

#include "studentHealthRecord.h"
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

int main(void)
{
	char healthState[3][10] = { "Health", "Normal", "Unhealth" };
	StudentInfo student[N] = {
		{ "王小林", 790631, 'm', 18, "计91", 0 },
		{ "陈红", 790632, 'f', 20, "计91", 1 },
		{ "刘建平", 790633, 'm', 21, "计91", 0 },
		{ "张立立", 790634, 'm', 17, "计91", 2 }
	};

	bool flag = true;
	int choose;
	LinkList studentList;
	InitList(&studentList);
	ElemType e;
	char fileName[30];
	long studentId;
	char name[30];
	LinkList p, q;
	while (flag) {
		ShowMenu();
		scanf_s("%d", &choose);
		switch (choose) {
			case 1:
				for (int i = 0; i < N; ++i) {
					InsertAscend(studentList, student[i]);
				}
				break;
			case 2: 
				printf("Please input file name: ");
				scanf_s("%s", fileName, (unsigned int)sizeof(fileName));
				FILE* fp;
				errno_t err_ret = fopen_s(&fp, fileName, "rb");
				if ( err_ret != 0) {
					printf("Open file failed!\n");
				}
				else {
					while (ReadFromFile(&e, fp)) {
						InsertAscend(studentList, e);
					}

					fclose(fp);
				}
				break;
			case 3: 
				ReadIn(healthState, 3, &e);
				InsertAscend(studentList, e);
				break;
			case 4: 
				printf("Please input the student ID to delete: ");
				scanf_s("%ld", &studentId);
				if (!DeleteByStudentId(studentList, studentId)) {
					printf("Error: No record of student ID of %ld.\n", studentId);
				}
				break;
			case 5:
				printf("Please input the name of the student of record to be deleted: ");
				scanf_s("%s", name, (unsigned int)sizeof(name));
				if (!DeleteByName(studentList, name)) {
					printf("Error: No record of student name of %s.", name);
				}
				break;
			case 6:
				printf("Please input the student ID of the record to be modified: ");
				scanf_s("%ld", &studentId);
				getchar();
				if (!FindByStudentId(studentList, studentId, &p, &q)) {
					printf("No record of the student Id of %ld\n", studentId);
				}
				else {
					ModifyStudentInfo(healthState, 3, &q->data);
					if (q->data.studentId != studentId) {
						p->next = q->next;
						InsertAscend(studentList, q->data);
						free(q);
					}
				}
				break;
			case 7:
				printf("Please input the name of the student of record to be deleted: ");
				scanf_s("%s", name, (unsigned int)sizeof(name));
				if (!FindByName(studentList, name, &p, &q)) {
					printf("No record of name of student %s.\n", name);
				}
				else {
					studentId = q->data.studentId;
					ModifyStudentInfo(healthState, 3, &q->data);
					if (q->data.studentId != studentId) {
						p->next = q->next;
						InsertAscend(studentList, q->data);
						free(q);
					}
				}
				break;
			case 8:
				printf("Please input the student ID of the record to be found: ");
				scanf_s("%ld", &studentId);
				if (!FindByStudentId(studentList, studentId, &p, &q)) {
					printf("No record of the student ID of %ld\n", studentId);
				}
				else {
					PrintStuentInfo(healthState, 3, q->data);
				}
				break;
			case 9:
				printf("Please input the name of the student of the record to be found: ");
				scanf_s("%s", name, (unsigned int)sizeof(name));
				if (!FindByName(studentList, name, &p, &q)) {
					printf("No record of the student name of %s.\n", name);
				}
				else {
					PrintStuentInfo(healthState, 3, q->data);
				}
				break;
			case 10:
				p = studentList->next;
				while (p) {
					PrintStuentInfo(healthState, 3, p->data);
					p = p->next;
				}
				break;
			case 11:
				printf("Please input the file name: ");
				scanf_s("%s", fileName, (unsigned int)sizeof(fileName));
				err_ret = fopen_s(&fp, fileName, "wb+");
				if (err_ret != 0) {
					printf("Open file failed!\n");
				}
				else {
					LinkList p = studentList->next;
					while (p) {
						WriteToFile(p->data, fp);
						p = p->next;
					}
				}

				fclose(fp);
				break;
			case 12:
				flag = false;
		}
	}

	int ret = DestroyList(&studentList);
	if (ret != RET_OK) {
		printf("Error: Destroy list failed!\n");
	}

	return 0;
}

 

2. 输出示例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/981788.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Datax抽取mysql的bit类型数据

背景&#xff1a;使用datax抽取mysql的一张表&#xff0c;里面有两个bit类型的字段&#xff0c;抽取出来显示如下&#xff1a; 需要在抽取reader里面进行处理配置 最终生成的datax的json文件reader的配置会转换为具体的数值 最终查询效果&#xff1a;

python1图书点评推荐系统的设计与实现vue

本次设计任务是要设计一个图书点评网&#xff0c;通过这个系统能够满足用户对图书信息下载、收藏功能。系统的主要功能包括&#xff1a;首页、个人中心、用户管理、图书分类管理、图书信息管理、留言板管理、系统管理等功能。 管理员可以根据系统给定的账号进行登录&#xff0c…

新版edge浏览器读取谷歌浏览器上的历史记录

上一篇&#xff1a;(3条消息) 新版edge浏览器读取谷歌浏览器上的历史记录_learningbilibili的博客-CSDN博客https://blog.csdn.net/learningbilibili/article/details/123662218 关于上次的读取历史记录的问题是现在的edge浏览器最近的版本更新后出现了每次启动时从 Google Chr…

为IT服务台构建自定义Zia操作

Zia是manageengine的商业人工智能助手&#xff0c;是ServiceDesk Plus Cloud的虚拟会话支持代理。使用Zia&#xff0c;您可以优化帮助台管理&#xff0c;还可以缩小最终用户与其帮助台之间的差距&#xff0c;Zia通过执行预配置的操作来帮助用户完成他们的服务台任务。 例如&…

【Linux】线程池读写锁

文章目录 线程池应用场景线程池原理构造线程池代码实现 读写锁应用场景读写锁的三种状态读写锁的接口初始化接口销毁接口以读模式加锁以写模式加锁解锁接口 常见问题 乐观锁/悲观锁乐观锁悲观锁自旋锁 线程池 应用场景 线程池不仅要提高程序运行效率&#xff0c;还要提高程序…

读SQL学习指南(第3版)笔记13_读后总结与感想兼导读

1. 基本信息 SQL学习指南(第3版) Learning SQL, Third Edition [美] 艾伦博利厄 &#xff08;Alan Beaulieu&#xff09; 人民邮电出版社,2022年4月出版 1.1. 读薄率 书籍总字数424千字&#xff0c;笔记总字数25969字。 读薄率25969424000≈6.13% 1.2. 读厚方向 SQL入门经…

探索多线程编程:线程的本质、状态和属性

目录 什么是线程线程状态新建线程可运行线程阻塞和等待线程终止线程 线程属性优先级线程名守护线程中断线程未捕获异常的处理器 在现代计算机编程中&#xff0c;多线程是一个重要而强大的概念。它使得我们能够更有效地利用多核处理器、提高程序性能并实现并发操作。 什么是线程…

docker从零部署jenkins保姆级教程(下)

上一篇文章&#xff0c;我们完成了以下工作。 1)、docker部署jenkins 2)、建立第一个jenkins job 3)、通过jenkins job自动编译构建我们的github项目 上面所做的3个工作&#xff0c;其实都是为了这一篇文章打基础&#xff0c;不管是部署docker还是部署jenkins&#xff0c;我们最…

d435i 相机和imu标定

一、IMU 标定 使用 imu_utils 功能包标定 IMU&#xff0c;由于imu_utils功能包的编译依赖于code_utils&#xff0c;需要先编译code_utils&#xff0c;主要参考 相机与IMU联合标定_熊猫飞天的博客-CSDN博客 Ubuntu20.04编译并运行imu_utils&#xff0c;并且标定IMU_学无止境的…

补码:将减法运算转化为另一种形式的加法运算

文章目录 解析 个人见解&#xff0c;如有错误&#xff0c;请多包涵。 解析 对于人来说&#xff0c;减法是简单容易的。 被减数和减数列式相减&#xff0c;从低位到高位分别计算&#xff0c;有需要的借位就可以了。 这是一种可以在计算机上成立的理论方案&#xff0c;但是由于…

SpringMVC常用注解介绍及参数传递说明

前言 上一篇文章介绍了SpringMVC是什么以及它的工作流程和核心组件&#xff0c;介绍入门示例时&#xff0c;提到了RequestMapping注解&#xff0c;那么这篇文章就来介绍SpringMVC中更多的常用的注解&#xff0c;以及它的参数传递。 一. SpringMVC常用注解 1.1 RequestParam …

Homebrew安装cocoapods: zsh: command not found: brew解决方法

问题描述: 通过Homebrew安装cocoapods时,输入命令行 brew install cocoapods出现如下报错: zsh: command not found: brew zsh:找不到命令&#xff1a;brew 问题解决: 使用以下命令,重新安装Homebrew. /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/ra…

永恒之黑_CVE-2020-0796漏洞复现

永恒之黑&#xff1a;CVE-2020-0796漏洞复现 目录 永恒之黑&#xff1a;CVE-2020-0796漏洞复现漏洞介绍漏洞影响范围漏洞复现1.环境准备2.复现过程 漏洞介绍 本漏洞源于SMBv3没有正确处理压缩的数据包&#xff0c;在解压数据包的时候使用客户端传过来的长度进行解压时&#xf…

机器学习——boosting之提升树(未完)

提升树和adaboost基本流程是相似的 我看到提升树的时候&#xff0c;懵了 这…跟adaboost有啥区别&#xff1f;&#xff1f;&#xff1f; 直到看到有个up主说了&#xff0c;我才稍微懂 相当于&#xff0c;我在adaboost里的弱分类器&#xff0c;换成CART决策树就好了呗&#xff1…

springboot + activiti实现activiti微服务化

概述 本文介绍如何将springbootactiviti进行整合,并配合eureka,zuul和feign实现activiti的微服务化,将流程控制和业务逻辑分离. 并实现了几个比较特殊的功能,比如时间段委托(某人请假或出差,出差时间内,所有待办交给被委托人处理),比如节点的无限级加签功能(流程本身有不确定性…

php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法非常简单

php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法&#xff0c;主要使用到了 php 的时间函数 mktime。下面首先还是以示例说明如何使用 mktime 获取今日、昨日、上周、本月的起始时间戳和结束时间戳&#xff0c;然后在介绍一下 mktime 函数作用和用法。非常简单哦…

vue3组件通信学习笔记

1、Prop 父组件 <template><div class"parent"><h1>我是父元素</h1><Child :msg"msg"></Child></div> </template><script setup> import Child from ./Child.vue let msg ref(我是父组件的数据…

单片机采集传感器数据(整形,浮点型)modbus上传

浮点型数据 占两个寄存器&#xff08;四个字节&#xff09; short 整形 占一个寄存器 &#xff08;两个字节&#xff09; 注意&#xff01;&#xff01;&#xff01;&#xff01; stm32 是小端模式&#xff0c;而modbus解析数据是大端模式 所以先发送高字节 如int a16777220…

【QML】使用 QtQuick2的ListView创建一个列表(一)

qtquick2版本和qtquick1版本分别提供了一个ListView组件供使用&#xff0c;两个组件在使用上和属性的提供上还是有比较大的差异的&#xff0c;因为qtquick2是新的&#xff0c;所以就以改版本为基础学习如何使用&#xff1b; 首先&#xff0c;要知道ListView提供了那些属性提供修…

2023年智能家居占消费电子出货量28%,蓝牙Mesh照明占据重要位置

市场研究机构 TechInsights 的最新报告显示&#xff0c;预计 2023 年全球消费者在智能家居相关硬件、服务和安装费方面的支出将复苏&#xff0c;达到 1310 亿美元&#xff0c;比 2022 年增长 10%。TechInsights 表示&#xff0c;消费者在智能家居系统和服务上的支出将继续强劲增…