深入讲解C++基础知识(二)

news2024/11/28 10:47:20

目录

  • 一、复合类型
    • 1.引用
      • 1.1 引用的定义和使用
      • 1.2 引用的注意事项
    • 2. 指针
      • 2.1 指针的定义和使用
      • 2.2 指针的四种状态
      • 2.3 指针的注意事项
      • 2.4 其他指针操作
      • 2.5 void* 指针
    • 3. 理解复合类型变量的声明
    • 4. const 限定符
      • 4.1 const 对象的注意事项
      • 4.2 const 和引用
        • 4.2.1 术语:常量引用是对 const 的引用
        • 4.2.2 const引用的注意事项
      • 4.3 const 和指针
        • 4.3.1指向 const 对象的指针注意事项
        • 4.3.2 const 指针
        • 4.3.3 顶层 const 和 底层 const
    • 5. constexpr 和常量表达式
      • 5.1 常量表达式
      • 5.2 constexpr 类型
      • 5.3 constexpr 类型的注意事项
    • 6. 处理类型
      • 6.1 类型别名
        • 6.1.1 关键字 typedef
        • 6.1.2 C++11新增 using 别名声明
        • 6.1.3 类型别名注意事项
      • 6.2 auto 类型说明符
        • 6.2.1 为什么需要 auto 类型说明符
        • 6.2.2 auto 类型说明符的注意事项
      • 6.3 decltype 类型指示符
        • 6.3.1 decltype 的不同
        • 6.3.2 decltype 和引用

一、复合类型

复合类型是基于其他类型定义的类型。C++语言有几种复合类型,这里介绍其中两种常用的复合类型:引用和指针。

前面定义变量的格式都是:基本数据类型+变量名。如:int a,double b = 3.14 等。而更通用变量定义的格式为:基本数据类型 + 声明符列表。每个声明符命名了一个变量并指定该变量为与基本数据类型有关的某种类型。

1.引用

引用其实是为已存在的对象起了个别名,实际上并未创建新的对象。创建对象的实质其实是编译器根据对象的类型开辟对应大小的空间,然后程序员通过变量名来访问这块空间。而引用就是给这块空间起了第二个名字,通过这个新名字访问这块空间的效果和通过原变量名访问的效果一样。

1.1 引用的定义和使用

引用的定义格式为:类型& 变量名 。
如下代码:
在这里插入图片描述

这里先创建了 int 类型的变量 a,并初始化为 10,然后定义了指向 a 的引用ra,然后 ra 就是 a 的别名,使用 ra 和使用 a 的效果是一样的,并且它们的地址相同,因为它们都是同一块空间的标识符。所以修改 ra 的值就是修改 a 的值。如下图所示:
在这里插入图片描述
引用类型的对象没有属于自己的存储空间,它们只是其他对象的别名,和其他对象共用一块空间。而且引用一旦绑定了对象,就不允许绑定其他对象,只能一直和最初的对象绑定在一起。所以,引用必须初始化。

对引用的操作就是对其绑定对象的操作,两者互为一体。为引用赋值其实就是为其绑定对象赋值。获取引用的值,实际上就是获取其绑定对象的值。

1.2 引用的注意事项

1. 引用本身不是对象,它只是其他对象的别名,所以不能定义引用的引用。

2. 允许在一条语句中定义多个引用,但是必须在每个引用标识符前面加上符号 & 。

int i = 10, j = 20;
int &ri = i, rj = j;  // 这里 ri 是引用,而 rj 是 int 类型的变量
int &ri = i; &rj = j;  // 这里的 ri 和 rj 都是引用

3. 引用必须和引用对象的类型严格匹配,否则编译器会报错。但是以下两种情况例外:
(1)const 引用既可以绑定 const 对象,也可以绑定非 const 对象。而非 const 对象只能绑定非 const 对象。而 const 对象还可以绑定字面值常量。
(2)在类继承中,基类对象的指针和引用可以在不显式转换的情况下绑定基类的对象。

类型不匹配的情况:
在这里插入图片描述
这里试图用 double 类型的引用绑定 int 类型的变量 a ,编译器报错。

