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

【C++】STL--String

这一节主要总结string类的常见接口,以及完成了string类的模拟实现。

目录

标准库的String类 

string类常见接口

string类对象的常见构造

string析构函数:~string

string类对象的容量操作

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

string类对象的修改操作

string类非成员函数

string类的模拟实现

经典的string类问题

浅拷贝

深拷贝

传统版写法的String类

现代版写法的String类

string类的模拟实现


标准库的String类 

为了符合C++面向对象的特性,引入了string类,string是表示字符串的字符串类。下面说明一下string类的特点:

1.string是表示字符串的字符串类

2.string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数

3.string类独立于所使用的编码来处理字节,如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。

提示: 在使用string类时,必须包含#include头文件以及using namespace std;

string类常见接口

string类对象的常见构造

(重点)1.string()

默认构造,构造空的string类对象,即空字符串

(重点)2.string(const string& str)

拷贝构造,使用str拷贝构造string类对象

(重点)3.string(const char* s)

使用C-string来构造string类对象

4.string(const string& str, size_t pos, size_t len=npos)

从str的第pos个位置,取len个字符构造,如果len超过字符串长度,那么只取到字符串末尾,如果len未给出,那么采用默认参数npos(0xFFFFFFFF)

5.string(const char* s, size_t n)

使用C-string的前n个字符来构造string类对象

6.string(size_t n, char c)

string类对象包含n个字符c

void test_string1()
{string s0;string s1("hello world");string s2(s1);string s3(s1, 5, 3);string s4(s1, 5, 10);string s5(s1, 5);string s6(10, '$');cout << s0 << endl;cout << s1 << endl;cout << s2 << endl;cout << s3 << endl;cout << s4 << endl;cout << s5 << endl;cout << s6 << endl;
}

string析构函数:~string

在string类对象生命周期结束时,会被自动调用。

string类对象的容量操作

1.size()和length()

这两个均可以返回字符串有效字符长度,功能一样。可以通过size遍历字符串。有两个功能一样的函数是由于历史原因造成的!

2.max_size() 

返回string最大的大小

3.capacity()

返回string类对象的容量大小。

//查看扩容机制
void test_string4()
{string s;size_t sz = s.capacity();cout << "capacity change:" << sz << endl;cout << "making s growing" << endl;for (int i = 0; i < 100; i++){s.push_back('c');if (sz != s.capacity()){sz = s.capacity();cout << "capacity changed" << sz << endl;}}
}

 

 虽然是15、31...,但是没有包括‘\0’,所以实际大小应该是16、32、48...,第一次是2倍扩容,以后每次是1.5倍扩容(VS平台下)。但是在Linux平台下,扩容机制不太一样:

这就说明,STL是一个标准,具体怎么实现由编译器决定! 

4.clear()

清除对象的数据,但是不会清空间。

 

 5.shrink_to_fit()

在clear()后,为了释放一些已开辟的空间,可以缩容

 

6.reserve()

如果提前知道要开辟空间的大小,可以用reserve()为字符串提前预留空间,防止频繁扩容,因为扩容一般是异地扩容,效率低下。

 避免了频繁扩容!

还有一个问题,reserve会不会缩容呢?不会的!当reserve()比capacity大,才会扩容!

7. resize()

调整字符串大小。

 

 如果采用第一种,那么默认用‘\0’插入,第二种用指定的char插入。

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

 1.operator[],返回pos位置的字符

string s1("hello world");
for (size_t i = 0; i < s1.size(); i++)
{cout << s1[i] << " ";
}

2.迭代器,begin+end,可以通过迭代器的方式遍历字符串,begin获取第一个字符的迭代器,end获取最后一个字符下一个位置的迭代器

string::iterator it1 = s1.begin();while (it1 != s1.end()){cout << *it1 << " ";++it1;}

我们感觉到迭代器很像指针,但是并不是指针!

3.rbegin+rend,支持倒着遍历,循环中用++rit,而不是--rit,对于反向迭代器而言,++就是倒着走

