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

C字符串与C++ string 类:用法万字详解(上)

目录

引言

一、C语言字符串

1.1 创建 C 字符串

1.2 字符串长度

1.3 字符串拼接 

1.4 比较字符串

1.5 复制字符串

二、C++字符串string类

2.1 解释

2.2 string构造函数

2.2.1 string() 默认构造函数

2.2.2 string(const char* s) 从 C 风格字符串构造

2.2.3 string(const string& str) 拷贝构造函数

2.2.4 string(int n, char c) 从重复字符构造

2.3 string类对象的容量操作函数

2.3.1 size()与length() 获取字符串的有效字符长度

2.3.2 capacity()

2.3.3 empty() 判断是否为空串

2.3.4 clear() 清空有效字符

2.3.5 reserve()

2.3.6 resize()

2.4 string类对象的访问及遍历操作

2.4.1 operator[]

2.4.2 迭代器访问

① 正向迭代器

②反向迭代器

疑惑

2.4.3 范围for循环

拓展


引言

当我们踏入编程的神秘世界,就像是探险家踏上未知的大陆。C 字符串犹如传统的地图,指引着我们从简单中发现力量,然而小心不经意的错误,就像深不见底的陷阱。🗺️🧩

而在这个奇幻的编码森林中,std::string 类则犹如一颗闪亮的宝石,散发出现代的光辉。它是那把能解锁高级魔法的钥匙,让我们能够探索更广阔的创造领域。✨🔑

本文将引导你踏上探索之旅,穿越时间的长河,探索 C 字符串 🕰️ 和 C++ std::string 类 🚀 的异同。无论你是选择继续弹奏古老的旋律,还是驾驭现代的编码风潮,都能在这里找到属于你的启示。一起开启这段奇妙的编程之旅吧!🌌🌈

一、C语言字符串

当在 C 语言中处理字符串时,主要是使用字符数组来表示字符串,通常被称为 C 风格字符串。C 字符串是以 null 结尾的字符数组,使用字符指针来访问字符串的各个字符。以下是关于 C 字符串的一些基本概念和操作:

1.1 创建 C 字符串

C 字符串是由字符数组构成的,以 null 终止(也就是以字符 '\0' 表示字符串的结束)。

char str[] = "Hello, world!"; // 创建并初始化 C 字符串

 在上述代码中,char str[] = "Hello, world!"; 创建了一个字符数组 str 并初始化为 "Hello, world!"。这个字符数组的大小会自动根据初始化的内容进行分配,且在该变量的作用域结束后会自动释放,不需要显式地进行内存释放操作。

接下来我们介绍C中需要手动释放的案例:

#include <stdio.h>
#include <string.h>int main() {// 创建一个字符数组并初始化为"Hello"char *c_str = (char *)malloc(6 * sizeof(char));printf("C String: %s\n", c_str);// 错误:忘记释放分配的内存,导致内存泄漏// free(c_str);return 0;
}

1.2 字符串长度

C 字符串的长度是不包括 null 终止符的字符数。

char str[] = "Hello, world!";
int length = strlen(str); // 获取字符串长度(不包括 null 终止符)

1.3 字符串拼接 

在 C 语言中,拼接字符串需要使用库函数 strcat()注意,这需要预先分配足够大的内存来存放拼接后的字符串。

char str1[] = "Hello, ";
char str2[] = "world!";
char result[20]; // 预分配足够大的内存
strcpy(result, str1); // 复制第一个字符串
strcat(result, str2); // 拼接第二个字符串

1.4 比较字符串

使用库函数 strcmp() 可以比较两个字符串是否相等。

char str1[] = "apple";
char str2[] = "banana";
int result = strcmp(str1, str2); // 比较字符串,返回 0 表示相等

1.5 复制字符串

使用库函数 strcpy() 可以复制一个字符串到另一个字符串。

char source[] = "Copy this.";
char destination[20]; // 预分配足够的内存
strcpy(destination, source); // 复制 source 到 destination

