C-关键字和关键库函数细论

news2024/7/6 20:38:01
sizeof 与 strlen

sizeofstrlen在C语言中各有其独特的用途和限制。sizeof主要用于获取对象或类型所占的内存字节数,而strlen则用于计算字符串的长度(不包括终止的空字符)。

char str[] = "Hello, World!";  
char *ptr = str;  
  
printf("%zu\n", sizeof(str)); // 输出整个数组所占的字节数,包括终止符'\0',可能是13(取决于编译器和平台)  
printf("%zu\n", sizeof(ptr)); // 输出指针变量ptr所占的字节数,通常是4或8(取决于平台)  
printf("%zu\n", strlen(str)); // 输出字符串的长度,不包括终止符'\0',输出12  
printf("%zu\n", strlen(ptr)); // 同样输出12,因为ptr指向str
static关键字

在C++中,static关键字在C++中主要用于限制变量的作用域和生命周期,隐藏函数实现细节,以及实现类的静态成员变量和静态成员函数,这些特性在程序设计中非常有用。

  1. 局部静态变量

    • static用于局部变量时(包括在函数内部定义的变量),这个变量在程序的整个执行期间只被初始化一次,并在函数调用结束后不会销毁,而是保持其值,直到程序结束。这意味着,在后续的函数调用中,这个局部静态变量的值会保持不变,除非在函数内部被显式修改。
  2. 全局静态变量

    • static用于全局变量时,该变量的作用域被限制在定义它的文件内,即它是文件作用域的(file-scoped)。这意呀着,其他文件无法直接访问这个变量,从而避免了命名冲突。全局静态变量具有静态存储期,即在程序开始执行时被分配内存,并在程序结束时释放内存。
  3. 静态函数

    • static用于函数声明时,这个函数就变成了静态函数。静态函数的作用域被限制在定义它的文件内,其他文件无法链接到这个函数。这有助于隐藏函数实现细节,减少命名空间污染。
  4. 静态成员变量

    • 在类定义中,static关键字用于声明类的静态成员变量。静态成员变量属于类本身,而不是类的某个特定对象。这意味着,无论创建了多少个类的对象,静态成员变量都只有一份拷贝,并由所有对象共享。静态成员变量必须在类定义外部进行初始化。
  5. 静态成员函数

    • static关键字也可以用于声明类的静态成员函数。静态成员函数只能访问类的静态成员变量和静态成员函数,不能访问类的非静态成员变量和非静态成员函数(因为它们属于类的特定对象)。静态成员函数不依赖于类的特定对象实例,因此可以通过类名直接调用,而无需创建类的实例。
  6. 静态类(注意:C++标准本身并不直接支持静态类概念,但可以通过静态成员变量和静态成员函数模拟静态类行为):

    • 虽然在C++中没有直接称为“静态类”的语法结构,但可以通过将所有成员变量和成员函数都声明为静态来模拟静态类的行为。这样的类本质上成为了一个只包含静态成员和静态函数的命名空间,不包含任何非静态成员。
const关键字

在C++中,const关键字是一个非常重要的修饰符,它用于声明一个变量、函数参数、返回值或成员函数为常量,即这些实体在声明之后其值(对于变量和函数参数)或行为(对于成员函数)将不能被修改。const的使用可以提高代码的可读性、安全性和可维护性。

  1. 修饰变量:当const修饰变量时,该变量成为常量,其值在初始化之后不能被修改。
const int maxVal = 100; // maxVal是一个常量,其值不能被修改
  1. 修饰指针const可以修饰指针,但需要注意const的位置,因为它决定了是指针指向的值是常量,还是指针本身是常量,或者是两者都是。
const int* ptr; // ptr是一个指向int类型常量的指针,即不能通过ptr修改它所指向的值
int* const ptr; // ptr是一个常量指针,指向int类型,即ptr的值(即它所指向的地址)不能被修改
const int* const ptr; // ptr是一个常量指针,指向int类型的常量,即ptr的值和它所指向的值都不能被修改
  1. 修饰函数参数:将const用于函数参数时,表明函数内部不会修改通过这个参数传入的变量。这可以提高函数的通用性,因为允许传入常量变量作为参数。
