当前位置: 首页 > news >正文

【C语言】关于C11的一些新特性

相比于VC++ 6.0使用的ANSI C标准,VS2022使用的C11标准与上一代有很多不同,相比之前的 C 标准(如 C89/C90 和 C99),引入了一些新的功能、特性和改进。以下是 C11 标准相对于之前版本的一些主要变化和新增内容:

1.多线程支持

在 C11 标准中引入了 <threads.h> 头文件,其中定义了一组函数和类型,用于支持线程相关的操作。这个头文件提供了一些函数和类型,可以用于创建、管理和同步线程。

以下是 <threads.h> 中常见的一些函数和类型:

  1. 类型定义

    • thrd_t:代表线程的类型。
    • mtx_t:代表互斥锁的类型。
    • cnd_t:代表条件变量的类型。
  2. 线程函数

    • thrd_create:创建一个新的线程。
    • thrd_exit:终止当前线程。
    • thrd_join:等待指定线程终止。
    • thrd_detach:设置线程为分离状态,使其在终止后自动释放资源。
  3. 互斥锁函数

    • mtx_init:初始化互斥锁。
    • mtx_lock:锁定互斥锁。
    • mtx_unlock:解锁互斥锁。
    • mtx_destroy:销毁互斥锁。
  4. 条件变量函数

    • cnd_init:初始化条件变量。
    • cnd_signal:发送信号给等待条件变量的线程。
    • cnd_broadcast:广播信号给所有等待条件变量的线程。
    • cnd_wait:等待条件变量变为真。

以下是一个示例用法:

#include <stdio.h>
#include <threads.h>mtx_t mutex; // 互斥锁int shared_data = 0; // 共享的数据int increment_data(void* arg) {mtx_lock(&mutex); // 锁定互斥锁shared_data++; // 修改共享数据mtx_unlock(&mutex); // 解锁互斥锁return 0;
}int main() {thrd_t thread;mtx_init(&mutex, mtx_plain); // 初始化互斥锁// 创建线程if (thrd_create(&thread, increment_data, NULL) != thrd_success) {fprintf(stderr, "无法创建线程\n");return 1;}// 等待线程终止if (thrd_join(thread, NULL) != thrd_success) {fprintf(stderr, "无法等待线程\n");return 1;}printf("共享数据的值: %d\n", shared_data);mtx_destroy(&mutex); // 销毁互斥锁return 0;
}

2.泛型选择表达式

_Generic 关键字是 C11 标准引入的一个新特性,用于根据表达式的类型选择不同的代码块。它主要用于实现泛型编程中的条件选择,允许编写更通用的代码,根据表达式的类型动态地选择不同的处理方式。

_Generic 关键字的基本语法形式如下:

_Generic(expression,type1: code_block1,type2: code_block2,//...default: default_code_block
)

其中:

  • expression 是要进行类型选择的表达式。
  • type1, type2, ... 是不同的类型。
  • code_block1, code_block2, ... 是与对应类型匹配的代码块。
  • default 是可选的默认代码块。

下举一个简单的例子:

#include <stdio.h>#define PrintValue(x) _Generic((x), \int: printf("整数: %d\n", x), \float: printf("浮点数: %f\n", x), \double: printf("双精度浮点数: %lf\n", x), \default: printf("其他类型\n") \
)int main() {int a = 10;float b = 3.14f;double c = 2.71828;PrintValue(a); // 整数: 10PrintValue(b); // 浮点数: 3.140000PrintValue(c); // 双精度浮点数: 2.718280char d = 'A';PrintValue(d); // 其他类型return 0;
}

在这个例子中,_Generic 根据传入参数的不同类型,选择不同的 printf 语句进行输出。如果传入的参数类型不在指定的类型范围内,则使用默认的输出方式。这样,可以根据表达式的类型,动态地选择不同的代码执行路径。

