进阶C语言 第四章-------《自定义类型》 (结构体、枚举、联合)知识点+完整思维导图+深入细节+通俗易懂+基本练习题+建议收藏

news2024/9/20 17:51:30

绪论

        书接上回,通过上章的一些函数,我们可以让我们对于一些数值的调整有很大的帮助,本章自定义类型在C语言中同样也有着非常重要的地位,相信只要认真的阅读了本章,一定会对你有很大的帮助。

所以安全带系好,发车啦(建议电脑观看)。

        附:红色,部分为重点部分;蓝颜色为需要记忆的部分(不是死记硬背哈,多敲);黑色加粗或者其余颜色为次重点;黑色为描述需要

思维导图:

 

要XMind思维导图的话可以私信哈

目录

1.结构体

1.1结构体的声明

1.2结构体变量的初始化

1.3结构体内存对齐

1.4修改默认对齐数

1.5结构体传参

2.位段

3.枚举(enum)

3.1枚举的定义

4.联合体(共用体union)


1.结构体

结构指一些值的集合,这些值被称为成员变量,而结构体成员可以是不同的类型(类似数组,数组也是一些值的集合,不过这些数组的值的类型是统一的)。

而结构体就像一张张体检表,上面有着一个人的许多信息,或者某样物的许多信息的集合

1.1结构体的声明

知识点:

语法:

struct name

{

        member;

        .....;

};

对于里面的成员至少是1个;

下面直接通过代码的形式来展示如何声明(让这个结构体合法)一个结构体

struct Stu
{
	char name[20];//名字
	int age;//年龄
	char sex[5];//性别
};

        这样就声明了一个结构体,其实结构体的声明也可以看成创建了一个新的类型,里面的成员有着不同的类型来修饰这个新的类型,这样就能对于一些复杂对象进行描述如上的学生

细节(注意点):

一种特别的声明匿名结构体类型(不完全声明):

struct
{
	int a;
};

此时的声明没有名字,只能跟在该声明后创建变量名/用typedef的实现

而对于结构体变量的定义有两种方法:

  1. 直接跟在结构体后面,这种是全局的
  2. 在函数内以结构体类型 + 变量名 的形式来创建一个变量(结构体类型是一种自定义类型),并且是局部的

具体如下:

//方法1
struct
{
	int a;
}s1,s2;//可以同时创建一个或多个结构体变量(s1,s2)

struct Stu student = { "张三",20,"男"};//(全局的)

//方法2
struct Stu
{
	char name[20];
	int age;
	char sex[5];
};

int main()
{
	struct Stu student = { "张三",20,"男"};//(结构体变量student)

	return 0;
}

所以对于匿名结构体来说他是没有结构体的名字的所以就会导致无法进行第二种,只能第一种直接在结构体后面创建变量,来使用和初始化

用typedef来对结构体来进行简化重命名

typedef struct Stu
{
    int age;
    char name[20];
    char sex[5];
}Stu;
当typedef重命名匿名结构体时让匿名结构体就可以让其在其余地方用
typedef struct
{
	int a;
}a;


int main()
{
	a b = { 20 };
	printf("%d", b.a);	 	
	return 0;
}

  但是要注意当嵌套时不能省略里面
typedef struct Stu
{
    int name;
    struct Stu * Node;//不能写成Stu* Node因为此时还不行因为重命名还在后面才执行
}Stu;

1.2结构体变量的初始化

知识点:

对于结构体变量的初始化的方法同样分为了两种方法,对应着创建结构体变量的两种方法:

  1. 在全局的结构体变量后直接初始化
    struct Stu
    {
    
    	char name[20];
    	int age;
    	char sex[5];
    
    }s1 = { "张三",20,"男"};
  2. 在局部的结构体变量后再初始化
    struct Stu
    {
    	char name[20];
    	int age;
    	char sex[5];
    	struct Stu* a;
    };
    
    int main()
    {
    	struct Stu student1;
    	struct Stu student = { "张三",18,"男",&student1 };
    
    	
    	printf("%s %d %s %p", student.name, student.age, student.sex,student.a);
    	return 0;
    }
  3. 单独逐一初始化
    struct Stu
    {
    	char name[20];
    	int age;
    	char sex[5];
    }student;
    int main()
    {
    
    	student.age = 25;
    //字符串数组的话,你要想赋值,你就必须要通过拷贝
        strcpy (student.name ,"LiSi");
        strcpy (student.sex ,"男"); 
    	printf("%s %d %s",student.name,student.age,student.sex);	
    	return 0;
    }