string s1("hello world");
string::reverse_iterator rit = s1.rbegin();
while (rit != s1.rend())
{cout << *rit << " ";++rit;
}

除了正向和反向的正常iterator外,还有正向和反向的const_iterator,是用来为const string构造迭代器,其特点是只能读不能写

//只读
const string s3("hello world");
string::const_iterator it3 = s3.begin();
while (it3 != s3.end())
{//*it3 += 3;//报错,因为只读cout << *it3 << " ";
}
cout << endl;
//string::const_reverse_iterator

4.用范围for遍历字符串 

for (auto s : s1){cout << s << " ";}

 但是范围for并没有什么特别之处,其底层是迭代器!

string类对象的修改操作

1.pushback()

在字符串末尾尾插字符

2.append()

在字符串后追加字符串

3.operator+=

在字符串后追加字符串str

4.assign()

用新内容覆盖原字符串

5.insert()

在某一个位置插入字符串

注意:insert()尽量不要使用,因为在使用过程中会挪动数据,效率低。

6.erase()

删除字符

同样,erase()函数能不用就不用。 

7.replace()

字符的替换 

8.find()

查找某个字符的位置

小练习:将一个字符串中的空格替换成“%20”。

总结一下,insert、erase、replace能少用就少用,因为基本都要挪动数据,效率不高。

9.c_str

返回C格式字符串

在C++程序中,我们有可能会调用C语言的函数,比如fopen函数,但是在程序中文件名可能是string对象,需要转换成C字符串才行。

void test_string()
{string filename("test.cpp");FILE* fout = fopen(filename.c_str(), "r");
}

10.find

找到某一个字符或字符串第一次出现的位置

例如:获取后缀

void test_string()
{string s1("test.cpp");size_t pos = s1.find('.');if (pos != string::npos){string suffix = s1.substr(pos);cout << suffix << endl;}else{cout << "没有后缀" << endl;}
}

11.rfind

从后往前找某一个字符或字符串第一次出现的位置

例如:获取后缀“file.c.tar.zip”的zip

void test_string()
{string s1("test.c.tar.zip");size_t pos = s1.rfind('.');if (pos != string::npos){string suffix = s1.substr(pos);cout << suffix << endl;}else{cout << "没有后缀" << endl;}
}

string类非成员函数

1.operator+

尽量少用,因为传值返回,导致深拷贝效率低

2.operator>>&&operator<<

输入和输出运算符重载

3.getline

获取一行字符串。弥补了cin>>的缺点,cin遇到了空格或者换行就提取结束。

4.==  != > >= < <=

大小比较

string类的模拟实现

经典的string类问题

首先来看一个经典关于浅拷贝的问题:

class String
{
public:
/*String()
:_str(new char[1])
{*_str = '\0';}
*/
//String(const char* str = "\0") 错误示范
//String(const char* str = nullptr) 错误示范,使用strlen时会涉及解引用
String(const char* str = "")
{// 构造String类对象时,如果传递nullptr指针,可以认为程序非if (nullptr == str){assert(false);return;}_str = new char[strlen(str) + 1];strcpy(_str, str);
}
~String()
{if (_str){delete[] _str;_str = nullptr;}
}
private:char* _str;
};
// 测试
void TestString()
{String s1("hello bit!!!");String s2(s1);
}

说明:在上面的String类中没有显式定义拷贝构造和赋值运算符重载,因此,当使用s1去构造时s2时,编译器会调用默认构造函数。这样导致的问题是,s1和s2指向同一块内存空间,在释放空间时,同一块空间会被释放两次而引起程序崩溃,这种拷贝方式,称为浅拷贝。

浅拷贝

浅拷贝:也称值拷贝,编译器只是将对象中的值拷贝过来。如果对象中管理资源,最后就会导致多个对象共享同一份资源,当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该资源已经被释放,以为还有效,所以当继续对资源进项操作时,就会发生发生了访问违规。

