C++入门语法

C++入门

首先第一点,C++中可以混用C语言中的语法。但是C语言是不兼容C++的。C++主要是为了改进C语言而创建的一门语言,就是有人用C语言用不爽了,改出来个C++。

在这里插入图片描述

命名空间

c语言中会有如下这样的问题:

在这里插入图片描述
那么C++为了解决这个问题就整出了一个命名空间。因为在日常作业中,我们为了使得代码的意思更加明确,我们创建的变量和函数有时候就会和c语言库里面创建的变量或者函数命名冲突。

或者是我和同事之间写的冲突,因为有可能大家负责不同板块,但是都要用到这个名字去定义一个函数或者变量,分开的时候没啥事,整合到一起就冲突了。

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存 在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化, 以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
在这里插入图片描述
可以看到,当我把我创建出来的那个rand变量放进我创建的一个命名空间lin中,就不会有报错了。

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{} 中即为命名空间的成员。

命名空间的名字尽量有意义些,一般最好不要和库里面的命名空间重复。不然还是有较大概率冲突的。

注意事项

  • 在 C++ 里,命名空间的名字是可以重复的。当重复定义命名空间时,这些同名的命名空间实际上会合并成一个命名空间,各个定义中的成员会被整合在一起。
    在这里插入图片描述

    • 命名空间的名字是区分大小写的。
      在这里插入图片描述

    • 成员冲突:若在不同的同名命名空间定义中存在同名的成员,就会引发冲突,编译时会报错。
      在这里插入图片描述

    • 组织代码:利用同名命名空间合并的特性,可将一个大型的命名空间拆分成多个文件进行定义,以此来组织代码。例如,在不同的头文件里定义同一个命名空间的不同部分,最后将这些头文件包含到源文件中,就能够使用完整的命名空间成员。

  • 命名空间可以嵌套定义。也就是在一个命名空间内部能够定义另一个命名空间。
    在这里插入图片描述

命名空间的使用:

  • 加命名空间名称及作用域限定符:
    在这里插入图片描述
    这样使用起来就比较麻烦了。

  • 使用using将命名空间中某个成员引入:

在这里插入图片描述

  • 使用using namespace 命名空间名称 引入:

在这里插入图片描述

"::"这个符号是域作用限定符。

注意事项:

  • 在日常作业中,我们一般最好是不要使用第三种方式使用命名空间,尤其是C++官方库中的命名空间std。我们一般使用的方式是第二种,“使用using将命名空间中某个成员引入”。这样既可以方便使用,又可以避免一些不必要的麻烦。
  • 毕竟使用命名空间把相关内容圈起来,肯定是不想你随意就展开的,这样命名空间的意义就不大了。当然了,如果只是平日的代码练习,直接展开也无碍,但是尽量形成良好的使用习惯。

输入(流提取)输出(流插入)

在这里插入图片描述

说明:

  1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件 以及按命名空间使用方法使用std。

  2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。

  3. <<是流插入运算符,>>是流提取运算符。

  4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。 C++的输入输出可以自动识别变量类型。

  5. 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识, 这些知识我们我们后续才会学习,所以我们这里只是简单学习他们的使用。后面我们还有有 一个章节更深入的学习IO流用法及原理。

  6. 关于cout和cin还有很多更复杂的用法,比如控制浮点数输出精度,控制整形输出进制格式等 等。因为C++兼容C语言的用法,这些又用得不是很多,我们这里就不展开学习了。

缺省参数

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

在这里插入图片描述

给大家举个生活中的例子:你有个异性朋友,你很喜欢她/他。你这个异性朋友平时呢对你爱搭不理,因为他/她平时有很多比你更好的选项,她/他就去找别人玩。不过有时候呢,你这个异性朋友也有无聊的时候,没人找他/她玩,这个时候,她/他就想到你了,她/他也知道你喜欢她/他。她/他就会跟逗狗一样的逗你玩玩,或者让你陪她/他看个电影吃个饭,把钱给付了。然后就又忘记你,找别人去了。