使用 _Generic 关键字可以编写更灵活和通用的代码,使得代码在编译期间就能进行类型检查和类型选择,提高了代码的可读性和通用性。

3.匿名结构体和联合体

在 C11 标准中引入了匿名结构体和匿名联合体的概念,允许在不提供名称的情况下定义结构体和联合体,使其更为灵活。

匿名结构体

匿名结构体允许您定义一个没有标签名称的结构体。这种结构体可以直接在声明变量时定义,而无需指定结构体名称。它在某些情况下能够简化代码。

#include <stdio.h>int main() {struct { // 匿名结构体int x;int y;} point; // 定义匿名结构体变量point.x = 10;point.y = 20;printf("x 坐标: %d, y 坐标: %d\n", point.x, point.y);return 0;
}

匿名联合体

匿名联合体与匿名结构体类似,允许定义没有标签名称的联合体。这种联合体也可以直接在声明变量时定义,而无需指定联合体名称。

#include <stdio.h>int main() {union { // 匿名联合体int intValue;float floatValue;} data; // 定义匿名联合体变量data.intValue = 42;printf("整数值: %d\n", data.intValue);data.floatValue = 3.14f;printf("浮点数值: %f\n", data.floatValue);return 0;
}

使用匿名结构体和匿名联合体时要注意,由于它们没有名称,因此无法在其他地方使用相同的定义。因此,这种方式适用于某些情况下仅需在局部范围内使用的结构体或联合体。

4.静态断言

_Static_assert 是 C11 标准引入的一个关键字,用于在编译时执行静态断言(static assertion)。静态断言是指在编译时检查条件是否为真,如果条件为假则会触发编译器错误,防止程序继续编译。

_Static_assert(constant_expression, "error_message");

constant_expression 是在编译时期计算结果为常量的表达式。如果该表达式的值为 0(假),则会触发静态断言,编译器会显示指定的错误信息。

error_message 是一个字符串常量,表示在触发断言时显示的错误信息。

#include <stdio.h>#define ARRAY_SIZE 10_Static_assert(ARRAY_SIZE > 5, "数组大小必须大于 5");int main() {printf("程序正常运行\n");return 0;
}

在上面的例子中,如果 ARRAY_SIZE 小于或等于 5,编译将会失败并显示 "数组大小必须大于 5" 的错误信息。这样的静态断言可用于在编译时期检查常量表达式的值,确保代码的正确性。

静态断言的使用可以在编译阶段发现潜在的错误,提高代码质量,并在一定程度上增强代码的可读性。通常用于检查各种常量表达式是否符合预期,并提前发现错误,避免将错误带入到运行时。

5.可重入的标准库函数

C11 引入了一些可重入的标准库函数,这些函数可以在多线程环境下安全地被多个线程同时调用,而不会导致竞态条件或数据损坏。

可重入函数具有以下特点:

  1. 不会使用静态数据。
  2. 不会修改除了传入参数和返回结果以外的任何数据。
  3. 在多线程环境下可以安全地并发调用。

以下是一些 C11 标准中引入的可重入函数示例:

  1. rand_r:生成伪随机数的函数,传入一个状态变量,返回下一个伪随机数。通过传递不同的状态变量,可以在多线程环境下安全地使用这个函数。

  2. gmtime_rlocaltime_r:这两个函数用于将时间表示为日历时间,分别用于将时间戳转换为 UTC 时间和本地时间。这些函数的可重入版本使用了用户提供的结构体指针作为输出参数,而不是使用静态缓冲区。

  3. asctime_rctime_rstrtok_r:这些函数是 asctimectimestrtok 的可重入版本。它们接收用户提供的缓冲区或状态指针,而不使用静态数据。

  4. getenvputenv:这两个函数是用于环境变量的操作,getenv_rgetenv 的可重入版本,接收用户提供的缓冲区来存储环境变量的值。

