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

c17 新特性 字面量,变量,函数,隐藏转换等

导论

        c17新特性引入了许多新的语法,这些语法特性更加清晰,不像传统语法,语义飘忽不定,比如‘a’你根本不知道是宽字符还是UTF-8 字符。以及测试i++ ++i,最后结果到底是多少。这种问题很大情况是根据编译器的优化进行猜测,不同环境,得出不同结果。而c17对这些问题给出完美的解决方案!

字符字面量

理论

官方给出的语法:

  • 普通字符字面量: 'c-char'

  • UTF-8 字符字面量: u8'c-char'

  • UTF-16 字符字面量: u'c-char'

  • UTF-32 字符字面量: U'c-char'

  • 宽字符字面量: L'c-char'

  • 普通多字符字面量: 'c-char-sequence'

  • 宽字符多字符字面量: L'c-char-sequence'

不太懂??基础薄弱!!

  1. 普通字符字面量:

    • 形式: 'c-char'
    • 表示: 一个单个的普通字符字面量,通常为 8 位 ASCII 字符。
    • 类型: char
  2. UTF-8 字符字面量:

    • 形式: u8'c-char'
    • 表示: 一个单个的 UTF-8 编码的字符字面量。
    • 类型: char8_t (C++20 引入)
  3. UTF-16 字符字面量:

    • 形式: u'c-char'
    • 表示: 一个单个的 UTF-16 编码的字符字面量。
    • 类型: char16_t
  4. UTF-32 字符字面量:

    • 形式: U'c-char'
    • 表示: 一个单个的 UTF-32 编码的字符字面量。
    • 类型: char32_t
  5. 宽字符字面量:

    • 形式: L'c-char'
    • 表示: 一个单个的宽字符字面量。宽字符的大小由实现定义,通常为 16 位或 32 位。
    • 类型: wchar_t
  6. 普通多字符字面量:

    • 形式: 'c-char-sequence'
    • 表示: 一个字符序列,由多个普通字符组成。
    • 类型: 数组类型 char[N],其中 N 为字符序列的长度。
  7. 宽字符多字符字面量:

    • 形式: L'c-char-sequence'
    • 表示: 一个字符序列,由多个宽字符组成。
    • 类型: 数组类型 wchar_t[N],其中 N 为字符序列的长度。

这些不同类型的字符字面量主要有以下区别:

  1. 字符编码:

    • 普通字符为 8 位 ASCII 编码。
    • UTF-8、UTF-16 和 UTF-32 字符分别采用 UTF-8、UTF-16 和 UTF-32 编码。
    • 宽字符的编码由实现定义,通常为 16 位或 32 位。
  2. 表示范围:

    • UTF-8、UTF-16 和 UTF-32 字符可以表示更广泛的字符集,包括非 ASCII 字符。
    • 宽字符的表示范围由实现定义。
  3. 内存占用:

    • 普通字符和 UTF-8 字符占用 1 个字节。
    • UTF-16 字符占用 2 个字节。
    • UTF-32 字符和宽字符占用 4 个字节。

        选择合适的字符类型取决于您的具体需求。对于仅需要处理 ASCII 字符的场景,使用普通字符就足够了。如果需要支持更广泛的字符集,可以考虑使用 UTF-8、UTF-16 或 UTF-32 字符。如果需要与遗留代码兼容,或者需要处理宽字符的场景,则可以使用宽字符。 现在我们可以定义出适合的字符串类型,写出最佳的程序。

实践

普通字符字面量:
char c1 = 'a';
char c2 = '\n';
char c3 = '\x2a'; // 等同于 '*'UTF-8 字符字面量:
char8_t c1 = u8'a';
// char8_t c2 = u8'¢'; // 错误,¢无法用单个UTF-8码元表示
// char8_t c3 = u8'猫'; // 错误,猫无法用单个UTF-8码元表示
// char8_t c4 = u8'🍌'; // 错误,🍌无法用单个UTF-8码元表示UTF-16 字符字面量:
char16_t c1 = u'a';
char16_t c2 = u'¢';
char16_t c3 = u'猫';
// char16_t c4 = u'🍌'; // 错误,🍌无法用单个UTF-16码元表示UTF-32 字符字面量:
char32_t c1 = U'a';
char32_t c2 = U'¢';
char32_t c3 = U'猫';
char32_t c4 = U'🍌';宽字符字面量:
wchar_t wc1 = L'a';
wchar_t wc2 = L'¢';
wchar_t wc3 = L'猫';
wchar_t wc4 = L'🍌'; // 在Windows上,这可能是非法的普通多字符字面量:
int mc1 = 'ab'; // 实现定义的值
int mc2 = 'abc'; // 实现定义的值宽字符多字符字面量:
wchar_t wmc1 = L'ab'; // 实现定义的值

有关变量的新语法

变量的评估顺序

表达式的求值顺序:

  • C++ 标准没有规定表达式中各个子表达式的求值顺序,除了一些特定的情况。

  • 通常编译器可以自由选择求值顺序,只要最终结果与按照左到右的顺序求值一致。

        x = (++x, ++y); 传统cpp并没有标准的定义到底谁先执行,都是由编译器优化,这就会造成环境不同,效果不同,争的你死我活。现在c17是这样解决的。

