C语言——结构体,位段,枚举和联合
目录
前言
结构体
1含义
2语法
3匿名结构体
4结构体自引用
5结构体的定义与初始化
6内存对齐
7修改对齐数
8结构体传参
位段
1含义
2位段的内存分配
编辑3位段的问题
4位段的应用
枚举
1含义
2定义
3枚举优点
4枚举使用
联合
1含义
2定义
3特点
4计算
通讯录
前言
C语言的结构体知识学好了的话对后面学习C++类对象就简单很多了
结构体
1含义
结构体是一些值的集合,这些值称为成员变量;每个成员变量可以是不同类型的变量。
2语法
struct tag//类型名
{member-list;//成员变量
}variable-list;//可在此时定义出结构体类型的变量 它是全局变量
假如我们用结构体来描述一个学生:
struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
}S1;//分号不能丢
3匿名结构体
也就是结构体不完全声明
//匿名结构体类型
struct
{int a;char b;float c;
}x;
匿名结构体省略了tag(结构体类型名),而且它只能用一次(声明后立即定义,不能声明后定义)
能否用指针来接收匿名结构体变量?
不能,编译器会认为这个两个类型(vs2019编都编不过,vs2022能编过!)
4结构体自引用
struct Node
{int data;struct Node next;
};int main()
{printf("%d", sizeof(struct Node));return 0;
}
上面这种引用行吗?
编译器认为:你在内部定义了同一个结构体成员,那这个成员变量里又包含了同一个结构体成员...这个大小是
无穷大的
所以正确的结构体自引用
struct Node
{int data;struct Node* next;
};
这种在链表中用的最多
其它的自引用定义:
typedef struct Node
{int data;N* next;
}N;
这种写法是错误的:结构体typedef之前内部并不知道
//正确写法
typedef struct Node
{int data;struct Node* next;
}N;
5结构体的定义与初始化
struct Poin
{int x;int y;
}p1 = {1,2};//可以在这里初始化struct stu
{int date;struct Poin p;
}s1;//全局变量int main()
{struct stu s2 = { 100,{20,30} };//局部变量 按顺序初始化//struct stu s2 = { .p={20,30},.date=100 };//指定成员初始化printf("%d %d %d\n", s2.date, s2.p.x, s2.p.y);return 0;
}
6内存对齐
计算结构体的大小:这个非常重要的一个内容!!!
来看下面的一段代码:
struct s1
{char a;int b;char c;
};struct s2
{char a;char c;int b;
};int main()
{printf("s1的大小:%d\n", sizeof(struct s1));printf("s2的大小:%d", sizeof(struct s2));return 0;
}
int是4字节,char是1字节,两个int和一个char加起来不是6字节吗?
不同的结构体放着相同的变量,只是顺序不同,为什么大小不一样?
介绍一个宏:offsetof,用来查看结构体变量相对于内存的偏移位置
按照打印出来的内存偏移位置进行安排成员变量的放置
一共9个字节就能结束了,偏偏还要在浪费3个字节,前面也浪费3个字节,为什么? 这时我们来看看内存对齐的规则:
1. 第一个成员在与结构体变量偏移量为0的地址处。
2. 其他成员变量要对齐到对齐数整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值
在VS中默认的值为8 而gcc是没有默认对齐数的
3. 结构体总大小为最大对齐数(每个成员变量计算出来的对齐数的最大值)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处
结构体嵌套的结构体大小:
#include<stdio.h>struct S3//总大小:16
{double d;//8 8 -> 8char c; //1 8 -> 1int i; //4 8 -> 4
};
struct S4
{char c1; //1 8 -> 1struct S3 s3;//16 8 -> 8double d; //8 8 -> 8
};
int main()
{printf("%d\n", sizeof(struct S4));return 0;
}
那为什么存在内存对齐?
1. 平台原因(移植原因):
可能硬件平台只能在某些地址处取某些特定类型的数据(否则硬件中断);
2. 性能原因:
为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问这本质上就是以空间换时间来提高效率!
那在设计结构体时:既要省空间,又要提高效率:
尽量让字节小的成员变量放在一起
#include<stdio.h>struct s1
{char c1;int i;char c2;
};struct s2
{char c1;char c2;int i;
};int main()
{printf("%d %d", sizeof(struct s1), sizeof(struct s2));return 0;
}
7修改对齐数
如果对应VS的默认对齐数不满意(最好不修改!),可以自己设定对齐数
#pragma pack(1)
//在#pragma的范围内的对齐数是1
struct s3
{char c1;int i;char c2;
};
#pragma()struct s4
{char c1;int i;char c2;
};int main()
{printf("s3=%d s4=%d", sizeof(struct s2), sizeof(struct s3));return 0;
}
8结构体传参
struct S
{int data[1000];int num;
};
struct S s = { {1,2,3,4}, 1000 };void print1(struct S s)
{printf("%d\n", s.num);
}void print2(struct S* ps)
{printf("%d\n", ps->num);
}int main()
{print1(s); //传结构体print2(&s); //传地址 //那种方式更优点?return 0;
}
关于结构体传参,尽量使用传址传参:
因为一个结构体大小可能很大,如果传值传参会加大系统资源的开销,导致性能的下降;而使用传址传参时数据不希望进行修改,要把const加上!
位段
1含义
位段是一种特殊的自定义类型;
对空间的利用精打细算
a 位段的成员必须是 int、char(整形家族);
b 位段的成员名后边有一个冒号和一个数字
struct A
{int _a : 2;int _b : 5;int _c : 10;int _d : 30;
};
与结构体相比大小方面有什么不同吗?
struct A//如果是结构体
{int _a : 2;int _b : 5;int _c : 10;int _d : 30;
};struct B
{int _a;int _b;int _c;int _d;
};int main()
{printf("A=%d B=%d", sizeof(struct A),sizeof(struct B));return 0;
}
答案:位段比结构体大小要小,更节省空间了!那这是怎么实现的呢?
2位段的内存分配
位段后面的数字代表要分配多少个bit空间给该成员;
位段的空间是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的
#include<stdio.h>struct S
{char a : 3;char b : 4;char c : 5;char d : 4;
};int main()
{struct S s = { 0 };s.a = 10;s.b = 12;s.c = 3;s.d = 4;return 0;
}
3位段的问题
1. int 位段被当成有符号数还是无符号数?
2. 位段中最大位的数目?(16位机器最大16,32位机器最大32,如果写成27,在16位机器会出问题)
3. 位段中的成员在内存中从左向右分配,还是从右向左分配?(在VS时从右向左)
4. 开辟的空间无法容纳下个位段时,是舍弃后另外开辟空间还是利用?(在VS时舍弃剩余的位)
4位段的应用
应用于各种协议(信息传到下一层时需要用到)
枚举
1含义
枚举就是一一列举;在现实生活中把一个星期进行枚举:星期一,星期二,星期三... 那么枚举怎么用代码来表示呢?
2定义
enum Day//星期
{Mon = 1,Tues,Wed,Thur,Fri,Sat,Sun
};
enum Day是一个枚举类型;
枚举括号内的内容都是常量;
枚举默认从0开始(与数组一样);但你也可以自己修改(Mon = 1)
3枚举优点
以上对于星期的枚举:我们也可以用#define Mon 1,#define Tues 2来表示,那是不是就说枚举就可以被替换了?
a 使用枚举方便调试(而#define在调试前就被替换成常量);
b 枚举有类型检查,更严谨写;
b 使用枚举能增加代码的可读性与可维护性;
c 枚举内定义变量不存在命名冲突(而#define可能有命名污染问题)
4枚举使用
enum Color//颜色
{RED=1,GREEN=2,BLUE=4
};
int main()
{enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异return 0;
}
联合
1含义
联合也是一种特殊的自定义类型;
这种类型定义的变量也包含一系列的成员,这些成员公用同一块空间(所以联合也叫共用体)。
2定义
#include<stdio.h>
//联合类型的声明
union Un
{char c;int i;
};
int main()
{union Un un;printf("%d\n", sizeof(un));return 0;
}
3特点
a 由于联合类型共有内存空间,所以比其它的结构体而言节省空间;
b 成员共有内存空间,所以定义变量时成员不能同时出现(后一个会改变前一个的数据)
使用场景1:判断大小端(之前通过地址方式访问判断)
#include<stdio.h>
int sys_call()
{//匿名联合union{char c;int i;}Un;Un.i = 1;// 01 00 00 00 还是 00 00 00 01//(c与i公用1字节的内存空间)return Un.c;
}int main()
{if (sys_call()){printf("小端\n");}else{printf("大端\n");}return 0;
}
使用场景2:设计一个礼物清单
struct git_list
{double price;char name[20];char author[20];int page;char form[20];double size;char flavour[20];char materials[20];
};//利用联合体设计清晰且省空间
struct git_list
{double price;char name[20];union{char author[20];int page;}book;union{char form[20];double size;}mug;union{char flavour[20];char materials[20];}cooike;
};
4计算
a 联合的大小至少是最大成员的大小;
b 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍;所以:联合大小 != 最大成员大小
#include<stdio.h>union Un1
{char c[5];int i;
};int main()
{printf("%d\n", sizeof(union Un1));return 0;
}
你可能会因为大小是5(char c[5]一共是5字节,比i 4字节大),但实际上:
最大是5没错,但它不是最大对齐数(max(char,int) = 4)的整数倍,进行要进行对齐
通讯录
实现一个通讯录,具备以下功能:
1增加联系人(名字,年龄,性别,电话,地址);
2删除联系人的信息;
3查找联系人的信息;
4更改联系人的信息;
5打印通讯录;
6对通讯录进行排序;
//Contact.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>#define Max_Size 100
#define Max_NameSize 20
#define Max_SexSize 5
#define Max_CallSize 20
#define Max_AddrSize 30enum
{ext,add,del,check,modify,print,sort,
};typedef struct Mess
{char name[Max_NameSize];int age;char sex[Max_SexSize];char call[Max_CallSize];char addr[Max_AddrSize];
}Mess;typedef struct Contact
{int sz;Mess message[Max_Size];
}Contact;void Add(Contact* con);
void Del(Contact* con);
void Check(const Contact* con);
void Modify(Contact* con);
void Print(const Contact* con);
void Sort(Contact* con);//Contact.c
#include"contact.h"void Add(Contact* con)
{assert(con);if (con->sz == Max_Size){printf("Contact Is Full\n");return;}printf("Input Name:");gets(con->message[con->sz].name);//scanf("%s", &con->message[con->sz].name);printf("Input Age:");scanf("%d", &con->message[con->sz].age);//如果输入的是非法字符串?getchar();//清空缓冲区的'\n'printf("Input Sex:");gets(con->message[con->sz].sex);//scanf("%s", &con->message[con->sz].sex);printf("Input Call:");gets(con->message[con->sz].call);//scanf("%s", &con->message[con->sz].call);printf("Input Addr:");gets(con->message[con->sz].addr);//scanf("%s", &con->message[con->sz].addr);con->sz++;printf("Add Finish\n");
}void Print(const Contact* con)
{assert(con);if (con->sz == 0){printf("Contact Is Empty\n");return;}printf("%-20s %-5s %-5s %-11s %-30s\n", "name", "age", "sex", "call", "addr");for (int i = 0; i < con->sz; i++){printf("%-20s %-5d %-5s %-11s %-30s\n",con->message[i].name, con->message[i].age, con->message[i].sex,con->message[i].call,con->message[i].addr);}
}static int Find(const Contact* con,char Name[])
{for (int i = 0; i < con->sz; i++){if (strcmp(con->message[i].name,Name)==0)//用strcmp比{printf("Find Sucess\n");return i;}}printf("Find Error\n");return -1;
}void Del(Contact* con)
{assert(con);char InputName[Max_NameSize];printf("Input Del Name:");gets(InputName);int DelPos = Find(con, InputName);if (DelPos == -1) return;for (int i = DelPos; i < con->sz - 1; i++){con->message[i] = con->message[i + 1];//后一个往前一个覆盖}con->sz--;printf("Del Sucess\n");}void Check(const Contact* con)
{assert(con);printf("Input Check Name:");char Check_Name[Max_NameSize];gets(Check_Name);int pos = Find(con, Check_Name);if (pos == -1) return;printf("Check Result:\n");printf("%-20s %-5s %-5s %-11s %-30s\n", "name", "age", "sex", "call", "addr");printf("%-20s %-5d %-5s %-11s %-30s\n",con->message[pos].name, con->message[pos].age,con->message[pos].sex, con->message[pos].call,con->message[pos].addr);
}void Modify(Contact* con)
{assert(con);char Modify_Name[Max_NameSize];printf("Input Modify Name:");gets(Modify_Name);int pos = Find(con, Modify_Name);if (pos == -1) return;printf("Modify Name:");gets(con->message[pos].name);printf("Input Modify Age:");scanf("%d", &con->message[pos].age);getchar();printf("Input Modify Sex:");gets(con->message[pos].sex);printf("Input Modify call:");gets(con->message[pos].call);printf("Input Modify addr:");gets(con->message[pos].addr);printf("Modify Sucess\n");
}int cmp(const void* a, const void* b)
{return ((*((Contact*)a)).message->age - (*((Contact*)b)).message->age);
}void Sort(Contact* con)
{qsort(con, con->sz, sizeof(con->message[0]), cmp);printf("排序完成\n");
}//test.c
#include"contact.h"void memu()
{printf("********************************\n");printf("***** 0.exit 1.add *****\n");printf("***** 2.del 3.check *****\n");printf("***** 4.modify 5.print *****\n");printf("***** 6sort *****\n");
}int main()
{Contact con;//对con空间进行清理memset(&con, 0, sizeof(con));int input;do{memu();printf("Please Select:");//防止读到字符串时发生死循环input = 123456;//防止下一次输入的是字符后input还是上一次的值scanf("%d", &input);getchar();//输入字符串时:清空缓冲区的'\n'switch (input){case ext:printf("Process Exit");break;case add:Add(&con);break;case del:Del(&con);break;case check:Check(&con);break;case modify: Modify(&con);break;case print:Print(&con);break;case sort:Sort(&con);break;default:printf("Select Error,Please Try Again\n");break;}}while(input);return 0;
}
但上面的通讯录无法做到:
通讯录满了无法再存信息(学习动态内存管理后解决);
关闭程序时通讯录信息还存在(学习完文件操作后解决);
以上便是全部内容,有问题欢迎在评论区指正,感谢观看!
相关文章:

C语言——结构体,位段,枚举和联合
目录 前言 结构体 1含义 2语法 3匿名结构体 4结构体自引用 5结构体的定义与初始化 6内存对齐 7修改对齐数 8结构体传参 位段 1含义 2位段的内存分配 编辑3位段的问题 4位段的应用 枚举 1含义 2定义 3枚举优点 4枚举使用 联合 1含义 2定义 3特点 4计…...

期末概率论总结提纲(仅适用于本校,看文中说明)
文章目录 说明A选择题1.硬币2.两个事件的关系 与或非3.概率和为14.概率密度 均匀分布5.联合分布率求未知参数6.联合分布率求未知参数7.什么是统计量(记忆即可)8.矩估计量9.117页12题10.显著水平阿尔法(背公式就完了) 判断题11.事件…...
Python视频处理:噪声矩阵与并行计算的完美融合
噪声级别对视频质量有显著的影响,主要体现在以下几个方面: 1. 视觉质量 低噪声级别:当噪声级别较低时,视频的视觉质量较好。噪声对图像细节的干扰较小,画面看起来较为清晰和自然。观众可以更容易地识别图像中的细节和…...
如何使用SparkSql
一、SparkSql的前世今生 Hive->Shark->Spark SQL 二、SparkSql依赖 <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-sql_2.11</artifactId> <version>2.1.2</version> </dependency> 三、…...

YOLOv8实战人员跌倒检测
本文采用YOLOv8作为核心算法框架,结合PyQt5构建用户界面,使用Python3进行开发。YOLOv8以其高效的实时检测能力,在多个目标检测任务中展现出卓越性能。本研究针对人员跌倒目标数据集进行训练和优化,该数据集包含丰富人员跌倒图像样…...
QT-TCP-server
为了实现高性能的TCP通讯,以下是一个基于Qt的示例,展示如何利用多个线程、非阻塞I/O、数据分块和自定义协议进行优化。该示例以TCP服务器和客户端的形式展示,能够承受高负载并实现快速数据传输。 高性能TCP Server示例 #include <QTcpSe…...
【STM32+QT项目】基于STM32与QT的智慧粮仓环境监测与管理系统设计(完整工程资料源码)
视频演示: 基于STM32与QT的智慧粮仓环境监测与管理系统设计 目录: 目录 视频演示: 目录: 前言:...
robot 仿真环境安装测试 [持续更新]
将持续更新各种robot simulation环境的安装过程. RLBench 安装CoppeliaSim、PyRep、RLBench git: https://github.com/stepjam/RLBench/tree/master (1)CoppeliaSim sudo gedit ~/.bashrc设置环境变量 export COPPELIASIM_ROOT=${HOME}/CoppeliaSim export LD_LIBRARY_…...

【FlutterDart】 拖动边界线改变列宽类似 vscode 那种拖动改变编辑框窗口大小(11 /100)
【Flutter&Dart】 拖动改变 widget 的窗口尺寸大小GestureDetector~简单实现(10 /100) 【Flutter&Dart】 拖动边界线改变列宽并且有边界高亮和鼠标效果(12 /100) 上效果: 这个在知乎里找到的效果&…...
R语言的循环实现
以R语言的循环实现 引言 R语言作为一种强大的统计分析和数据可视化工具,广泛应用于数据科学、统计学和机器学习等领域。在R语言中,循环是一个基本的控制结构,用于重复执行一段代码。循环不仅可以提高代码的可读性,还可以方便地处…...

Web应用安全-漏洞扫描器设计与实现
摘 要 随着Web2.0、社交网络、微博等一系列新型的互联网产品的诞生,基于Web环境的互联网应用越来越广泛,企业信息化的过程中各种应用都架设在Web平台上。Web应用的迅速发展也引起黑客们的强烈关注,接踵而至的就是Web安全威胁的凸显ÿ…...

视频生成Sora的全面解析:从AI绘画、ViT到ViViT、TECO、DiT、VDT、NaViT等
前言 真没想到,距离视频生成上一轮的集中爆发(详见《Sora之前的视频生成发展史:从Gen2、Emu Video到PixelDance、SVD、Pika 1.0》)才过去三个月,没想OpenAI一出手,该领域又直接变天了 自打2.16日OpenAI发布sora以来(其开发团队包…...
【已解决】如何让容器内的应用程序使用代理?
首先,按照这种配置方法,即通过在 /etc/systemd/system/docker.service.d/http-proxy.conf 中设置代理,它只会影响 Docker 守护进程本身,并不会自动影响 Docker 容器内部的软件或容器中的网络行为。 这意味着: Docker …...

DC/AC并网逆变器模型与仿真MATLAB
DC/AC并网逆变器是一种将直流电(DC)转化为交流电(AC),并将其与电网并联的设备。它的核心功能是实现直流电源(如光伏电池板或储能电池)与电网的有效连接,同时保证输出电能质量满足电网…...
P10424 [蓝桥杯 2024 省 B] 好数
题目描述 一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位……)上的数字是奇数,偶数位(十位、千位、十万位……)上的数字是偶数,我们就称之为“好数”。 给定一个正整数 N…...

【Word_笔记】Word的修订模式内容改为颜色标记
需求如下:请把修改后的部分直接在原文标出来,不要采用修订模式 步骤1:打开需要转换的word后,同时按住alt和F11 进入(Microsoft Visual Basic for Appliations) 步骤2:插入 ---- 模块 步骤3:输入以下代码,点击运行 Sub HighlightInsertedText() Dim r As Revision…...

oracle位运算、左移右移、标签算法等
文章目录 位运算基础与或非同或同或应用场景 异或异或应用场景 什么是真值表 oracle基础函数创建bitor(按位或)函数bitnot(按位非)函数bitxor(按位异或)函数左移函数BITSHIFT()函数(实测不可用,废弃掉该方案)右移函数(略,有此场景吗?) 实际应用资质字典…...

spring boot学习第二十三篇:Spring Boot集成RocketMQ
前置条件先安装好RocketMQ 希望在Window10安装rocketMQ并简单使用,可以参考如下文章: Window10安装rocketMQ并简单使用-CSDN博客 1、pom.xml文件里面加上依赖 <dependency><groupId>org.apache.rocketmq</groupId><artifactId&…...

去掉el-table中自带的边框线
1.问题:el-table中自带的边框线 2.解决后的效果: 3.分析:明明在el-table中没有添加border,但是会出现边框线. 可能的原因: 由 Element UI 的默认样式或者表格的某些内置样式引起的。比如,<el-table> 会通过 border-collapse 或 border-spacing 等属性影响边框的显示。 4…...

C语言gdb调试
目录 1.gdb介绍 2.设置断点 2.1.测试代码 2.2.设置函数断点 2.3.设置文件行号断点 2.4.设置条件断点 2.5.多线程调试 3.删除断点 3.1.删除指定断点 3.2.删除全部断点 4.查看变量信息 4.1.p命令 4.2.display命令 4.3.watch命令 5.coredump日志 6.总结 1.gdb介绍…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...
2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案
一、延迟敏感行业面临的DDoS攻击新挑战 2025年,金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征: AI驱动的自适应攻击:攻击流量模拟真实用户行为,差异率低至0.5%,传统规则引…...