C语言总结十一:自定义类型:结构体、枚举、联合(共用体)

        本篇博客详细介绍C语言最后的三种自定义类型,它们分别有着各自的特点和应用场景,重点在于理解这三种自定义类型的声明方式和使用,以及各自的特点,最后重点掌握该章节常考的考点,如:结构体内存对齐问题,使用联合判断字节序的存储问题。学完本篇博客达到理解会运用!

一、结构体(struct)

      数组可理解为一种自定义数据类型,它存放的是一组相同数据类型数据的集合,每个数据可看作是一个变量,但是现实生活只有这些内置类型还是不够的,假设我想描述学生,描述一本书,这时单一的内置类型是不行的。描述一个学生需要名字、年龄、学号、身高、体重等;描述一本书需要作者、出版社、定价等。需要不同的数据类型,因此,C语言为了解决这个问题,增加了结构体这种自定义的数据类型,让程序员可以自己创造适合的类型。

      结构体是一种存放不同数据类型的数据集合,同样也是一种自定义数据类型。结构体是C语言由面向过程向面向对象的一种转变。

1.1 结构体类型的声明和结构体的嵌套以及结构体指针(是指针)

       结构体类型的声明通常包括结构体的名称和其成员变量的定义,结构体的成员变量可以包括基本数据类型变量、数组、结构体类型(结构体的嵌套)指针类型

      结构体指针是指向结构体类型变量内存地址的指针。通过使用结构体指针可以访问或者修改结构体成员变量;

      下面使用一个具体的例子说明如何进行结构体类型的声明和结构体的嵌套以及定义结构体指针。

       结构体的声明必须放在函数的外部,它告知编译器这个结构体包括哪些成员,按照如下格式进行声明:

              struct  结构体名
             {
                        成员列表(结构体所包含的变量或数组或结构体或指针)
             }
;

     此时,结构体名就是类型名。