C++ 标准库中的 std::evaluatestd::as_const 这两个工具函数:

  1. std::evaluate (C++23):

    • 功能: 强制求值一个表达式,确保其副作用按照预期顺序发生。

    • 声明: template<class T> constexpr T&& evaluate(T&& t) noexcept;

    • 使用:

      int x = 0, y = 0;
      x = (++x, ++y); // 存在顺序未定义,可能 x 或 y 先增加
      x = std::evaluate((++x, ++y)); // 确保 x 和 y 按从左到右的顺序增加
    • 作用: 帮助开发者明确表达式的求值顺序,避免由于未定义行为导致的bug。

  2. std::as_const (C++17):

    • 功能: 获取一个表达式的常量引用,避免意外修改。

    • 声明: template<class T> constexpr const T& as_const(T& t) noexcept;

    • 使用:

      std::string s = "hello";
      std::string_view sv = s; // 可能意外修改 s
      std::string_view sv = std::as_const(s); // 确保 sv 只能读取 s 的内容
    • 作用: 帮助开发者强制使用只读引用,防止无意中修改原对象。

        总之, std::evaluatestd::as_const 是 C++ 标准库提供的两个有用的工具函数,前者解决表达式求值顺序的问题,后者解决引用可能被意外修改的问题。开发者可以在需要时使用它们来编写更加健壮的代码。

ifswitch初始化

这种多说无益,直接看示例就明白了。

auto lambda = [](int x) {if (int y = x * x; y > 100) {return y;} else {return 0;}
};int result = lambda(11); // result 为 121auto lambda = [](char c) {switch (int x = c; x) {case 'a':return 1;case 'b':return 2;default:return 0;}
};int result = lambda('b'); // result 为 2

 结构化绑定声明 简化代码。

可以看我往期文章,在此简单举个例子

#include <iostream>
#include <tuple>int main() {std::tuple<int, char, std::string> t{42, 'a', "hello"};//变量的数量必须与复合类型的元素数量一致。auto [x, y, z] = t;std::cout << x << ", " << y << ", " << z << '\n'; // 输出: 42, a, helloreturn 0;
}

左值引用和右值引用

可以看我往期文章,就不再赘述,这是重中之重。

constexpr consteval 编译时求值

constexpr 和 consteval 是 C++11 和 C++20 引入的两个关键字,它们都用于在编译时执行计算,但是它们之间有一些区别:

  1. constexpr:

    • constexpr 表示该变量或函数在编译时就可以计算出它的值。
    • constexpr 函数可以在编译时执行,也可以在运行时执行。
    • 如果 constexpr 函数在编译时无法计算出结果,编译器会尝试在运行时执行该函数。
    • constexpr 可以用于变量、函数和类的成员函数。
  2. consteval:

    • consteval 是 C++20 引入的,它比 constexpr 更加严格。
    • consteval 函数必须在编译时就能计算出结果,不能在运行时执行。
    • 如果 consteval 函数在编译时无法计算出结果,编译器会报错。
    • consteval 只能用于函数,不能用于变量或类的成员函数。

举例

constexpr 变量
constexpr int x = 42;
constexpr std::array<int, 3> arr = {1, 2, 3};constexpr 构造函数
struct Point {constexpr Point(int x, int y) : x(x), y(y) {}int x, y;
};
constexpr Point p(1, 2); // 在编译时创建 p 对象consteval关键字
consteval int square(int x) {return x * x;
}
constexpr int y = square(3); // 在编译时计算出 y = 9

总的来说:

  • constexpr 是一种"可能在编译时计算"的函数或变量,而 consteval 是一种"必须在编译时计算"的函数。
  • constexpr 提供了更大的灵活性,但 consteval 提供了更严格的编译时计算保证。
  • 开发者应该根据具体需求选择使用 constexpr 还是 consteval如果一个函数在编译时就能计算出结果,使用 consteval 更合适;如果需要在运行时也能正常执行,使用 constexpr 更合适。

任意类型变量 any variant

variant 编译期

std::variant 是 C++17 引入的一个非常有用的类型,它可以表示一个在多个类型之间进行选择的值。它提供了一种安全和高效的方式来处理可能出现的多种类型。

以下是 std::variant 的一些主要特点:

  1. 可以包含多种类型: std::variant 可以存储不同类型的值,这些类型由开发者在定义 std::variant 时指定。

  2. 类型安全: 与使用 void* 或者联合(union)相比, std::variant 提供了更好的类型安全性。它可以在编译时就检查访问是否合法,从而避免运行时错误。

  3. 访问安全: std::variant 提供了多种安全的访问方式,如 std::getstd::visit 等,可以确保在访问时不会出现未定义行为。

  4. 无需手动内存管理: std::variant 会自动管理其包含的值的生命周期,开发者不需要手动分配或释放内存。

any  运行期

std::any 是 C++17 引入的一个很有用的类型,它可以用来存储和传递任意类型的值。它提供了一个安全和高效的方式来处理动态类型的数据。