2. 指针

指针是一种指向其他类型的复合类型,它和引用类似,也实现了对其他对象的间接访问。但是指针与引用又有许多不同点:
(1)指针本身是一个对象,拥有属于自己的存储空间,存储指向对象的地址。
(2)允许对指针赋值和拷贝,且在指针的生命周期中可以前后指向多个不同对象。
(3)指针可以不初始化。和其他内置类型一样,如果是局部指针变量,那么其内存储的地址就是随机值。

2.1 指针的定义和使用

指针的定义格式:类型* 变量名 。
如下代码:
在这里插入图片描述
通过取地址符(&)可以得到变量的地址。可以看到指针 pa 指向了变量 a,然后指针 pa 中存储了变量 a 的地址。然后便可以通过解引用操作符(*)对指针 pa 进行解引用来访问变量 a 。如下代码:
在这里插入图片描述
可以看到,通过对指针 pa 进行解引操作得到了其指向对象 a,并修改了变量 a 的值。可以这么理解,*pa 就是变量 a,对*pa的操作就是对变量 a 的操作,这一点和引用类似。

2.2 指针的四种状态

指针应属于下列四种状态之一:
(1)指向某个已存在的对象。
(2)指向紧邻对象所占空间的下一个位置。
(3)空指针,意味着指针没有指向任何对象。
(4)无效指针,上述三种情况之外的其他情况。

2.3 指针的注意事项

1. 不能对无效指针进行解引用操作。
例如:如果指针未初始化,则其中存储的地址是随机值,若该地址上面刚好存储了计算机系统的重要信息,我们通过解引用操作去访问这些信息会造成难以预测的结果。

2. 创建指针变量最好初始化,若实在不知道指向哪个对象,则将其初始化为空指针(nullptr)。
空指针(nullptr)不指向任何对象,可以在使用指针之前对其进行判断是否为空,这样安全性就大大提高。在过去的程序中还使用一个名为 NULL 的预处理变量对指针赋值,使其成为空指针。但是,在新标准下,最好使用现在的 nullptr 。
如下代码给指针 pi 初始化为空指针:

int *pi = nullptr;  // 把指针 pi 初始化为空指针

3. 除了以下两种情况,其他所有指针的类型必须和被指向的类型严格配对。
(1)const 指针既可以指向 const 对象,也可以指向非 const 对象,还可以指向字面值常量。而非 const 指针只能指向非 const 常量。
(2)在类继承中,基类的引用和指针可以在不进行显式转换的情况下直接指向派生类对象。

2.4 其他指针操作

可以对指针进行加减整数,结果是在当前位置的基础上移动该整数乘以其类型大小的字节数。如下代码:
在这里插入图片描述
可以看到对 int 类型的指针 pi 加 5 实际上增加了 5*4 = 20(字节),其他类型也是如此。

只要指针是合法的,就可以把它用在条件表达式中,任何非空指针(nullptr)的条件值都是 true。如下代码:
在这里插入图片描述
对于两个类型相同的合法指针,可以使用相等操作符(==)或不等操作符(!=)来比较它们,比较的结果为 bool 类型。如果两个指针存放的地址相同,则它们相等;否则它们不相等。这里指针存放的地址相等有三种可能:它们都为空、都指向同一个对象,或者都指向了同一个对象的下一地址。注意, 一个指针指向某个对象,另一个指针指向该对象的下一地址,此时也有可能出现这两个指针值相同的情况,即指针相等。

2.5 void* 指针

void* 是一种特殊类型的指针,可以存放任意已经存在的对象的地址。如下代码:

int a = 10;
double b = 20;
void* p = &a;  // 可以指向 int 变量
p = &b;  // 也可以指向 double 变量

但是 void* 类型的指针仅仅只能存放对象的地址,并不能通过解引用操作访问该对象。因为编译器并不知道该对象的类型,不能对该地址往后的空间进行操作。但是可以拿 void* 类型的指针与别的指针进行比较、作为函数的参数或者返回值,也可以赋值给另一个 void* 指针。

