【C++】标准库:介绍string类
string
- 一.string类介绍
- 二.string类的静态成员变量
- 三.string类的常用接口
- 1.构造函数(constructor)
- 2.析构函数(destructor)
- 3.运算符重载(operator)
- 1.operator=
- 2.operator[]
- 3.operator+=
- 4.operator+
- 4.string的四种迭代器(iterator)
- 1.正向迭代器 iterator
- 2.反向迭代器 reverse_iterator
- 3.const修饰的正向迭代器 const_iterator
- 4.const修饰的反向迭代器 const_reverse_iterator
- 5.四种迭代器源代码
- 5.string类对象的容量操作
- 6.string类对象的修改操作
- 7.string类对象的查找操作
- 8.string类对象的遍历操作
- 1.下标 + []
- 2.迭代器
- 3.auto和范围for
- 1.auto关键字
- 2.范围for
- 四.非成员函数:getline()
- 五.string——>OJ题
一.string类介绍
C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
C++中将string封装为单独的类,string 类是 C++ 标准库中的一个非常重要的类,用于表示和操作字符串。string类位于命名空间std(标准库)下,使用string类记得加上头文件#include,并且使用命名空间using namespace std或者using std::string。
//使用时记得加上
#include<string>
using std::string;//或者using namespace std;//源代码大致框架
namespace std
{class string{private:char* _str;size_t _size;size_t _capacity;};
}
二.string类的静态成员变量
静态成员变量:static const size_t npos = -1;
int main()
{//static const size_t npos = -1;//typedef unsigned long long size_t//-1的原码:10000000 00000000 00000000 00000001//-1的反码:11111111 11111111 11111111 11111110//-1的补码:11111111 11111111 11111111 11111111//npos:-1的补码按照无符号整形打印出的值,由于静态成员变量,类外使用时加上类域cout << string::npos << endl;//32位环境:4294967295return 0;
}
三.string类的常用接口
1.构造函数(constructor)
无参构造:string(); 构造空的string类对象,即空字符串。常用。有参构造:string (const char* s); 用常量字符串来构造string类对象常用。拷贝构造:string (const string& str); 用str拷贝构造string类对象常用。- string (const string& str, size_t pos, size_t len = npos); 构造从下标pos开始,长度为len的子串,含缺省参数npos。
- string (const char* s, size_t n); 构造前n个字符组成的子串。
- string (size_t n, char c); 构造n个字符c组成的字符串。
int main()
{string s1;string s2("hello xzy");string s3(s2);string s4(s2, 6, 8);string s5("hello xzy", 5);string s6(10, 'x');cout << s1 << endl;//输出:cout << s2 << endl;//输出:hello xzycout << s3 << endl;//输出:hello xzycout << s4 << endl;//输出:xzycout << s5 << endl;//输出:hellocout << s6 << endl;//输出:xxxxxxxxxxreturn 0;
}
2.析构函数(destructor)
~string(); 程序结束前自动调用,释放堆区动态开辟的资源
3.运算符重载(operator)
1.operator=
-
string& operator= (const string& str); 常用。 -
string& operator= (const char* s);
-
string& operator= (char c);
int main()
{string s1;string s2;string s3;//赋值重载s1 = "hello xzy";s2 = s1;s3 = 'v';//拷贝构造string s4 = s1;cout << s1 << endl;//输出:hello xzycout << s2 << endl;//输出:hello xzycout << s3 << endl;//输出:vcout << s4 << endl;//输出:hello xzyreturn 0;
}
2.operator[]
char& operator[] (size_t pos); 返回字符引用,用于下标访问,且可以修改。常用。
int main()
{string s1("hello xzy");s1[6] = 'w';s1[7] = 'j';s1[8] = '\0';cout << s1 << endl;//输出:hello wjs1[10] = 'A';//下标越界,内部断言assert报错return 0;
}
3.operator+=
string& operator+= (const string& str); 常用。- string& operator+= (const char* s);
- string& operator+= (char c);
int main()
{string s1("hello xzy");string s2(" how are you");s1 += s2;cout << s1 << endl;s1 += "???";cout << s1 << endl;s1 += '!';cout << s1 << endl;return 0;
}