二、C++字符串string类

当我们进入C++的世界,我们会遇到一个强大而便捷的工具,那就是std::string类。与C语言的字符数组不同,C++中的std::string为我们提供了更加安全和高效的字符串处理方式,让我们在编码的旅途中更加游刃有余。😊🎉

std::string类是C++标准库中的一员,它被设计用来处理字符串,不仅能够存储文本数据,还提供了丰富的方法来操作字符串,避免了C语言中处理字符串时的许多繁琐问题。使用std::string我们可以更专注于业务逻辑而不必担心内存管理和其他细节。✨💼

下面让我们一起来探索一下std::string的基本用法和一些特性,看看它是如何让我们摆脱繁琐的字符数组操作,更加轻松地处理字符串任务的。无论你是新手还是经验丰富的开发者,std::string都会成为你编程工具箱中的一把利器。🔧🚀

2.1 解释

介绍C++string之前,补充一些知识点!

string本质:

  • string是C++风格的字符串,而string本质上是一个类。

string和char * 区别:

  • char * 是一个指针。

  • string是一个类,类内部封装了char*,管理这个字符串,是一个char*型的容器。

  • std::string str;  // 创建一个空字符串
    

2.2 string构造函数

 如图所示是cplusplus官网string类的全部构造函数。

笔者将介绍其中主要使用的几种。

2.2.1 string() 默认构造函数

std::string str;  // 创建一个空字符串

2.2.2 string(const char* s) 从 C 风格字符串构造

const char* cstr = "Hello, world!";
std::string str(cstr);  // 从 C 风格字符串构造

2.2.3 string(const string& str) 拷贝构造函数

使用一个string对象初始化另一个string对象。

std::string original = "Hello, world!";
std::string str(original);  // 从另一个字符串构造

2.2.4 string(int n, char c) 从重复字符构造

std::string str(5, 'X');  // 创建由 5 个 'X' 组成的字符串

总结:string的多种构造方式没有可比性,灵活使用即可。

2.3 string类对象的容量操作函数

2.3.1 size()length() 获取字符串的有效字符长度

std::string 类中,size()length() 都是用来获取字符串的长度的成员函数,它们在功能上是等价的,可以互换使用。

std::string str = "Hello, world!";
int len = str.size();  // 获取字符串长度
std::string str = "Hello, world!";
int len = str.length();  // 获取字符串长度

这两个函数都返回一个 size_t 类型的值,表示字符串的字符数(不包括 null 终止符 \0)。它们的实际操作是相同的,只是函数名不同,你可以根据个人偏好选择使用哪个。

需要注意的是,size_t 是无符号整数类型,因此在使用 size()length() 返回的值时,要确保不会与负数进行比较或运算,以避免不必要的问题。

2.3.2 capacity()

std::string 类中,capacity() 是一个成员函数,用于获取字符串对象内部分配的存储容量(内存大小),而不仅仅是字符串的长度。这个函数对于了解和优化内存分配非常有用。 

当你创建一个 std::string 对象时,它会分配一块内存来存储字符串数据。capacity() 函数返回的值是这块内存能够容纳的字符数量(不包括 null 终止符 \0)。

std::string str = "Hello";
std::cout << "String length: " << str.length() << std::endl;  // 输出 5
std::cout << "String capacity: " << str.capacity() << std::endl;  // 输出至少 5

在上面的例子中,str 的长度是 5(包括 "Hello" 的字符),而 capacity() 函数可能会返回至少 5,但实际上会分配更多的内存,以便在需要时能够追加更多字符而不需要频繁重新分配内存。

2.3.3 empty() 判断是否为空串

std::string 类中,empty() 是一个成员函数,用于检查字符串是否为空,即字符串中是否没有字符。 

std::string str1 = "Hello";
std::string str2;bool is_str1_empty = str1.empty();  // 返回 false,因为 str1 不为空
bool is_str2_empty = str2.empty();  // 返回 true,因为 str2 为空