以下是 std::any 的一些主要特点:

  1. 可以存储任意类型的值: std::any 可以存储任何类型的值,包括基本数据类型、自定义类型、数组、指针等。

  2. 类型安全: 与使用 void* 相比, std::any 提供了更好的类型安全性。它会在运行时检查访问是否合法,从而避免未定义的行为。

  3. 无需手动内存管理: std::any 会自动管理其包含的值的生命周期,开发者不需要手动分配或释放内存。

  4. 支持赋值和拷贝: std::any 支持赋值和拷贝操作,这使得它可以很方便地在代码中传递和存储值。

示例

#include <iostream>
#include <any>
#include <variant>
#include <string>int main() {// 使用 std::anystd::any anyValue = 42;std::cout << "std::any value: " << std::any_cast<int>(anyValue) << std::endl;anyValue = std::string("hello");std::cout << "std::any value: " << std::any_cast<std::string>(anyValue) << std::endl;// 使用 std::variantstd::variant<int, std::string> variantValue = 42;std::cout << "std::variant value: " << std::get<int>(variantValue) << std::endl;variantValue = std::string("hello");std::cout << "std::variant value: " << std::get<std::string>(variantValue) << std::endl;return 0;
}

anyvariant区别

std::anystd::variant 都是 C++17 引入的非常有用的类型,但它们在功能和使用场景上有一些区别:

  1. 存储类型:

    • std::any 可以存储任意类型的值,包括自定义类型、数组、指针等

    • std::variant 只能存储在定义时指定的有限个类型中的一种

  2. 类型安全:

    • std::any 提供了运行时类型检查,通过 std::any_cast 访问时会检查类型是否匹配,不匹配则抛出 std::bad_any_cast 异常。

    • std::variant 则是在编译时就确定了可能存储的类型,通过 std::get 等函数访问时也可以在编译时检查类型是否匹配。

  3. 访问方式:

    • std::any 通过 std::any_cast 进行访问,需要显式指定类型。

    • std::variant 可以使用 std::getstd::visit 等多种方式进行访问。

  4. 使用场景:

    • std::any 适用于需要处理动态类型数据的场景,如插件系统、配置文件解析等

    • std::variant 则更适用于在有限的几种类型之间进行选择的场景,如函数重载、状态机等。

隐藏转换

这个模块可谓是本文的重点,坑点是最多的。

临时对象具体化 抛砖

        在 C++ 中,临时对象的具体化是一个非常重要的概念。临时对象是在表达式求值过程中创建的短暂对象,它们通常会在表达式结束后被销毁。

std::string getStr() {return "hello";
}
std::string s = getStr(); // 临时对象被具体化并赋值给s
在这个例子中, getStr() 函数返回一个临时的 std::string 对象,该对象会在 main()
函数中被具体化并赋值给 s。int x = 1, y = 2;
int z = x + y; // 临时对象被具体化并赋值给z
在这个例子中,x + y 表达式创建了一个临时的 int 对象,该对象会被具体化并赋值给 z。std::function<int(int)> get_lambda() {return [](int x) { return x * x; };
}
auto square_lambda = get_lambda();
int result = square_lambda(5); // 结果是 25在这个例子中:
1. `get_lambda()` 函数返回一个 lambda 表达式。
2. 这个 lambda 表达式产生了一个临时的 lambda 对象。
3. 这个临时的 lambda 对象被用于初始化 `square_lambda` 变量。
这个临时的 lambda 对象就是通过"临时对象具体化"的过程产生的。编译器会确保这个临时对象的生命周期足够长,以满足初始化 `square_lambda` 的需求。

保证拷贝省略 引玉

        保证拷贝省略(Guaranteed Copy Elision, GCE)并不是 C++17 引入的新特性,它实际上是在 C++11 中引入的。

  C++11中引入了以下几种情况下的拷贝省略:

  1. 返回值优化(RVO):

    • 当函数返回一个局部对象时,编译器可以直接在调用方的位置构造该对象,而无需进行拷贝。
  2. 移动语义优化:

    • 当返回一个临时对象时,编译器可以使用移动构造函数而不是拷贝构造函数
  3. 构造函数参数优化:

    • 当构造函数的参数是一个临时对象时,编译器可以直接在目标位置构造该对象,而无需进行拷贝。

C++17进一步扩展了拷贝省略的范围,增加了以下几种情况:

  1. 无参数构造函数拷贝省略:

    • 当函数返回一个局部对象,且该对象没有参数的构造函数时,编译器可以直接在调用方的位置构造该对象,而无需进行拷贝。
  2. 聚合类型拷贝省略:

    • 当函数返回一个聚合类型(如数组或结构体)的局部对象时,编译器可以直接在调用方的位置构造该对象,而无需进行拷贝。

总的来说,C++11和C++17中的拷贝省略优化可以显著提高程序的性能,减少不必要的拷贝操作。编译器会自动进行这些优化,开发者无需手动干预。

性能优化巅峰   

先举个例子