//.c文件中(C语言语法)普通的声明结构体的方式和定义结构体变量
struct Address
{char name[20];char area[20];
};                  //分号不能少struct Student
{char * name1;         //字符串指针const char * name2;   //字符串指针,用const修饰,只可通过指针解引用访问,不可进行修改char name3[20];       //字符数组int id;float  score;Address address;     //结构体嵌套
};         int main()
{//定义结构体变量struct Student s={"张三","李四","王五",111,98.5,{"王麻子","陕西"}};//定义结构体指针struct Student * ps=&s;//.cpp文件中(C++语法)语普通的声明结构体的方式和定义结构体变量
struct Address
{char name[20];char area[20];
};                  //分号不能少struct Student
{char * name1;         //字符串指针const char * name2;   //字符串指针,用const修饰,只可通过指针解引用访问,不可进行修改char name3[20];       //字符数组int id;float  score;Address address;     //结构体嵌套
};         int main()
{//定义结构体变量Student s={"张三","李四","王五",111,98.5,{"王麻子","陕西"}};//定义结构体指针Student * ps=&s;return 0;
}

从上面可以看出,.c和.cpp语法的区别在于:c++语法可以省略关键字struct,而c语言语法不能省略struct,为了实际开发统一使用,可以结合使用typedef进行类型重命名,便可在两个文件同时使用,省略关键字struct。

//结构体声明结合typedef使用typedef struct Address
{char name[20];char area[20];
}Address;                  //分号不能少typedef struct Student
{char * name1;         //字符串指针const char * name2;   //字符串指针,用const修饰,只可通过指针解引用访问,不可进行修改char name3[20];       //字符数组int id;float  score;Address address;     //结构体嵌套
}Student,*Ps;         //利用typedef对结构体和结构体指针进行重命名
//相当于:typedef struct Student  Student
//相当于:typedef struct Student*  Psint main()
{//定义结构体变量Student s={"张三","李四","王五",111,98.5,{"王麻子","陕西"}};//定义结构体指针Ps=&s;

注意事项:

        在对结构体成员设计时,要考虑两个方面:

  1. 考虑数据的长度,用合适的数据类型变量保存!
  2. 对于较大的数据,可以用字符串进行保存!

如:字符数组 char str[20];    内存开辟在栈区,保存的是实际的数据
       字符串指针 const char * str;     字符串存储在常量区,指针开辟在栈区,保存的是这个数据的地址
        整型数据int存放不下时,可以用字符串的方式存储也可使用上述方法。

1.2 结构体变量的定义及初始化

      结构体和数组类似,因此初始化方式和数组一样,采用花括号赋值!结构体嵌套时,里面的结构体也是需要花括号进行初始化的。

       注意对结构体中的字符数组或者字符串进行初始化,必须使用字符串拷贝函数,切不可直接赋值,如:s.name="张三",因为左边是字符数组名为字符首元素的地址,地址是编号,是一个常量,常量不可以做左值,左值必须是可以修改的变量,右边是一个字符串常量存储在数据区,且不可以进行修改,代表首元素的地址。改正:strcpy(s.name,"张三");

注意事项:

      数组与结构体类似,但是存在以下两点不同之处:

  1. 结构体变量名和数组名不同,数组名在表达式中会被转换成指针/地址,而结构体变量名并不会,无论在任何表达式中它表示的都是整个集合本身,要想取得结构体变量的地址必须要加取地址符&;
  2. 数组在内存中存放的,并且随着下标的增大,数组元素的地址也随着增大,数组所占的字节数等于数组元素个数乘以单个元素所占字节数,而结构体所占内存空间的大小,需要结合内存对齐问题进行计算!
    Student s={"张三","李四","王五",111,98.5,{"王麻子","陕西"}};

       结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据,需要内存空间来存储。 

1.3 结构体成员的三种访问方式

结构体成员的访问,一共有3种方式,但实际为了开发方便,常常使用2种

1.通过结构体变量访问结构体成员,语法形式:结构体变量.结构体成员名

2.通过结构体指针变量先解引用找到该结构体变量再 . 访问,

                                                         语法形式:(*结构体指针变量).结构体成员名

3.为了简化第二种引入指向符: -> ,语法形式:结构体指针变量->结构体成员名

        实际开发,常常用的是第1种和第3种,第3种更加实用。

#include <stdio.h>
typedef struct Address
{char name[20];char area[20];
}Address,* Pa;typedef struct Student
{const char* name1;   //字符串指针,用const修饰,只可通过指针解引用访问,不可进行修改int id;float  score;Address address;     //结构体嵌套
}Student, * Ps;int main()
{Student s = { "张三",22203,99.5,{"王恒","西安市"} };Ps p = &s;//使用代码实现访问s中的成员address中的area成员(嵌套访问)//第一种访问方式:通过结构体变量访问结构体成员:结构体变量.结构体成员名printf("%s ""%d ""%f ""%s ""%s \n",s.name1,s.id,s.score,s.address.name,s.address.area);//第二种访问方式:通过结构体指针变量先解引用找到该结构体变量再 . 访问printf("%s ""%d ""%f ""%s ""%s \n", (*p).name1, (*p).id, (*p).score, (*p).address.name, (*p).address.area);//第三种访问方式:为了简化第二种引入指向符: ->访问printf("%s ""%d ""%f ""%s ""%s ", p->name1, p->id, p->score, p->address.name, p->address.area);return 0;
}

1.4 结构体数组(是数组)

        结构体数组是包含结构体类型元素的数组。通过使用结构体数组,可以创建多个结构体类型的实例,并以数组的形式组织这些实例。

#include <stdio.h>// 结构体声明
typedef struct Person 
{char name[50];int age;float height;
}Person;int main() 
{// 创建结构体数组并初始化Person people[3] = {{"Alice", 30, 160.5},{"Bob", 25, 175.0},{"Charlie", 35, 180.2}};// 访问结构体数组元素for (int i = 0; i < 3; ++i) {printf("Person %d\n", i + 1);printf("Name: %s\n", people[i].name);printf("Age: %d\n", people[i].age);printf("Height: %.2f\n", people[i].height);printf("\n");}return 0;
}

1.5 结构体的内存对齐及结构体占用内存的计算(重点)

1.5.1 为什么存在内存对齐?

        计算机内存是以字节为单位划分的,理论上CPU可以访问任意编号的字节,但实际情况并非如此,CPU通过地址总线来访问内存,一次能处理几个字节的数据,就命令地址总线读取几个字节的数据,32位CPU一次可以处理四个字节的数据,那么就从内存中读取4个字节的数据少了浪费主频,多了没有用,64位处理器同样,每次读取8个字节。

       以32位CPU为例,实际寻址步长为4个字节,也就是只对地址编号为4的倍数的内存寻址,例如:4,8,12....这样做可以以最快的速度寻址,不遗漏一个字节,也不重复对一个字节寻址,对于程序来说,一个变量的最好位于一个寻址步长的范围内,这样一次就可以读取变量的值,如果跨步长存储,就需要读取两次,然后拼接数据,效率显然降低!

       将一个数据尽量放在一个步长之内,避免跨步长存储,这就要求各种数据类型按照一定的规则在内存空间上排列,这就是内存对齐,提高了读取效率,代价就是浪费内存空间!

     总体来说: 结构体的内存对齐是拿空间来换取时间的做法。

那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到???

让占用空间小的成员尽量集中在一起!!!

1.5.2 结构体大小的计算(重点)

1)结构体变量的首地址从偶数地址开始(用0表示)

(2)结构体每个成员相对于结构体首地址的偏移量都是min{该成员数据类型字节数,指定对齐方式}大小的整数倍,即每个成员在内存上开辟的起始地址必须是这个数,否则存在空间浪费。

(3)结构体的大小为min{结构体最大基本数据类型成员所占字节数(将嵌套结构体里的基本数据类型也算上,得到最大的基本数据类型所占字节数),指定对齐方式}大小的整数倍。

      预处理指令#pragma pack(n) 可以改变默认对齐数。n 取值是 1, 2, 4, 8 , 16。

vs中默认值 = 8,gcc中默认值 = 4

     
//练习1
#include<stdio.h>
struct S1
{char c1;int i;char c2;
};int main()
{printf("%d\n", sizeof(struct S1));return 0;
}

//练习2
#include<stdio.h>
struct S2
{char c1;char c2;int i;
};int main()
{printf("%d\n", sizeof(struct S2));return 0;
}

//练习3
#include<stdio.h>
struct S3
{double d;char c;int i;
};
int main()
{printf("%d\n", sizeof(struct S3));return 0;
}

//练习4-结构体嵌套问题
#include<stdio.h>struct S3
{double d;char c;int i;
};
struct S4
{char c1;struct S3 s3;double d;
};int main()
{printf("%d\n", sizeof(struct S4));return 0;
}

 

结构在对齐方式不合适的时候,我们可以自己更改默认对齐数。 

#include <stdio.h>
#pragma pack(8)//设置默认对齐数为8
struct S1
{char c1;int i;char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认#pragma pack(1)//设置默认对齐数为1
struct S2
{char c1;int i;char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认

1.6 结构体传参

       结构体变量名代表的是整个集合本身,作为函数参数时,传递的是整个集合,也就是说是原来结构体成员的一份临时拷贝,而不是像数组名一样被编译器转换成一个指针,如果结构体成员较多,尤其是成员为数组时,函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。传送的时间和空间开销会很大,影响程序的执行效率,此外,这种值传递不可以通过函数内部来修改外部数据!最好的办法是使用结构体指针,这时由实参传向形参只是传递一个地址,即结构体变量的地址,占用4个字节,非常迅速,并且可以在函数内部通过解引用结构体指针从而修改外部数据,另外如果不想改变外部的数据,可以给形参加上const进行修饰!

       结论: 结构体传参的时候,要传结构体的地址。

1.7 位段(了解)

1.7.1 什么是位段

      有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位。正是基于这种考虑,C语言又提供了一种叫做位段的数据结构。在结构体定义时,我们可以指定某个成员变量所占用的二进制位数(Bit),这就是位段。

  1. 位段的成员必须是 int、unsigned int 或signed int 或者char。
  2. 位段的成员名后边有一个冒号和一个数字。
struct bs
{unsigned m;unsigned n: 4;unsigned char ch: 6;
};

:后面的数字用来限定成员变量占用的位数。成员 m 没有限制,根据数据类型即可推算出它占用 4 个字节(Byte)的内存。成员 n、ch 被:后面的数字限制,不能再根据数据类型计算长度,它们分别占用 4、6 位(Bit)的内存。C语言标准规定,位域的宽度不能超过它所依附的数据类型的长度。通俗地讲,成员变量都是有类型的,这个类型限制了成员变量的最大长度,:后面的数字不能超过这个长度。

1.7.2 位段的内存分配

  1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
  2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
  3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

1.7.3 位段的跨平台问题

  1. int 位段被当成有符号数还是无符号数是不确定的。
  2. 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机 器会出问题。
  3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
  4.  当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是 舍弃剩余的位还是利用,这是不确定的。

总结:跟结构相比,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。

二、枚举(enum)

2.1 枚举类型的定义

        在实际编程中,有些数据的取值往往是有限的,只能是非常少量的整数,并且最好为每个值都取一个名字,以方便在后续代码中使用,比如一个星期只有七天,一年只有十二个月,一个班每周有六门课程等。#define命令虽然能解决问题,但也带来了不小的副作用,导致宏名过多,代码松散,看起来总有点不舒服。C语言提供了一种枚举(Enum)类型,能够列出所有可能的取值,并给它们取一个名字。

#include <stdio.h>#define Mon 1
#define Tues 2
#define Wed 3
#define Thurs 4
#define Fri 5
#define Sat 6
#define Sun 7int main(){int day;scanf("%d", &day);switch(day){case Mon: puts("Monday"); break;case Tues: puts("Tuesday"); break;case Wed: puts("Wednesday"); break;case Thurs: puts("Thursday"); break;case Fri: puts("Friday"); break;case Sat: puts("Saturday"); break;case Sun: puts("Sunday"); break;default: puts("Error!");}return 0;
}

枚举类型定义方式如下:

      enum 枚举类型名字 {枚举值列表};

      enum是一个新的关键字,专门用来定义枚举类型,这也是它在C语言中的唯一用途;注意最后的;不能少。并且枚举值必须是有符号整型类型。枚举类型变量需要存放的是一个整数,它的字节长度和 int 相同。

例如,列出一个星期有几天:
enum week{ Mon, Tues, Wed, Thurs, Fri, Sat, Sun };
可以看到,我们仅仅给出了名字,却没有给出名字对应的值,这是因为枚举值默认从 0 开始,往后逐个加 1(递增);也就是说,week 中的 Mon、Tues ...... Sun 对应的值分别为 0、1 ...... 6。我们也可以给每个名字都指定一个值:
enum week{ Mon = 1, Tues = 2, Wed = 3, Thurs = 4, Fri = 5, Sat = 6, Sun = 7 };更为简单的方法是只给第一个名字指定值:
enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };
这样枚举值就从 1 开始递增,跟上面的写法是等效的。

枚举是一种类型,通过它可以定义枚举变量 ,有了枚举变量,就可以把列表中的值赋给它


enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };
enum week a, b, c;
enum week a = Mon, b = Wed, c = Sat;
判断用户输入的是星期几。
#include <stdio.h>
int main(){enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } day;scanf("%d", &day);switch(day){case Mon: puts("Monday"); break;case Tues: puts("Tuesday"); break;case Wed: puts("Wednesday"); break;case Thurs: puts("Thursday"); break;case Fri: puts("Friday"); break;case Sat: puts("Saturday"); break;case Sun: puts("Sunday"); break;default: puts("Error!");}return 0;
}

