C语言——结构体

一、定义和使用结构体

1.1概述

        前面我们见过的数据类型,比如int,float,char等是在程序中简单的使用,如果我们要根据自己的需求来建立一些复杂的数据,就需要用到结构体。

        例如,一个学生的学号,姓名,性别,年龄等是同属于一个学生的,但是这些变量又属于不同的类型,如果只是利用不同的变量分别进行简单的定义,那很难反应出来它们之间内在的联系。那么我们创建一个变量,能够将这些数据进行组合后放在变量中,这样使用起来就简单的多,这就是引出来结构体的学习;

结构体类型:struct Student{int num;//学号为整形;char name[20];//姓名为字符串;char sex;//性别为字符型;int age;//年龄为整形float score;//成绩为浮点型char addr[30];//地址为字符型;}

其中:

        struct Student  为结构体类型;

        struct是声明结构体类型的关键字。

        Student是结构体名,为了同其他结构进行区分;

        花括号中是该结构体的成员,组在一起称为成员列表,其命名与变量的命名是一致的;

注:结构体类型是可以有多中的;如:struct Student;struct Teacher;struct Worker;

        结构体的成员也可以是另一个结构体的类型;

struct Date

{        

        int month;

        int day;

        int year;      

};

struct Student

{

        int num;

        char name[20];

        char sex;

        int age;

        struct Date birthday;

        char addr[30];

}

1.2结构体变量的定义

        前面我们只定义了一个结构体类型,相当于一个模型,并没有定义变量,下面我们定义结构体变量,并在其中存放具体的数据,3种方法;

  方法1:先声明结构体类型,在定义结构变量

        在前面结构体类型的基础上 struct Student,定义结构体变量;

         struct Student student1,student2;

        这种方式类似于int a,b;只是前提是已经有了结构体类型,在类型的基础上定义结构体变量。

    方法2:在声明类型的同时定义变量

        形式:

                struct 结构体名

                {

                        成员列表;

                }变量名列表;

        举例:

                  struct Student
                {
                      int num;
                      char name[20];
                      char sex;
                      int age;
                      float score;
                      char addr[30];
                }student1,student2;

        方法3:不指定类型名而直接定义结构体类型变量

                形式:

                        struct

                        {

                                成员变量;

                        }变量名列表;

        其为一个无名的结构体类型,不经常使用;

注:1、结构体变量中的成员名可以与程序中的变量名相同;

        2、结构体变量中的成员可以单独使用;他的地位和作用相当于普通变量;

1.3结构体变量的初始化和引用 

        在定义结构体变量的时候顺便对其初始化;

      举例:把一个学生的信息(包括学号、姓名、性别、住址)放在一个结构体变量中,然后输出该学生的信息;

#include <stdio.h>int main()
{struct Student{int num;char name[20];char sex;char addr[20];}student1 = {101,"Li li",'M',"123XiAn"};printf("NO:%d,\nname:%s\nssex:%c\naddress:%s\n",student1.num,student1.name,student1.sex,student1.addr);return 0;

结果分析:

        在定义结构体变量的时候顺便对其进行成员初始化,初始化列表是用花括号括起来的一些常量,这些常量是一次赋给结构体变量的成员,注意:是对结构体变量初始化,不是对结构体类型初始化。

        结构体变量中成员的值,引用方式为:

 结构体变量名.成员名

 student1.name

        对于结构体成员本是又属于一个结构体类型,则要一级一级地找到最低一级的成员,例如上面所述的struct Student中包含 struct Date birthday;则引用的方式为:

        Student birthday.month

同类型的结构体可以相互赋值: student1= student2;

        举例:输入两个学生的学号、姓名和成绩,输出成绩较高的学生的学号、姓名和成绩;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{struct Student{int num;char name[20];float score;}student1,student2;scanf("%d%s%f", &student1.num, student1.name, &student1.score);scanf("%d%s%f", &student2.num, student2.name, &student2.score);printf("The higher score is:\n");if (student1.score > student2.score){printf("%d %s %6.2f\n", student1.num, student1.name, student1.score);}else if (student1.score < student2.score){printf("%d %s %6.2f\n", student2.num, student2.name, student2.score);}else{printf("%d %s %6.2f\n", student1.num, student1.name, student1.score);printf("%d %s %6.2f\n", student2.num, student2.name, student2.score);}
}

        用scanf函数输入结构体变量的时候,必须分别输入,不能在scanf函数中使用结构体变量名一次性输入全部成员的值,注意,scanf函数在student1.name前面没有&,因为数组名本来就代表了地址。 

二、使用结构体数组

2.1定义结构体数组

        我们前面在定义结构体变量的时候,是一个一个进行定义的,但是,如果是一组有关联得数据需要参与运算,显然就需要用到数据,例如10名同学的信息,这就是结构体数组,结构体数组的每一个数组元素都是一个结构体。

举例:有3名候选人,每一个选民只能投票选一个人,要求编写一个统计票数的程序,先输入备选人的姓名,最后显示各人得票的结果。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>struct Person
{char name[20];int count;
}leader[3] = { "wang", 0, "zhang", 0, "li", 0 };
int main()
{int i, j;char lead_name[20];for (i = 0; i < 10; i++){scanf("%s", lead_name);for (j = 0; j < 3; j++){if (strcmp(lead_name, leader[j].name) == 0)leader[j].count++;}}printf("\nResult\n");for (i = 0; i < 3; i++){printf("name:%s,count:%d\n", leader[i].name, leader[i].count);}return 0;}

定义结构体数组的一般形式:

        struct 结构体名

        {

                变量列表

        } 数组名[数组长度];

        先声明一个结构体类型,如:struct student,然后在定义结构体数组;

        结构体类型 数组名[数组长度];

对于结构体数组初始化的形式是在定义后加:

        ={初值列表};     

2.2使用结构体数组

        举例:有n个学生的信息(包括学号、姓名、成绩),要求按照成绩的高低顺序输出各个学生的信息;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>struct Student
{int num;char name[20];float score;
};int main()
{struct Student stu[5] = { 1001, "Wangwei", 98.25, 1002, "Liuliu", 91, 1003, "Zhangli", 98, 1004, "Xiaozhao", 85, 1005, "Baibai", 94 };struct Student temp;printf("The order id:\n");int i, j,k;for (i = 0; i < 4; i++){k = i;for (j = i + 1; j < 5; j++){if (stu[j].score>stu[k].score){k = j;}}temp = stu[k]; stu[k] = stu[i]; stu[i] = temp;	}for (i = 0; i < 5; i++){printf("%d  %s  %5.2f", stu[i].num, stu[i].name, stu[i].score);printf("\n");}return 0;
}

三、结构体指针

3.1指向结构体变量的指针

          所谓的结构体指针就是指向结构体变量的指针,一个结构体变量的起始地址就是这个结构体变量的指针。   

        指向结构体对象的指针变量既可以指向结构体变量,也可以指向结构体数组的元素,指针变量的基类型必须与结构体变量的类型相同。

如:struct Student * pt;   

举例:通过指向结构体变量的指针变量输出结构体变量中成员的信息;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>struct Student
{long num; char name[20];char sex;float score;
};int main()
{struct Student stu1;struct Student *pt;pt = &stu1;stu1.num = 10001;strcpy(stu1.name, "Lili");stu1.sex = 'M';stu1.score = 96.5;printf("No:%d\nname:%s\nsex:%c\nscore:%5.1f\n", stu1.num, stu1.name, stu1.sex, stu1.score);printf("\n");printf("No:%d\nname:%s\nsex:%c\nscore:%5.1f\n", (*pt).num, (*pt).name, (*pt).sex, (*pt).score);printf("\n");printf("No:%d\nname:%s\nsex:%c\nscore:%5.1f\n", pt->num, pt->name, pt->sex, pt->score);return 0;
}

结果分析:

         在函数中,第一个printf函数是通过结构体变量名stu1进行成员的访问;

        第二个printf函数是通过指向结构体变量的指针变量访问他的成员的,(* pt)表示指向的结构体变量,(*pt).num表示指向的结构体成员。

        此外,在c语言中,允许将(*pt).num用pt->num代替;

3.2指向结构体数组的指针

        可以用指针变量指向结构体数组的元素。

举例:有三个学生的信息,放在结构体数组中,要求输出学生的信息;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>struct Student
{long num; char name[20];char sex;float score;
};int main()
{struct Student stu[3] = { 1001, "wangle", 'M', 95, 1002, "chengcai", 'M', 99.9, 1003, "shangmin", 'F', 85.2 };struct Student *pt;printf("No.  name       sex  score\n");for (pt = stu; pt < stu + 3; pt++){printf("%d %s %c %5.2f\n", pt->num, pt->name, pt->sex, pt->score);}return 0;
}

        程序中pt是一个指向struct Student类型结构体变量的指针变,它用来指向的是结构体变量,不是用来指向结构体中某一个成员,pt=stu[1].name是不合法的,因为一个是结构体变量,一个是结构体成员变量。p++,p的值增加的是结构体的长度。

3.3用结构体变量和结构体变量的指针作为函数参数

将一个结构体变量的值传递给函数,共有三种方法;

1、将结构体变量的成员作为参数,这种方法就是相当于传递了普通的变量,应该注意形参与实参(结构体成员)的类型相同;

2、用结构体变量作为实参。用结构体变量作为实参时,也是值传递,将结构体变量所占的内存单元的内容全部传递给形参,形参必须也是结构体变量。

3、利用指向结构体变量(数组)的指针作为实参,将结构体变量(数组)的地址传递给形参。

举例:

        有n个结构体,包括学生学号,姓名和3门课程的成绩,要求输出平均成绩最高学生的信息(包括学号、姓名、3门课程成绩、平均成绩)。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
void print(struct Student stud);
struct Student Max(struct Student stu[]);
void input(struct Student stu[]);
struct Student
{int num; char name[20];float score[3];float aver;
};int main()
{struct Student stu[3], *pt;pt = stu;input(pt);print(Max(pt));return 0;
}
void input(struct Student stu[])
{int i;printf("请输入各学生的信息:学号、姓名、3门成绩:\n");for (i = 0; i < 3;i++){scanf("%d%s%f%f%f", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);stu[i].aver = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3.0;	}
}struct Student Max(struct Student stu[])
{int i, m = 0;for (i = 0; i < 3; i++){if (stu[i].aver > stu[m].aver)m = i;}return  stu[m];
}
void print(struct Student stud)
{printf("成绩最好的学生是:\n");printf("学号:%d 姓名:%s 三门课程:%5.2f %5.2f %5.2f平均成绩:%5.2f\n", stud.num, stud.name, stud.score[0], stud.score[1], stud.score[2], stud.aver);
}

 1、调用input函数时,实参是指针变量pt,形参是结构体数组,传递的是结构体元素的起始地址,函数无返回值;

2、调用Max函数时,实参是指针变量pt,形参是结构体数组,传递的是结构体元素的起始地址,函数返回值为结构体类型数据。

3、调用print函数时,实参是结构体变量(结构体数组元素),形参是结构体变量,传递的是结构体变量中各成员的值,函数无返回值。

四、链表

4.1概述

        链表是一种常见的数据结构,它是动态进行存储分配的一种结构。

        数组在存放数据的时候,必须事先定义好数组长度(多个数组),如果有的班级有100人,有的班级有30人,若用同一个数组存放不同的班级学生的数据,则必须定义长度为100的数组,但是这样往往会存在资源的浪费,链表没有这样的缺点,他根据需要开辟内存单元。

        链表有一个“头指针”变量,图中用head表示,它存放一个地址,该地址指向一个元素,链表中每一个元素称为“结点”,每个节点应该包括两个部分:

        1、用户需要的实际数据;

        2、下一个元素的地址;

         可以看见链表中各元素在内存中的地址可以是不连续的,要找到某一元素,必须先找到前一个元素,根据前一个元素的地址才能找到下一个元素。如果不提供“头指针”,则整个链表都无法访问。

        那这样来说,用结构体建立链表是最合适的,一个结构体包含若干个成员,用指针类型成员来存放下一个节点的地址。

struct Student

        {

                int num;

                int score;

                struct Student *next;

        }

               其中,num,score用来存放用户数据,next用于存放下一个节点的地址。

4.2静态链表

案例:

        建立一个静态链表,由3个学生的数据的节点组成,要求输出各个节点的数据;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>struct Student
{int num; float score;struct Student * next;
};int main()
{struct Student a, b, c, *head, *p;a.num = 1001; a.score = 85.5;b.num = 1002; b.score = 95.5;c.num = 1003; c.score = 84.5;head = &a;a.next = &b;b.next = &c;c.next = NULL;p = head;do{printf("%d %5.2f\n", p->num, p->score);p = p->next;} while (p != NULL);return 0;
}

        为例建立链表,使head指向a结点,a.next指向b结点,b.next指向c结点,c.next指向null,这就构成了链表关系。

        在输出链表的时候,要先借助p,先使p指向a,然后输出a中的数据,p=p->next是输出位下一个结点做准备。

4.3动态链表       

4.3.1 动态内存分配 

        在说动态链表之前我们先给大家介绍,动态内存分配。

        在前面我们说变量分为全局变量与局部变量,全局变量分配在内存的静态存储区,非静态存储的局部变量是分配在内存中的动态存储区,这个存储区被称为

        此外,C语言还允许建立内存动态分配区域,以存放一些临时用的数据,这些数据需要时开辟,不需要时释放,这些数据是临时存放在一个特别的自由存储区,这个存储区被称为

        对于内存的动态分配,是通过系统提供的函数来实现的:malloc、calloc、free以及realloc函数。

1、用malloc函数开辟动态存储区

函数: void *malloc (unsigned int size);

功能:

        在内存的动态存储区分配一个长度为size的连续空间(单位:字节)。

返回值:

        所分配的第一个字节的地址;此地址没有类型,只是一个纯地址;

2、用calloc函数开辟动态存储区

函数:void * calloc(unsigned n,unsigned size);

功能:

        在内存的动态存储区分配n个字节长度为size的连续空间。这个空间比较大足以保存一个数组;

        用calloc函数可以为一维数组开辟动态存储空间,n为数组元素个数,size为元素长度。

返回值:

        所分配的第一个字节的地址;此地址没有类型,只是一个纯地址;

3、用realloc函数重新分配动态存储区

函数:void * realloc(void *p ,unsigned int size);

功能:

        对已经分配的动态内存进行重新分配。

        用recalloc函数将p所指向的动态空间的大小改为size。p的值保持不变;

返回值:

        更新后动态内存的第一个字节的地址,实质上也就是p所指向的地址。

4、用free函数释放动态存储区

函数: void free(void *p);

功能:

        释放指针变量p所指向的动态空间,使这部分空间能被其他变量使用,

        p是最近一次调用malloc、calloc函数所得的返回值;

返回值:

        无;

:以上4个函数的声明都在stdlib.h头文件中。      

 void指针类型:

        在上面的函数malloc函数与calloc函数的返回值都是void *类型,它表示不指向任何类型的数据,不要把其理解为指向任何的类型,而是指向空类型或者不指向确定类型的数据。

        在调用动态内存的时候,程序只是利用了该函数带回来的纯地址,并没有用到指向哪一个数据类型的属性,如果要使用这个地址,必须将其进行转化。

例如:

        int *p;

        p=(int*)malloc(100);

案例:

        建立一个动态数据,输入5个学生的成绩,另外用一个函数检车其中有无低于60分的,输出不合格的成绩;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>int main()
{void check(int * p);int *p1, i;p1 = (int *)malloc(5 * sizeof(int));for (i = 0; i < 5; i++){scanf("%d", p1 + i);}check(p1);return 0;
}
void check(int * p)
{int i;printf("they are fail:\n");for (i = 0; i < 5; i++){if (*(p+i) < 60)printf("%d  ", *(p + i));}
}

运行结果:

结果分析:

        在程序中并没有定义数组,只是开辟了一段的动态自由分配区,作为数组使用。

        在malloc函数中,并没有直接传递具体的数值用来分配动态空间,而是利用sizeof计算此系统整型的字节数,然后创建5个元素。利用p指向第一个字节地址,并将其转化为int类型,p+1指向下一个元素。

4.3.2动态链表建立

        写一函数建立一个有4名学生数据的动态链表。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>#define LEN sizeof(struct Student)struct Student
{long num;float score;struct Student * next;
};int n;
struct Student * creat(void)
{struct Student * head, *p1, *p2;n = 0; p1 = p2 = malloc(LEN);scanf("%ld%f", &p1->num, &p1->score);head = NULL;while (p1->num != 0){n = n + 1;if (n == 1)head = p1;else  p2->next = p1;p2 = p1;p1 = (struct Student *)malloc(LEN);scanf("%ld%f", &p1->num, &p1->score);}p2->next = NULL;return (head);}int main()
{struct Student * pt;pt = creat();printf("\n num:%ld score:%5.2f\n", pt->num, pt->score);return 0;
}

运行结果: 

结果分析:动态链表的创建先指定了三个结构体指针,然后利用malloc函数先创建了一个节点,将三个结构体指针都指向这个结点,然后p1再去利用malloc函数进行创建节点,并将p2的next指向创建的结点,指向后p2=p1,p1再去创建p2的next指向创建的结点,p2=p1....直到p1中元素的值为0,p2的next不指向新创建的结点,指向NULL,这样一个动态链表就创建完毕,head指向最开始的结点,自己就是头结点。

动态链表的输入与输出:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>#define LEN sizeof(struct Student)struct Student
{long num;float score;struct Student * next;
};
int n;
struct Student * creat(void)
{struct Student * head, *p1, *p2;head = NULL;n = 0;p2 = p1 = malloc(LEN);scanf("%ld%f", &p1->num, &p1->score);while (p1->num != 0){n = n + 1;if (n == 1)head = p1;elsep2->next = p1;p2 = p1;p1 = malloc(LEN);scanf("%ld %f", &p1->num, &p1->score);}p2->next = NULL;return head;
}void print(struct Student * p)
{do{printf("%ld %5.2f\n", p->num ,p->score);p=p->next;} while (p->num != NULL);
}int main(void)
{struct Student * pt;pt = creat();print(pt);return 0;
}

 运行结果:

五、共用体类型 

5.1概述    

    在有些时候,希望再通一段内存单元中存放不同类型的变量,例如,将整型变量,字符型变量以及浮点型变量放在同一个地址开始的内存单元中,这使得几个变量共享同一段内存结构,称为“共用体”。

定义共用体的一般形式:

        union 共用体名

        {

                成员列表;

        }变量列表;

例如:

        union Data

        {

                int i;

                char ch;

                float f;

        }a,b,c;

        结构体变量所占的内存长度是各成员占的内存长度之和;而共用体所占的内存长度是最长成员的长度。

5.2引用

        只有事先定义好共用体变量,才能引用,注意,我们引用的不是共用体变量而是引用的共用体变量中的成员。

a.i   引用共用体变量中的整形变量;

a.ch   引用共用体变量中的字符变量;

a.f   引用共用体变量中的实型变量;

5.3特点

1、在内存段中可以用来存放几种不同类型的成员,但是在每一瞬间只能存放其中的一个成员,而不是同时存放几个。

2、可以对共用体变量初始化,但是初始化表中只能有一个常量。

3、共用体变量中其作用的成员,是最后一次被赋值的成员,前面原有的变量被覆盖取代。

4、共用体变量的地址和它的各成员的地址都是一样的。

5、不能对共用体变量名称赋值,也不能企图引用变量名来得到一个值。

六、枚举类型

        如果有的变量的取值只有几种可能性,则可以定义为枚举类型;所谓的枚举就是将可能出现的值一一进行列举。

        声明枚举类型用enum开头;例如

        eunm Weekday{sun,mon,tue,wed,thu,fri,sat};

        以上声明了一个枚举类型enum Weekday。然后可以用此类型来定义变量。

        enum Weekday workday,weekend;

其中,workday与weekend被定义为枚举变量,花括号中称为枚举元素或枚举常量。

声明枚举类型的一般形式:

        enum [枚举名] {枚举元素列表};

举例:

        口袋中有红黄蓝白黑5种小球,每次从口袋中先后取出3个,问得到3种不同颜色的球的可能取法并进行排列;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{enum Color {red,yellow,bule,white,black};enum Color i, j, k, pri;int n, loop;n = 0;for (i = red; i <= black; i++)for (j = red; j <= black; j++)if (i != j){for (k = red; k <= black; k++)if ((k != i) && (k != j)){n++;printf("%d ", n);for (loop = 1; loop <= 3; loop++){switch (loop){case 1:pri = i; break;case 2:pri = j; break;case 3:pri = k; break;default:break;}switch (pri){case red:printf("%s ", "red"); break;case yellow:printf("%s ", "yellow"); break;case bule:printf("%s ", "bule"); break;case white:printf("%s ", "white"); break;case black:printf("%s ", "black"); break;default:break;}}printf("\n");}}printf("\n total:%d\n", n);return 0;
}

运行结果:

七、用typedef声明新类型名

 利用typedef指定新的类型名代替已有的类型名;

1、简单地用一个新的类型名代替原有的类型名

      例如:

        typedef int Integer;

        typedef float Real;

        这样,下面两行是等价的:

        int i,j;———   Integer i,j;

2、命名一个简单的类型名代替复杂的类型表示方法

     命名新的类型名代表结构体类型:

        typedef struct

        {

                int mun;

                ......

        }  Data; 

        则用新的类型名Data去定义变量;

        Data brithday;

        Data * p;

      命名一个新的类型名代替数组类型:

        typedef int Num[100];

        Num a;

       命名一个新的类型名代表指针类型

        typedef char * String;

        String p,a[10];

       命名一个新的类型名代表指向函数的指针;

        typedef int (* Pointer)();

        Pointer p1,p2;

           归纳:按照定义变量的方式,把变量名换成新的类型名,并且在最前面加typedef,就声明了新类型名代表原来的类型。

typetef只是对已经存在的类型指定一个新的类型名,而并没有创造新的类型。

typetef和#define表面上有相似之处。

typedef int Count

#define Count int

        他们的作用都是用Count代替int,但是事实上他们两者是不同的,#define是在预编译是处理的,他只能作为简单的字符串替换,而typedef是在编译阶段处理。实际上并不是简单的替换。而是生成了一个新的类型名,再去定义变量。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 利用pandas处理CSV文件(DataFrame的基础用法)

前面介绍过通过Python标准库中的CSV模块处理CSV文件&#xff1a; Python 利用CSV模块处理数据 相比CSV模块&#xff0c;pandas的功能更加强大&#xff0c;本文将简单介绍如何通过pandas来处理CSV文件。 文章目录 一、pandas简介二、用法示例2.1 读取CSV文件2.1.1 read_csv参数…

Python 视频的色彩转换

这篇教学会介绍使用OpenCV 的cvtcolor() 方法&#xff0c;将视频的色彩模型从RGB 转换为灰阶、HLS、HSV...等。 因为程式中的OpenCV 会需要使用镜头或GPU&#xff0c;所以请使用本机环境( 参考&#xff1a;使用Python 虚拟环境) 或使用Anaconda Jupyter 进行实作( 参考&#x…

火柴棒图python绘画

使用Python绘制二项分布的概率质量函数&#xff08;PMF&#xff09; 在这篇博客中&#xff0c;我们将探讨如何使用Python中的scipy库和matplotlib库来绘制二项分布的概率质量函数&#xff08;PMF&#xff09;。二项分布是统计学中常见的离散概率分布&#xff0c;描述了在固定次…

MUNIK解读ISO26262--系统架构

功能安全之系统阶段-系统架构 我们来浅析下功能安全系统阶段重要话题——“系统架构” 目录概览&#xff1a; 系统架构的作用系统架构类型系统架构层级的相关安全机制梳理 1.系统架构的作用 架构的思维包括抽象思维、分层思维、结构化思维和演化思维。通过将复杂系统分解…

OZON生活家居用品爆款新品

OZON生活家居用品爆款新品涵盖了多个方面&#xff0c;这些产品不仅满足了消费者对生活品质的追求&#xff0c;也反映了当前市场的热门趋势。以下是一些在OZON平台上备受关注的生活家居用品爆款新品&#xff1a; OZON生活家居用品爆款新品工具&#xff1a;D。DDqbt。COm/74rD T…

昇思25天学习打卡营第17天|基于MobileNetv2的垃圾分类

今天学习的内容是利用视觉图像技术&#xff0c;来实现垃圾分类代码开发的方法。通过读取本地图像数据作为输入&#xff0c;对图像中的垃圾物体进行检测&#xff0c;并且将检测结果图片保存到文件中。 本章节主要包括8部分内容&#xff1a; 1、实验目的 1、了解熟悉垃圾分类应用…

防御笔记第四天(持续更新)

1.状态检测技术 检测数据包是否符合协议的逻辑顺序&#xff1b;检查是否是逻辑上的首包&#xff0c;只有首包才会创建会话表。 状态检测机制可以选择关闭或则开启 [USG6000V1]firewall session link-state tcp ? check Indicate link state check [USG6000V1]firewall ses…

实践致知第12享:如何新建一个Word并设置格式

一、背景需求 小姑电话说&#xff1a;要新建一个Word文档&#xff0c;并将每段的首行设置空2格。 二、解决方案 1、在电脑桌面上空白地方&#xff0c;点击鼠标右键&#xff0c;在下拉的功能框中选择“DOC文档”或“DOCX文档”都可以&#xff0c;如下图所示。 之后&#xff0…

光学传感器图像处理流程(二)

光学传感器图像处理流程&#xff08;二&#xff09; 2.4. 图像增强2.4.1. 彩色合成2.4.2 直方图变换2.4.3. 密度分割2.4.4. 图像间运算2.4.5. 邻域增强2.4.6. 主成分分析2.4.7. 图像融合 2.5. 裁剪与镶嵌2.5.1. 图像裁剪2.5.2. 图像镶嵌 2.6. 遥感信息提取2.6.1. 目视解译2.6.2…

沙龙回顾|MongoDB如何充当企业开发加速器?

数据不仅是企业发展转型的驱动力&#xff0c;也是开发者最棘手的问题。前日&#xff0c;MongoDB携手阿里云、NineData在杭州成功举办了“数据驱动&#xff0c;敏捷前行——MongoDB企业开发加速器”技术沙龙。此次活动吸引了来自各行各业的专业人员&#xff0c;共同探讨MongoDB的…

vscode c++可以找到声明却无法自动补全

这个问题折磨了我将近一个月&#xff0c;今天终于被解决了&#xff0c;特此记录 情景再现 事情的起因是我在学习华为的Ascend C算子&#xff0c;需要编写C代码。关于怎么下载库文件怎么编译之类的不是本文的重点&#xff0c;重点是自动补全。 我已经拿到库文件了&#xff0c…

Git命令常规操作

目录 常用操作示意图 文件的状态变化周期 1. 创建文件 2. 修改原有文件 3. 删除原有文件 没有添加到暂存区的数据直接 rm 删除即可&#xff1a; 对于添加到暂存区的数据 文件或目录&#xff1a; 4. 重命名暂存区数据 5. 查看历史记录 6. 还原历史数据 恢复过程的原…

vue 路由

文章目录 作用如何设置路由注意点路由器工作模式to的两种写法(跳转去哪里的链接的写法)命名路由(后续可以用名字进行跳转)嵌套路由(多个层级的路由) 作用 一句话说完,就是用来,跳转页面的 如何设置路由 效果: 整体框架的图 components 代码 About.vue 简单的显示主键 &l…

星辰计划02-独特视角的spring动态代理

承接上一文 动态代理 &#xff0c;这里探究spring 动态代理 会话1&#xff1a;spring动态代理 quick start &#x1f467;哥哥&#xff0c;哥哥&#xff0c;spring 怎么去搞动态代理的呢&#x1f468; 来来来&#xff0c;听我细细来说 quick start通过Spring的 ProxyFactory…

云视频监控中的高效视频转码策略:视频汇聚EasyCVR平台H.265自动转码H.264能力解析

随着科技的快速发展&#xff0c;视频监控技术已经广泛应用于各个领域&#xff0c;如公共安全、商业管理、教育医疗等。与此同时&#xff0c;视频转码技术作为视频处理的关键环节&#xff0c;也在不断提高视频的质量和传输效率。 一、视频监控技术的演进 视频监控技术的发展历…

前后端如何实现非对称加解密-使用RSA为例讲解!

写在最前面&#xff0c;RSA是一种非对称加密算法&#xff0c;使用不同的公钥和私钥进行加密和解密。 下面是使用RSA进行加密和解密的代码示例&#xff1a; 前端&#xff1a;使用CryptoJS进行RSA加密 在前端JavaScript中&#xff0c;使用jsencrypt库来进行RSA加密&#xff1a…

【React】Ant Design -- Table分页功能实现

实现步骤 为Table组件指定pagination属性来展示分页效果在分页切换事件中获取到筛选表单中选中的数据使用当前页数据修改params参数依赖引起接口重新调用获取最新数据 const pageChange (page) > {// 拿到当前页参数 修改params 引起接口更新setParams({...params,page})…

前端web在线PPT编辑器-PPTLIST

哈喽&#xff0c;大家好&#xff0c;今天给大家介绍一款的在线的PPT编辑器开源框架-PPTLIST&#xff1b;他是一个基于 Vue3.x TypeScript 的在线演示文稿&#xff08;幻灯片&#xff09;应用&#xff0c;还原了大部分 Office PowerPoint 常用功能&#xff0c;支持 文字、图片、…

JMH325【剑侠情缘3】第2版80级橙武网游单机更稳定亲测视频安装教学更新整合收集各类修改教学补丁兴趣可以慢慢探索

资源介绍&#xff1a; 是否需要虚拟机&#xff1a;是 文件大小&#xff1a;压缩包约14G 支持系统&#xff1a;win10、win11 硬件需求&#xff1a;运行内存8G 4核及以上CPU独立显卡 下载方式&#xff1a;百度网盘 任务修复&#xff1a; 1&#xff0c;掌门任务&#xff08…

小程序内容管理系统设计

设计一个小程序内容管理系统&#xff08;CMS&#xff09;时&#xff0c;需要考虑以下几个关键方面来确保其功能完善、用户友好且高效&#xff1a; 1. 需求分析 目标用户&#xff1a;明确你的目标用户群体&#xff0c;比如企业、媒体、个人博主等&#xff0c;这将决定系统的功…