如上所示,empty() 函数会返回一个布尔值,表示字符串是否为空。如果字符串中没有字符(即长度为 0),则返回 true,否则返回 false

2.3.4 clear() 清空有效字符

 在 std::string 类中,clear() 是一个成员函数,用于清空字符串中的内容,使字符串变为空字符串。

std::string str = "Hello, world!";
std::cout << "Before clear: " << str << std::endl;str.clear();  // 清空字符串std::cout << "After clear: " << str << std::endl;  // 输出空字符串

在上述示例中,调用 str.clear() 后,字符串 str 的内容将被清空,变成了一个空字符串。注意,clear() 函数会保留内存分配,以便在后续操作中可能需要添加字符时不必重新分配内存。

2.3.5 reserve()

std::string 类中,reserve() 是一个成员函数,用于预分配字符串对象的内存空间,以便存储未来可能的字符。这个函数在需要高效管理内存分配和避免频繁的重新分配时非常有用。 

std::string str;
std::cout << "Before reserve: Capacity = " << str.capacity() << std::endl;str.reserve(100);  // 预分配至少能容纳 100 个字符的内存std::cout << "After reserve: Capacity = " << str.capacity() << std::endl;

在上面的例子中,我们首先创建了一个空字符串 str,然后使用 reserve() 函数预分配了至少能容纳 100 个字符的内存。这样,在后续添加字符时,不会频繁地进行内存重新分配,从而提高性能。

需要注意的是,reserve() 函数并不会改变字符串的长度,只是在内部分配足够的内存,以便在需要时可以高效地添加字符。如果你知道字符串的大致长度,使用 reserve() 可以帮助你减少内存重新分配的次数。

疑问:

如果参数比我现在的有效字符数还要小呢?如何处理?

如果给 reserve() 函数的参数值太小,它会根据情况进行内存分配,以确保能够容纳至少指定数量的字符。如果指定的值比当前字符串长度要小,那么 reserve() 将会忽略这个请求,因为当前内存已经足够容纳现有的字符。

以下是一个示例,演示了当给 reserve() 函数传递一个较小值时的行为:

#include <iostream>
#include <string>int main() {std::string str = "Hello, world!";std::cout << "Before reserve: Capacity = " << str.capacity() << std::endl;str.reserve(5);  // 预分配至少能容纳 5 个字符的内存std::cout << "After reserve: Capacity = " << str.capacity() << std::endl;return 0;
}

在这个示例中,尽管我们传递了 reserve(5),字符串的当前长度已经是 13("Hello, world!"),因此 reserve() 函数会保留当前的内存分配,不会将内存缩减到只能容纳 5 个字符,以保持已有的内容。

所以,如果 reserve() 函数的参数值比当前字符串长度小,函数会尽可能保留当前的内存分配,以适应现有的字符串内容。这种行为确保了已有内容不会被截断或丢失

2.3.6 resize()

std::string 类中,resize() 是一个成员函数,用于改变字符串的长度,同时可以选择如何填充新增的部分。 

#include <iostream>
#include <string>int main() {std::string str = "Hello";std::cout << "Before resize: " << str << std::endl;str.resize(10, '!');  // 将字符串长度改变为 10,多出部分用 '!' 填充std::cout << "After resize: " << str << std::endl;return 0;
}

在上面的例子中,我们首先创建了一个字符串 str,然后使用 resize() 函数将其长度改变为 10。如果指定的新长度大于当前长度,那么多出的部分将使用指定的字符(在这个例子中是 '!')进行填充。

如果指定的新长度小于当前长度,字符串将被截断,保留前面的字符,而多余的字符将被删除。

需要注意的是,resize() 函数可以接受两个参数:新的长度和用于填充的字符。如果只提供新的长度,函数会用 null 字符('\0')填充新增部分。

2.4 string类对象的访问及遍历操作