需要注意的两点是:
1) 枚举列表中的 Mon、Tues、Wed 这些标识符的作用范围是全局的(严格来说是 main() 函数内部),不能再定义与它们名字相同的变量。
2) Mon、Tues、Wed 等都是常量,不能对它们赋值,只能将它们的值赋给其他的变量。
        枚举和宏其实非常类似:宏在预处理阶段将名字替换成对应的值,枚举在编译阶段将名字替换成对应的值。我们可以将枚举理解为编译阶段的宏。 

2.2 枚举类型的使用

enum Color//颜色
{RED=1,GREEN=2,BLUE=4
};
enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
clr = 5;               //ok??错误!!!

2.3 枚举类型的特点

为什么使用枚举? 我们可以使用 #define 定义常量,为什么非要使用枚举?

枚举的优点:

  1. 增加代码的可读性和可维护性
  2. 和#define定义的标识符比较枚举有类型检查,更加严谨。
  3. 便于调试
  4. 使用方便,一次可以定义多个常量

三、联合(共用体)(union)

       在C语言中,变量的定义是分配存储空间的过程。一般的,每个变量都具有其独有的 存储空间,那么可不可以在同一个内存空间中存储不同的数据类型(不是同时存储)呢? 答案是可以的,使用联合体就可以达到这样的目的。联合体也叫共用体,在C语言中 定义联合体的关键字是union。 