懂?

诶,所以说做人不要当“缺省参数”。明白不?别TM当舔狗,当备胎。

不过“缺省参数”在C++中是条好狗,还是很好用的有时候。

缺省参数分类

  • 全缺省参数

在这里插入图片描述

  • 半缺省参数

在这里插入图片描述

注意:
  1. 半缺省参数必须从右往左依次来给出,不能间隔着给 ,必须是连续的给。
  2. 传参数的时候也是,必须连续的传,不能间隔,跳跃的传参数,而且必须从左往右传。
  3. 缺省参数不能在函数声明和定义中同时出现。缺省参数规定只能在函数声明时设置好,定义的时候就不用再设置缺省参数了。
  4. 如果声明与定义位置同时出现缺省参数,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值。就存在歧义了。

函数重载

函数重载就是可以有重名函数,但是重名函数之间的参数不同。

参数不同又有哪几种不同呢?

  1. 参数类型不同
    • 参数类型不同中有一种是参数个数相同,但是参数类型的顺序不同
  2. 参数个数不同

在这里插入图片描述

在这里插入图片描述

看了这两幅图的解释之后,顺便说一下为什么返回值不能作为函数重载的依据,一样的,因为调用二义性。你只有返回值不同,鬼知道你到底要用哪个函数,对吧。

int func()
{return 0;
}double func()
{return 1.1;
}
来,你调用func()的时候,你说,你要调用哪个函数。这不就歧义了嘛,对吧。

这里还有个麻烦事,就是为什么C++支持函数重载,C语言不支持,这里我就不细说了,我把老师讲课的时候画的图给大家放出来,大家自己看看吧,我就不再讲了。

在这里插入图片描述

引用

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空 间,它和它引用的变量共用同一块内存空间。

在这里插入图片描述

在这里插入图片描述

这就像啥,像孙悟空似的,a是孙悟空,b是齐天大圣,c是弼马温,d是大圣,d是b的别名,总的来说b c d都指向着a:孙悟空。

注意:

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体。也就是说,你不能既是a的别名,还是另一个别的变量的别名
void TestRef(){int a = 10;int b = 100;// int& ra;   // 该条语句编译时会出错int& ra = a;// int& ra = b;//这个也是会报错的,不能引用多个实体int& rra = a;printf("%p  %p  %p\n", &a, &ra, &rra);  
}

常引用

void TestConstRef(){const int a = 10;//int& ra = a;   // 该语句编译时会出错,a为常量const int& ra = a;// int& b = 10;  // 该语句编译时会出错,b为常量const int& b = 10;double d = 12.34;//int& rd = d;  // 该语句编译时会出错,类型不同const int& rd = d;}
 double d = 12.34;//int& rd = d;  // 该语句编译时会出错,类型不同const int& rd = d;

这里大家可以会疑惑上面那个,为啥 //int& rd = d; // 该语句编译时会出错,类型不同,但是加了一个const修饰就可以了呢?首先呢大家可以看到,这里是double类型隐式转换为int类型,这种类型转换之间都会产生一个临时变量,啥意思呢?意思就是隐式类型转换不是原来那个变量真的改变类型了,是用了一个临时变量存储了改变类型的原变量。用这里的例子就是,不是变量d真的变成了int类型,而是有一个临时变量存储了变量d变成int类型的值,然后赋值给变成新变量rd,这个临时变量是一个常量,所以引用的时候也要加一个const修饰。就像给常量10取别名一样。

// 权限不能放大
const int a = 10;
//int& b = a;//这样会报错
//大概意思就是:
//菩萨让孙悟空护唐僧取经,不能说你换个别名叫大圣了就不去护唐僧取经了
//或者说:小明在家里爸妈叫他有两个称呼,一个叫小明,一个是儿子
//现在爸妈不允许儿子吃饭,难道小明可以说:我叫小明,我可以吃饭。
//可以这样吗?不可以!
//这就类似权限的放大,你该干啥就要干啥,你不能干啥就不能干啥。
const int& b = a;// 权限可以缩小
int c = 20;
const int& d = c;
const int& e = 10;

在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。

在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。
下面这幅图是反汇编:
在这里插入图片描述

在C++中引用是无法完全替换指针的,指针和引用更多是相辅相成,引用是优化了一些原来C语言使用指针麻烦的地方。

引用和指针的不同点:

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何 一个同类型实体。比如指针a本来是变量1的地址,但是后面你想让指针a变成变量2的地址,这是可以的。但是引用就不行,引用一旦确定,就不能再改变它引用的实体,也就是说引用无法改变指向,所以在一些需要改变指向的功能中,就只能使用指针。
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32 位平台下占4个字节)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,但是没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来相对更安全