2.4.1 operator[]

 在 std::string 类中,operator[] 是一个用于访问字符串中特定位置字符的运算符重载。通过这个运算符,你可以直接访问字符串中的单个字符,就像访问数组元素一样。

#include <iostream>
#include <string>int main() {std::string str = "Hello, world!";char firstChar = str[0];  // 获取第一个字符 'H'char sixthChar = str[5];  // 获取第六个字符 ','std::cout << "First character: " << firstChar << std::endl;std::cout << "Sixth character: " << sixthChar << std::endl;return 0;
}

在上面的例子中,我们通过 str[0]str[5] 分别获取了字符串 str 的第一个和第六个字符。需要注意的是,字符串的索引是从 0 开始的,因此第一个字符的索引是 0。

如果使用 operator[] 访问超出字符串长度的索引,将会导致未定义的行为,因此在使用时需要确保索引的范围是有效的。

2.4.2 迭代器访问

① 正向迭代器

std::string 类中,你可以使用 begin() 函数获取一个指向字符串开头的迭代器,使用 end() 函数获取一个指向字符串结尾的迭代器的下一个位置。这些迭代器可以用于遍历字符串中的字符。

#include <iostream>
#include <string>int main() {std::string str = "Hello, world!";// 使用迭代器遍历字符串for (std::string::iterator it = str.begin(); it != str.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;// 使用 const 迭代器遍历字符串(不修改字符串内容)for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) {std::cout << *it << " ";}return 0;
}

在上述示例中,我们使用 begin()end() 函数获取了迭代器,然后使用迭代器遍历字符串中的字符。需要注意的是,end() 函数返回的迭代器指向字符串的结尾的下一个位置,因此在使用时应该注意边界。

如果你不需要修改字符串内容,建议使用 const 版本的迭代器(const_iterator,以便在遍历过程中不意外地修改字符串内容。

②反向迭代器

在 C++11 及更高版本中,std::string 提供了 rbegin()rend() 成员函数,它们分别返回一个反向迭代器,用于从字符串末尾向开头遍历字符串的字符。这对于需要从末尾开始遍历字符串的场景非常有用。

#include <iostream>
#include <string>int main() {std::string str = "Hello, world!";// 使用反向迭代器遍历字符串for (std::string::reverse_iterator it = str.rbegin(); it != str.rend(); ++it) {std::cout << *it << " ";}return 0;
}

在上述示例中,我们使用 rbegin()rend() 函数获取了反向迭代器,然后使用迭代器遍历字符串中的字符。rbegin() 返回一个指向最后一个字符的迭代器rend() 返回一个指向第一个字符前面的位置的迭代器。

需要注意的是,反向迭代器遍历的顺序是从字符串末尾向开头,因此输出结果将会从右往左显示字符串的字符。

当使用 const 版本的迭代器遍历字符串时,可以使用 crbegin()crend() 成员函数。这些函数返回的是 const 版本的反向迭代器,用于遍历字符串的字符,同时不允许修改字符串内容。

#include <iostream>
#include <string>int main() {const std::string str = "Hello, world!";// 使用 const 反向迭代器遍历字符串for (std::string::const_reverse_iterator it = str.crbegin(); it != str.crend(); ++it) {std::cout << *it << " ";}return 0;
}

总之,crbegin()crend() 是用于使用 const 反向迭代器遍历 std::string 字符的函数,适用于不允许修改字符串内容的场景。

疑惑

为什么反向迭代器更新也是使用递增运算符呢?

😄 良好的设计和一致性是C++标准库的重要支柱之一。在整个库中,无论是正向迭代器还是反向迭代器,它们都秉承着相似的操作方式,这样使用者能够更加轻松地理解和使用。

在C++中,递增操作符 ++ 的含义异常清晰:它让迭代器指向容器中的下一个元素。这一操作无论是用于正向迭代器还是反向迭代器,都保持一致。通过维持这种一致性,C++标准库让不同类型的迭代器都能够使用相似的方式操作,这极大地降低了学习和使用的难度。