3.1 联合类型的定义

    它的定义格式为:

union 共用体名

{
        成员列表
};

    共用体也是一种自定义类型,可以通过它来创建变量

union data{int n;char ch;double f;
};
union data a, b, c;

3.2 联合类型的特点及利用联合判断判断字节序的存储方式

3.2.1 特点

       联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联 合至少得有能力保存最大的那个成员)。

#include<stdio.h>
union Un
{int i;char c;
};
union Un un;int main()
{// 下面输出的结果是一样的吗?printf("%d\n", &(un.i));printf("%d\n", &(un.c));
在联合体中,所有成员共享同一块内存,因此这两行输出的地址应该是相同的。//下面输出的结果是什么?un.i = 0x11223344;un.c = 0x55;printf("%x\n", un.i);;
//由于联合体的特性,此时整型成员i的值将被覆盖为字符型成员c的值,因此输出的结果将是55。return 0;
}

3.2.2 利用联合判断判断字节序的存储方式

#include <stdio.h>
union union_test 
{int s; char t;
}test;int main(){printf("联合体 union_test 所占的字节数:%d\n", sizeof(union union_test));test.s = 0x12345678;if (0x78 == test.t) {printf("小端模式\n");}else {printf("大端模式\n");}return 0;
}

       以上便是自定义类型全部内容,认真理解消化,一定会有极大的收获,可以留下你们点赞、关注、评论,您的支持是对我极大的鼓励,下期再见!

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

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