3. 理解复合类型变量的声明

复合类型变量的声明包含一个基本数据类型和一组声明符。虽然一条声明语句中的基本数据类型只有一个,但是声明符的形式可以不同。如下代码,分别定义了一个 int 的变量、int* 类型的指针和 int& 类型的引用:

int a = 10, *pa = &a, &ra = a;  // 定义了三种不同类型的变量

再次证明,如果要在一条声明语句中定义多个指针或者引用,需要在每个标识符前面加上符号(*)或者(&)。

由于引用并不是一个对象,所以不能创建引用的引用,也不能创建引用的指针。但是指针是一个对象,可以创建指针的引用。如下所示:
在这里插入图片描述
可以看到指向指针 pi 的引用 rpi 与指针 pi 不但存储的地址相同,而且同样可以进行解引用操作,再次证明对引用的操作,实际上是对其所指向对象的操作,引用只是其所指向对象的别名。

还可以声明指向指针的指针,因为指针是一个对象,它也有自己的地址。如下代码:

int a = 10;
int *pa = &a;  // 指向变量 a 的指针
int **ppa = &pa;  // 指向指针 pa 的指针

其他类型也是如此,上述 ppa 也称为二级指针。如果想定义三级指针,则再加上一个符号(*),以此类推。而对二级指针 ppa 解引用一次得到指针 pa,再解引用一次得到变量 a 。如下代码:
在这里插入图片描述

4. const 限定符

const 限定符的作用是使变量的值不能被修改,只能在声明变量的时候使用,且必须初始化,否则编译器会报错。如下代码:
在这里插入图片描述
使用 const 修饰的变量依旧是变量,不是常量。只是它的属性变成了只读。const 变量除了不能修改其值以外和普通变量没有什么区别,普通变量能进行的操作它也能进行。

4.1 const 对象的注意事项

(1)对于简单的并且能在编译时就确定值的 const 对象,编译器将在编译过程中把用到该变量的地方替换为其对应的值。
(2)const 对象默认状态下只在当前文件有效,如果在头文件中声明了 const 对象,则包含该头文件的每个文件中都定义了一个该 const 对象。如果想在多个文件中使用同一个 const 对象,则不能将其放在头文件中。并且需要在一个文件中定义该 const 对象时添加 extren 关键字,在其需要使用该 const 对象的文件中也使用 extren 关键字进行声明。
如下代码:

// text1.cpp 文件
extern const int SIZE = 20;  // 定义
// text2.cpp 文件
extern const int SIZE;  // 声明

上述代码在 text1.cpp 文件中对 const 对象 SIZE 进行定义,然后在 text2.cpp 中声明,告诉编译器该对象的定义在其他文件。这样,两个文件中使用的都是同一个 const 对象。

4.2 const 和引用

在引用声明前添加 const 就可以绑定 const 对象,我们称之为对常量的引用。但是不能通过对常量的引用修改它绑定的对象,否则编译器会报错。如下代码:
在这里插入图片描述
但是除了修改自身值这个操作以外,rA 和 A 都可以进行其他变量可以进行的操作。

4.2.1 术语:常量引用是对 const 的引用

C++程序员们经常把词组 ”对 const 的引用“ 简称为 ”常量引用“,这一简称还是挺靠谱的,不过前提是你的时刻记得这就是个简称而已。

严格来说,并不存在常量引用。因为引用不是一个对象,所以我们没法让引用本身恒定不变。事实上,由于C++语言并不允许随意改变引用所绑定的对象,所以从这层意义上理解所有的引用又都算常量。引用的对象是常量还是非常量可以决定其所能参与的操作,却无论如何都不会影响到引用和对象的绑定关系本身。

4.2.2 const引用的注意事项

(1)const 引用还可以绑定非 const 对象和字面值常量。
如下代码:
在这里插入图片描述(2)const 引用也可以绑定一个表达式
如下代码:
在这里插入图片描述
(3)不能通过 const 引用改变 绑定的对象的值,不管绑定的对象是否为 const 对象。
如下代码:
在这里插入图片描述