4.operator+
- string operator+ (const string& lhs, const string& rhs);
- string operator+ (const string& lhs, const char* rhs);
- string operator+ (const char* lhs, const string& rhs);
int main()
{string s1("hello");string s2 = s1 + " world";string s3 = "xzy " + s1;string s4 = s2 + s3;cout << s2 << endl; //hello worldcout << s3 << endl; //xzy hellocout << s4 << endl; //hello worldxzy helloreturn 0;
}
4.string的四种迭代器(iterator)
迭代器是一种用于遍历容器元素的对象(并非类,而是设计模式中的一种行为模式),它提供了一种通用的访问容器元素的方式,无论容器的类型和数据结构如何。迭代器在C++标准库中被广泛使用,特别是在处理如vector、list、map等容器时。
1.正向迭代器 iterator
返回正向迭代器:可以修改字符串。
iterator begin(); 返回字符串的第一个字符。iterator end(); 返回字符串最后一个有效字符(不含\0)的下一个字符。

2.反向迭代器 reverse_iterator
返回反向迭代器:可以修改字符串。
reverse_iterator rbegin(); 返回字符串最后一个有效字符(不含\0)。reverse_iterator rend(); 返回字符串第一个字符的前一个字符。

3.const修饰的正向迭代器 const_iterator
返回const修饰的正向迭代器:不可以修改字符串。
const_iterator begin() const;const_iterator end() const;
4.const修饰的反向迭代器 const_reverse_iterator
返回const修饰的反向迭代器:不可以修改字符串。
const_reverse_iterator rbegin() const;const_reverse_iterator rend() const;