相关文章

C++PythonC# 三语言OpenCV从零开发(5):ROI截取

文章目录 前言ROI测试图片部分区域截取CCsharpPython 颜色区域分割CCsharpPython 颜色通道合并CCsharpPython 总结 前言 C&Python&Csharp in OpenCV 专栏 【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 全套课程&#xff08;附带课程课件资料课件笔记&#xff09…

Mybatis Plus baomidou EasyCode插件自动生成驼峰字段实体类,而不是全小写字段实体类

开发环境&#xff1a; springboot 2.4.3baomidou 3.4.0mybatis plus 3.4.0jdk8 问题描述&#xff1a; 1、mybatis 使用baomidou 插件&#xff0c;EasyCode自动生成实体类&#xff0c;但字段都是全部小写的&#xff0c;不太符合编码规范。 2、mysql表字段全是驼峰&#xff0c…

大数据技术原理及应用课实验3 :熟悉常用的HBase操作

目录 实验3 熟悉常用的HBase操作 一、实验目的 二、实验平台 三、实验步骤&#xff08;每个步骤下均需有运行截图&#xff09; &#xff08;一&#xff09;编程实现以下指定功能&#xff0c;并用Hadoop提供的HBase Shell命令完成相同任务&#xff1a; 1.列出HBase所有的表…

科大讯飞将于1月30日发布星火大模型 V3.5,基于全国产化算力底座训练

科大讯飞即将发布全新AI大模型——星火认知大模型 V3.5&#xff0c;该模型将于14:00正式发布。据透露&#xff0c;相比于去年10月24日发布的V3.0版本&#xff0c;V3.5在逻辑推理、文本生成、数学答题及小样本学习能力上均实现了显著提升。 科大讯飞官网链接&#xff1a;讯飞星…

Leetcode的AC指南 —— 栈与队列:20. 有效的括号

摘要&#xff1a; **Leetcode的AC指南 —— 栈与队列&#xff1a;20. 有效的括号 **。题目介绍&#xff1a;给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字…

CMeet系列技术生态沙龙---城市开发者组织年度聚会·杭州 《把握未来趋势,持续学习创新》

CSDN始终致力于促进城市区域内尖端新兴技术开发者交流,提供开放自由的切磋平台。在这个充满挑战和机遇的一年即将结束之际&#xff0c;通过本次聚会&#xff0c;汇聚杭州本地各行各业的开发者朋友&#xff0c;回顾过去一年城市社区的成就和收获&#xff0c;感谢携手同行的各位,…

makefile的机制,执行命令的流程分析

makefile的机制&#xff0c;流程分析 calc:add.o sub.o multi.ogcc add.o sub.o multi.o calc.cpp -o calcadd.o:add.cppgcc -c add.cpp -o add.osub.o:sub.cppgcc -c sub.cpp -o sub.omulti.o:multi.cppgcc -c multi.cpp -o multi.oclean:rm -rf *.o calc按照这个例子分析&am…

常见网站结构

网站架构与部署架构 1、初始阶段的网站架构 一般来讲&#xff0c;大型网站都是从小型网站发展而来&#xff0c;一开始的架构都比较简单&#xff0c;随着业务复杂和用户量的激增&#xff0c;才开始做很多架构上的改进。当它还是小型网站的时候&#xff0c;没有太多访客&#…

数据结构之栈和队列

数据结构之栈和队列 1、栈1.1、栈的定义及基本运算1.2、栈的存储结构 2、队列2.1、队列的定义及基本运算2.2、队列的存储结构2.3、队列的应用 数据结构是程序设计的重要基础&#xff0c;它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从…