计算表达式时,不会改变参与表达式运算的变量,而是会在其中生成临时变量存储表达式的计算结果,执行完该语句之后,该临时变量会被销毁。临时变量具有常性,即不能被修改,只读属性。

4.3 const 和指针

与引用一样,指针也可以指向常量。指向常量的指针不能修改所指向对象的值。想要存放常量的地址必须使用指向常量的指针,否则编译器会报错。如下代码:
在这里插入图片描述
第二行代码试图让 int* 指针 pi 指向 const int 变量 a,编译器报错。

4.3.1指向 const 对象的指针注意事项

(1) 指向 const 对象的指针和 const 引用一样,既可以指向 const 对象,也可以指向非 const 对象。
如下代码:
在这里插入图片描述
(2)不能通过指向 const 对象的指针去修改被指向对象的值,不管被指向对象是否为 const 对象。
如下代码:
在这里插入图片描述

4.3.2 const 指针

指针和引用不一样,引用不是对象并且引用一旦绑定一个对象就必须一直绑定该对象,相当于该引用本身就被 const 修饰。而指针是对象且不管是否为指向 const 对象的指针,它都可以再次指向其他对象。我们可以通过改变 const 的位置,使其修饰指针本身,这样指针就不能指向其他对象了,该指针称为常量指针。如下代码:
在这里插入图片描述
如果 const 是修饰指针的,则需要把 const 放在 * 号的后面。且试图使常量指针指向其他对象是非法的,编译器会报错。常量指针必须初始化。

4.3.3 顶层 const 和 底层 const

顶层 const 表示 指针本身被 const 修饰,指针本身是常量。而底层 const 表示指针所指向的对象被 const 修饰,该被指向的对象是常量。实际上就是上述指针的两种 const 形式,只是换了个叫法。

引用只能是底层 const,因为引用必须初始化,且一旦绑定对象就不能修改,相当于自带引用本身自带 const 修饰。而我们使用 const 只能修饰其绑定对象。

5. constexpr 和常量表达式

5.1 常量表达式

常量表达式是指值不会改变并且在编译过程中就能得到计算结果的表达式。显然字面值属于常量表达式,用常量表达式初始化的 const 对象也是常量表达式。

一个对象是不是常量表达式由它的数据类型和初始值共同决定,如下代码:

const int A = 65;  // A 为常量表达式
const int B = A + 1;  // B 为常量表达式
int C = 67;  // C 为常量表达式
const int sz = get_size();  // D 为常量表达式

A 是 const 对象,B 是const 对象且用常量表达式初始化,所以 A 和 B 均为常量表达式。而 C 不是 const 对象,D 虽然是 const 对象,但是 D 的值需要在运行时才能确定,所以 C 和 D 均不是常量表达式。

5.2 constexpr 类型

C++11 规定,可以将变量声明为 constexpr 类型,表明该变量的值是一个常量表达式,且编译器会对其进行检查,若其值不是常量表达式,则报错。如下代码:
在这里插入图片描述
一般来说,如果你认定变量是一个常量表达式,那就把它声明为 constexpr 类型。

5.3 constexpr 类型的注意事项

指针和引用虽然都可以定义成 constexpr,但是用来初始化它们的值有严格的限制。
(1)一个 constexpr 指针的初始值必须是空指针(nullptr 或者 0),或者存储于某个固定地址中的对象。即,不能使用局部变量初始化该类指针,否则编译器会报错,因为局部变量出了其作用域就会被销毁。如下代码:
在这里插入图片描述

(2)constexpr 只能修饰指针本身,不能修饰指针所指向的对象。效果相当于常量指针,即指针的指向不能改变。如下代码:
在这里插入图片描述

6. 处理类型

6.1 类型别名

类型别名顾名思义就是其他类型的别名,使用它就和使用原类型是一个效果。当类型名称较长难以理解时,用自己的方式定义该类型别名,便于写代码和理解。下面有两种方法可以定义类型别名。

6.1.1 关键字 typedef

如下代码:
在这里插入图片描述
上述代码把 INT 声明为了 int 的别名,然后使用 INT 相当于使用 int,所以 a 和 b 均为 int 类型的变量。