细节:

  1. 不能在自己的结构体成员中有和自己一样的结构体类型这样的话这个类型的大小将无限大,(要创建只能是别的结构体类型)
    struct Stu
    {
    	int age;
    };
    
    
    struct Stu
    {
    
    	char name[20];
    	int age;	
    
    	//struct Stu b;error
    
    	struct Stu p;  
        char sex[5];
    }s1 = { "张三",20,{0},"男"};
    
    int main()
    {
    	printf("%s %d %s", s1.name, s1.age, s1.p.age , s1.sex);
    	
    	return 0;
    }
  2. 当创建了结构体变量后,对于结构体变量初始化,只能单独改变了,不能同时改变了(只能在struct Stu student = {....}这种形式时改)
    struct Stu
    {
    	char name[20];
    	int age;
    	char sex[5];
    };
    
    int main()
    {
    	struct Stu student1 = { "张三",20,"男" };
    
    	student = { "lisi",18,"nan" };error
    	student.age = 25;
    	printf("%s %d %s", student.name, student.age, student.sex);
    	
    	return 0;
    }
  3. 乱序初始化:
    struct Stu
    {
    	char name[20];
    	int age;
    	char sex[5];
    	struct Stu* a;
    };
    
    int main()
    {
    	struct Stu student1;
    	struct Stu student = { .a = &student1 , .age = 20 , .name= "lisi",.sex= "nan"};
    
    	
    	printf("%s %d %s %p", student.name, student.age, student.sex,student.a);
    	return 0;
    }

1.3结构体内存对齐

知识点:

是当我们要求一个结构体大小时就需要用到结构体内存对齐 