#include <iostream>class Noisy {
public:Noisy() { std::cout << "Noisy object constructed at " << this << '\n'; }Noisy(const Noisy& other) {std::cout << "Noisy object copy-constructed at " << this << '\n';}Noisy(Noisy&& other) noexcept {std::cout << "Noisy object move-constructed at " << this << '\n';}Noisy& operator=(const Noisy& other) {if (this != &other) {std::cout << "Noisy object copy-assigned at " << this << '\n';}return *this;}Noisy& operator=(Noisy&& other) noexcept {if (this != &other) {std::cout << "Noisy object move-assigned at " << this << '\n';}return *this;}~Noisy() {std::cout << "Noisy object destructed at " << this << '\n';}
};Noisy f(){// c11传统调用 创建一个临时 Noisy 对象,然后将其拷贝构造或移动构造到 v 中    // c17 编译器可以直接在 v 上构造 Noisy 对象,省略掉不必要的拷贝/移动操作。 称为(since C++17) "保证拷贝省略"Noisy v = Noisy();   //注意这里没有任何函数调用!!! 它是怎么做到给返回值给变量v赋值的??
/*
解答:
1.编译器识别到 Noisy v = Noisy(); 是一个直接初始化语句。 
2.它会在 v 的位置直接构造一个 Noisy 对象(Noisy v),而不是先创建一个临时对象,然后再拷贝或移动到 v 中。
3.这个构造过程会调用 Noisy 类的默认构造函数,输出 "Noisy object constructed at 0x[地址]"。
4.最终,v 就直接成为一个 Noisy 类型的对象,不需要经过任何拷贝或移动操作。
*/ return v; 
}void g(Noisy arg)
{std::cout << "&arg = " << &arg << '\n';
}int main()
{// c11  会执行一次拷贝或移动操作,将 v 的内容复制或移动到返回值中。//C++17引入命名返回值优化( NRVO)允许编译器直接在返回值位置构造对象(不调用构造函数),避免不必要的拷贝或移动。Noisy v = f();  //同理 f()返回值v 如何实现给v初始化的?/*
如果 f() 返回一个临时 Noisy 对象或者返回一个命名的 Noisy 对象(例如一个局部变量),编译器会尝试应用 RVO 和 NRVO 等优化,
尽量避免不必要的拷贝和移动操作。
编译器可以直接在 v 的位置构造这个返回的 Noisy 对象,避免任何拷贝或移动。
*/              std::cout << "&v = " << &v << '\n';g(f());// (since C++17)  "拷贝省略"
}

输出


constructed at 0x7fff1d765096    解释:代码行 Noisy v = Noisy(); 的调用
&v = 0x7fff1d765096
constructed at 0x7fff1d765097    解释:代码行 Noisy v = Noisy(); 的调用
&arg = 0x7fff1d765097destructed at 0x7fff1d765097
destructed at 0x7fff1d765096

 C++11 和 C++17 在这些优化上的差异:

  1. 临时变量的初始化:

    • C++11 及更早的版本中,Noisy v = Noisy(); 会先创建一个临时 Noisy 对象,然后将其拷贝或移动到 v 中。这会涉及一次构造和一次拷贝/移动操作。
    • C++17 引入了"保证拷贝省略"(Guaranteed Copy Elision, GCE)特性,编译器可以直接在 v 上构造 Noisy 对象,省略掉不必要的拷贝/移动操作。
  2. 函数返回值的优化:

    • C++11 及更早的版本中,return v; 会执行一次拷贝或移动操作,将 v 的内容复制或移动到返回值中。
    • C++17 引入的"命名返回值优化"(Named Return Value Optimization, NRVO)允许编译器直接在返回值位置构造对象,避免不必要的拷贝或移动。
  3. 函数参数的传递:

    • C++11 及更早的版本中,g(f()); 会先创建一个临时 Noisy 对象,然后将其拷贝或移动到 arg 中。
    • C++17 的"拷贝省略"(Copy Elision)特性允许编译器直接在 arg 上构造 Noisy 对象,避免不必要的拷贝或移动。

 上列的例子,应该能让读者更清楚的对c17”保证拷贝省略“进一步的理解,最后我们在整理一下思路,

临时变量的初始化: Noisy v = Noisy()  -> Nosiy v(); 
函数返回值的优化: Noisy v = {Noisy v; return v;} -> Nosiy v(); 
函数参数的传递:主函数 nrvo优化:
Noisy v = f(); -> 
Noisy v = {Noisy v = Noisy();  return v; }->   //临时变量初始化的优化
Noisy v = {Noisy v();  return v; } -> 
Noisy v = {return v} ->                      //函数返回值的优化
Noisy v = Noisy() ->  
Noisy v;g(f())
g(Noisy arg = {Noisy v = Noisy();  return v;})
g(Noisy arg =  {Noisy v();  return v;})
g(Noisy  arg )

隐式转换

C++ 隐式转换的内容总结如下:

  1. 隐式转换的顺序:

    • 标准转换序列 - 包括值转换和一些数值转换

    • 用户定义转换 - 通过单参数构造函数或转换函数进行

    • 可能的额外标准转换序列

  2. 值转换:

    • 左值到右值

    • 数组到指针

    • 函数到指针

    • 临时对象化 - 将右值转换为左值

  3. 整数提升:

    • 将小整数类型提升为 int 或 unsigned int

  4. 浮点提升:

    • float 转换为 double

  5. 数值转换:

    • 整数间转换

    • 浮点间转换

    • 浮点和整数间转换

    • 指针间转换

    • 指针到成员间转换

    • 布尔转换

  6. 限定符转换:

    • 在相似类型间添加或删除 const/volatile 限定符

  7. 上下文转换:

    • 在特定上下文中进行的隐式转换,如条件表达式、逻辑运算符等

举例