6.1.2 C++11新增 using 别名声明

如下代码:
在这里插入图片描述
此代码和上述使用 typedef 关键字的代码一致,INT 均为 int 类型的别名,且 a 和 b 均为 int 类型的变量。

6.1.3 类型别名注意事项

如果对复合类型定义类型别名,则在使用时有些许不同。

1. 类型别名在定义中为基本数据类型
如下代码:

typedef char* pstr;
const pstr cstr = 0;
const pstr *ps;

第一条语句让 pstr 成为 char* 的别名,则在下面两行代码中,pstr 是基本数据类型,且 const 修饰 pstr,则 cstr 为指向字符常量的指针。而 * 修饰 ps 所以,ps 本身是一个指针,它指向的对象为 const pstr,即指向字符常量的指针。

2. 不需要在每个变量前都加修饰符

如下代码分别使用正常方式和类型别名声明两个 int 类型的指针。
在这里插入图片描述

正常声明复合类型时,每个变量名前都需要添加相应的修饰符,而类型别名在定义时作为基本数据类型,所以 pint 表示其基本类型就是 int 类型的指针。所以,就不需要在变量名前面添加 * 修饰。

6.2 auto 类型说明符

auto 类型说明符在变量初始化时,通过对初始值进行分析,来推断所创建变量的类型。如下代码:

int a = 0;
auto b = a;  // b 的类型也是 int
auto c = 0;  // c 的类型也是 int

第二条语句,编译器根据 a 的类型为 int,推断出 b 的类型也为 int,并且用 b 的值来初始化 a。第三条语句类似,只不过 0 时 int 类型字面值。

6.2.1 为什么需要 auto 类型说明符

当编写大型程序时,用到一个比较前面的变量来初始化现有刚创建的变量时,使用 auto 能提供很大的方便。且当要创建的变量类型复杂时,通过使用 auto 使代码简洁,节省时间。

6.2.2 auto 类型说明符的注意事项

(1)使用 auto 创建的变量必须初始化,不然编译器推断不出其类型。
如下代码:
在这里插入图片描述
(2)编译器推断 auto 类型的变量时有时和初始值的类型并不完全一样,编译器会适当改变结果的类型使其更符合初始化规则。
规则如下:
a. 我们在使用引用时,其实使用的是引用所绑定的对象,特别当引用被用作初始值时。所以当使用引用对象来推断 auto 的类型时,实际上是根据引用所绑定的对象来进行推断的。

b. auto 一般会忽略顶层 const,保留底层 const 。
如下代码:
在这里插入图片描述
这里 a 的类型为 const int,但是该 const 为顶层 const,被 auto 忽略,所以 b 推断出来的类型为 int 。

如下代码:
在这里插入图片描述
上述代码中,指针 pa 既是顶层 const 又是底层 const,但是 auto 在推断类型时忽略了顶层 const,保留底层 const。则指针 pi 只是底层 const,可以修改指针的指向,但是不能修改指针所指向的值。

(3)可以使用 auto 来设置引用,但是初始值中的顶层 const 仍保留。
如下代码:
在这里插入图片描述
使用 auto 设置引用时,若初始值是顶层 const 对象,则该 const 会保留。若想绑定 字面值,则需要前缀 const,表明该类型是 const 引用。

(4)在一条语句中使用 auto 定义多个变量时,符号 & 和 * 只属于某个变量名,而不是基本数据类型的一部分,因此初始值必须是同一种基本类型。
如下代码:
在这里插入图片描述
第一条 auto 声明语句,ra 是 int 类型的引用,则编译器推断基本数据类型为 int,所以 pb 为指向 int 的指针。第二条 auto 声明语句,c 是 double 类型的引用,但是后面的 pi 为 int 类型,导致编译器判断不了该条声明语句的基本数据类型,故报错。

6.3 decltype 类型指示符

decltype 类型指示符和 auto 类型说明符相似。但是 decltype 类型指示符只通过表达式的类型来判断所创建的变量的类型,但不使用该表达式来对变量进行初始化。
如下代码:

decltype(f()) a = b;

上述代码通过函数 f() 的返回类型来确定变量 a 的类型,但是通过变量 b 类初始化变量 a。

6.3.1 decltype 的不同

decltype 处理顶层 const 的方式和 auto 有所不同。如果 decltype 使用的表达式是一个变量,则返回该变变量的类型(包括顶层 const 的引用在内)。
如下代码:
在这里插入图片描述
上述代码中,第一条 decltype 语句中由于变量 ci 的类型为 const int,则变量 x 的类型也为 const int,顶层 const 保留。第二条 decltype 语句中 cj 的类型为 const int 类型的引用,则 y 也为 const int 类型的引用,绑定变量 x 。最后 z 为 const int 类型的引用,但是没有初始化,编译器报错。

6.3.2 decltype 和引用

如果 decltype 使用的是一个表达式而不是变量,则 decltype 返回表达式结果对应的类型。如下代码:

decltype d = 1 + 3.0;  // d 为 double 类型

上述表达式最后的计算结果为 double 类型,则变量 d 的类型为 double 。

如果表达式的内容是解引用操作,则 decltype 得到引用类型。
如下代码:
在这里插入图片描述
上述代码中 *pa 等价于 &a,则 c 的类型推断出来为 int 类型的引用,然后没有对其初始化,编译器报错。

如果 decltype 使用的是一个不加括号的变量,则得到的类型就是该变量的类型;如果给该变量加上一层或多层括号,则编译器把它当作一个表达式。一般会得到引用类型。
如下代码:
在这里插入图片描述
这里第一条语句 a 为 int 类型,而第二条语句多加了一个括号,则 ri 为 int 类型的引用,必须初始化。

注意: decltype( (variable) ) 的结果永远是引用;而 decltype( variable) 的结果只有 variable本身是引用时,其结果才是引用。

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

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

相关文章

MAS马氏数控制榫机控制面板维修显示屏MDK3113B

马氏数控榫头机触摸屏/显示面板维修型号:MX3810A;MDK3113B;MXK2815B MAS马氏数控开榫机触摸屏/显示面板维修型号: MX2108B;MD2108A;MJ105А 数控面板维修包括:马氏数控榫头机、开榫机、制榫机…

STM32自己从零开始实操07:电机电路原理图

一、LC滤波电路 其实以下的滤波都可以叫低通滤波器。 1.1倒 “L” 型 LC 滤波电路 1.1.1定性分析 1.1.2仿真实验 电感:通低频阻高频的。仿真中高频信号通过电感,因为电感会阻止电流发生变化,故说阻止高频信号 电容:隔直通交。…

Prometheus + Grafana 监控系统搭建使用指南-mysqld_exporter 安装与配置

使用mysqld_exporter 实现Prometheus 监控Mysql 系列文章目录 Prometheus 的安装部署Grafana的安装部署Linux服务器接入Prometheus监控-Node Exporter 安装指南Prometheus 接入SpringBoot微服务监控Mysql 接入 Prometheus RocketMQ 接入Prometheus 监控ElasticSearch 接入 Pr…

Renderless 思想正在影响前端开发

本文由前端小伙伴方长_beezen 原创。欢迎大家踊跃投稿。 原文链接:https://juejin.cn/post/7385752495535472655 前言 截止到 2024 年,跨端应用开发所需要考虑的兼容性,已经涵盖了框架、平台和设备类型等多个方面,例如&#xff1…

AI学习与实践6_AI解场景Agent应用预研demo

前言 学习大模型Agent相关知识,使用llama_index实现python版的Agent demo,根据AI解题场景知识密集型任务特点,需要实现一个偏RAG的Agent WorkFlow,辅助AI解题。 使用Java结合Langchain4j支持的RAG流程一些优化点以及自定义图结构…

基于工业互联网的智能制造:未来制造业的新引擎

随着科技的飞速发展,工业互联网通过提供强大的数据支撑和通信基础,成为智能制造的重要基石。智能制造的引入,不仅显著提升了制造业的生产效率、降低了成本,而且提高了产品质量,满足了市场的多样化、个性化需求。 智能制…