使用场景

引用一般两个使用场景,一个是:做参数,一个是:做返回值。

两种场景使用引用之后的主要效果都是:提高程序运行效率。

做参数的时候:(我们以传值和传引用做比较)
  • 传值:在调用函数时,会把实参的值复制一份给形参。函数内部操作的是这个复制的值,而并非实参本身。所以,函数内部对形参的修改不会影响到实参。
  • 传引用:调用函数时,传递给形参的是实参的引用,也就是实参的内存地址。函数内部对形参的操作实际上就是对实参本身进行操作,因此函数内部对形参的修改会影响到实参。

性能开销

  • 传值:由于需要复制实参的值,当实参是较大的对象(如大型结构体、类对象)时,复制操作会消耗较多的时间和内存。
  • 传引用:只需要传递对象的引用(内存地址),无需复制对象本身,所以在处理大型对象时,传引用的性能开销通常比传值小。

数据安全性

  • 传值:函数内部无法修改实参的值,因此实参的数据在函数调用过程中是安全的。
  • 传引用:函数内部可以直接修改实参的值,这可能会导致意外的数据修改。若不希望函数修改实参的值,可以使用 const 引用。示例如下:
#include <iostream>// 使用 const 引用,防止函数内部修改实参
void printValue(const int& num) {std::cout << "num 的值: " << num << std::endl;// num = 20; // 编译错误,不能修改 const 引用的值
}int main() {int num = 10;printValue(num);return 0;
}
引用做返回值的时候

在 C++ 中,使用引用作为函数的返回值有特定的条件、会产生相应的效果,同时也存在一些潜在的隐患。

使用引用做返回值的条件

1. 返回的对象必须在函数外部仍然有效

当函数返回一个引用时,这个引用所指向的对象必须在函数调用结束后仍然存在于内存中。如果返回的是函数内部的局部对象的引用,会导致未定义行为,因为局部对象在函数结束时会被销毁。因此,通常可以返回以下几种类型的引用:

  • 全局变量或静态变量的引用:全局变量和静态变量的生命周期是整个程序运行期间,函数返回它们的引用是安全的。
#include <iostream>// 全局变量
int globalVar = 10;// 返回全局变量的引用
int& getGlobalVar() {return globalVar;
}// 静态变量
int& getStaticVar() {static int staticVar = 20;return staticVar;
}int main() {int& ref1 = getGlobalVar();int& ref2 = getStaticVar();std::cout << "Global var: " << ref1 << std::endl;std::cout << "Static var: " << ref2 << std::endl;return 0;
}
  • 作为参数传入的对象的引用:如果函数接受一个对象的引用作为参数,那么可以安全地返回这个引用。
#include <iostream>int& modifyValue(int& num) {num *= 2;return num;
}int main() {int value = 5;int& result = modifyValue(value);std::cout << "Modified value: " << result << std::endl;return 0;
}
  • 对象成员的引用:如果函数是类的成员函数,并且返回类对象的成员的引用,只要对象本身在函数调用结束后仍然有效,这种返回方式就是安全的。