标准转换序列:
int x = 3.14; // float 到 int 的隐式转换用户定义转换:
class Rational {
public:Rational(int numerator, int denominator = 1) {// 用户定义的单参数构造函数}
};
Rational r = 5; // int 到 Rational 的隐式转换 5->Rational  因为没加explicit值转换:
int* p = new int[10]; 
int x = p[0]; // 数组到指针的隐式转换,然后左值到右值的隐式转换整数提升:
char c = 'a';int i = c; // char 提升到 int浮点提升:
float f = 3.14f;
double d = f; // float 提升到 double限定符转换:
const int* p = new int;
int* q = const_cast<int*>(p); // 从 const int* 到 int* 的转换上下文转换:
if (Rational r = 5) { // Rational 到 bool 的隐式转换// ...
}

总结

        总的来说,这篇文章全面介绍了C++17中的一些重要语法和概念变化,对于了解和掌握C++17的新特性很有帮助。文章内容丰富,逻辑清晰,可以作为C++17学习的良好参考资料。

相关文章:

c17 新特性 字面量,变量,函数,隐藏转换等

导论 c17新特性引入了许多新的语法&#xff0c;这些语法特性更加清晰&#xff0c;不像传统语法&#xff0c;语义飘忽不定&#xff0c;比如‘a’你根本不知道是宽字符还是UTF-8 字符。以及测试i i&#xff0c;最后结果到底是多少。这种问题很大情况是根据编译器的优化进行猜测&a…...

git操作的一些备忘录

1.回退本地合并 git merge --abort 2.撤销上一次的提交 方法一&#xff1a;(已经提交到git线上仓库了&#xff0c;git reset操作&#xff0c;会把之前提交的都删除&#xff0c;感觉有点危险) 想要让Git回退历史&#xff0c;有以下步骤&#xff1a; 使用git log命令&#xff0c…...

vscode回退不显示了,不方便操作

一、后退前进按钮 顶部显示&#xff0c;方便调试 <—— ——> 文件-> 首选项 -> 设置->commandcenter->勾选 Window: Title Bar Style->custom 将native —>custom...

常见的CSS属性(一)——字体、文本、边框、内边距、外边距、背景、行高、圆角、透明度、颜色值

一、字体 二、文本 三、边框 四、外边距 五、内边距 六、背景 七、行高 八、圆角 九、透明度 九、颜色值 元素的继承性是指给父元素设置了某些属性&#xff0c;子元素或后代元素也会有作用。 一、字体 “font-*”是字体相关的属性&#xff0c;具有继承性。代码如下&a…...

react入门到实战-day2-7.21

昨天晚上刚学完已经一点了&#xff0c;来不及写笔记&#xff0c;主要是想睡觉哈&#xff0c;所以今天补上&#xff0c;我发现效率还挺高的&#xff0c;今天重新做笔记&#xff0c;加固了昨天的知识点&#xff0c;要不以后都这样子哈&#xff0c;学完第二天再写哈&#xff0c;要…...

Springboot集成Elasticsearch High Level REST Client实现增删改查实战

获取源码&#x1f6a9; 需要完整代码资料&#xff0c;请一键三连后评论区留下邮箱&#xff0c;安排发送&#xff01;&#xff01;&#xff01;&#x1f916; 什么是High Level REST Client&#xff1f; Elasticsearch 的 High Level REST Client 是一个用于与 Elasticsearch…...

2023河南萌新联赛第(二)场 南阳理工学院

A. 国际旅行Ⅰ 题目&#xff1a; 思路&#xff1a; 因为题意上每个国家可以相互到达&#xff0c;所以只需要排序&#xff0c;输出第k小的值就可以了。 AC代码&#xff1a; #include<bits/stdc.h> #define int long long #define IOS ios::sync_with_stdio(0);cin.tie…...

使用Docker Compose给自己上传的JAR打包成镜像并自动启动容器

Docker Compose是一个用于定义和运行多容器Docker应用程序的工具。通过编写一个docker-compose.yml文件&#xff0c;可以简化Docker容器的管理。本文将介绍如何使用Docker Compose将一个上传的JAR文件打包成Docker镜像&#xff0c;并在容器中自动启动该应用程序。 一、准备工作…...

NET8部署Kestrel服务HTTPS深入解读TLS协议之Certificate证书

Certificate证书 Certificate称为数字证书。数字证书是一种证明身份的电子凭证&#xff0c;它包含一个公钥和一些身份信息&#xff0c;用于验证数字签名和加密通信。数字证书在网络通信、电子签名、认证授权等场景中都有广泛应用。其特征如下&#xff1a; 由权威机构颁发&…...

DML数据库的数据类型

DML 用于改变数据表中的数据的操作语言。 包括INSERT&#xff08;将数据插入到数据表中&#xff09;,UPDATE&#xff08;更新表中已经存在的数据&#xff09;,DELETE&#xff08;删除表中已经存在的数据&#xff09; INSERT 用法 INSERT INTO 表名&#xff08;字段1&#x…...

@RequestParam和@PathVariable 处理 HTTP 请求参数的注解

RequestParam 请求参数 可解析前端get请求路径后以问号拼接的参数,查询参数是 URL 后面的问号 (?) 后跟的一系列键值对,RequestParam 可以设置参数是否是必需的&#xff08;使用 required 属性&#xff09; GetMapping("/users") public String getUsers(RequestPar…...

《代码大全》读书笔记-第Ⅰ部分 奠定基础

0.欢迎来到软件构建世界 什么是软件构件&#xff1a; 对于非正式及项目&#xff0c;会觉得罗列出来的这些活动太过于繁复。但是这些对于正式项目都是很有必要的(大部分人都没经历过&#xff0c;比如说我)。一般一些小公司主要也就是需求分析、编码、开发人员自测、集成测试这几…...

杰发科技Bootloader(1)—— Keil配置地址

IAP方式 BootLoader方式 UDSBoot方式 AC7801的地址分配 用户空间的的地址从8000000开始分配&#xff0c;大小是64页&#xff0c;即128K。 RAM地址从20000000开始 基于UDSboot调试-Boot 烧录Boot之后&#xff0c;ATClinkTool无法连接 用keil查看内存&#xff0c;地址到8005388…...

338. 比特位计数

338. 比特位计数 题目链接&#xff1a;338. 比特位计数 代码如下&#xff1a; class Solution { public:vector<int> countBits(int n) {vector<int> res(n 1, 0);for (int i 1; i < n; i){if (i % 2 1) { res[i] res[i - 1] 1; }else { res[i] res[i …...

flask后端+vue前端——后端怎么发文件给前端?

首先&#xff0c;前端axios请求的responseType要设置为blob const service axios.create({baseURL: http://127.0.0.1/api,timeout: 5000});//向后端发送数据&#xff0c;后端根据这个数据data生成文件返回send_coordinate(data){return service.post(/,data,{responseType: …...

计算机毕业设计django+hadoop+scrapy租房可视化 租房推荐系统 租房大屏可视化 租房爬虫 spark 58同城租房爬虫 房源推荐系统

python scrapy bootstrap jquery css javascript html 租房信息数据展示 租房地址数量分布 租房类型统计 租房价格统计分析 租房面积分析 房屋朝向分析 房屋户型平均价格统计分析 房屋楼层统计分析 房屋楼层与价格统计分析 房屋地址与价格统计分析 房屋相关信息词云展示 租房…...

【Tomcat】Mac M3 Pro安装Tomcat7

文章目录 下载配置环境变量修改权限启动和关闭 下载 官网&#xff1a;https://tomcat.apache.org/ cd ~/Library tar -zxvf /Users/用户名/Downloads/apache-tomcat-7.0.99.tar.gz mv apache-tomcat-7.0.99 ~/Library/tomcat配置环境变量 vi ~/.bash_profileexport TOMCAT…...

Spring Boot(八十二):SpringBoot通过rsa实现API加密

项目中使用RSA加密方式对API接口返回的数据加密,让API数据更加安全。别人无法对提供的数据进行破解。Spring Boot接口加密,可以对返回值、参数值通过注解的方式自动加解密 。 下面开始代码演示 1 接口加密 1.1 新建一个springboot项目 1.2 添加依赖 <dependency>&l…...

巴黎奥运启幕 PLM系统助力中国制造闪耀全球

2024巴黎奥运会将于法国当地时间7月26日在塞纳河畔正式开幕。即将亮相巴黎奥运会赛场的除了中国运动员之外&#xff0c;还有一批批中国制造企业为奥运会设计并制造的体育设备也将惊艳亮相&#xff0c;成为赛场上另一道亮丽的风景线。 在新时代的浪潮中&#xff0c;中国制造业坚…...

基于STM32瑞士军刀--【FreeRTOS开发】学习笔记(一)|| RISC / 底层代码执行步骤 / 汇编指令

本篇文章基于韦东山老师讲课笔记和自己理解编写。 RISC ARM芯片属于精简指令集计算机(RISC&#xff1a;Reduced Instruction Set Computing)&#xff0c;它所用的指令比较简单&#xff0c;有如下特点&#xff1a; ① 对内存只有读、写指令 ② 对于数据的运算是在CPU内部实现 …...

【JavaScript】01数组原型对象的最后一个元素、计数器

题目一&#xff1a;数组原型对象的最后一个元素 请你编写一段代码实现一个数组方法&#xff0c;使任何数组都可以调用 array.last() 方法&#xff0c;这个方法将返回数组最后一个元素。如果数组中没有元素&#xff0c;则返回 -1 。 你可以假设数组是 JSON.parse 的输出结果。…...

解决R语言找不到系统库导致的报错

1、基本需知 1.1、系统库 系统库&#xff08;System library&#xff09;是一组预先编写和编译好的软件模块集合&#xff0c;用于支持操作系统的基本功能和提供一些常见的服务。这些库通常由操作系统或第三方开发者提供&#xff0c;并且在系统安装过程中被预装或者用户可以额…...

Java高并发理论基础

并发级别 由于临界区的存在&#xff0c;多线程之间的并发必须受到控制。根据控制并发的策略&#xff0c;我们可以把并发的级别分为 阻塞、无饥饿、无障碍、无锁、无等待 几种。 阻塞 一个线程是阻塞的&#xff0c;那么在其他线程释放资源之前&#xff0c;当前线程无法继续执…...

Spring事件机制

文章目录 一、Spring事件二、实现Spring事件1、自定义事件2、事件监听器2.1 实现ApplicationListener接口2.2 EventListener2.3 TransactionalEventListener 3、事件发布4、异步使用 三、EventBus1、事件模式2、EventBus三要素3、同步事件3.1 定义事件类3.2 定义事件监听3.3 测…...

vue+canvas音频可视化

1.代码 <template><div class"subGuide"><canvas id"canvas"></canvas><br><audio id"audio" src"./audio.mp3" controls></audio></div> </template><script> export…...

俊昭stm32笔记

stm32——中断优先级 stm32——创建基础工程模板stm32——创建基础工程模板-CSDN博客 stm32——MCU启动方式stm32——MCU启动方式_stm32调试时程序启动方式-CSDN博客 stm32——串口stm32——串口_stm32 串口-CSDN博客 stm32——lcd液晶显示stm32——lcd液晶显示-CSDN博客...

W30-python03-pytest+selenium+allure访问百度网站实例

此篇文章为总结性&#xff0c;将pystest、selenium、allure结合起来 功能如下&#xff0c;web自动化&#xff0c;输入baidu网站&#xff0c;搜索“雷军”、打开网页中第一条内容 pytestsel.py如下&#xff1a; import time import re import allure import pytest from tools…...

如何在 Debian 8 上安装和使用 PostgreSQL 9.4

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 简介 关系型数据库是满足多种需求的数据组织的基石。它们支持从在线购物到火箭发射等各种应用。PostgreSQL 是一种历史悠久但仍然活跃的…...

【微信小程序】微信小程序设置本地背景图片在真机无法显示的解决方案

微信小程序设置本地背景图片在真机无法显示的解决方案 在开发微信小程序时&#xff0c;很多开发者会遇到一个常见的问题&#xff1a;在调试环境中设置本地背景图片可以正常显示&#xff0c;但在真机上却无法显示。本文将详细探讨这一问题的原因&#xff0c;并提供三种解决方案…...

Arthas在线诊断案例实战整理

Arthas - Java 应用诊断利器 Arthas 是一款线上监控诊断产品&#xff0c;通过全局视角实时查看应用 load、内存、gc、线程的状态信息&#xff0c;并能在不修改应用代码的情况下&#xff0c;对业务问题进行诊断&#xff0c;包括查看方法调用的出入参、异常&#xff0c;监测方法…...

使用 XRDP 远程linux主机

一、简介 XRDP是一个开源的远程桌面协议&#xff08;Remote Desktop Protocol,RDP&#xff09;服务器&#xff0c;采用的是标准的RDP。 官网地址&#xff1a;https://www.xrdp.org/ github地址&#xff1a; https://github.com/neutrinolabs/xrdp/releases XRDP也是C/S架构&…...

学习小型gpt源码(自用)

数据集构建_哔哩哔哩_bilibili &#xff08;b站上有一系列课&#xff0c;从数据处理到模型构建和训练使用&#xff09; 什么是batch&#xff1f; 为什么一个batch内的句子要一样长&#xff1f; 不同batch的长度可以不一样&#xff0c;但是同一个batch内长度一样&#xff01;…...

@Transactional使用的注意事项

在项目中涉及到CRUD操作时&#xff0c;一般都会在方法上添加该注解&#xff0c;以为加上Transactional&#xff0c;Spring就可以自动帮我们进行事务的开启、提交 有一个很多人都会犯的误区&#xff1a; 将Spring事务与Transactional划上了等号&#xff0c;只要有数据库相关操作…...

快手可灵视频生成大模型全方位测评

快手视频生成大模型“可灵”&#xff08;Kling&#xff09;&#xff0c;是全球首个真正用户可用的视频生成大模型&#xff0c;自面世以来&#xff0c;凭借其无与伦比的视频生成效果&#xff0c;在全球范围内赢得了用户的热烈追捧与高度评价。截至目前&#xff0c;申请体验其内测…...

【JavaScript】`Map` 数据结构

文章目录 一、Map 的基本概念二、常见操作三、与对象的对比四、实际应用场景 在现代 JavaScript 中&#xff0c;Map 是一种非常重要且强大的数据结构。与传统的对象&#xff08;Object&#xff09;不同&#xff0c;Map 允许您使用各种类型的值作为键&#xff0c;不限于字符串或…...

Ubuntu22.04使用NVM安装多版本Node.js和版本切换

Fabric官方目前支持Node.js开发区块链应用&#xff0c;建议使用Node长期支持版本&#xff08;LTS&#xff09;。 建议使用NVM安装Node.js&#xff0c;NVM可以帮助我们方便的在Node的不同版本之间进行切换&#xff0c;这样我们就可以同时工作在不同的项目上。 下面是安装的脚本…...

基于C51和OLED12864实现Goole小恐龙

在数字娱乐领域&#xff0c;Google小恐龙&#xff08;T-Rex Runner&#xff09;以其简单而上瘾的游戏机制赢得了广泛的关注和喜爱。这款内置于Chrome浏览器的离线小游戏&#xff0c;不仅为用户带来了乐趣&#xff0c;也激发了开发者们对其进行各种创新和扩展的灵感。本文将介绍…...

【Docker】CentOS7环境下的安装

环境展示 安装 配置仓库 sudo yum install -y yum-utils # docker官方key文件下载 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 建议使用阿里云key文件下载 sudo yum-config-manager --add-repo https://mirrors.aliyun.…...

浏览器的最大并发数(http1.1)

HTTP/1.1&#xff1a;每个资源请求通常需要单独的TCP连接&#xff0c;尽管支持Keep-Alive机制&#xff0c;允许在同一个TCP连接上连续发送多个请求。但通常浏览器限制并发TCP连接数&#xff08;例如&#xff0c;每个域名最多6个并发连接&#xff09;。 HTTP/2&#xff1a;引入…...

Android 开发中px、dpi 和 dp三个单位的介绍

Android 开发中px、dpi 和 dp三个单位的介绍 在 Android 开发中&#xff0c;px、dpi 和 dp 是用来描述屏幕尺寸和密度的单位&#xff0c;它们在设计和开发中有着不同的作用和用途。 1. px&#xff08;像素&#xff09; 定义&#xff1a; px 表示屏幕上的一个像素点&#xff0c…...

zookeeper开启SASL权限认证

目录 一、SASL介绍 二、使用 SASL 进行身份验证 2.1 服务器到服务器的身份验证 2.2 客户端到服务器身份验证 三、验证功能 一、SASL介绍 默认情况下&#xff0c;ZooKeeper 不使用任何形式的身份验证并允许匿名连接。但是&#xff0c;它支持 Java 身份验证与授权服务(JAAS)…...

mysql一个小问题引发的思考-mysql类型转换-查询缓存 及 MYSQL查询缓存以及自动选择不使用查询缓存的情况

一、mysql一个小问题引发的思考-mysql类型转换-查询缓存 最近在做的一个项目中有一个SQL语句发现点问题&#xff0c;大概如下&#xff1a; select * from table where cid0 or find_in_set(1, cid); 数据表中的字段cid是字符串类型&#xff0c;原来的后端同学未提过此字段还能是…...

css更改图片颜色

css更改图片颜色&#xff0c;比较时候颜色单一的图片&#xff0c;比如logo之类的 css中的 filter 属性定义元素&#xff08;通常是 <img>&#xff09;的视觉效果&#xff08;如模糊和饱和度&#xff09; img{ -webkit-filter: invert(51%) sepia(94%) saturate(6433%) h…...

通过POST请求往Elastic批量插入数据

文章目录 引言I 请求文档请求参数请求例子引言 调试工具:Apifox 需求: 向Elasticsearch中的’test_index’索引批量插入文档 情况认证: Basic Auth 在 Header 添加参数 Authorization,其值为在 Basic 之后拼接空格,以及经过 Base64 编码的 {{Username}}:{{Password}} 示…...

JAW:一款针对客户端JavaScript的图形化安全分析框架

关于JAW JAW是一款针对客户端JavaScript的图形化安全分析框架&#xff0c;该工具基于esprima解析器和EsTree SpiderMonkey Spec实现其功能&#xff0c;广大研究人员可以使用该工具分析Web应用程序和基于JavaScript的客户端程序的安全性。 工具特性 1、动态可扩展的框架&#x…...

错误解决 error CS0117: ‘Buffer‘ does not contain a definition for ‘BlockCopy‘

Unity 2022.3.9f1 导入 Runtime OBJ Importer 后出现&#xff1a; error CS0117: ‘Buffer’ does not contain a definition for ‘BlockCopy’ 解决办法&#xff1a; 源代码&#xff1a; int DDS_HEADER_SIZE 128; byte[] dxtBytes new byte[ddsBytes.Length - DDS_HEAD…...

ICMPv6与DHCPv6之网络工程师软考中级

ICMPv6概述 ICMPv6是IPv6的基础协议之一。 在IPv6报文头部中&#xff0c;Next Header字段值为58则对应为ICMPv6报文。 ICMPv6报文用于通告相关信息或错误。 ICMPv6报文被广泛应用于其它协议中&#xff0c;包括NDP、Path MTU发现机制等 ICMPv6控制着IPv6中的地址自动配置、地址…...

【HTML — 构建网络】HTML 入门

在本文中,我们将介绍 HTML 的绝对基础知识。为了帮助您入门,本文定义了元素、属性以及您可能听说过的所有其他重要术语。它还解释了这些在 HTML 中的位置。您将学习 HTML 元素的结构、典型的 HTML 页面的结构以及其他重要的基本语言功能。在此过程中,也将有机会玩转 HTML! …...

javafx的ListView代入项目的使用

目录 1. 创建一个可观察的列表&#xff0c;用于存储ListView中的数据,这里的User是包装了用户的相关信息。 2.通过本人id获取friendid&#xff0c;及好友的id&#xff0c;然后用集合接送&#xff0c;更方便直观一点。 3.用for遍历集合&#xff0c;逐个添加。 4.渲染器&…...

基于ABAP OLE技术实现对服务器文件进行读写操作

使用ABAP中的OLE&#xff08;Object Linking and Embedding&#xff09;技术&#xff0c;可以实现对服务器文件的读写操作。以下是一个示例&#xff0c;演示如何通过ABAP代码使用OLE自动化对象来读写服务器上的文件。这里主要以Excel文件的读写操作为例。 1. 读Excel文件 代码…...