举例来说,当你使用反向迭代器遍历字符串时,++ 操作将迭代器指向前一个字符,这样一来,正向迭代器和反向迭代器的操作行为就得以保持一致。这种一致性不仅增强了代码的可读性,还有助于提升代码的维护性。

总之,一致性和清晰的设计在C++标准库中扮演着重要角色,迭代器的 ++ 操作在不同类型的迭代器之间始终保持一致。这种一致性大大方便了使用者在容器中操作元素时的思维切换。🚀📘

2.4.3 范围for循环

C++11 引入了基于范围的 for 循环(Range-based for loop),可以方便地遍历容器(包括字符串)中的元素,包括 std::string

下面是如何使用范围 for 循环来遍历 std::string 中的字符的示例:

#include <iostream>
#include <string>int main() {std::string str = "Hello, world!";// 使用范围 for 循环遍历字符串中的字符for (char c : str) {std::cout << c << " ";}return 0;
}

在上述示例中,我们使用范围 for 循环直接遍历了字符串 str 中的字符,并将每个字符输出到控制台。范围 for 循环会自动迭代容器中的每个元素,并将其赋值给指定的变量。

需要注意的是,范围 for 循环中的变量类型应该与容器中的元素类型匹配。在遍历 std::string 时,可以使用 char 类型来匹配字符串中的字符。

拓展

当使用范围 for 循环遍历 std::string 中的字符时,你可以使用 auto 或者 const auto来更简洁地声明循环变量。这可以让代码更加清晰,同时减少了类型匹配的烦恼。

与此同时,必要时还可以加上&。

#include <iostream>
#include <string>int main() {std::string str = "Hello, world!";// 使用 auto 遍历字符串中的字符for (auto c : str) {std::cout << c << " ";}std::cout << std::endl;// 使用 const auto & 遍历字符串中的字符for (const auto &c : str) {std::cout << c << " ";}return 0;
}

在第一个范围 for 循环中,我们使用 auto 来自动推断循环变量的类型,这里会自动推断为 char。在第二个范围 for 循环中,我们使用 const auto &,它将循环变量声明为对字符的常量引用。

使用 const auto & 可以减少拷贝,特别是当处理容器内元素较大时,效率会有所提高。而使用 auto 则会进行元素的拷贝。

相关文章:

C字符串与C++ string 类:用法万字详解(上)