#include <iostream>class MyClass {
public:int data;int& getData() {return data;}
};int main() {MyClass obj;obj.data = 10;int& ref = obj.getData();std::cout << "Data: " << ref << std::endl;return 0;
}
2. 函数的返回类型必须是引用类型

函数的返回类型需要明确指定为引用类型,即在类型后面加上 &。例如:

int& func(); // 返回 int 类型的引用

使用引用做返回值的效果

1. 避免复制开销

返回引用可以避免对返回对象进行复制,特别是对于大型对象,这样可以提高程序的性能。例如:

#include <iostream>
#include <vector>// 返回向量的引用
std::vector<int>& getVector(std::vector<int>& vec) {return vec;
}int main() {std::vector<int> myVector = {1, 2, 3};std::vector<int>& result = getVector(myVector);// 没有进行复制操作,result 直接引用 myVectorreturn 0;
}
2. 可以作为左值使用

返回引用的函数可以作为左值,即可以出现在赋值语句的左边。这使得函数调用可以直接修改所引用的对象。

#include <iostream>int& getValue(int& num) {return num;
}int main() {int value = 5;getValue(value) = 10; // 函数调用作为左值std::cout << "Value: " << value << std::endl;return 0;
}

使用引用做返回值的隐患

1. 悬空引用

如果返回的引用指向的对象在函数调用结束后被销毁,就会产生悬空引用。访问悬空引用会导致未定义行为,可能会使程序崩溃或产生不可预测的结果。

#include <iostream>// 错误示例:返回局部变量的引用
int& getLocalValue() {int local = 10;return local; // 局部变量在函数结束时被销毁
}int main() {int& ref = getLocalValue();std::cout << ref << std::endl; // 悬空引用,未定义行为return 0;
}
2. 数据修改的风险

由于返回的引用可以直接修改所引用的对象,可能会导致意外的数据修改,特别是在多线程环境下,这种风险会更加明显。因此,在使用引用返回值时,需要谨慎考虑数据的安全性。

3. 代码可读性降低

过多使用引用返回值可能会使代码的可读性降低,因为引用的使用可能会让代码的逻辑变得复杂,尤其是在涉及多个函数调用和引用传递的情况下。开发者需要更加仔细地理解代码的执行流程和数据流向。

内联函数

那么内联函数主要是改变C语言中的啥呢?主要改变的是宏定义的问题。

宏定义

宏定义是在预处理阶段由预处理器处理的,它利用 #define 指令把一个标识符定义为一个字符串。在编译代码之前,预处理器会将代码里所有该标识符替换成对应的字符串。

语法
#define 宏名 替换文本
示例
#include <iostream>
// 定义一个简单的宏
#define PI 3.14159
// 定义一个带参数的宏
#define ADD(a, b) ((a) + (b))int main() {double radius = 5.0;double area = PI * radius * radius;std::cout << "圆的面积: " << area << std::endl;int x = 3, y = 4;int sum = ADD(x, y);std::cout << "两数之和: " << sum << std::endl;return 0;
}
优点
  • 简单灵活:宏定义非常简单,能快速定义常量或者进行简单的代码替换,无需考虑类型。
  • 无函数调用开销:由于宏只是简单的文本替换,不会产生函数调用的开销,在一些简单计算场景下能提高效率。
缺点
  • 缺乏类型检查:宏只是简单的文本替换,预处理器不会对其进行类型检查,容易引发错误。
  • 可能导致代码膨胀:如果宏在代码中被大量使用,会使代码体积增大,因为每次使用宏都会进行文本替换。
  • 存在副作用:带参数的宏可能会产生副作用,例如宏参数可能会被多次求值。
  • 不能调试
  • 容易出错:在一些涉及运算符优先级的问题上,有时候你少一个括号,多一个括号就会有不同的后果。

内联函数