创建react的脚手架

Create React App 中文文档 (bootcss.com) 网址:creat-react-app.bootcss.com 主流的脚手架:creat-react-app 创建脚手架的方法: 方法一(JS默认): 1. npx create-react-app my-app 2. cd my-app 3. …

(三十一)Flask之wtforms库【剖析源码下篇】

每篇前言: 🏆🏆作者介绍:【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者 🔥🔥本文已收录于Flask框架从入门到实战专栏:《Flask框架从入…

ESP32CAM物联网教学08

ESP32CAM物联网教学08 本地网页控制小车 小智制作的物联网小车,在与云台监控摄像头的PK中,一路攻城掠地、勇往直前。突然有一天,他觉得似乎忘了最开始时的初衷,忘了一路走来的首发站:这个不就是一辆遥控车吗?我能不能就做一辆快乐的、纯粹的遥控车。 CameraWebServer转换…

相关款式1111

一、花梨木迎客松 1. 风速打单 发现只有在兄弟店铺有售卖 六月份成交订单数有62笔 2. 生意参谋 兄弟店铺商品访客数:3548,支付件数:95件 二. 竹节茶刷(引流) 1. 风速打单 六月订单数有165笔 兄弟:…

【技术支持】console控制台输出美化(腾讯文档)

function style(color, size 12){return display:inline-block;background-color:${color};color:#fff;padding:2px 4px;font-size:${size}px; } const dataVersion 3.0.0 const codeVersion 3.0.28657969 const branchVersion release-20240617-f98487dc //注意此处%c后面…

CDC实时同步进行时遇到不可抗力中断了怎么办?

目录 一、CDC技术的概念 二、CDC技术的应用场景 1.数据复制和同步 2.实时数据仓库 3.业务过程监控和审计 4.ETL 进程优化 三、CDC与数据管道的关系 1.区别 CDC(Change Data Capture) 数据管道(Data Pipeline) 2.联系 CDC是数据管道…

【pycharm】 Virtualenv创建venv报错

一、背景 在启动django项目时,需要创建venv环境,有时候能顺利创建成功,当python版本换成3.8时,会报错 ImportError: DLL load failed while importing _ssl: 找不到指定的模块。 二、原因和解决措施 之所以执行这个报错&#…

六西格玛绿带培训如何告别“走过场”?落地生根

近年来,六西格玛绿带培训已经成为了众多企业提升管理水平和员工技能的重要途径。然而,不少企业在实施六西格玛绿带培训时,往往陷入形式主义的泥潭,导致培训效果大打折扣。那么,如何避免六西格玛绿带培训变成“走过场”…

前端面试项目细节重难点(十)(已工作|做分享)

面试官:现场出需求:我想让一个左侧盒子可以进行拉伸、缩小、展示或隐藏这些功能,你会如何实现? 答:(1)分析问题:其实,我听到这个问题后: 我的第一种想法&am…

化学合成水热釜 加热反应釜 实验室高温高压设备

水热釜,也称为高压消解罐或高压釜,是一种能够在高温高压条件下进行化学反应的实验室设备。它广泛应用于化学、地质、材料科学、环境科学等领域,特别是在需要在高压环境下加速化学反应或溶解难溶物质的实验中。以下是水热釜的一些关键特性和用…

Android14之获取包名/类名/服务名(二百二十三)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

短链接学习day2

用户敏感信息脱敏展示: RequestParam 和 PathVariable的区别 注解是用于从request中接收请求的,两个都可以接收参数,关键点不同的是RequestParam 是从request里面拿取值,而 PathVariable 是从一个URI模板里面来填充。 PathVari…

3033. 修改矩阵 Easy

给你一个下标从 0 开始、大小为 m x n 的整数矩阵 matrix ,新建一个下标从 0 开始、名为 answer 的矩阵。使 answer 与 matrix 相等,接着将其中每个值为 -1 的元素替换为所在列的 最大 元素。 返回矩阵 answer 。 示例 1: 输入:…