这些可重入的标准库函数为多线程编程提供了更安全和可靠的基础,因为它们避免了使用静态数据,而是使用用户提供的参数来存储结果或中间状态。这样可以确保这些函数在多线程环境中能够安全地被调用,而不会产生竞态条件或数据损坏。

6.原子操作

C11 标准引入了原子操作,提供了一组函数和类型,用于支持多线程并发访问共享变量时的原子性操作。原子操作是在不被中断的情况下执行的操作,保证了对共享变量的操作不会被其他线程的操作所干扰。

C11 中原子操作的函数位于 <stdatomic.h> 头文件中,并定义了一些原子类型和原子操作函数。以下是一些常见的原子操作函数和类型:

  1. 原子类型:

    • atomic_bool, atomic_char, atomic_int, atomic_long, atomic_llong, atomic_short, atomic_float, atomic_double, atomic_ptr 等,这些类型用于创建对应类型的原子变量。
  2. 原子加载和存储操作:

    • atomic_load:从原子变量中加载值。
    • atomic_store:将值存储到原子变量。
    • atomic_exchange:交换原子变量的值,并返回原来的值。
  3. 原子递增和递减操作:

    • atomic_fetch_add:将指定值加到原子变量上。
    • atomic_fetch_sub:将指定值从原子变量中减去。
  4. 原子比较和交换操作(CAS):

    • atomic_compare_exchange_strong:如果原子变量的值等于给定的旧值,则用新值替换它。
    • atomic_compare_exchange_weak:类似于 atomic_compare_exchange_strong,但在某些情况下会使用弱型别的 CAS。
#include <stdio.h>
#include <stdatomic.h>
#include <threads.h>atomic_int counter = ATOMIC_VAR_INIT(0); // 初始化原子变量int increment_counter(void* arg) {for (int i = 0; i < 10000; ++i) {atomic_fetch_add(&counter, 1); // 原子递增操作}return 0;
}int main() {thrd_t thread1, thread2;thrd_create(&thread1, increment_counter, NULL);thrd_create(&thread2, increment_counter, NULL);thrd_join(thread1, NULL);thrd_join(thread2, NULL);printf("Counter: %d\n", atomic_load(&counter)); // 输出原子变量的值return 0;
}

 这个示例演示了如何使用 C11 的原子操作来安全地递增一个共享的原子变量 counter。原子操作确保了对共享变量的递增操作不会被其他线程的操作所干扰,避免了竞态条件。原子操作函数提供了一种安全而有效的方式来处理并发编程中的共享资源。

7.内存模型

C11 引入了对 C 语言的内存模型的显式支持,定义了一些规则和保证,以便程序员更好地理解并发程序中的内存访问和同步。C11 内存模型描述了程序中各种内存访问操作的行为和规则。

C11 中的内存模型包含以下重要概念:

1.顺序一致性(Sequential Consistency):

C11 内存模型默认情况下提供了顺序一致性的保证。这意味着程序中的所有线程看到的内存操作都好像是按照一个全局的、全局顺序的序列来执行的。这种模型简化了多线程编程中对内存操作的理解。

2.原子类型和原子操作:

C11 引入了原子类型(例如 atomic_int 等)和原子操作函数(例如 atomic_loadatomic_store 等),用于执行原子性操作,保证在多线程环境中对共享变量的操作是原子的。

3.内存顺序(Memory Orderings):

C11 提供了对内存操作的顺序控制,即通过指定适当的 memory order 来控制原子操作的顺序。比如 memory_order_relaxedmemory_order_acquirememory_order_release 等。

4.原子性操作的同步语义:

使用原子操作函数可以实现一些同步语义,比如 release-acquire、acquire-release 和 sequentially-consistent。

5.内存屏障(Memory Barriers):

内存屏障是一种指令,用于强制内存操作的顺序和同步。C11 中使用 atomic_thread_fence 函数来实现内存屏障,它可以确保在其前后的内存操作的执行顺序。