内联函数是一种特殊的函数,在编译时,编译器会尝试把函数调用处用函数体替换,以此避免函数调用的开销。

语法
inline 返回类型 函数名(参数列表) {// 函数体
}
//内联函数其实就是原本的函数多加一个inline修饰
示例
#include <iostream>
// 定义一个内联函数
inline int add(int a, int b) {return a + b;
}int main() {int x = 3, y = 4;int sum = add(x, y);std::cout << "两数之和: " << sum << std::endl;return 0;
}
优点
  • 类型安全:内联函数是真正的函数,会进行类型检查,能减少因类型不匹配导致的错误。
  • 避免代码膨胀:虽然内联函数会在调用处展开,但编译器会根据具体情况决定是否真正内联,能避免不必要的代码膨胀。一般函数内容如果超过10行就不会展开了。
  • 代码可维护性高:内联函数和普通函数一样,有明确的函数定义和作用域,便于代码的维护和调试。
缺点
  • 编译器决策:是否真正内联由编译器决定,即使使用了 inline 关键字,编译器也可能不进行内联。
  • 不适合复杂函数:如果函数体比较复杂,内联可能会导致代码体积过大,反而降低性能。

宏定义和内联函数的区别

  • 处理阶段不同:宏定义在预处理阶段处理,只是简单的文本替换;内联函数在编译阶段处理,由编译器决定是否内联。
  • 类型检查:宏定义没有类型检查,内联函数有类型检查,更加安全。
  • 代码膨胀:宏定义容易导致代码膨胀,内联函数由编译器控制,能避免不必要的代码膨胀。
  • 调试难度:宏定义调试比较困难,因为预处理器替换后的代码可能和原始代码差异较大;内联函数和普通函数一样,调试相对容易。

下面这幅图就是假设函数内容是100行的时候,展开和不展开的时候反汇编的情况:(不严谨的)
在这里插入图片描述

这里补充一下,如果平时是分文件编写,那么内联函数声明和定义是不能分离的,也就是说不能你在头文件声明之后再去.c文件中定义,这里大家就在.h头文件里直接声明加定义写好就行了。因为虽说是内联函数,但是内联函数在编译链接的时候是直接展开的,不严谨的可以说他没有函数地址的,你要是声明和定义分离,到时候编译链接就会找不到你写的那个函数,明白嘛。

auto关键字

在这里插入图片描述

【注意】
使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。

auto的使用细则

  1. auto与指针和引用结合起来使用
    用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
    在这里插入图片描述
  2. 在同一行定义多个变量
    当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