FDM3D打印系列——宝可梦妙蛙种子

fdm打印妙蛙种子 大家好&#xff0c;我是阿赵。   每次打印3D模型&#xff0c;都有新的感觉&#xff0c;这次打印了个宝可梦里面的妙蛙种子&#xff0c;也就是俗称的蒜头王八。   先来看看成果&#xff0c;然后在后面再聊一下关于3D打印的一些体会。使用创想三维的Sermoon …

华为机考入门python3--(0)测试题1-句子平均重量

分类&#xff1a;字符串 知识点&#xff1a; 获取输入 input().strip().split(" ") 拼接列表 " ".join(list) 输出指定位数的浮点数 print("%.2f" % value) 题目来自【华为招聘模拟考试】 # If you need to import additional packages or c…

Dell戴尔XPS 8930笔记本电脑原装Win10系统 恢复出厂预装OEM系统

链接&#xff1a;https://pan.baidu.com/s/1eaTQeX-LnPJwWt3fBJD8lg?pwdajy2 提取码&#xff1a;ajy2 原厂系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、Office办公软件、MyDell等预装程序 文件格式&#xff1a;esd/wim/swm 安装方式&am…

一文梳理金融风控建模全流程(Python)

▍目录 一、简介 风控信用评分卡简介 Scorecardpy库简介 二、目标定义与数据准备 目标定义 数据准备 三、安装scorecardpy包 四、数据检查 五、数据筛选 六、数据划分 七、变量分箱 卡方分箱 手动调整分箱 八、建立模型 相关性分析 多重共线性检验VIF KS和AUC …

李宏毅 Generative Adversarial Network(GAN)生成对抗网络

(延申)GAN Lecture 1 (2018)- Introduction_哔哩哔哩_bilibili Basic Idea of GAN 附课程提到的各式各样的GAN&#xff1a;https://github.com/hindupuravinash/the-gan-zoo 想要让机器做到的是生成东西。->训练出来一个generator。 假设要做图像生成&#xff0c;要做的是…

【Qt之模型视图】5. Qt库提供的视图便捷类

1. 前言 Qt提供了一些便捷的视图类&#xff0c;如QListWidget提供项目列表&#xff0c;QTreeWidget显示多级树结构&#xff0c;QTableWidget提供单元格项的表格。每个类都继承了QAbstractItemView类的行为&#xff0c;QAbstractItemView类实现了项目选择和标题管理的通用行为。…

16.5 参考文献——深度学习定位

16.5 一种高效鲁棒的多楼层室内环境指纹定位方法 同济大学 Zhao Y, Gong W, Li L, et al. An Efficient and Robust Fingerprint Based Localization Method for Multi Floor Indoor Environment[J]. IEEEa Internet of Things Journal, 2023. 2.相关工作 B.基于深度学习的…

固态硬盘优化设置

目录 前言&#xff1a; 关闭Windows Search 禁用系统保护&#xff08;不建议&#xff09; 不建议禁用系统保护原因 关闭碎片整理【机械硬盘】 提升固态硬盘速度 开启TRIM 合理使用固态硬盘的容量 正确关机 关闭开机自启 前言&#xff1a; 电脑配备固态硬盘就能一劳…

自我摸索:如何运营并玩转CSDN?

自注册CSDN以来已有七年之久&#xff0c;但真正运营CSDN也是最近一年的事情&#xff0c;大概就是22年底&#xff0c;参加2022 博客之星 的竞选。接触了很多大佬&#xff0c;也学习模仿着开始玩转CSDN&#xff0c;虽然没有同期运营的大佬们玩的6&#xff0c;但也有一些经验可以来…

this指针相关

一、类对象的存储方式 先说一下结论&#xff1a;一个类的大小&#xff0c;实际就是该类中”成员变量”之和&#xff0c;当然要注意内存对齐 注意空类和没有成员变量的类的大小&#xff0c;编译器给了这两种类一个字节来唯一标识这个类的对象。 class A { public:int _a;int _b…

Python多线程—threading模块

参考&#xff1a;《Python核心编程》 threading 模块的Thread 类是主要的执行对象&#xff0c;而且&#xff0c;使用Thread类可以有很多方法来创建线程&#xff0c;这里介绍以下两种方法&#xff1a; 创建 Thread 实例&#xff0c;传给它一个函数。派生 Thread 的子类&#xf…