C11 内存模型提供了一种明确定义多线程程序中对共享内存访问的行为方式,有助于程序员更好地理解和控制多线程程序中的内存访问。这对于编写并发程序,避免竞态条件(Race Conditions)、数据竞争(Data Races)以及其他并发问题是非常重要的。

8.Unicode支持改进

C11 标准增强了对 Unicode 字符集的支持,以更好地处理和操作 Unicode 字符串和字符。这些改进包括一些新的数据类型、宏以及支持 Unicode 的字符串处理函数。

以下是 C11 中 Unicode 支持的一些改进:

1.char16_tchar32_t 类型

引入了 char16_tchar32_t 类型,用于分别表示 UTF-16 和 UTF-32 编码的 Unicode 字符。这些类型提供了直接处理不同宽度的 Unicode 字符的机制。

2.u 前缀和 U 前缀

C11 标准引入了 u 前缀表示 UTF-16 编码的字符串字面量,以及 U 前缀表示 UTF-32 编码的字符串字面量。例如,u"Hello" 表示一个 UTF-16 编码的字符串。

3.char16_tchar32_t 字符串处理函数

C11 引入了一些新的 Unicode 字符串处理函数,如 u16lenu32lenu16tou32u32tou16 等,用于处理 char16_tchar32_t 类型的 Unicode 字符串。

4.<uchar.h> 头文件

C11 引入了 <uchar.h> 头文件,其中包含了用于 Unicode 字符处理的新函数和宏,例如 c16rtombc32rtombmbrtoc16mbrtoc32 等函数。

这些改进使得 C11 更好地支持 Unicode 字符串和字符的处理,提供了更直接、更全面的机制来处理不同宽度的 Unicode 编码。这些改进有助于编写更具有国际化和多语言支持的程序,使得处理 Unicode 字符集更加方便和灵活。

9.新增的库函数

引入了一些新的标准库函数,如 aligned_allocfmax, fmin 等,用于提供更多的数学和内存管理功能。

C11 标准引入了一些新的库函数,以增强 C 语言的功能性和标准库的支持。这些新函数提供了更多的功能,以适应新的需求和编程模式。以下是一些 C11 新增的库函数:

宽字符字符串处理函数

wchar_t 类型的字符串处理函数:wcsncpy_swcsncat_swcsnlen 等函数,用于宽字符字符串的拷贝、连接和长度计算。

安全性增强函数

安全性增强函数:例如 strcpy_sstrncpy_sstrcat_sstrtok_s 等函数,用于字符串操作,可以避免缓冲区溢出问题。

快速数学运算函数

快速数学运算函数:例如 sin, cos, tan, exp, log, sqrt 等数学函数的 _FMA_FMAF_FMAL 版本,用于提高数学运算的性能。

aligned_alloc()

aligned_alloc 是 C11 引入的函数,用于分配内存并保证返回的内存地址满足特定的对齐要求。它的函数原型如下:

void *aligned_alloc(size_t alignment, size_t size);

alignment 参数是所需对齐的字节数,必须是 2 的幂且至少为 sizeof(void *) 的倍数。

size 参数是要分配的内存大小,以字节为单位。

aligned_alloc 函数会返回一个指向对齐内存块的指针。该函数可以用于需要特定内存对齐要求的情况,比如 SSE、AVX 等特定指令集的数据要求特定对齐方式的情况。

fmax(), fmin()

fmax()fmin() 是 C11 新增的数学函数,用于返回两个浮点数的最大值和最小值。fmax 返回两个参数中的最大值,fmin 返回两个参数中的最小值。

double fmax(double x, double y);
float fmaxf(float x, float y);
long double fmaxl(long double x, long double y);

这些新增的函数增强了 C 语言标准库的功能性和安全性,提供了更多的工具和功能,使得编程更为方便、高效和安全。这些函数能够更好地支持并发编程、Unicode 字符串处理、泛型编程和数学运算等方面。