目录 引言 一、C语言字符串 1.1 创建 C 字符串 1.2 字符串长度 1.3 字符串拼接 1.4 比较字符串 1.5 复制字符串 二、C字符串string类 2.1 解释 2.2 string构造函数 2.2.1 string() 默认构造函数 2.2.2 string(const char* s) 从 C 风格字符串构造 2.2.3 string(co…...

async/await函数需要trycatch吗?

前言 写异步函数的时候&#xff0c;promise 和 async 两种方案都非常常见&#xff0c;甚至同一个项目里&#xff0c;不同的开发人员都使用不同的习惯, 不过关于两者的比较不是本文关注的重点&#xff0c;只总结为一句话&#xff1a;“async 是异步编程的终极解决方案”。 当使…...

Jenkins集成appium自动化测试(Windows篇)

一&#xff0c;引入问题 自动化测试脚本绝大部分用于回归测试&#xff0c;这就需要制定执行策略&#xff0c;如每天、代码更新后、项目上线前定时执行&#xff0c;才能达到最好的效果&#xff0c;这时就需要进行Jenkins集成。 不像web UI自动化测试可以使用无痕浏览器做到无界…...

MongoDB:切换log日志文件

可以不重启MongoDB&#xff0c;切换日志文件 use admin db.runCommand({logRotate:1})参考 MongoDB 日志切割三种方式...

代码随想录第三十五天

代码随想录第三十五天 Leetcode 860. 柠檬水找零Leetcode 406. 根据身高重建队列Leetcode 452. 用最少数量的箭引爆气球 Leetcode 860. 柠檬水找零 题目链接: 柠檬水找零 自己的思路:我的垃圾思路&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;复…...

块、行内块水平垂直居中

1.定位实现水平垂直居中 <div class"outer"><div class"test inner1">定位实现水平垂直居中</div></div><style>.outer {width: 300px;height: 300px;border: 1px solid gray;margin: 100px auto 0;position: relative;}.te…...

Mybatis引出的一系列问题-动态 SQL

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架&#xff0c;你应该能理解根据不同条件拼接 SQL 语句有多痛苦&#xff0c;例如拼接时要确保不能忘记添加必要的空格&#xff0c;还要注意去掉列表最后一个列名的逗号。利用动态 SQL&#xff0c;可以彻底…...

Docker学习之构建Base Image

构建Base Image 目标是构建一个类似官方Hello world的镜像&#xff0c;需要配置好Docker运行环境。 创建目录&#xff0c;编写代码 创建并进入docker目录。 mkdir docker cd dockertouch hello.cvim hello.chello.c文件的内容如下&#xff1a; #include <stdio.h>in…...

SFM(Structure from Motion)和NeRF(Neural Radiance Fields)

SFM&#xff08;Structure from Motion&#xff09;和NeRF&#xff08;Neural Radiance Fields&#xff09;都是计算机视觉领域中的重要算法&#xff0c;用于不同的任务和应用。 SFM&#xff08;Structure from Motion&#xff09;&#xff1a; SFM是一种从图像序列中重建三维场…...

[Vue] Vue2和Vue3的生命周期函数

vue2有11个生命周期钩子, vue3有8个生命周期钩子 从vue创建、运行、到销毁总是伴随着各种事件, 创建、挂载、更新到销毁。 1.vue2系列生命周期 ⑴【beforecreate】实例创建前。 vue完全创建之前&#xff0c;会自动执行这个函数。 ⑵【Created】实例创建后。 这也是个生命…...

springboot集成分布式任务调度系统xxl-job(调度器和执行器)

一、部署xxl-job服务端 下载xxl-job源码 下载地址&#xff1a; https://gitee.com/xuxueli0323/xxl-job 二、导入项目、创建xxl_job数据库、修改配置文件为自己的数据库 三、启动项目、访问首页 访问地址&#xff1a; http://localhost:8080/xxl-job-admin/ 账号&#xff1…...

11_Vue3中的新的组件

1. Fragment 在Vue2中&#xff1a;组件必须要有一个跟标签在Vue3中&#xff1a;组件可以没有根标签&#xff0c;内部会将多个标签包含在一个Fragment虚拟元素中好处&#xff1a;减少标签层级&#xff0c;减少内存占用 2. Teleport 什么是Teleport?——Teleport 是一种能够将…...

详解推送Git分支时发生的 cannot lock ref 错误

在码云上建了一个项目仓库,分支模型使用 git-flow ,并在本地新建了一个功能分支 feature/feature-poll。后来在推送时发生错误,提示 cannot lock ref ...... 这样的错误信息。下面复盘一下具体过程和解决办法,以供参考。 在码云中建立仓库时,考虑到想按照 GitFlow 的模式…...

[国产MCU]-BL602开发实例-PWM

PWM 文章目录 PWM1、BL602的PWM介绍2、PWM驱动API介绍3、PWM使用示例脉冲宽度调制(Pulse width modulation,简称PWM)是一种模拟控制方式,根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳定电源输出的改变。这种方…...

【JMeter】 使用Synchronizing Timer设置请求集合点,实现绝对并发

目录 布局设置说明 Number of Simulated Users to Group Timeout in milliseconds 使用时需要注意的点 集合点作用域 实际运行 资料获取方法 布局设置说明 参数说明&#xff1a; Number of Simulated Users to Group 每次释放的线程数量。如果设置为0&#xff0c;等同…...

无法对watchdog.sys等系统文件删除,弯道修复,这里解决办法很简单

右击360强力删除...

ClickHouse(九):Clickhouse表引擎 - Log系列表引擎

进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术&#xff0c;IT贫道_Apache Doris,Kerberos安全认证,大数据OLAP体系技术栈-CSDN博客 &…...

3.1 计算机网络和网络设备

数据参考&#xff1a;CISP官方 目录 计算机网络基础网络互联设备网络传输介质 一、计算机网络基础 1、ENIAC&#xff1a;世界上第一台计算机的诞生 1946年2月14日&#xff0c;宾夕法尼亚大学诞生了世界上第一台计算机&#xff0c;名为电子数字积分计算机&#xff08;ENIAC…...

值得中国人民大学与加拿大女王大学金融硕士中的金融人观看的五部电影

积金累玉的机会每个人都会把握&#xff0c;那么学习可以实现&#xff0c;生活娱乐一样可以。当电影遇见金融会产生怎样的化学变化呢&#xff1f;今天我们就带着这样的疑问来一起走进英国时报发布的经典电影&#xff0c;也是最值得中国人民大学与加拿大女王大学金融硕士中的金融…...

【数据库】Redis可以替代Mysql吗

Redis和Mysql的搭配 Redis可以替代Mysql吗什么是RedisRedis适用的场景以及优点Redis的缺点 什么是MysqlMysql的优点Mysql缺点 总结 Redis可以替代Mysql吗 Redis不能代替MySQL&#xff0c; Redis和MySQL只能是一种互补。 什么是Redis Redis是一种非关系型数据库&#xff0c;也…...

5 指针与多维数组:多维数组在内存中的存储与指针的关系

推荐最近在工作学习用的一款好用的智能助手AIRight 网址是www.airight.fun。 指针与多维数组&#xff1a;多维数组在内存中的存储与指针的关系 引言 多维数组是数据结构中常见且重要的概念&#xff0c;它是由多个一维数组组成的数据集合。在计算机内存中&#xff0c;多维数组…...

Spring 创建 Bean 的三种方式

在使用 Spring 框架后&#xff0c;对象以 Bean 的形式统一交给 IOC 容器去创建和管理。现阶段主流的方式是基于 SpringBoot 框架&#xff0c;基于注解的方式实现 Bean 的创建&#xff0c;但在原生 Spring 框架中其实存在三种创建 Bean 的方式。 一、基础类 BeanProcess 实体类…...

软工导论知识框架(五)面向对象方法学

传统软件工程方法学适用于中小型软件产品开发&#xff1b; 面向对象软件工程方法学适用于大型软件产品开发。 一.四要素 对象&#xff0b;类&#xff0b;继承&#xff0b;传递消息实现通信 二.概念 1.对象&#xff1a;具有相同状态的一组操作的集合&#xff0c;对状态和操作…...

MyBatisPlus代码生成器

首先需要mybaits-plus依赖和自动代码生成器依赖 <!-- mybatis-plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.0.5</version></dependency><!-…...

文件传输软件常见问题解决办法大全

文件传输软件是我们工作中不可缺少的一种工具&#xff0c;它可以帮助我们快速、安全、稳定地传输各种文件&#xff0c;如文档、图片、视频等。但是在使用文件传输软件的过程中&#xff0c;我们也可能会遇到一些问题&#xff0c;影响我们的工作效率和传输质量。那么&#xff0c;…...

springboot工程测试临时数据修改技巧

目录 properties临时属性测试注入 args临时参数测试注入 bean配置类属性注入&#xff08;Import&#xff09; SpringBootTest是一个注解&#xff0c;用于测试Spring Boot应用程序。它可用于指示Spring Boot测试应用程序的启动点&#xff0c;并为测试提供一个可用的Spring应用…...

Echarts 清空画布空白以及鼠标悬浮提示信息格式化问题

清空画布用clear()会导致图表空白 const option1 = this.myEchart1.getOption()const option2 = this.myEchart2.getOption()const option3 = this.myEchart3.getOption()// 清空数据option1.series = []option1.xAxis[0].data = []option2.series = []option2.xAxis[0].data …...

数据结构入门:栈

目录 前言 1. 栈 1.1栈的概念及结构 1.2 栈的实现 1.2.1 栈的定义 1.2.2 栈的初始化 1.2.3 入栈 1.2.4 出栈 1.2.5 栈的元素个数 1.2.6 栈顶数据 1.2.7 栈的判空 2.栈的应用 2.1 题目一&#xff1a;括号匹配 2.1.1 思路 2.1.2 分析 2.1.3 题解 总结 前言 无论你是计算机科学专…...

《UNUX环境高级编程》(14)高级I/O

1、引言 2、 非阻塞I/O 系统调用分为两类&#xff1a;低速系统调用和其他系统调用。低速系统调用是可能会使进程永远阻塞的一类系统调用&#xff0c;包括&#xff1a; 如果某些文件类型&#xff08;如读管道、终端设备和网络设备&#xff09;的数据并不存在&#xff0c;读操作…...

第5讲:如何构建类的方法

【分享成果&#xff0c;随喜正能量】在这个社会上&#xff0c;对别人好一点&#xff0c;多站在别人的角度考虑&#xff0c;不要为小事争执&#xff0c;不要取笑他人&#xff0c;不要在别人背后嚼舌根&#xff0c;更不能逼人太甚。凡事退一步&#xff0c;对你有好处。。 《VBA中…...

绵阳的网站建设公司哪家好/平台推广怎么做

一&#xff1a;J2SE 面向对象&#xff0d;封装、继承、多态 内存的分析 递归 集合类、泛型、自动打包与解包、Annotation IO 多线程、线程同步 TCP/UDP AWT、事件模型、匿名类 正则表达式 反射机制 2&#xff1a;数据库&#xff08;Oracle或者MySQL&#xff09; SQL…...

展览中心网站建设/百度网盘下载安装

2019独角兽企业重金招聘Python工程师标准>>> UIRequiresFullScreen: YES - 不使用Slide Over 和 Split View NO - 使用Slide Over 和 Split View 转载于:https://my.oschina.net/ilrrong/blog/720120...

如何开始做网站/百度趋势搜索

文件类文件 getParentFile()软件包java.io.File.getParentFile()中提供了此方法。此方法用于返回给定文件对象的父文件。此方法的返回类型为File(即&#xff0c;它返回给定文件对象的父文件&#xff0c;而父文件为File形式。语法&#xff1a;File getParentFile(){}参数&#x…...

免费创建自己的网站/seo优化培训公司

5G网络能够被广泛推行&#xff0c;主要原因是5G融合了很多关键技术&#xff0c;这些关键技术使得5G在很多方面具有得天独厚的优势&#xff0c;这些优势也使得5G会被广泛应用在新一代智慧物流行业中。 &#xff08;1&#xff09;高速度数据传输 5G需要在网络速度方面进行提升&…...

免费域名注册工具/上海网站排名seo公司

经济学中有个著名的结论&#xff0c;贸易可以让贸易双方都获益&#xff0c;这里我们用一个例子来说明&#xff0c;为什么是这样的。 分析如下&#xff1a; 馒头对于甲的价值: 0.5瓶啤酒&#xff1d;&#xff11;个馒头 馒头对于乙的价值: &#xff16;瓶啤酒&#xff1d;&…...

安徽黄山网站建设/百度seo入驻

朋友们&#xff0c;如需转载请标明出处&#xff1a;http://blog.csdn.net/jiangjunshow 在大多数时候&#xff0c;你是没有足够的图像来训练深度神经网络的。本文将教你如何从小样本数据快速学习你的模型。 为什么我们关心小样本学习&#xff1f; 1980年&#xff0c; Kunihiko…...