void TestAuto(){auto a = 1, b = 2; auto c = 3, d = 4.0;  // 该行代码会编译失败,因为c和d的初始化表达式类型不同}

auto不能推导的场景

  1. auto不能作为函数的参数
  2. auto不能直接用来声明数组

这里没有为啥,这主要是C++祖师爷的规定。然后这个auto的作用其实就是当一个变量的类型名很长的时候可以不用写嘛,但是目前我们还没有接触到很长了,等到后面学了之后就会慢慢接触到了。

基于范围的for循环

这里注意使用这个范围for,数组大小一定得是确定了的。
在这里插入图片描述

指针空值nullptr

NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:


void TestPtr() {
int* p1 = NULL;
int* p2 = 0;
// ……
}


NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:
#ifndef NULL
#ifdef __cplusplus 
#define NULL    0 
#else 
#define NULL    ((void *)0)
#endif 
#endif

可以看到,NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。不论采取何种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦,比如:
在这里插入图片描述
所以以后定义空指针换成nullptr就ok。

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

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

相关文章

输入框仅支持英文、特殊符号、全角自动转半角 vue3

需求&#xff1a;封装一个输入框组件 1.只能输入英文。 2.输入的小写英文自动转大写。 3.输入的全角特殊符号自动转半角特殊字符 效果图 代码 <script setup> import { defineEmits, defineModel, defineProps } from "vue"; import { debounce } from "…

Uniapp:创建项目

目录 一、前提准备二、创建项目三、项目结构四、运行测试 一、前提准备 首先要创建uniapp项目&#xff0c;需要先下载HBuilderX&#xff0c;HBuilderX是一款开箱即用的工具&#xff0c;下载完毕之后&#xff0c;解压到指定的目录即可使用&#xff0c;需要注意的是最好路径里面…

ESM 内功心法:化解 require 中的夺命一击!

前言 传闻在JavaScript与TypeScript武林中,曾有两大绝世心法:CommonJS与ESM。两派高手比肩而立,各自称霸一方,江湖一度风平浪静。 岂料,时局突变。ESM逐步修成阳春白雪之姿,登堂入室,成为主流正统。CommonJS则渐入下风,功力不济,逐渐退出主舞台。 话说某日,一位前…

【STL】unordered_set

在 C C C 11 11 11 中&#xff0c; S T L STL STL 标准库引入了一个新的标准关联式容器&#xff1a; u n o r d e r e d _ s e t unordered\_set unordered_set&#xff08;无序集合&#xff09;。功能和 s e t set set 类似&#xff0c;都用于存储唯一元素。但是其底层数据结…

go语言八股文

1.go语言的接口是怎么实现 接口&#xff08;interface&#xff09;是一种类型&#xff0c;它定义了一组方法的集合。任何类型只要实现了接口中定义的所有方法&#xff0c;就被认为实现了该接口。 代码的实现 package mainimport "fmt"// 定义接口 type Shape inte…

kafka auto.offset.reset详解

在 Kafka 中&#xff0c;auto.offset.reset latest 的含义及行为如下&#xff1a; 1. ​​核心定义​​ 当消费者组​​首次启动​​或​​无法找到有效的 offset​​&#xff08;例如 offset 过期、被删除或从未提交&#xff09;时&#xff0c;消费者会从分区的​​最新位置…

深度学习-损失函数

目录 1. 线性回归损失函数 1.1 MAE损失 1.2 MSE损失 2. CrossEntropyLoss 2.1 信息量 2.2 信息熵 2.3 KL散度 2.4 交叉熵 3. BCELoss 4. 总结 1. 线性回归损失函数 1.1 MAE损失 MAE&#xff08;Mean Absolute Error&#xff0c;平均绝对误差&#xff09;通常也被称…

第六篇:linux之解压缩、软件管理

第六篇&#xff1a;linux之解压缩、软件管理 文章目录 第六篇&#xff1a;linux之解压缩、软件管理一、解压和压缩1、window压缩包与linux压缩包能否互通&#xff1f;2、linux下压缩包的类型3、打包与压缩 二、软件管理1、rpm1、什么是rpm&#xff1f;2、rpm包名组成部分3、如何…

Redis 键管理

Redis 键管理 以下从键重命名、随机返回键、键过期机制和键迁移四个维度展开详细说明&#xff0c;结合 Redis 核心命令与底层逻辑进行深入分析&#xff1a; 一、键重命名 1. ​RENAME​​ 与 ​RENAMENX​​ **RENAME key newkey​**&#xff1a; 功能&#xff1a;强制重命名…

OpenCV 模板匹配方法详解

文章目录 1. 什么是模板匹配&#xff1f;2. 模板匹配的原理2.1数学表达 3. OpenCV 实现模板匹配3.1基本步骤 4. 模板匹配的局限性5. 总结 1. 什么是模板匹配&#xff1f; 模板匹配&#xff08;Template Matching&#xff09;是计算机视觉中的一种基础技术&#xff0c;用于在目…

TextCNN 模型文本分类实战:深度学习在自然语言处理中的应用

在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;文本分类是研究最多且应用最广泛的任务之一。从情感分析到主题识别&#xff0c;文本分类技术在众多场景中都发挥着重要作用。最近&#xff0c;我参与了一次基于 TextCNN 模型的文本分类实验&#xff0c;从数据准备到…

Qt-创建模块化.pri文件

文章目录 一、.pri文件的作用与基本结构作用基本结构 二、创建.pri文件如何添加模块代码&#xff1f; 一、.pri文件的作用与基本结构 作用 在Qt开发中&#xff0c;.pri文件&#xff08;Project Include File&#xff09;是一种配置包含文件&#xff0c;用于模块化管理和复用项…

SpringCloud组件——Eureka

一.背景 1.问题提出 我们在一个父项目下写了两个子项目&#xff0c;需要两个子项目之间相互调用。我们可以发送HTTP请求来获取我们想要的资源&#xff0c;具体实现的方法有很多&#xff0c;可以用HttpURLConnection、HttpClient、Okhttp、 RestTemplate等。 举个例子&#x…

EAL4+与等保2.0:解读中国网络安全双标准

EAL4与等保2.0&#xff1a;解读中国网络安全双标准 在当今数字化时代&#xff0c;网络安全已成为各个行业不可忽视的重要议题。特别是在金融、政府、医疗等领域&#xff0c;保护信息的安全性和隐私性显得尤为关键。在中国&#xff0c;EAL4和等级保护2.0&#xff08;简称“等保…

FFmpeg+Nginx+VLC打造M3U8直播

一、视频直播的技术原理和架构方案 直播模型一般包括三个模块&#xff1a;主播方、服务器端和播放端 主播放创造视频&#xff0c;加美颜、水印、特效、采集后推送给直播服务器 播放端&#xff1a; 直播服务器端&#xff1a;收集主播端的视频推流&#xff0c;将其放大后推送给…

【Redis】缓存三剑客问题实践(上)

本篇对缓存三剑客问题进行介绍和解决方案说明&#xff0c;下篇将进行实践&#xff0c;有需要的同学可以跳转下篇查看实践篇&#xff1a;&#xff08;待发布&#xff09; 缓存三剑客是什么&#xff1f; 缓存三剑客指的是在分布式系统下使用缓存技术最常见的三类典型问题。它们分…

Flink 2.0 编译

文章目录 Flink 2.0 编译第一个问题 java 版本太低maven 版本太低maven 版本太高开始编译扩展多版本jdk 配置 Flink 2.0 编译 看到Flink2.0 出来了&#xff0c;想去玩玩&#xff0c;看看怎么样&#xff0c;当然第一件事&#xff0c;就是编译代码&#xff0c;但是没想到这么多问…

获取印度股票市场列表、查询IPO信息以及通过WebSocket实时接收数据

为了对接印度股票市场&#xff0c;获取市场列表、查询IPO信息、查看涨跌排行榜以及通过WebSocket实时接收数据等步骤。 1. 获取市场列表 首先&#xff0c;您需要获取支持的市场列表&#xff0c;这有助于了解哪些市场可以交易或监控。 请求方法&#xff1a;GETURL&#xff1a…

云原生--CNCF-1-云原生计算基金会介绍(云原生生态的发展目标和未来)

1、CNCF定义与背景 云原生计算基金会&#xff08;Cloud Native Computing Foundation&#xff0c;CNCF&#xff09;是由Linux基金会于2015年12月发起成立的非营利组织&#xff0c;旨在推动云原生技术的标准化、开源生态建设和行业协作。其核心目标是通过开源项目和社区协作&am…

【Rust 精进之路之第5篇-数据基石·下】复合类型:元组 (Tuple) 与数组 (Array) 的定长世界

系列&#xff1a; Rust 精进之路&#xff1a;构建可靠、高效软件的底层逻辑 作者&#xff1a; 码觉客 发布日期&#xff1a; 2025-04-20 引言&#xff1a;从原子到分子——组合的力量 在上一篇【数据基石上】中&#xff0c;我们仔细研究了 Rust 的四种基本标量类型&#xff1…