5.四种迭代器源代码
int main()
{string s1("hello xzy");string::iterator it = s1.begin();while (it != s1.end()){cout << *it << " ";++it;}cout << endl;string s2("hello xzy");string::reverse_iterator rit = s2.rbegin();while (rit != s2.rend()){cout << *rit << " ";++rit;}cout << endl;const string s3("hello xzy");string::const_iterator cit = s3.begin();while (cit != s3.end()){//*cit += 2; s3不能修改cout << *cit << " ";++cit;}cout << endl;const string s4("hello xzy");string::const_reverse_iterator crit = s4.rbegin();while (crit != s4.rend()){//*crit += 2; s4不能修改cout << *crit << " ";++crit;}cout << endl;return 0;
}

5.string类对象的容量操作
size_t size() const; 返回字符串有效字符长度(不包括\0)。常用。- size_t length() const; 返回字符串有效字符长度(不包括\0)。
size_t capacity() const; 返回空间总大小(不包括\0)。常用。void resize (size_t n); 为字符串预留大于等于n的空间(不包括\0),避免扩容,提高效率。常用。void clear(); 清空数据,但是一般不清容量。常用。bool empty() const; 判断是否为空。常用。- void resize (size_t n); 只保留前n个数据。
- void resize (size_t n, char c); 保留前n个数据,若n大于容量,后面用字符c补上。
注意:
-
size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
-
clear()只是将string中有效字符清空,不改变底层空间大小。
-
resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用 ‘\0’ 来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
-
reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。
-
在VS2022中的容量变化:有效数据小于16时,数据存放在_buff中,无需扩容;当有效数据大于等于16时,数据存放在_str中,先2倍扩容一次,之后1.5倍扩容。
-
再linux中的g++编译器中的容量变化:数据只存放在_str中,容量不足就2倍扩容,感觉相当完美!
//在VS2022下的string类
class string
{
private:char* _buff[16]; //有效数据小于16,存放在这里char* _str; //有效数据大于等于16,存放在这里size_t _size;size_t capacity;
};
int main()
{string s;size_t sz = s.capacity();cout << "capacity changed: " << sz << '\n';cout << "making s grow:\n";for (int i = 0; i < 100; ++i){s.push_back('c');if (sz != s.capacity()){sz = s.capacity();cout << "capacity changed: " << sz << '\n';}}cout << "VS2022下的string类的大小:" << sizeof(s) << endl;return 0;
}

int main()
{string s1("hello xzy how are you");cout << s1.length() << endl; //21cout << s1.size() << endl; //21cout << s1.max_size() << endl; //2147483647cout << s1.capacity() << endl; //31string s2("hello xzy how are you");s2.reserve(100);//扩容:不一定扩100,但一定大于等于n,取决于编译器,Linux中的g++编译器扩的是100cout << s2.empty() << endl; //0cout << s2.capacity() << endl; //111s2.shrink_to_fit(); //缩容cout << s2.capacity() << endl; //31string s3("hello xzy how are you");s3.resize(9);cout << s3 << endl; //hello xzys3.resize(15, 'w');cout << s3 << endl; //hello xzywwwwwwreturn 0;
}
6.string类对象的修改操作
- void push_back (char c); 在字符串后尾插字符c。
- void pop_back(); 在字符串尾删一个字符。
- string& append (const string& str); 在字符串后追加一个字符串。
- string& assign (const string& str, size_t subpos, size_t sublen); 拷贝字符串:从下标为subpos开始,拷贝长度为sublen的字符串到string类对象里面。
- string& insert (size_t pos, const string& str); 在pos位置处插入字符串到string类对象里面。(
由于效率问题(移动数据),谨慎使用)。 - string& erase (size_t pos = 0, size_t len = npos); 从pos位置开始删除长度为npos个字符。(
由于效率问题(移动数据),谨慎使用)。 - string& replace (size_t pos, size_t len, const string& str); 从pos位置开始的长度为len的子串,替换为str。(
伴随着插入与删除,效率低,谨慎使用)。 void swap (string& str); 交换字符串。
int main()
{string s1("hello xzy");s1.push_back('!');cout << s1 << endl; //hello xzy!s1.pop_back();cout << s1 << endl; //hello xzys1.append(" how are you");cout << s1 << endl; //hello xzy! how are you//可以用+=取代尾插s1 += "???";cout << s1 << endl; //hello xzy! how are you???string s2("hello xzy!!!");string s3;s3.assign(s2, 6, 3);cout << s3 << endl; //xzystring s4("hello xzy");s4.insert(0, "hello wj ");cout << s4 << endl; //hello wj hello xzystring s5("hello xzy!!!");s5.erase(9, 2);cout << s5 << endl; //hello xzy!string s6("hello xzy!!!");s6.replace(6, 5, "wj");cout << s6 << endl; //hello wj!string s7("hello x hello x");string tmp;tmp.reserve(s7.size());for (auto ch : s7){if (ch == 'x')tmp += "wj";elsetmp += ch;}cout << tmp << endl; //hello wj hello wjs7.swap(tmp);cout << s7 << endl; //hello wj hello wjreturn 0;
}
const char* c_str() const; 返回C格式字符串。方便调用C中的接口。
int main()
{string file;cin >> file;//c_str()函数用于调用C语言的函数,若直接传string,类型不符合(类和指针)FILE* fout = fopen(file.c_str(), "r");if (fout == NULL){perror("open file fail!");exit(1);}char ch = fgetc(fout);while (ch != EOF){cout << ch;ch = fgetc(fout);}fclose(fout);fout = NULL;return 0;
}
7.string类对象的查找操作
string substr (size_t pos = 0, size_t len = npos) const; 找子串:返回从pos位置开始,长度为npos的string类。size_t find (char c, size_t pos = 0) const; 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置。size_t rfind (char c, size_t pos = npos) const; 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置。- size_t find_first_of (const char* s, size_t pos = 0) const; 从字符串pos位置开始
从前往后找字符串s中出现的字符,返回该字符在字符串中的位置。 - size_t find_last_of (const char* s, size_t pos = npos) const; 从字符串pos位置开始
从后往前找字符串s中出现的字符,返回该字符在字符串中的位置。 - size_t find_first_not_of (const char* s, size_t pos = 0) const; 从字符串pos位置开始
从前往后找字符串s中没有出现的字符,返回该字符在字符串中的位置。 - size_t find_last_not_of (const char* s, size_t pos = npos) const; 从字符串pos位置开始
从后往前找字符串s中没有出现的字符,返回该字符在字符串中的位置。
int main()
{//suffix:后缀string s1("test.cpp");size_t pos1 = s1.find(".");string suffix1 = s1.substr(pos1);cout << suffix1 << endl; //.cppstring s2("test.cpp.zip");size_t pos2 = s2.rfind(".");string suffix2 = s2.substr(pos2);cout << suffix2 << endl; //.zipstring s3("hello xzy");size_t found = s3.find_first_of("xzy");while (found != string::npos){s3[found] = '*';found = s3.find_first_of("xzy", found + 1);}cout << s3 << endl; //hello ***string str1("/user/bin/man");cout << endl << str1 << "的路径名与文件名如下:" << endl;size_t found1 = str1.find_last_of("/\\");cout << "path:" << str1.substr(0, found1) << endl;cout << "file:" << str1.substr(found1 + 1) << endl;string str2("c:\\windows\\winhelp.exe");cout << endl << str2 << "的路径名与文件名如下:" << endl;size_t found2 = str2.find_last_of("/\\");cout << "path:" << str2.substr(0, found2) << endl;cout << "file:" << str2.substr(found2 + 1) << endl;return 0;
}
8.string类对象的遍历操作
1.下标 + []
int main()
{string s1("hello xzy");//1.下标+[]for (int i = 0; i < s1.size(); i++){s1[i] += 2;//可以修改cout << s1[i] << " ";}cout << endl << s1 << endl;return 0;
}

2.迭代器
int main()
{string s1("hello xzy");//2.迭代器string::iterator it = s1.begin();while (it != s1.end()){*it += 2;//可以修改cout << *it << " ";++it;}cout << endl << s1 << endl;return 0;
}

3.auto和范围for
int main()
{string s1("hello xzy");//3.范围for:字符赋值,自动迭代,自动判断结束// 底层就是迭代器for (auto ch : s1){ch += 2;//修改ch对于s1无影响,ch是它的拷贝cout << ch << ' ';}cout << endl << s1 << endl;return 0;
}

int main()
{string s1("hello xzy");for (auto& ch : s1)//引用:取别名,就可以修改s1{ch += 2;cout << ch << ' ';}cout << endl << s1 << endl;return 0;
}

1.auto关键字
-
在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,后来这个不重要了。C++11中,标准委员会变废为宝赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个
新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期 推导而得。 -
用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&。
-
当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
-
auto不能作为函数的参数,可以做返回值,但是建议谨慎使用。
-
auto不能直接用来声明数组。
#include<map>
//auto不能做参数
//void func1(auto a) error
//{}//auto可以做返回值,但是建议谨慎使用
auto func2()
{return 2;
}int main()
{int a = 10;auto b = a;//编译期间自动推导类型auto c = 'a';auto d = func2();//auto e; auto必须初始化,否则不知道开多少空间int x = 10;auto y = &x;auto* z = &x;//可以不写*auto& m = x;//必须加上&auto aa = 1, bb = 2;//right//auto cc = 3, dd = 4.0; error必须始终推导为同一类型//auto array[] = { 4, 5, 6 }; error数组不能具有其中包含“auto”的元素类型// auto 的价值map<string, string> dict; //初始化二叉树//map<string, string>::iterator mit = dict.begin();auto mit = dict.begin();cout << typeid(mit).name() << endl;return 0;
}

2.范围for
-
对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围,自动迭代,自动取数据,自动判断结束。
-
范围for可以作用到数组和容器对象上进行遍历。
-
范围for的底层很简单,容器遍历实际就是替换为迭代器,这个从汇编层也可以看到。
int main()
{int array[] = { 1, 2, 3, 4, 5 };//范围for适用于《容器》和《数组》// C++98的遍历for (int i = 0; i < sizeof(array) / sizeof(array[0]); i++){cout << array[i] << ' ';}cout << endl;// C++11的遍历for (auto& i : array){cout << i << ' ';}cout << endl;return 0;
}
四.非成员函数:getline()
istream& getline (istream& is, string& str, char delim); delim:分隔符istream& getline (istream& is, string& str);
类似C语言中的scanf(“%s”, str),但是其遇到空格会停止;
C++中引入了getline优化了scanf遇到的问题,默认遇到\n才停止,也可以自定义停止字符delim。
例题:字符串最后一个单词的长度

#include <iostream>
#include<string>
using namespace std;int main()
{string str;getline(cin, str);size_t pos = str.rfind(' ');string sub = str.substr(pos + 1);cout << sub.size() << endl;
}
五.string——>OJ题
- 把字符串转换成整数(atoi)
- 字符串相加
- 反转字符串
- 字符串最后一个单词的长度
- 验证回文串
- 反转字符串||
- 字符串中的第一个唯一字符
- 反转字符串中的单词|||
- 字符串相乘
相关文章:
【C++】标准库:介绍string类
string 一.string类介绍二.string类的静态成员变量三.string类的常用接口1.构造函数(constructor)2.析构函数(destructor)3.运算符重载(operator)1.operator2.operator[]3.operator4.operator 4.string的四…...
未来不会使用 AI 的人真的会被淘汰吗?
AI 是今年大火的一个话题,随着 ChatGPT 之类的一系列大模型开始流行以后,有不少的培训机构宣称这样的口号: “未来不会使用 AI 的人将会被淘汰”。我觉得这个观点本身并没有错,但是关键在于那些培训机构出于自身的利益,故意忽略了…...
K8S及Rancher部署
前言 这篇文写的有点子啰嗦,甚至为了控制篇幅我还分出了其他好几篇文章,只在本文中保留了我认为必须存在。而之所以篇幅这么长,一方面是我在相关领域完全新手,啥啥都不会;而另一方面是我所参考的资料都过于精简&#…...
Qt Creator使用git管理代码
1.在GitHub中新建仓库,设置好仓库名后,其它的设置默认即可。 2.打开git bash,输入以下命令: git config --global user.name "xxxxx" #设置你的GitHub用户名 git config --global user.email "xxxxxxxxx.…...
pandas教程:pandas读取csv文件并指定字段数据类型
文章目录 pandas指定数据类型处理数据类型错误parse_dates参数pandas数据类型处理示例pandas指定数据类型 在读取csv文件时,我们可以使用dtype参数来指定每个列的数据类型。这个参数接受一个字典类型的值,其中键是列名,值是数据类型。数据类型可以是Pandas类型或NumPy类型,…...
c#中使用数据验证器
前言 在很多情况下,用户的输入不一定满足我们的设计要求,需要验证输入是否正确,传统的方案是拿到控件数据进行逻辑判定验证后,给用户弹窗提示。这种方法有点职责延后的感觉,数据视图层应该很好的处理用户的输入。使用…...
Java真人版猫爪老鼠活动报名平台系统
🐾“真人版猫爪老鼠活动报名平台系统”——趣味追逐,等你来战!🐭 🐱【萌宠变主角,现实版趣味游戏】 厌倦了电子屏幕的虚拟游戏?来试试“真人版猫爪老鼠活动”吧!在这个平台上&…...
Git原理与用法系统总结
目录 Reference前言版本控制系统Git的诞生配置Git配置用户名和邮件配置颜色配置.gitignore文件 Git的基础用法初始化仓库克隆现有的仓库添加暂存文件提交变动到仓库比较变动查看日志Git回退Git重置暂存区 Git版本管理重新提交取消暂存撤销对文件的修改 Git分支Git分支的优势Git…...
连载|浅谈红队中的权限维持(六)-Linux 主机后门与Linux 隐藏文件
本文来源无问社区,更多实战内容,渗透思路可前往查看http://www.wwlib.cn/index.php/artread/artid/11584.html 0x01 Linux 主机后门 1、添加用户 一句话添加用户 useradd test;echo -e "123456n123456n" |passwd test 或者使用 openssl …...
tomato-靶机渗透
tomato-靶机 一、安装靶机环境 下载双击.ova文件,写文件名路径导入 打开虚拟机用NAT模式 编辑–>虚拟网络编辑器查看IP段 二、信息收集 1.御剑端口扫描查找该虚拟机的IP 访问网站 扫目录 dirb http://192.168.30.130 收集到目录 /server-status /antibot_im…...
git的配置使用
第三周 Tursday 早 git日志的安装使用 [rootweb ~]# yum -y install git.x86_64 //安装软件包 [rootweb ~]# rpm -ql git //查看git的包 [rootweb ~]# mkdir /yy000 //创建新目录 [rootweb ~]# cd /yy000/ [rootweb yy000]# git init //将当前目录做为仓库…...
【1.0】drf初识
【1.0】drf初识 【一】前后端开发模式 【1】前后端混合开发 【示例】flask混合、django混合【案例】bbs项目 模板:dtl语法(django template language)模板语法 {{}} /{% %}后端渲染 qs对象–遍历循环到模板中–使用模板语法渲染渲染完成后 得到纯粹的…...
SparkSQL---编程模型的操作,数据加载与落地及自定义函数的使用
一、SparkSQL编程模型的创建与转化 1、DataFrame的构建 people.txt数据: 1 zhangsan 20 2 lisi 29 3 wangwu 25 4 zhaoliu 30 5 tianqi 35 6 kobe 40 people.json数据:在SparkSQL—简介及RDD V.S DataFrame V.S Dataset编程模型详解里 1、从Spark数据…...
文件解析漏洞--IIS--Vulhub
文件解析漏洞 一、IIS解析漏洞 用windowserver2003安装IIS测试 1.1 IIS6.X 方法一:目录解析 在网站下建立文件夹的名字为.asp/.asa的文件夹,其目录内的任何扩展名的文件都被IIS当作asp文件来解析并执行。 1.txt文件里是asp文件的语法查看当前时间 方…...
你知道缓存的这个问题到底把多少程序员坑惨了吗?
在现代系统中,缓存可以极大地提升性能,减少数据库的压力。 然而,一旦缓存和数据库的数据不一致,就会引发各种诡异的问题。 我们来看看几种常见的解决缓存与数据库不一致的方案,每种方案都有各自的优缺点 先更新缓存&…...
飞创直线模组桁架机械手优势及应用领域
随着工业自动化和智能制造的发展,直线模组桁架机械手极大地减轻了人类的体力劳动负担,在危险性、重复性高的作业环境中展现出了非凡的替代能力,引领着工业生产向自动化、智能化方向迈进。 一、飞创直线模组桁架机械手优势 飞创直线模组桁架…...
TongHttpServer 简介
1. 概述 随着网络技术的飞速发展,高并发大用户场景越来越普遍,单一应用服务节点已经不能满足并发需求,为了提高整个系统可靠性,扩展性,吞吐率,通常将多个应用服务器通过硬负载/软负载组成集群,负载均衡器根据不同负载算法将请求分发到各个应用服务器节点。 Tong…...
回溯法---组合总和
题目: 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限…...
将Android Library项目发布到JitPack仓库
将项目代码导入Github 1.将本地项目目录初始化为 Git 仓库。 默认情况下,初始分支称为 main; 如果使用 Git 2.28.0 或更高版本,则可以使用 -b 设置默认分支的名称。 git init -b main 如果使用 Git 2.27.1 或更低版本,则可以使用 git symbo…...
JAVAWeb实战(后端篇)
因为前后端代码内容过多,这篇只写后端的代码,前端的在另一篇写 项目实战一: 1.创建数据库,表等数据 创建数据库 create database schedule_system 创建表,并添加内容 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- ---------…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