可以用深拷贝解决浅拷贝问题,也就是:每个对象都有一份独立的资源,不要和其他对象共享

深拷贝

如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给出。一般情况都是按照深拷贝方式提供。

传统版写法的String类

namespace ghs
{class string{public:string(const char* str=""):_size(strlen(str)){_str = new char[_size + 1];strcpy(_str, str);_capacity = _size;}string(const string& str){_str = new char[str._capacity + 1];strcpy(_str, str._str);_size = str._size;_capacity = str._capacity;}//s1 = s2string& operator=(const string& str){char* tmp = new char[str._capacity + 1];strcpy(tmp, str._str);delete[] _str;_str = tmp;_size = str._size;_capacity = str._capacity;return *this;}~string(){delete[] _str;_str = nullptr;_size = 0;_capacity = 0;}private:char* _str = nullptr;size_t _size = 0; size_t _capacity = 0;public:static const int npos;};const int string::npos = -1;
}

在传统版的写法中,拷贝构造和赋值构造都是通过自己手动开空间,然后使用strcpy函数拷贝完成的,下面的现代写法在实现上更为简洁: 

现代版写法的String类

namespace ghs
{class string{public:string(const char* str=""):_size(strlen(str)){_str = new char[_size + 1];strcpy(_str, str);_capacity = _size;}string(const string& s){string tmp(s._str);swap(tmp);}//s1 = s2//string& operator=(const string& str)//{//	string ss(str);//	swap(ss);//	return *this;//}//上面的再优化,这种更推荐string& operator=(string ss)//传值传参,调用拷贝构造{swap(ss);return *this;}~string(){delete[] _str;_str = nullptr;_size = 0;_capacity = 0;}private:char* _str = nullptr;size_t _size = 0; size_t _capacity = 0;public:static const int npos;};const int string::npos = -1;
}

在现代写法中,拷贝构造是通过调用string(const char* str="")构造函数来生成临时的string对象(tmp),再将*this和tmp交换,完成拷贝。在赋值构造中,使用传值传参,其实调用拷贝构造,生成临时对象ss,再将ss和*this交换,完成拷贝。

总结:传统版的现代版的效率一样,只是现代版调用了之前已经实现好的函数,所以看起来更加简洁!

string类的模拟实现
 

namespace ghs
{class string{public:/*string():_str(nullptr),_size(0),_capacity(0){}*//*string():_str(new char[1]),_size(0),_capacity(0){_str[0] = '\0';}*/typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}const_iterator begin()const{return _str;}const_iterator end()const{return _str + _size;}string(const char* str=""):_size(strlen(str)){_str = new char[_size + 1];strcpy(_str, str);_capacity = _size;}//string(const string& str)//{//	_str = new char[str._capacity + 1];//	strcpy(_str, str._str);//	_size = str._size;//	_capacity = str._capacity;//}string(const string& s){string tmp(s._str);swap(tmp);}//s1 = s2//string& operator=(const string& str)//{//	char* tmp = new char[str._capacity + 1];//	strcpy(tmp, str._str);//	delete[] _str;//	_str = tmp;//	_size = str._size;//	_capacity = str._capacity;//	return *this;//}string& operator=(const string& str){string ss(str);swap(ss);return *this;}//上面的再优化,这种更推荐//string& operator=(string ss)//传值传参,调用拷贝构造//{//	swap(ss);//	return *this;//}const char* c_str()const{return _str;}size_t size()const{return _size;}char& operator[](size_t pos){assert(pos < _size);return _str[pos];}void reserve(size_t sz){if (sz > _capacity){char* p = new char[sz + 1];strcpy(p, _str);delete[] _str;_str = p;_capacity = sz;}}void push_back(char ch){//扩容2倍/*if (_size == _capacity){reserve(_capacity == 0 ? 4 : 2 * _capacity);}_str[_size] = ch;_size++;_str[_size] = '\0';*/insert(_size, ch);}void append(const char* str){//扩容//size_t len = strlen(str);//if (_size + len > _capacity)//{//	reserve(_size + len);//}//strcpy(_str + _size, str);///*for (size_t i = 0; i < len; i++)//{//	push_back(str[i]);//}*///_size += len;insert(_size, str);}string& operator+=(char ch){push_back(ch);return *this;}string& operator+=(const char* str){append(str);return *this;}const char& operator[](size_t pos)const{assert(pos < _size);return _str[pos];}size_t capacity()const{return _capacity;}void insert(size_t pos, char ch){assert(pos <= _size);if (_size == _capacity){reserve(_capacity == 0 ? 4 : 2 * _capacity);}for (size_t end = _size+1; end > pos; end--){_str[end] = _str[end - 1];}_str[pos] = ch;_size++;}void insert(size_t pos, const char* str){assert(pos <= _size);size_t len = strlen(str);if (_size + len > _capacity){reserve(len + _size);}for (size_t end = _size+len; end > pos+len-1; end--){_str[end] = _str[end-len];}/*for (size_t i = 0; i < len; i++){_str[pos + i] = str[i];}*/strncpy(_str + pos, str, len);_size += len;}void erase(size_t pos, size_t len = npos){assert(pos < _size);if (len == npos ||  len>=_size-pos){_size = pos;_str[_size] = '\0';}else{strcpy(_str + pos, _str + pos + len);_size -= len;}}void resize(size_t n, char ch = '\0'){if (n <= _size){_str[n] = '\0';_size = n;}else{reserve(n);for (size_t i = _size; i < n; i++){_str[i] = ch;}_str[n] = '\0';_size = n;}}void swap(string& s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}size_t find(char ch, size_t pos = 0)const{assert(pos < _size);for (size_t i = pos; i < _size; i++){if (_str[i] == ch){return i;}}return npos;}size_t find(const char* str, size_t pos = 0)const{assert(pos < _size);char* tmp = strstr(_str+pos, str);if (tmp != nullptr){return tmp - _str;}else{return npos;}}string substr(size_t pos = 0, size_t len = npos){string s;if (len == npos || len >= _size-pos){for (size_t i = pos; i < _size; i++){s += _str[i];}}else{for (size_t i = pos; i < pos + len; i++){s += _str[i];}}return s;}void clear(){_size = 0;_str[_size] = '\0';}/*bool operator==(const string& str){int ret = strcmp(_str, str._str);return ret == 0;}*/~string(){delete[] _str;_str = nullptr;_size = 0;_capacity = 0;}private:char* _str = nullptr;size_t _size = 0; size_t _capacity = 0;public:static const int npos;};const int string::npos = -1;void swap(string& x, string& y){x.swap(y);}bool operator==(const string& s1,const string& s2){int ret = strcmp(s1.c_str(), s2.c_str());return ret == 0;}bool operator<(const string& s1, const string& s2){int ret = strcmp(s1.c_str(), s2.c_str());return ret < 0;}bool operator<=(const string& s1, const string& s2){return s1 < s2 || s1 == s2;}bool operator>(const string& s1, const string& s2){return !(s1 <= s2);}bool operator>=(const string& s1, const string& s2){return !(s1 < s2);}ostream& operator<<(ostream& out, const string& str){for (auto ch : str){out << ch; }return out;}istream& operator>>(istream& in, string& str){char ch;str.clear();//in >> ch;ch = in.get();char buff[100];size_t i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 99){buff[99] = '\0';str += buff;i = 0;}ch = in.get();}if (i > 0){buff[i] = '\0';str += buff;}return in; }istream& getline(istream& in, string& str){char ch;str.clear();char buff[100];//in >> ch;/*ch = in.get();while (ch != '\n'){str += ch;ch = in.get();}*/ch = in.get();size_t i = 0;while (ch != '\n'){buff[i++] = ch;if (i == 99){buff[99] = '\0';str += buff;i = 0;}ch = in.get();}if (i > 0){buff[i] = '\0';str += buff;}return in;}
}

相关文章:

【C++】STL--String

这一节主要总结string类的常见接口&#xff0c;以及完成了string类的模拟实现。 目录 标准库的String类 string类常见接口 string类对象的常见构造 string析构函数&#xff1a;~string string类对象的容量操作 string类对象的访问及遍历操作 string类对象的修改操作 s…...

深入理解与使用go之中间件--实现

深入理解与使用go之--中间件实现 目录 引子 中间件 定义 原理 简单实现 多个中间件 优化 扩展 gin框架实现 引子 我们在做web开发的时候,经常会遇到下面一些需求: 统计耗时:想程序内部统计某个路由的请求耗时 预处理:接口需要登录鉴权后才能继续进行 错误捕获:当…...

移动端研发技术的进化历程

移动端研发技术 移动端研发技术主要分为原生开发和跨平台开发。本章主要介绍一下移动开发技术的过去、当下和未来&#xff0c;一步一步介绍移动技术的进化历程。 原生开发 原生应用程序是指某一个移动平台&#xff08;比如iOS或Android&#xff09;所特有的应用&#xff0c;使…...

ChromeDriver 122 版本为例 国内下载地址及安装教程

ChromeDriver 国内下载地址 https://chromedriver.com/download 靠谱 千千万万别下载错了 先确认 Chrome 浏览器版本 以 win64 版本为例 那我们下载这一个啊&#xff0c;不要下载错了 下载地址贴在这哈 https://storage.googleapis.com/chrome-for-testing-public/122.0.…...

【数据结构】双向链表及LRU缓存的实现

目录 前言 1. 在原有的自定义链表类 Linked 的基础上&#xff0c;添加新的 “节点添加”方法 addNode(Node node) 测试用例 测试结果 2. 在自定义链表类的基础上&#xff0c;使用双重循环“强力” 判断两个节点是否发生相交 测试用例 测试结果 3. 在自定义链表类的基础上…...

2、计划任务不显示UI的问题

计划任务不显示UI的问题 1、原因&#xff1a; 在windows7以上系统&#xff0c;使用system权限启动的进程默认是没有ui界面&#xff0c;这是windows系统出于安全考虑的限制。防止用户在高权限下误删重要的文件。 2、解决方案&#xff1a; 1、降权 解决的办法&#xff1a;降…...

学C还是学C++?

计算机专业学生&#xff0c;大一上学期学习了C语言&#xff0c;下学期学校要学C&#xff0c;请问我寒假继续深入学习C还是提前学C,大佬们有什么建议吗&#xff1f;&#xff08;个人感觉C学的不是很明白&#xff0c;链表文件什么的还不是很懂…&#xff09; 这个并没有一个统一的…...

Springboot参数分组校验

Springboot参数分组校验 文章目录 Springboot参数分组校验简介代码准备单个或多个参数的校验非 JSON 格式的对象参数校验JSON 格式的对象参数校验Service 层校验项目地址 简介 Java API规范(JSR303)定义了Bean校验的标准validation-api&#xff0c;但没有提供实现。hibernate …...

无缝集成 MongoDB Relational Migrator,Tapdata 提供关系型到 MongoDB 实时迁移优化方案

在去年的 MongoDB 用户大会纽约站上&#xff0c;MongoDB 正式宣布全面推出新工具 MongoDB Relational Migrator&#xff08;MongoDB RM&#xff09;&#xff0c;用以简化应用程序迁移和转换——即从传统关系型数据模型到现代的文档数据模型&#xff0c;助力组织快速提升运营效率…...

【C++】每日一题 146 LRU缓存

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&#xff0c;否则返回 -1 …...

CentOS搭建NAS服务器并使用

CentOS搭建NAS服务器并使用 文章目录 前言一、配置NAS服务器安装 NFS 服务&#xff1a;启动 NFS 服务&#xff1a;使 NFS 服务在系统启动时自动启动&#xff1a; 二、挂载服务器三、常见错误以及解决方案1、mount.nfs: No route to host2、mount.nfs: access denied by server …...

爬虫入门到精通_框架篇16(Scrapy框架基本使用)_名人名言的抓取

1 目标站点分析 抓取网站&#xff1a;http://quotes.toscrape.com/ 主要显示了一些名人名言&#xff0c;以及作者、标签等等信息&#xff1a; 点击next&#xff0c;page变为2&#xff1a; 2 流程框架 抓取第一页&#xff1a;请求第一页的URL并得到源代码&#xff0c;进行下…...

mac inter 芯片遇到程序无法打开(无法验证开发者)

mac inter 芯片遇到程序无法打开&#xff08;无法验证开发者&#xff09; 解决方案 终端运行命令&#xff1a; sudo xattr -r -d com.apple.quarantine 文件路径(直接把文件拖入到终端&#xff0c;可以自动找到文件路径)即可令其获得权限 补充知识&#xff1a; 通过gpt可以…...

科技成果鉴定测试如何进行?第三方检测机构进行鉴定测试的好处

科技成果鉴定测试&#xff0c;作为科技领域中一项重要的质量检验手段&#xff0c;具有广泛的应用范围。旨在为科技成果的研发者和使用者提供客观、科学、权威的鉴定结果&#xff0c;从而评估科技成果的技术水平和市场竞争力。   科技成果鉴定测试是对科技成果进行系统、全面的…...

八、词嵌入语言模型(Word Embedding)

词嵌入&#xff08;Word Embedding, WE&#xff09;&#xff0c;任务是把不可计算、非结构化的词转换为可以计算、结构化的向量&#xff0c;从而便于进行数学处理。 一个更官方一点的定义是&#xff1a;词嵌入是是指把一个维数为所有词的数量的高维空间&#xff08;one-hot形式…...

重学SpringBoot3-WebMvcConfigurer接口

摘要&#xff1a; 本文详细介绍了SpringBoot 3中的WebMvcConfigurer接口&#xff0c;旨在帮助读者深入理解其原理和实现&#xff0c;从而能够更好地使用SpringBoot进行Web开发。阅读本文需要大约30分钟。 关键词&#xff1a;SpringBoot, WebMvcConfigurer, SpringMVC, Web开发…...

《深入理解springCloud与微服务》笔记

第一章 微服务介绍 1.3 微服务的不足 1.3.2 分布式事务 CAP 理论&#xff0c;即同时满足“一致性”“可用性”和“分区容错”是 件不可能的事。 Consistency &#xff1a;指数据的强一致性。如果写入某个数据成功&#xff0c;之后读取&#xff0c;读到的都是新写入的数据&a…...

Vivado原语模板

1.原语的概念 原语是一种元件! FPGA原语是芯片制造商已经定义好的基本电路元件,是一系列组成逻辑电路的基本单元,FPGA开发者编写逻辑代码时可以调用原语进行底层构建。 2.原语的分类 原语可分为预定义原语和用户自定义原语。预定义原语为如and/or等门级原语不需要例化,可以…...

【linux本地安装tinycudann包教程】

【linux本地安装tinycudann包教程】 tiny-cuda-nn官网链接 如果你是windows 10系统的,想要安装tiny-cuda-nn可以参考我的文章——windows 10安装tiny-cuda-n包 根据官网要求:C++要求对应14,其实这样就已经告诉我们linux系统中的gcc版本不能高于9,同时下面又告诉我们gcc版…...

使用Nginx进行负载均衡

什么是负载均衡 Nginx是一个高性能的开源反向代理服务器&#xff0c;也可以用作负载均衡器。通过Nginx的负载均衡功能&#xff0c;可以将流量分发到多台后端服务器上&#xff0c;实现负载均衡&#xff0c;提高系统的性能、可用性和稳定性。 如下图所示&#xff1a; Nginx负…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...