相关文章:

【C语言】关于C11的一些新特性

相比于VC 6.0使用的ANSI C标准&#xff0c;VS2022使用的C11标准与上一代有很多不同&#xff0c;相比之前的 C 标准&#xff08;如 C89/C90 和 C99&#xff09;&#xff0c;引入了一些新的功能、特性和改进。以下是 C11 标准相对于之前版本的一些主要变化和新增内容&#xff1a;…...

牛的速记(c++题解)

题目描述 奶牛们误解了速记的含义。他们是这样理解的&#xff1a; 给出一个少于255个字母的小写字母串。 找到一个出现次数最多的字母&#xff0c;将该字母从字母串中统统删去&#xff0c;如果出现次数最多的字母不止一个&#xff0c;就删去在字母表中靠前的一个&#xff0c;即…...

使用ffmpeg+flv.js + websokect播放rtsp格式视频流

对于rtsp的视频流网上有很多种的解决方案&#xff0c;但是大的趋势还是利用ffmpeg的工具进行rtsp的视频解析进行一个推流&#xff0c;我最终选择bilibili开源的flv.js&#xff0c;代码十分的简单全部都在底层封装好了。实现的方式也比较容易理解&#xff0c;ffmpeg进行rtsp的视…...

OAI openair3代码结构整理

openair3代码框架结构 OAI&#xff08;OpenAirInterface&#xff09;是一个开源的5G网络软件平台&#xff0c;用于研究和开发5G网络技术。OpenAir3是OAI项目中的一个子项目&#xff0c;专注于5G核心网络的功能实现。 一、OpenAir3的代码主要包括以下几个部分&#xff1a; NAS…...

Kubernets(K8S)启动和运行 01-01 Kubernetes简介

Kubernets(K8S)启动和运行 01-01 Kubernetes简介 Kubernetes is an open source orchestrator for deploying containerized applications. It was originally developed by Google, inspired by a decade of experience deploying scalable, reliable systems in containers …...

PHP特性知识点扫盲 - 下篇

概述 在实际的生产环境中遇到了实际需要解决的问题&#xff0c;需要把服务部署的方式梳理出来&#xff0c;在同一个服务器中部署多个PHP环境&#xff0c;架构图如下&#xff1a; 架构方案 在工作实践中遇到的很多问题的普遍性都是相通的&#xff0c;公司运行的可新项目都是版…...

HarmonyOS应用开发之DevEco Studio安装与初次使用

1、DevEco Studio介绍 DevEco Studio是基于IntelliJ IDEA Community开源版本打造&#xff0c;面向华为终端全场景多设备的一站式集成开发环境&#xff08;IDE&#xff09;&#xff0c;为开发者提供工程模板创建、开发、编译、调试、发布等E2E的HarmonyOS应用/服务的开发工具。…...

记录第一次在GitHub上面提交Issue

第一次在GitHub上面提交Issue&#xff0c;记录一下。 对着源码调了好久才发现&#xff0c;问题并不在程序而在模型&#xff08;虽然只是一个很小的问题&#xff0c;但是能够解决问题&#xff0c;并且做出了自己的一点小小贡献&#xff0c;还是很开心。嘻嘻&#xff0c;发博客记…...

【数据库设计和SQL基础语法】--用户权限管理--数据备份和恢复策略

一、引言 数据备份和恢复是数据库管理中至关重要的任务&#xff0c;对于确保数据安全性和业务连续性具有重大的意义。以下是一些关键的重要性方面&#xff1a; 防止数据丢失&#xff1a; 数据备份是防止因硬件故障、人为错误、恶意攻击或其他意外事件导致数据丢失的主要手段。…...

java数据结构与算法刷题-----LeetCode70. 爬楼梯

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 很多人觉得动态规划很难&#xff0c;但它就是固定套路而已。其实动态规划只…...