对齐规则:

  1. 第一个成员变量直接对齐到偏移量为0的地址处
  2. 从第二个成员变量开始要对齐到偏移量为自身对齐数的整数倍处                                                  对齐数 = 判断自身大小和默认对齐数并取较小值(在vs环境下默认的一个对齐数值是8
  3. 结构体的总大小最终要为所有成员变量中的取过的最大对齐数的整数倍
  4. 如果有镶嵌结构体,那这个最大对齐数的判断也要包括所镶嵌的结构体 内的 成员的对齐数 ,并且这个镶嵌结构体也要对齐到自身的最大的对齐数上(在外部的结构体内)

附:在Linux gcc 环境下没有默认对齐数 对齐数就是其本身大小

下面通过例子就可以更好的去理解和记忆

细节:

计算偏移量的宏offsetof

两个参数:offsetof(结构体类型成员名

头文件:#include<stddef.h>

为什么要有内存对齐

  1. 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。(如int 4 double 8)
  2. 性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。(例:在32位机器上一次读取数据是4byte 假如结构体存中存着char 和 int  其中char 要占1byte int 占 4byte 这样总共就是5byte  那当我们要读取int 时机器就会先读取前面的4byte 那int还剩1byte要读所以就会再读一次,可若当我们进行了内存对齐就只需要一次就能将4byte的int 读完)
  3. 总体来说:结构体的内存对齐是拿空间来换取时间的做法。

所以因为存在内存对齐:所以一个成员相同的结构体,其大小都有可能不同:

struct s
{
    char c1;
    int i;
    char c2;  
};// 1 -> 4 + 4 -> 8 + 1 -> 12(要是最大对齐数的整数倍)

struct c
{
    char c1;
    char c2;
    int i;
};// 1 -> 1 + 1 -> 4 + 4 -> 8 

所以我们要有内存对齐的概念并且通过改变写法来节约空间

所以我们在写结构体时应该经量将小的成员放在一起

练习:

例1:

#include<stdio.h>
#include<stddef.h>
struct S1
{
    char c1;
    int i;
    char c2;
};
int main()
{
    printf("%d\n", sizeof(struct S1));   
    printf("%d\n", offsetof(struct S1,c1));
    printf("%d\n", offsetof(struct S1,i));
    printf("%d\n", offsetof(struct S1, c2)); 
}

分析:

  1. 首先将c1对齐到偏移量为0处                                                                                                              
  2. 其次看其余的成员变量:

    i --> 自身大小为4byte 、 默认对齐数大小为8byte 、取较小值4为最终的对齐数(取较小值)

    所以i要对齐到偏移量为4的倍数的地址去,0处往后就有偏移量为4处的地址可以 存i的4byte

    c2 --> 自身大小为1byte、默认为8、取1为对齐数(取较小值)

    c2要对齐到偏移量为1的倍数中去,4偏移处存了i的4byte后 就到了8偏移处 往后的任意位置都是1倍数,所以在8偏移处存c2                                                                                                    

  3. 最后:从0 ~ 8 结构体的总大小变成了9并不是移处不是最大对齐数(1 4 1)4的倍数,所以最终要放到偏移量为11处,所以最终大小为12byte(0 ~ 11)

偏移量:可以看成距离起始位置(箭头指向的)的距离(看线)

附加一种我自己的判断方法(不用画图直接口算):

第一个成员直接放(毋庸置疑),从第二个成员开始就要满足从对齐数的整数倍地址放,这样举个例子来解释:如当一个int 类型大小为4 所以就要从偏移量(而这个偏移量就直接找倍数即可不用想的太多)为 4处开始 ,那么就有:

从某一开始的偏移量(满足对齐数的倍数) +  自身元素大小 = 总大小  /  所到的偏移量处(继续往后开始的偏移量)

这个公式是我自己总结的可以细品,多来两道体就可以很快的算出结构体大小

具体如下:

struct name
{
    int a;
    char b;
    int c;
    int d;

};

直接口算:

先放了int 这样就是 0 + 4 = 4 此时还没放完  所以是位移到了4偏移量处 (继续往后开始的偏移量

再放char 此处因为char的对齐数肯定是1 所以可以放到任何位置  4 + 1 = 5 

再放int 应该找到8偏移处开始, 所以就是 8 + 4 = 12 移动到12偏移处(继续往加开始的偏移量,直接找倍数"8"

再放int 直接从12开始 ,12 + 4 = 16 就为最终的总大小

再快一点就可以直接 :4 -> 4 + 1 -> 8(直接找倍数"8")+ 4 - > 12(已经是4的倍数) + 4 = 16

例2:

struct S3
{
	double d;// 对齐数8
	char c;// 1
	int i;//4
};//总大小为 8 -> 8 + 1 -> 12 + 4 -> 16

struct S4
{
	char c1;// 1
	struct S3 s3;// 16
	double d;// 8
};
//此处double类型的大小是8 默认也是8 所以最终对齐数就是8 ,其次注意嵌套结构体 放在外部的结构体时要对
		//齐到嵌套结构体内部最大对齐数的整数倍即8的倍数
int main()
{
	printf("%d\n", sizeof(struct S4));//总大小为:1 - > 8(直接找倍数) + 16 - > 24 + 8 -> 32
	return 0;
}

附:对于结构体成员是数组是如 char arr[5];这是其实可以直接把他们看成5和char类型的成员,char c1 ;char c2 ;char c3 ;char c4 ;char c5;在用对齐知识进行正常对齐   

1.4修改默认对齐数

知识点:

如标题所示:默认对齐数是可以修改的方法如下:

#pragma pack( )在括号内填所要修改成的值:如#pragma pack( 4 ) 

如果#pragma pack( )单独出现时表示回复默认对齐数

细节:

不能随意的修改默认对齐数应该根据所需,如当修改成了#pragma pack( 1 )这样其实也就不存在内存对齐了

就会导致这时的对齐数一定都是1

所以当对齐方式不合适时,我们就可以自行修改默认对齐数

1.5结构体传参

知识点:

当我们把结构体变量放在函数里时,我们同样可以分成值传递、和址传递。

具体如下:

struct s
{
    int a;
    char b;
}s1;


void print1(struct s s1)
{
    printf("%d\n",s1.a);
    printf("%c\n",s1.b);
}

void print2(struct s * s1)
{

    printf("%d\n",(*s1).a);
    printf("%c\n",(*s1).b);

    printf("%d\n",s1->a);
    printf("%c\n",s1->b);
}



int main()
{
    print(s1);
    print(&s1);

    return 0;
}

当然,print2传地址肯定比print1传值是要好的(函数传参要压栈,如果结构体过大对于时间和空间上都会有损失),所以最好直接统一直接传结构体的地址

练习:通讯录(学生信息管理系统)​​​​​

2.位段

2.1位段的基本知识

知识点:

位段是一种附于结构体之上的一种改变结构体成员所占内存的功能(类似结构体的一种新的结构体),位(比特位);

位段的用法是在结构体成员后加上冒号和数字位段的成员一般只是int / unsigned int / signed int 、char(整形家族)

位段的意义对于数值来说有时候一些数值并不一定需要一个整形的大小(32bit)才能放的下,他可能只需几个bit即可放的下,所以通过位段的形式来对所开辟的空间进行限制来节约空间

细节:

  1. 一般来说位段里的成员类型都是相同的或者是其有无符号位的类型
  2. 通过其结构体成员的类型来依次开辟空间4byte(int)、1byte(char),只有当不够的时候才会再次开辟
  3. 位段的使用,对于后面的数字来说不能超过其自身类型大小int (32bit)char(8bit)
  4. 因为位段涉及这许多的不确定因素,所以位段是不跨平台的,如果是可移植程序中要慎用(避免)

通过代码进行具体讲解:

 #define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct A
{
	int a : 2;
	int b : 5;
	int c : 10;
	int d : 30;
};

int main()
{
	
	printf("%d", sizeof(struct A));//最终打印出8,而不是16
    
	return 0;
}

对于上面的代码为什么最终大小是8:

首先其全部是int类型,所以先开辟32bit,a的所需大小是2bit,所以还剩30,b:5,所以还剩25、c:10 ,还剩15,当到d时,所剩的空间已不够,所以就需要才开辟32bit,所以最终开辟64bit(8byte)

对于第一次开辟的空间最后还剩下的15bit 是否使用 这C语言中并没有严格的规定 所以就导致位段有不确定因素

对于位段的跨平台问题

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

练习:

  1. 当开辟了一个32bit的空间第一个 成员变量的值 从左边开始放还是从右边开始放也就是对于位段在内存中是如何存成员的数据的?
  2. 以及当空间不够时,到底是利用剩余的空间再加上新开辟的空间还是直接只用新开辟的空间?                                                                                                                                        下面通过调试的方法来看

通过调试的方法我们可以得到在vs2019环境下:

(小端存储):实际应该是 04 03 62 此时位段是将前名的成员从右往左开始放的,并对于前面剩下的空间也不会利用(最后的03 04 就能看出:04(d)并没有用到前面剩下的空间0)

数据的存储问题

  1. 对于开辟好的空间存放成员的数据时他会从右往左一次放进对应的bit
  2. 如果之前开辟的空间不够后他不会再利用那些不够的空间,而是直接将数据放在新空间内

 

 对于b.d 我就不写了方法是一样的,先将要存的数字转化成二进制,在通过所分配的bit 将这个二进制放到内存中,如果空间不够就开辟新空间(新空间开辟的地址大于老空间)

   最终大小就是3byte


3.枚举(enum)

对也就是一一列举,对一些值进行列举:如一周的星期,一年的月份

将这些周进行列举,创建一个枚举常量来确定这个实际的事

3.1枚举的定义

知识点:

语法如下

enum name

{

        e1,

        e2,e3

};

对于枚举名(name)一般起的有意义点,枚举常量(e1,e2,e3)间用逗号隔开最后一个不需要加,而枚举常量是枚举变量的可能取值(enum name s = e1

//如星期
enum Day
{
    Mon,
    Tues,
    Wed,
    Thur,
    Fri,
    Sat,
    Sun
};

细节:

每个枚举常量都有对应可代替的数值,当你不初始化时他默认从0开始递增

这样你就可以通过Mod来代替0;

当然你还有自定义开始的值,从后开始跟着递增,如:

 所以你在整月份时就可以将 Jan = 1 然后以此递增

不能在枚举外的其余地方进行枚举常量的修改

对于枚举定义常量相较于#define定义常量的区别:

  1. 增加了可读性
    1. 有了类型检查                                                                                                                
  2. 将常量进行了封装让其不能被轻易更改
  3. 可以调试
  4. 方便使用,一次定义多个常量

对于枚举的大小,因为其内容可以代表整形所以其大小也和整型一样(4byte)


4.联合体(共用体union)

知识点:

联合体同样也是一种自定义类型,这种类型定义的变量也包含一系列的成员,而这些成员不同于结构体他们是共用同一块空间的(他就想一个自习室,大家都可以用,不过大家的用法不同,你可能要用到电脑、而别人只看书空间共享,当使用方法可能不同,并且假如上一个人在使用完后没有拿自己的电脑,就会导致下一个人来对时候电脑还在这个空间内)。

联合体的大小

  1. 联合体这块空间的大小是至少等于一系列成员中最大的成员的类型大小
  2. 并且这块空间的大小也要对齐其中最大对齐数的整数倍

细节:

 #define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
union A
{
	char arr[6];
	int a;
};
int main()
{
	printf("%d", sizeof(union A));//8
	return 0;
}

附:对于联合体所共用的空间,当前一个成员用过后,如果另一个成员使用时并不覆盖的话仍然会存留之前的数据,并不会自动销毁

练习:

写一个函数来实现判断计算机是大端还是小端

union A
{
	char arr;
	int i;
};

int Judge_system(union A* a)
{
	a->i = 1;
	return a->arr;
}

int main()
{
	union A a = {0};
	int ret = Judge_system(&a);
	if (ret == 0)
	{
		printf("大端\n");
	}
	else
	{

		printf("%d小端\n",ret);
	}
	return 0;
}

本章完。预知后事如何,暂听下回分说。

持续更新大量C语言细致内容,三连关注哈

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

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

相关文章

使用Cmake从源码编译Lua

前置要求&#xff1a;电脑已经设置好了Cmake能够使用 首先下载Lua源码&#xff0c;文件后缀是tar.gz 各版本可以从这里找到&#xff1a;Lua - Version history 解压下载文件至所需目录&#xff0c;文件内容如下图&#xff1a; 解压即可。 在解压的文件夹&#xff08;本例是lua…

使用PyTorch-LSTM进行单变量时间序列预测的示例教程

时间序列是指在一段时间内发生的任何可量化的度量或事件。尽管这听起来微不足道&#xff0c;但几乎任何东西都可以被认为是时间序列。一个月里你每小时的平均心率&#xff0c;一年里一只股票的日收盘价&#xff0c;一年里某个城市每周发生的交通事故数。在任何一段时间段内记录…

Python控制本地浏览器并获取网页数据

1、前言 在自动化办公中&#xff0c;我们经常需要利用爬虫技能去批量获取网页的数据&#xff0c;但是有时候我们在利用爬虫的时候&#xff0c;会遇到一个问题&#xff0c;就是登录的时候要携带参数&#xff0c;不如账号、密码、其他的加密信息 就好比我现在公司&#xff0c;好…

JSP 质量管理系统myeclipse定制开发sqlserver数据库网页模式java编程jdbc

一、源码特点 JSP 质量管理系统是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开 发&#xff0c;数据库为SQLServer2008&#xff0c…

狂飙Linux平台,软件部署大全

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

图形的面积与周长计算程序-课后程序(JAVA基础案例教程-黑马程序员编著-第四章-课后作业)

【案例4-7】图形的面积与周长计算程序 欢迎点赞关注收藏 【案例介绍】 案例描述 长方形和圆形都属于几何图形&#xff0c;都有周长和面积&#xff0c;并且它们都有自己的周长和面积计算公式。使用抽象类的知识设计一个程序&#xff0c;可以计算不同图形的面积和周长。 运行…

Redis服务器配置

服务器基础配置服务器端设定 设置服务器以守护进程的方式运行daemonize yes|no 绑定主机地址bind 127.0.0.1 设置服务器端口号port 6379 设置数据库数量databases 16日志配置 设置服务器以指定日志记录级别loglevel debug|verbose|notice|warning开发期 debug 线上no…

【蓝桥杯PythonB组备赛】【Acwing周赛】第91场非常详细的过程思路分析理解分享Python解

好难哈哈哈我依旧只做对了第一题&#xff0c;第二题在比赛结束后才做出来…… 不过没关系每天努力一点啦~ 分享一下个人做的解析&#xff0c;供大家参考&#xff0c;一起努力哇&#xff01; 目录 A AcWing 4861. 构造数列 1.题目描述 2.思路分析 3.代码实现 B Ac…

从每刻到金蝶云星空通过接口配置打通数据

对接源平台:每刻刻报销是每刻科技旗下的产品&#xff0c;是国内领先的企业差旅及费用管理云平台&#xff0c;为事前差旅预订&#xff0c;事后报销的全流程费用管控服务。每刻报销融合人工智能云计算、移动互联网大数据等先进技术&#xff0c;融合财务共享和信用管理的理念&…

SPDK应用框架

SPDK应用框架SPDK应用框架1&#xff09;对CPU core和线程的管理2&#xff09;线程间的高效通信3&#xff09;I/O的处理模型及数据路径的无锁化机制SPDK用户态块设备层1.内核通用块层2.SPDK用户态通用块层SPDK架构解析3.通用块层的管理4.逻辑卷1&#xff09;内核LVM2&#xff09…

企业级信息系统开发学习笔记1.2 初探Spring——利用组件注解符精简Spring配置文件

文章目录零、本讲学习目标一、课程引入二、打开项目【SpringDemo2021】三、利用组件注解符精简Spring配置文件1、创建net.hw.spring.lesson02包2、将lesson01子包的四个类拷贝到lesson02子包3、修改杀龙任务类 - SlayDragonQuest4、修改救美任务类 - RescueDamselQuest5、修改勇…

2022爱分析·事务型关系数据库市场厂商评估报告:万里数据库

目录 1. 研究范围定义 2. 事务型关系数据库市场定义 3. 厂商评估&#xff1a;万里数据库 4. 入选证书 1. 研究范围定义 在国内数字化转型以及信创建设持续推进的大背景下&#xff0c;众多厂商入局国内数据库市场&#xff0c;为企业提供了面向多种应用场景的数据库&am…

taobao.trade.memo.update( 修改交易备注 )

&#xffe5;开放平台基础API必须用户授权 需要商家或以上权限才可调用此接口&#xff0c;可重复调用本接口更新交易备注&#xff0c;本接口同时具有添加备注的功能 公共参数 点击获取 请求示例 TaobaoClient client new DefaultTaobaoClient(url, appkey, secret); Trade…

2022年AI顶级论文 —生成模型之年(上)

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 过去十年来&#xff0c;人工智能技术在持续提高和飞速发展&#xff0c;并不断冲击着人类的认知。 2012年&#xff0c;在ImageNet图像识别挑战赛中&#xff0c;一种神经网络模型&#xff08;AlexNet&…

Java程序员进阶宝典,让你学习面试无忧!

心净则明,心诚则灵如果你想要一个月速成程序员&#xff0c;那么这篇文章不适合&#xff0c;如果你仅想要在IT圈“耍酷”&#xff0c;那你也不需要研读&#xff0c;如果你执着询问“退化”成为一名程序猿有啥捷径&#xff0c;那我只能告诉你&#xff0c;此路不通&#xff01;不可…

Flink-处理函数(ProcessFunction、KeyedProcessFunction、ProcessWindowFunctionHe侧输出流)

文章目录处理函数基本处理函数&#xff08;ProcessFunction&#xff09;功能和使用ProcessFunction 解析分类按键分区处理函数&#xff08;KeyedProcessFunction&#xff09;定时器&#xff08;Timer&#xff09;和定时服务&#xff08;TimerService&#xff09;KeyedProcessFu…

Vue的模板语法(双大括号表达式、插值、v-bind 指令、v-on、指令缩写)

模板语法前言知识点1、双大括号表达式2、插值2.1 文本2.2 原始 HTML2.3 特性2.4 javascript 表达式3、指令3.1 参数3.2 动态参数3.3 修饰符4、指令缩写4.1 v-bind4.2 v-on前言 相信模板语法大家多少都有所接触&#xff0c;例如百度模板引擎、ejs 等等。同样 Vue.js 也使用了基于…

基于springboot+vue物流项目

基于springbootvue物流项目 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#x…

内网渗透(四十二)之横向移动篇-WMIC远程执行命令横向移动

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

业内人士告诉你,买流量卡时一定要问的几个问题?

互联网时代&#xff0c;流量当然是至关重要&#xff0c;但是&#xff0c;在网上搜索流量卡时&#xff0c;广告可谓是铺天盖地&#xff0c;五花八门&#xff0c;所以&#xff0c;小编提醒大家&#xff0c;为了选择性价比较高的卡&#xff0c;在购买流量卡时一定要关注几个问题。…