void func(const int& x); // x是通过引用传入的,但在函数内部不能被修改
  1. 修饰函数返回值const也可以修饰函数的返回值,但这在大多数情况下并不是特别有用,因为返回值通常会被赋值给另一个变量,而赋值操作会丢弃const修饰符。然而,在返回引用或指针时,const修饰符可以表明返回的引用或指针指向的值不应被修改。
const int& getConstRef() {
    static int value = 0;
    return value; // 返回对静态变量的const引用
}
  1. 修饰成员函数:在类定义中,const可以修饰成员函数,表明该函数不会修改类的任何成员变量(除了那些被声明为mutable的成员变量)。这使得该函数可以被常量对象调用。
class MyClass {
public:
    void func() const {
        // 这里不能修改类的任何成员变量(除了mutable的)
    }
};

const MyClass obj;
obj.func(); // 合法,因为func()是const成员函数
define 与 const区别

defineconst在C/C++等编程语言中都是用于定义常量的方式,但它们之间存在显著的区别。

特性defineconst
编译器处理方式预处理阶段文本替换编译时类型检查
类型检查无类型,仅文本替换有明确类型,进行类型检查
内存占用不占用运行时内存(但可能增加代码段大小)占用运行时内存(可能通过优化减少)
调试调试时难以直接查看值调试时可直接查看值
作用域和生命周期全局有效(除非#undef),无作用域限制受限于定义位置的作用域和生命周期
使用场景全局常量定义,条件编译局部常量、类成员常量,提供类型安全和调试支持
类型安全不提供提供
存储位置预处理后嵌入代码中可能存储在符号表或内存中
灵活性灵活,可用于复杂宏定义适用于简单常量定义,易于理解和维护
inline关键字

inline关键字在C++中是一个非常重要的特性,它用于向编译器建议将函数的调用替换为函数体本身的直接展开,从而消除函数调用的开销,提高程序的执行效率。

// 示例:内联函数的定义  
inline int square(int n) {  
    return n * n;  
}  
  
// 类的成员函数示例  
class MyClass {  
public:  
    MyClass(int value) : m_value(value) {}  
    inline int getValue() const {  
        return m_value;  
    }  
private:  
    int m_value;  
};  
  
// 在类外定义时添加inline关键字  
inline int MyClass::getValue() const {  
    return m_value;  
}
define 与 inline

下表格总结了defineinline之间的主要区别:

特性define宏定义inline内联函数
定义方式预处理指令#defineC++关键字inline
作用阶段预处理阶段编译阶段
作用域无作用域限制,整个源文件有效遵循C++作用域规则
类型检查无类型检查,仅文本替换有类型检查,与普通函数相同
安全性可能引入副作用,如优先级问题、重复求值编译器进行更严格的检查,更安全
调试能力调试困难,因为宏展开后不易识别原始宏调试更容易,与普通函数一样
性能影响可能因重复求值或宏展开过大导致性能问题编译器决定是否内联,可能提高性能
使用场景定义常量、简单的表达式或代码片段,条件编译频繁调用且函数体较小的函数,以减少函数调用开销
编译器行为总是进行文本替换可能忽略inline建议,不内联函数
new 与 malloc

newmalloc 都是用于动态内存分配的机制,new 是 C++ 语言中的操作符,而 malloc是 C 语言标准库中的一个函数。

特性new (C++)malloc ©
所属语言/库C++ 语言操作符C 标准库函数
语法Type* ptr = new Type(initializer);void* ptr = malloc(size);
初始化支持自动初始化(调用构造函数)不自动初始化,需手动(如使用memset
类型安全是,编译器检查类型否,返回void*,需显式类型转换
内存管理使用delete释放,自动调用析构函数使用free释放,不调用析构函数
数组分配使用new[]分配,delete[]释放分配时指定总大小,释放时同样使用free
异常安全在分配失败时抛出std::bad_alloc异常分配失败时返回NULL(或nullptr,取决于C标准版本和编译器)
用途分配并初始化对象分配原始内存块
性能可能稍慢(因为调用构造函数)通常更快(仅分配内存)
调试支持更好的调试信息(如类型信息)调试信息较少,依赖于类型转换和初始化
delete 与 free

在 C++ 中,除非你有特殊理由需要使用 C 风格的内存管理(例如,与 C 代码库互操作),否则通常建议使用 newdelete,因为它们提供了更好的类型安全性和资源管理。

特性delete (C++)free ©
所属语言C++C
用途释放通过 new 分配的内存,并调用对象的析构函数(如果有)释放通过 malloccallocrealloc 分配的内存块
语法delete ptr;(单个对象)
delete[] ptr;(对象数组)
free(void* ptr);
行为释放内存,并调用对象的析构函数(如果对象有析构函数)仅释放内存块,不调用析构函数
类型安全是,与对象的类型相关联否,返回 void*,需显式类型转换
对NULL的处理如果 ptrnullptr(或 NULL,取决于C++标准版本),则不执行任何操作如果 ptrNULL,则不执行任何操作
异常安全分配失败时抛出 std::bad_alloc 异常;释放内存时通常不失败不抛出异常,分配失败时返回 NULL(或 nullptr
内存管理负责释放内存,并调用析构函数进行资源管理负责释放内存,但不负责资源管理(如文件句柄等)
野指针问题释放后应将指针设置为 nullptr(C++11及更高版本)以避免野指针释放后应将指针设置为 NULL 或指向其他有效内存
用途场景C++ 语言中的动态内存和对象生命周期管理C 语言中的动态内存管理
volatile

在C++中,volatile关键字主要用于处理多线程环境或硬件访问时,确保变量的可见性和防止编译器对代码进行过度优化。

  • 可见性:当一个变量被声明为volatile时,它告诉编译器该变量的值可能会在程序的控制之外被改变(例如,由另一个线程或硬件事件改变)。因此,编译器在每次访问该变量时都必须重新从内存中读取它的值,而不是使用可能已经缓存在寄存器或CPU缓存中的值。

  • 防止优化:volatile还阻止编译器对包含该变量的代码进行某些优化,比如将多次读取该变量的操作合并为一个,或者将写入操作延迟到更晚的时间点。

  • 在某些嵌入式系统或需要直接与硬件交互的程序中,volatile可能用于确保对特定内存地址的访问不会被编译器优化掉,因为这些地址可能映射到硬件寄存器上。

struct关键字

虽然C和C++都支持struct,但它们在用法和特性上存在一些差异,尤其是在C++中,随着类的引入,struct的一些行为变得与类相似,但也有一些关键区别。

  • C语言:struct用于定义记录(record),它是一个或多个不同类型变量的集合。使用struct时,你需要首先声明它,然后才能创建该类型的变量。C中的struct默认访问权限是public(虽然C中没有直接使用publicprivate这样的关键字),这意味着结构体内的所有成员都可以从外部直接访问。
struct Person {  
    char name[50];  
    int age;  
    float height;  
};  
  
// 创建Person类型的变量  
struct Person person1;
  • C++:C++在C的基础上扩展了struct的功能,使其更加类似于类。C++中的struct和类的主要区别在于:

    默认访问权限:在C++中,struct的默认访问权限是public,而类的默认访问权限是private

    继承:当struct或类被用作基类时,struct默认是公有继承(public inheritance),而类默认是私有继承(private inheritance)。但这一点在大多数情况下并不显著,因为在实际编程中通常会明确指定继承类型。

struct Person {  
    std::string name;  
    int age;  
    float height;  
  
    // 构造函数  
    Person(std::string n, int a, float h) : name(n), age(a), height(h) {}  
  
    // 成员函数  
    void display() const {  
        std::cout << "Name: " << name << ", Age: " << age << ", Height: " << height << std::endl;  
    }  
};  
  
// 创建Person类型的变量  
Person person1("John Doe", 30, 1.75f);  
person1.display();
struct 与 union 的区别

struct(结构体)和union(共用体)是C和C++中两种用于定义复合数据类型的关键字,它们之间在多个方面存在显著的区别。

  1. 成员存储方式
  • struct:结构体在内存中为每个成员分配独立的内存空间,所有成员变量都同时存在。结构体的大小是其所有成员大小的总和(加上可能的填充字节以满足内存对齐要求)。
  • union:共用体在内存中只分配足够的空间来存储其最大成员,所有成员共享同一段内存空间。在任何时刻,共用体只能存储其一个成员的值,对其他成员的赋值会覆盖当前成员的值。
  1. 内存分配
  • struct:每个成员都有自己的内存位置,且成员在内存中的顺序与它们在结构体中声明的顺序相同。结构体的大小是其成员大小之和加上可能的填充字节,以确保结构体的对齐。
  • union:所有成员共享同一内存位置,共用体的大小是其最大成员的大小(按照该成员类型的倍数进行对齐)。这意味着,无论共用体声明了多少个成员,它在内存中占用的空间都是固定的,且等于其最大成员的大小。
  1. 成员访问和赋值
  • struct:对结构体中不同成员的赋值是独立的,互不影响。可以通过结构体变量直接访问其任何成员。
  • union:对共用体中不同成员的赋值会覆盖当前成员的值。在任一时刻,只能访问并安全地使用共用体中被赋值的那个成员。尝试访问未被赋值的成员将导致未定义行为。

6. 示例

// struct 示例
struct Person {
    char name[50];
    int age;
    float height;
};

// union 示例
union Data {
    int i;
    float f;
    char str[20];
};

// 结构体变量
Person person;
// 共用体变量
Data data;

在上面的示例中,Person结构体将为其成员nameageheight分别分配内存空间,而Data共用体则只分配足够的空间来存储一个int、一个float或一个char数组(取其中最大者),并且这些成员共享这段空间。

extern"C"

在C和C++编程中,extern "C"这个语法结构主要用于在C++代码中链接C代码,确保C++编译器能够正确地处理C语言编写的代码或库。

这是因为C++支持函数重载,而C不支持。C++编译器为了支持函数重载,会对函数名进行修饰(Name Mangling),这样编译后的函数名会包含函数参数类型的信息。然而,C编译器不会进行这样的修饰,因此如果C++代码直接调用C语言编写的函数,链接器会因为找不到未修饰的函数名而报错。

为了解决这个问题,extern "C"告诉C++编译器,被其修饰的代码应该按照C语言的编译和链接规则来处理。

  1. 对单个函数使用

    extern "C" {
        void my_c_function();
    }
    
  2. 对整个文件使用
    如果一个头文件完全是用C语言编写的,并且打算被C和C++代码共同使用,可以在该头文件的开始处加上extern "C"的块包围整个文件的内容。但是,通常的做法是在C++代码中包含该头文件时,使用extern "C",而不是修改头文件本身。

    extern "C" {
    #include "myclib.h"
    }
    
strcpy函数

strcpy函数的主要缺陷在于它不会检查目标缓冲区的大小,这可能导致缓冲区溢出。如果源字符串的长度超过目标缓冲区的大小,strcpy会继续复制直到遇到源字符串的终止符,从而覆盖相邻内存区域的数据,可能引发数据损坏、程序崩溃或安全漏洞。

为避免strcpy的缺陷,推荐使用更安全的字符串复制函数,如strncpy(需手动确保终止符)或strncpy_s(指定目标缓冲区大小)。这些函数提供了额外的边界检查,有助于防止缓冲区溢出。同时,也可以考虑使用高级语言特性,如C++中的std::string类,它自动管理内存并提供了更安全的字符串操作。

lambda 表达式的应用

Lambda 表达式可以捕获其所在作用域中的变量,并允许你在需要函数对象的地方使用它们,而无需显式地定义一个函数或函数对象类型。

  • 基本语法:
[capture](parameters) mutable -> return_type { body }
  • 示例:
#include <iostream>  
#include <vector>  
#include <algorithm>  
  
int main() {  
    std::vector<int> numbers = {1, 2, 3, 4, 5};  
  
    // 使用 Lambda 表达式对 vector 中的元素进行排序  
    std::sort(numbers.begin(), numbers.end(), [](int a, int b) {  
        return a < b; // Lambda 表达式,表示升序排序  
    });  
  
    // 使用 Lambda 表达式和 std::for_each 遍历 vector  
    std::for_each(numbers.begin(), numbers.end(), [](int n) {  
        std::cout << n << ' ';  
    });  
  
    return 0;  
}
explicit 的作用

当构造函数被声明为explicit时,它只能被显式地调用,不能通过隐式类型转换自动调用。explicit关键字主要用于修饰只有一个参数的构造函数。对于多参数构造函数,如果所有参数都有默认值,并且只有第一个参数是必需的,也可以使用explicit(尽管这种情况较少见)。

class MyClass {  
public:  
    explicit MyClass(int value) {  
        // 构造函数的实现  
    }  
};  
  
void func(MyClass obj) {  
    // 函数的实现  
}  
  
int main() {  
    MyClass obj1(10); // 正确,显式调用构造函数  
    // MyClass obj2 = 20; // 错误,如果构造函数是explicit的,则此行会编译失败  
    MyClass obj3(MyClass(20)); // 正确,虽然绕了一点,但显式调用了构造函数  
    func(obj1); // 正确  
    // func(30); // 错误,如果构造函数是explicit的,则此行会编译失败  
    return 0;  
}
define 与 typedef 的区别
特性#definetypedef
执行时间和处理方式在预处理阶段进行文本替换,不进行类型检查或语法分析在编译阶段处理,具有类型检查功能
作用域从定义点开始,直到文件结束,除非使用#undef取消定义;可能跨越文件界限限定在定义的作用域内,如文件、命名空间或函数内
功能定义常量、变量、编译开关、类型别名等;可以进行带参数的宏定义主要用于定义类型的别名,简化复杂的类型声明
用途条件编译、宏展开、定义常量等;也可用于类型别名,但不如typedef清晰提高代码的可读性和可维护性,特别是处理复杂类型声明和跨平台编程时
// #define 示例  
#define INT_PTR int*  
INT_PTR p1, p2; // p1 和 p2 都是 int* 类型  
  
// typedef 示例  
typedef int* IntPtr;  
IntPtr q1, q2; // q1 和 q2 都是 int* 类型
class 与 struct 的异同
  • 相似之处

    自定义数据类型:两者都允许用户定义自己的数据类型,封装数据成员和成员函数。

    成员组成:都可以包含成员变量(属性)和成员函数(方法)。

    继承:都支持继承机制,可以创建基于现有类型的新类型。

    访问控制:都可以使用访问修饰符(如publicprivateprotected)来控制成员的访问权限。

  • 不同之处

    默认访问权限class的默认成员访问权限是privatestruct的默认成员访问权限是public

    继承方式class默认使用private继承。struct默认使用public继承。

    用途和语义class更常用于面向对象编程,表示具有行为和属性的对象。struct虽然也可以用于面向对象编程,但更常用于表示简单的数据结构或记录,其成员通常是可以直接访问的公共数据。

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

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

相关文章

匠心独运:红酒与手工艺的很好结合

在岁月的长河中&#xff0c;红酒与手工艺都以其不同的魅力和技艺&#xff0c;书写着各自的故事。当这两者相遇&#xff0c;仿佛是一场跨越时空的对话&#xff0c;不仅展现了匠心独运的技艺之美&#xff0c;更在无声中诉说着对品质与生活的热爱。今天&#xff0c;就让我们一起探…

CVE-2024-6387漏洞预警:尽快升级OpenSSH

OpenSSH维护者发布了安全更新&#xff0c;其中包含一个严重的安全漏洞&#xff0c;该漏洞可能导致在基于glibc的Linux系统中使用root权限执行未经身份验证的远程代码。该漏洞的代号为regreSSHion&#xff0c;CVE标识符为CVE-2024-6387。它驻留在OpenSSH服务器组件&#xff08;也…

基于Vue.js和SpringBoot的地方美食分享网站系统设计与实现

你好&#xff0c;我是计算机专业的学姐&#xff0c;专注于前端开发和系统设计。如果你对地方美食分享网站感兴趣或有相关需求&#xff0c;欢迎随时联系我。 开发语言 Java 数据库 MySQL 技术 Vue.js SpringBoot Java 工具 Eclipse, MySQL Workbench, Maven 系统展示…

swiftui中常用组件picker的使用,以及它的可选样式

一个可选项列表就是一个picker组件搞出来的&#xff0c;它有多个样式可以选择&#xff0c;并且可以传递进去一些可选数据&#xff0c;有点像前端页面里面的seleted组件&#xff0c;但是picker组件的样式可以更多。可以看官方英文文档&#xff1a;PickerStyle | Apple Developer…

1分钟了解,预写日志WAL的核心思路...

上一篇《刷盘&#xff0c;还是不刷盘&#xff0c;是一个问题》中我们遇到了哪些问题&#xff1f; 1. 已提交事务未提交事务的ACID特性怎么保证&#xff1f; 画外音&#xff1a;上一篇中遇到的问题&#xff0c;主要是原子性与持久性。 2. 数据库崩溃&#xff0c;怎么实施故障恢复…

Python28-5 k-means算法

k-means 算法介绍 k-means 算法是一种经典的聚类算法&#xff0c;其目的是将数据集分成 ( k ) 个不同的簇&#xff0c;每个簇内的数据点尽可能接近。算法的基本思想是通过反复迭代优化簇中心的位置&#xff0c;使得每个簇内的点与簇中心的距离之和最小。k-means 算法的具体步骤…

如何使用ECharts和Java接口实现可视化的数据挖掘

如何使用ECharts和Java接口实现可视化的数据挖掘 【引言】 随着大数据时代的到来&#xff0c;数据挖掘成为了一项重要的技术&#xff0c;在企业决策、市场分析等领域发挥着重要作用。数据挖掘需要将大量的数据进行分析和展示&#xff0c;而可视化是一种直观、形象的展示方式。…

【kafka】可视化工具cmak(原kafka-manager)安装问题解决

众所周知&#xff08;反正不管你知不知道&#xff09;&#xff0c;kafka-maneger更名了&#xff0c;现在叫cmak&#xff01;原因是什么呢&#xff1f;据不可靠小道信息说&#xff0c;原kafka-manager这个名字涉及到kafka商标使用问题&#xff0c;应该是被律师函警告了&#xff…

DeepFaceLive----AI换脸简单使用

非常强大的软件,官方github https://github.com/iperov/DeepFaceLive 百度云链接: 链接&#xff1a;https://pan.baidu.com/s/1VHY-wxqJXSh5lCn1c4whZg 提取码&#xff1a;nhev 1下载解压软件 下载完成后双击.exe文件进行解压.完成后双击.bat文件打开软件 2 视频使用图片换…

零基础入门GIS开发,必看实用教程【附智慧校园实战笔记源码】

GIS开发也叫webgis&#xff0c;web就是指网页端&#xff0c;所以GIS开发大部分情况下是指网页端的地图可视化开发。 因此GIS开发需要学习前端开发HTML/CSS/JS&#xff0c;以及一些常见的前端框架&#xff0c;例如vue和react等&#xff08;新中地教育通常是教vue&#xff0c;其…

【Kafka】记录一次Kafka消费者重复消费问题

文章目录 现象业务背景排查过程Push与Pull 现象 用户反馈消费者出现消息积压&#xff0c;并且通过日志看&#xff0c;一直重复消费&#xff0c;且没有报错日志。 业务背景 用户的消费者是一个将文件做Embedding的任务&#xff0c;&#xff08;由于AI技术的兴起&#xff0c;大…

Windows下Visual Studio 中配置第一个CUDA工程

今天整NVIDIA 的CUDA 安装和第一个CUDA 代码&#xff0c;顺便添加一个有CUDA工程的空框架。 &#xff08;1&#xff09;首先确认自己的CUDA 已经安装成功 >>cmd 进入命令窗&#xff0c;在窗口输入查看cuda 是否安装成功&#xff0c;能查到CUDA的版本号&#xff0c;表示安…

2.WeBASE一键部署

一、官方文档 一键部署可以在 同机 快速搭建WeBASE管理台环境&#xff0c;方便用户快速体验WeBASE管理平台。 一键部署会搭建&#xff1a;节点&#xff08;FISCO-BCOS 2.0&#xff09;、管理平台&#xff08;WeBASE-Web&#xff09;、节点管理子系统&#xff08;WeBASE-Node-…

统计信号处理基础 习题解答11-11

题目 考虑矢量MAP估计量 证明这个估计量对于代价函数 使贝叶斯风险最小。其中&#xff1a;, &#xff0c;且. 解答 贝叶斯风险函数&#xff1a; 基于概率密度的非负特性&#xff0c;上述对积分要求最小&#xff0c;那就需要内层积分达到最小。令内层积分为&#xff1a; 上述积…

视频批量剪辑一键垂直翻转,轻松转换格式为mov,视频制作从此事半功倍!

在视频制作的海洋中&#xff0c;我们时常需要面对各种挑战&#xff0c;其中之一就是视频的翻转与调整。不论是出于创意需求还是格式转换的需要&#xff0c;视频翻转都是一个不可或缺的功能。今天&#xff0c;我要向大家介绍一款真正的批量视频翻转神器——视频剪辑高手&#xf…

Python高速下载及安装的十大必备事项与C++联调

选择正确的版本&#xff1a; 访问Python官网&#xff08;https://www.python.org/&#xff09;下载最新稳定版本&#xff0c;目前最新稳定版本为3.12.4 避免下载并安装Python 2.x版本&#xff0c;因为它已经停止维护。 选择适合操作系统的安装包&#xff1a; 根据你的操作系…

2.4 C#开发环境 xml格式保存参数----范例实现

2.4C#开发环境 xml格式保存参数----范例实现 1 程序参数保存目录层次说明 1 选择程序号| 相机号|窗口号 2 导入参数&#xff1a;就会从本地目录读取参数&#xff0c;并且显示图片和ROI 3 保存参数&#xff1a;把当前控件图片和ROI信息保存到指定程序号|相机号|窗口号中 2 参数…

Xilinx FPGA:vivado单端RAM实现输出偶数(单端RAM的简单应用)

一、实验步骤 &#xff08;1&#xff09;先创建一个工程 &#xff08;2&#xff09;调用IP资源找到RAMs&ROMs&BRAMs&#xff0c;选择其中的块资源 &#xff08;3&#xff09;修改配置参数 timescale 1ns / 1ps //写入0-99的数据&#xff0c;读出偶数 module single_ra…

MeEdu网校系统搜索功能问题处理

MeEdu通过 MeiliSearch 实现全文搜索服务。 一、下载 MeiliSearch 程序 https://github.com/meilisearch/MeiliSearch/releases/tag/v0.24.0 只能下载 v0.24.0 版本&#xff0c;其版本不支持 下载 meilisearch-linux-amd64就可以了 二、上传 MeiliSearch 三、启动命令如下…

如何用简单的html,css,js写出一个带有背景层的删除弹出框

虽然每次项目都是主要写后端&#xff0c;但是有时候前端的样式太丑了&#xff0c;也有点看不下去。弹出框是项目中用的比较多的&#xff0c;比如删除&#xff0c;修改或者添加什么的&#xff0c;都需要一个弹出框。 所以这里简单记录一下&#xff0c;应该如何实现。实现效果如…