【Unity入门】UGUI之Slider(滑动条)

目录 一、什么是Slider&#xff1f;二、Slider属性与功能 一、什么是Slider&#xff1f; Slider控件允许用户可以通过鼠标来在预先确定的范围调节数值 我们可以在Hierarchy视图右键 -> UI ->Slider来创建滑动条 通过上图可以发现Unity内置的Slider主要有3部分&#x…...

MySQL中UNION和UNION ALL的区别有哪些?

在MySQL中如何想要对两个结果集进行合并操作&#xff0c;可以使用UNION和UNION ALL&#xff0c;如果只是想要去除掉重复的记录&#xff0c;属于UNION ALL 即可&#xff0c;但是如何想要除掉没有重复行数据&#xff0c;就要使用Union。本文详细向大家介绍MySQL中UNION和UNION AL…...

Android kotlin build.gradle.kts配置

1. 添加 maven 仓库 1. 1. settings配置 1. 1.1. settings.gradle repositories {maven {url https://maven.aliyun.com/repository/public/}mavenCentral() }1. 1.2. settings.gradle.kts repositories {maven {setUrl("https://maven.aliyun.com/repository/public/…...

css、js、vue常考部分面试题

css css盒子水平垂直居中方法 方法一&#xff1a;定位 .child{height: 100px;position: absolute;//父元素相对定位top:50%;left:50%;transform: translate(-50%,-50%); } 方法二&#xff1a;定位 .child{width: 100px;height: 100px;position: absolute;top:50%;left:50%…...

OpenAI ChatGPT-4开发笔记2024-03:Chat之Function Calling/Function/Tool/Tool_Choice

Updates on Function Calling were a major highlight at OpenAI DevDay. In another world,原来的function call都不再正常工作了&#xff0c;必须全部重写。 function和function call全部由tool和tool_choice取代。2023年11月之前关于function call的代码都准备翘翘。 干嘛…...

二叉搜索树与双向链表

解题思路一&#xff1a; /** public class TreeNode {int val 0;TreeNode left null;TreeNode right null;public TreeNode(int val) {this.val val;} } */ // 一定要用自己的理解真正弄出来才行&#xff0c;否则没有用&#xff01; // 再次提醒&#xff0c;计算机这种工科…...

uniapp中组件库的Checkbox 复选框 的丰富使用方法

目录 #平台差异说明 #基本使用 #自定义形状 #禁用checkbox #自定义形状 #自定义颜色 #横向排列形式 #横向两端排列形式 API #Checkbox Props #CheckboxGroup Props #CheckboxGroup Event 复选框组件一般用于需要多个选择的场景&#xff0c;该组件功能完整&#xff…...

Spring Cloud + Vue前后端分离-第10章 基于阿里云OSS的文件上传

源代码在GitHub - 629y/course: Spring Cloud Vue前后端分离-在线课程 Spring Cloud Vue前后端分离-第10章 基于阿里云OSS的文件上传 前面介绍的文件上传是基于本地文件服务器的文件上传&#xff0c;但是自己搭文件服务器会有很多运维的问题&#xff0c;比如磁盘满了要扩容…...

C++ 中的耗时计算函数

#include <time.h>int clock_gettime (clockid_t clock_id, struct timespec *tp) 获取当前 clock_id 的时钟值并存储在 tp 中。 其中 tp 是一个 timespec 结构体&#xff0c;在 time.h 头文件中定义&#xff1a; #include <time.h>:struct timespec {time_t t…...

【Element】el-form和el-table嵌套实现表格编辑并提交表单校验

一、背景 页面需要用到表格采集用户数据&#xff0c;提交时进行表单校验&#xff1b;即表格中嵌套着表单&#xff0c;保存时进行表单校验 二、功能实现 2.1、el-form和el-table嵌套说明 ① :model"formData" 给表单绑定数据&#xff0c;formData是表单的数据对象 …...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...