C++深入学习string类成员函数(3):访问与修饰

news2024/9/28 16:51:19

引言

       在 C++ 中,std::string 提供了丰富的成员函数来访问和修改字符串中的字符。通过这些函数,程序员可以灵活地处理字符串中的各个元素,无论是读取特定位置的字符,还是修改字符串的内容。此外,std::string 类还确保了访问的安全性和高效性,例如提供边界检查的函数以防止非法操作。理解这些元素访问与修饰的函数,是编写健壮、灵活的字符串操作代码的基础。

1.string类的元素访问函数

std::string类提供了多种元素访问函数,用来访问或修改字符串中的单个字符,主要的访问函数如下:

1.1 at() 与 front()

1.1.1 at()

       at() 用于通过索引(也称下标)访问字符串中的字符。与 operator[] 不同,at()执行边界检查,如果索引超出范围,会抛出 std::out_of_range 异常,从而提高了操作的安全性。

(1)函数原型 

    char& at (size_t pos);
const char& at (size_t pos) const;

- 通过索引 pos 访问字符串中的字符。
- 如果索引合法,返回对应位置的字符引用。
- 如果索引超出范围,抛出 out_of_range 异常。

(2)示例代码 

#include <iostream>
using namespace std;

int main() 
{
	string str = "Hello";

	// 安全地访问字符串中的字符
	try 
	{
		str.at(1) = 'a'; // 修改字符
		cout << str << endl; // 输出 "Hallo"

		// 尝试访问越界的字符,抛出异常
		cout << str.at(10) << endl;
	}
	catch (const out_of_range& e) 
	{
		cerr << "Exception: " << e.what() << endl;
	}

	return 0;
}

(3)优缺点 

优点:提供了边界检查,防止索引超出字符串长度时导致未定义行为。适用于需要严格检查的场景,尤其是在用户输入或动态索引时。

缺点:较 operator[] 稍慢,因为多了一步边界检查。

1.1.2 operator[] (下标操作符)

      operator[] 是 std::string 类中的下标操作符,用于通过索引访问字符串中的字符。

(1)函数原型 

      char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;

 - 它提供了两种形式:非常量版本可以修改字符串中的字符常量版本则只能读取字符

- 与 at() 不同,operator[]不执行边界检查,因此如果访问越界会导致未定义行为。

(2)示例代码 

#include <iostream>
using namespace std;

int main()
{
	string s1 = "Hello";
	const string s2 = "henu";

	cout << s1[1] << endl;//e

	s1[1] = 'a';
	//s2[2] = 'a';//报错,表达式必须是可修改的左值
	cout << s1 << endl;//Hallo

	return 0;
}

(3)注意事项:
- operator[] 的效率很高,因为它不进行边界检查。
- 如果需要更安全的操作,建议使用 at() 函数,它会抛出异常处理越界问题。

1.3 front() 与 back()

(1)front

front()用于返回对字符串的第一个字符的引用。非常量版本可修改字符,常量版本只能读取字符。
只能在非空字符串上调用,如果字符串为空,行为未定义。

      char& front();
const char& front() const;
#include <iostream>
using namespace std;

int main()
{
	string s1 = "Hello";
	const string s2 = "henu";

	cout << s1.front() << endl;//H
	cout << s2.front() << endl;//h

	s1.front() = 'L';

	cout << s1.front() << endl;//L
	return 0;
}

(2)back()

back()用于返回对字符串的第一个字符的引用。非常量版本可修改字符,常量版本只能读取字符。
只能在非空字符串上调用,如果字符串为空,行为未定义。

char& back();               // 非常量版本,可修改字符
const char& back() const;    // 常量版本,只能读取字符
#include <iostream>
using namespace std;

int main()
{
	string str = "Hello";

	// 访问最后一个字符
	cout << str.back() << endl; // 输出 'o'

	// 修改最后一个字符
	str.back() = '!';
	cout << str << endl; // 输出 "Hell!"
	return 0;
}

总结:
- operator[] 和 at():按索引访问字符串中的字符,at() 提供边界检查。
- front() 和 back():用于访问或修改字符串的第一个和最后一个字符。

这些访问函数提供了灵活的操作方式,既可以修改字符串内容,也可以确保访问的安全性。 

2.string类的修饰函数

2.1 append()


- 功能:append()用于将字符串或其他类型的数据追加到当前字符串对象的末尾。
- 重载形式:append()有多种重载形式,可以追加不同的数据类型,包括C风格字符串、std::string对象、字符数组的指定子串等。
- 返回值:返回对修改后的字符串对象的引用(this),因此可以进行链式调用。

(1)函数原型 

string (1)	    string& append (const string& str);
substring (2)	string& append (const string& str, size_t subpos, size_t sublen);
c-string (3)	string& append (const char* s);
buffer (4)	    string& append (const char* s, size_t n);
fill (5)	    string& append (size_t n, char c);
range (6)	    template <class InputIterator>
                  string& append (InputIterator first, InputIterator last);
initializer list(7)	string& append (initializer_list<char> il);

(2)深入解析

1. string& append (const string& str)
将整个字符串 str 追加到当前字符串末尾。

	string s1 = "Hello ";
	string s2 = "henu";

	s1.append(s2);

	cout << s1 << endl;//Hello henu
	cout << s2 << endl;//henu

2. string& append (const string& str, size_t subpos, size_t sublen)
从字符串 str subpos位置的字符开始sublen个字符,追加到当前字符。

	string s1 = "Hello ";
	string s2 = "henu";

	s1.append(s2, 0, 2);

	cout << s1 << endl;//Hello he
	cout << s2 << endl;//henu

3. string& append (const char* s)
将 C 风格的字符串 s 追加到当前字符串。

	string s1 = "Hello ";

	s1.append("world");

	cout << s1 << endl;//Hello world

4. string& append (const char* s, size_t n)
将 C 风格字符串 s 的前 n 个字符追加到当前字符串。

	string s1 = "Hello ";

	s1.append("world!!!", 6);

	cout << s1 << endl;//Hello world!

5.string& append (size_t n, char c)
将 n 个字符 c 追加到当前字符串。

	string s1 = "Hello ";

	s1.append(5, 'x');

	cout << s1 << endl;//Hello xxxxx

6. template <class InputIterator> string& append (InputIterator first, InputIterator last)
将范围 [first, last) 内的元素追加到当前字符串。这可以用于迭代器范围。

	string s1 = "Hello ";
	string s2 = "henu";

	s1.append(s2.begin(), s2.end());

	cout << s1 << endl;//Hello henu

7.string& append (initializer_list<char> il)
使用初始化列表追加字符。

	string s1 = "Hello ";

	s1.append({ 'W', 'o', 'r', 'l', 'd' });

	cout << s1 << endl;//Hello World

这些不同形式的append()函数为字符串操作提供了丰富的灵活性,可以根据需求追加整个字符串、子串、字符数组、或者指定范围的字符。

在C++中,std::string类提供了两种常见的方式来将字符串追加到现有字符串:append()函数和operator+=运算符。尽管它们在效果上相似,都用于拼接字符串,但它们在使用上有一些细微差别。  

 2.2 operator+=

- 功能:operator+=运算符也是用于将字符串或其他数据追加到字符串对象末尾的运算符。它的功能和append()类似,但更加简洁,适合简单的字符串拼接操作。
- 重载形式:它同样支持多种数据类型,包括`std::string`对象、C风格字符串和单个字符等。
- 返回值:与append()一样,operator+=返回修改后的字符串对象的引用(*this),支持链式调用。

 (1)函数原型

string (1)	          string& operator+= (const string& str);
c-string (2)	      string& operator+= (const char* s);
character (3)	      string& operator+= (char c);
initializer list (4)  string& operator+= (initializer_list<char> il);

(2)深入解析 

1. string& operator+= (const string& str)
将 std::string 对象 str 追加到当前字符串的末尾。

	string s1 = "Hello ";
	string s2 = "henu";

	s1 += s2;
	cout << s1 << endl;//Hello henu

2. string& operator+= (const char* s)
将C风格字符串 s 追加到当前字符串的末尾。

	string s1 = "Hello ";
	s1 += " World";
	cout << s1 << endl;//Hello World

3. string& operator+= (char c)
单个字符 c 追加到当前字符串的末尾。

	string s1 = "Hello ";

	s1 += "!";
	cout << s1 << endl;//Hello !

4. string& operator+= (initializer_list<char> il)
将初始化列表中的字符追加到当前字符串的末尾。

	string s1 = "Hello ";

	s1 += {'W', 'o', 'r', 'l', 'd'}; // str 变为 "Hello World"
	cout << s1 << endl;

这些运算符重载使得字符串拼接变得更加方便,简洁地处理不同类型的数据(字符串、字符数组、单个字符等)。

(3)与append()的区别与使用场景:
1. 简洁性:operator+=通常用于简洁的拼接操作,尤其适合简单的字符或字符串拼接;而`append()`可以提供更灵活的重载版本,适合更复杂的场景。
   
2. 重载灵活性:append()的重载更多,能更精细地控制如何拼接字符串。例如,指定要追加子串的起始位置和长度等。
   
3. 代码可读性:operator+=运算符在某些情况下代码更简洁、更易读,尤其是单个字符或简单字符串的拼接;而`append()`适合需要明确控制拼接逻辑的场合。

性能方面:
从性能上看,append()和operator+=基本没有明显的差异,除非在某些特定的优化场景下。编译器通常会对这两者进行类似的优化。

2.3 assign() 

assign()函数用来将一个新值赋给字符串对象。支持多种重载形式。需要注意的是,assign的作用是赋值而不是拼接,会修改原字符串的内容

(1)函数原型

string (1)	
string& assign (const string& str);
substring (2)	
string& assign (const string& str, size_t subpos, size_t sublen);
c-string (3)	
string& assign (const char* s);
buffer (4)	
string& assign (const char* s, size_t n);
fill (5)	
string& assign (size_t n, char c);
range (6)	
template <class InputIterator>
   string& assign (InputIterator first, InputIterator last);
initializer list(7)	
string& assign (initializer_list<char> il)

(2)深入解析

1.string& assign (const string& str)

从另一个字符串赋值

	string s1 = "Hello";
	string s2 = "henu";

	s1.assign(s2);

	cout << s1 << endl;//henu
	cout << s2 << endl;//henu

2.string& assign (const string& str, size_t subpos, size_t sublen);
赋值部分字符串

	string s1 = "Hello";
	string s2 = "henu";

	s1.assign(s2, 0, 4);

	cout << s1 << endl;//henu

3.string& assign (const char* s)

从 C 风格字符串赋值

	string s2 = "henu";

	s2.assign("Hello World");

	cout << s2 << endl;//Hello World

4.string& assign (size_t n, char c)
用指定字符重复赋值

	string s1 = "Hello";

	s1.assign(5, 'x');
	cout << s1 << endl;//xxxxx

5.string& assign (const char* s, size_t n)
从字符指针赋值指定长度的字符串

	string s1 = "Hello";

	s1.assign("World", 5);
	cout << s1 << endl;//World

6.string& assign (InputIterator first, InputIterator last)

使用迭代器赋值

	string s1 = "Hello";
	string s2 = ", henu";

	s1.assign(s2.begin() + 2, s2.end());

	cout << s1 << endl;//henu

 7.string& assign (initializer_list<char> il)

使用初始化列表为字符串赋值

	string str = "Hello";

	str.assign({ 'W','o','r','l','d' });
	cout << str << endl;//World


assign()函数灵活多样,可以根据不同的需求从字符串、字符指针、部分字符串、重复字符等来赋值给 std::string 对象。

2.4 insert()

insert()用于在字符串中的指定位置插入字符或字符串,注意,这里是插入,插入的字符不会覆盖原来的字符。

(1)函数原型 

string (1)	    string& insert (size_t pos, const string& str);
substring (2)	string& insert (size_t pos, const string& str, size_t subpos, size_t 
                                                                                   sublen);                        
c-string (3)	string& insert (size_t pos, const char* s);
buffer (4)	    string& insert (size_t pos, const char* s, size_t n);
fill (5)	    string& insert (size_t pos, size_t n, char c);
                void insert (iterator p, size_t n, char c);

single character (6)	iterator insert (iterator p, char c);
range (7)	         template <class InputIterator>
                        void insert (iterator p, InputIterator first, InputIterator last);
initializer list (8)	
 string& insert (const_iterator p, initializer_list<char> il)

(2)深入解析 

好的,以下将每个 insert() 的示例分开写出,确保每个示例独立运行,便于理解与复制:

1.string& insert (size_t pos, const string& str)

插入整个字符串

	string s1 = "Hello";
    string s2 = " henu ";

	s1.insert(5, s2);

	cout << s1 << endl;//Hello henu

2.string& insert (size_t pos, const string& str, size_t subpos, size_t sublen)

在指定位置插入另一个字符串的的子串,该子串从subpos位置开始插入sublen个字符

	string s1 = "Hello";
	string s2 = " henu ";

	s1.insert(5, s2, 0, 4);

	cout << s1 << endl;//Hello hen

3.string& insert (size_t pos, const char* s)

插入 C 风格字符串

	string s1 = "Hello";

	s1.insert(5, " World");

	cout << s1 << endl;//Hello World

4.string& insert (size_t pos, const char* s, size_t n)

插入字符缓冲区

	string s1 = "Hello";

	const char* but = " World!!!";

	s1.insert(5, but, 7);

	cout << s1 << endl;//Hello World!

5. string& insert (size_t pos, size_t n, char c);
                void insert (iterator p, size_t n, char c)

插入重复字符

	string s1 = "Hello";

	s1.insert(0, 5, 'x');
	s1.insert(s1.end(), 5, 'x');

	cout << s1 << endl;//xxxxxHelloxxxxx

6.iterator insert (iterator p, char c)

在迭代器位置插入单个字符

	string s1 = "Hello";

	s1.insert(s1.begin() + 1, 'a');

	cout << s1 << endl;//Haello

7. void insert (iterator p, InputIterator first, InputIterator last)

插入范围

	string s1 = "代码";
	string s2 = "编写";

	s1.insert(s1.begin() + 2, s2.begin(), s2.end());

	cout << s1 << endl;//代码编写

8. initializer list (8)    
 string& insert (const_iterator p, initializer_list<char> il)

通过初始化列表在字符串的指定位置插入一组字符

	string str = "Hello, ";

	str.insert(str.begin() + 7, { 'W','o','r','l','d' });
	cout << str << endl;//Hello, World

2.5 replace()

replace用于替换字符串中的某些字符或字符串。

(1)函数原型

string (1)	
string& replace (size_t pos,  size_t len,  const string& str);
string& replace (iterator i1, iterator i2, const string& str);
substring (2)	
string& replace (size_t pos,  size_t len,  const string& str,
                 size_t subpos, size_t sublen);
c-string (3)	
string& replace (size_t pos,  size_t len,  const char* s);
string& replace (iterator i1, iterator i2, const char* s);
buffer (4)	
string& replace (size_t pos,  size_t len,  const char* s, size_t n);
string& replace (iterator i1, iterator i2, const char* s, size_t n);
fill (5)	
string& replace (size_t pos,  size_t len,  size_t n, char c);
string& replace (iterator i1, iterator i2, size_t n, char c);
range (6)	
template <class InputIterator>
  string& replace (iterator i1, iterator i2,InputIterator first, InputIterator last);
initializer list (7)	
string& replace (const_iterator i1, const_iterator i2, initializer_list<char> il);

(2) 深入解析

1.替换字符串

string& replace (size_t pos,  size_t len,  const string& str);
string& replace (iterator i1, iterator i2, const string& str);
	string s1 = "Hello, henu";
	string s2 = "World";

	s1.replace(7, 4, s2);//s1从索引为7的字符开始后的4个字符用s2替换
    cout << s1 << endl;//Hello, World

	s1.replace(s1.begin(), s1.end(), s2);
    cout << s1 << endl;//World

 2.替换子字符串

string& replace (size_t pos,  size_t len,  const string& str,
                 size_t subpos, size_t sublen);
	string s1 = "Hello, henu";
	string s2 = "World";

	s1.replace(7, 4, s2, 1, 4);
    cout << s1 << endl;//Hello, orld

3. 替换C风格字符串

string& replace (size_t pos,  size_t len,  const char* s);
string& replace (iterator i1, iterator i2, const char* s);
	string s1 = "Hello, henu";

	s1.replace(7, 4, "World");
    cout << s1 << endl;//Hello, World

	s1.replace(s1.begin() + 7, s1.end(), "henu");
    cout << s1 << endl;//Hello, henu

 4.替换缓冲区的指定字符数

string& replace (size_t pos,  size_t len,  const char* s, size_t n);
string& replace (iterator i1, iterator i2, const char* s, size_t n);
	string s1 = "Hello, henu";
	const char* s2 = "World";

	s1.replace(7, 4, s2, 4);//用s2的前四个字符替换
    cout << s1 << endl;//Hello, Worl

	s1.replace(s1.begin() + 7, s1.end(), "henu", 4);
    cout << s1 << endl;//Hello, henu

 5.用字符填充

string& replace (size_t pos,  size_t len,  size_t n, char c);
string& replace (iterator i1, iterator i2, size_t n, char c);
	string s1 = "Hello, henu";

	s1.replace(7, 4, 5, 'x');
	cout << s1 << endl;//Hello, xxxxx

	s1.replace(s1.begin() + 7, s1.end(), 4, 'a');
	cout << s1 << endl;//Hello, aaaa

 6.替换范围

template <class InputIterator>
  string& replace (iterator i1, iterator i2,InputIterator first, InputIterator last);
	string s1 = "Hello, henu";
	string s2 = "World";

	s1.replace(s1.begin() + 7, s1.end(), s2.begin(), s2.end());
	cout << s1 << endl;//Hello, World

7.用初始化列表替换

 

initializer list (7)	
string& replace (const_iterator i1, const_iterator i2, initializer_list<char> il);
	string str = "Hello, henu";

	str.replace(str.begin() + 7, str.end(), {'W','o','r','l','d'});
	cout << str << endl;//Hello, World

2.6其它成员函数

(1)push_back()

push_back用于添加字符到字符串的末尾,是字符串的长度加一

void push_back (char c);
#include <iostream>
using namespace std;

int main()
{
	string s1 = "Hello, hen";
	s1.push_back('u');
	cout << s1 << endl;//Hello, henu
	return 0;
}

(2)pop_back()

pop_back用来删除字符串最后一个字符,字符串长度减一

void pop_back();
#include <iostream>
using namespace std;

int main()
{
	string s1 = "Hello, henua";
	s1.pop_back();
	cout << s1 << endl;//Hello, henu
	return 0;
}

通过对 C++ std::string 类的访问函数和修饰函数的深入了解,我们可以更灵活、有效地处理字符串操作。在编程实践中,选择合适的函数不仅能提高代码的可读性,还能提升程序的执行效率。掌握这些字符串操作的方法,能够帮助我们在应对复杂的字符串处理需求时游刃有余。

更多string成员函数:string::find - C++ Reference (cplusplus.com)

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

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

相关文章

git使用“保姆级”教程3——添加暂存区及提交本地库

1、存入暂存区——命令行git add 要将代码放入暂存区&#xff0c;要使用git add指令注意&#xff1a;只是把在工作区的文件往暂存区复制了一份&#xff0c;并不是工作区的文件就消失了 将单文件放在暂存区 // 把文件夹下的1.txt文本放在暂存区 > 1.txt可以替换成任意文件名…

搭建高效知识库:教培机构数字教学的关键一步

在数字化时代&#xff0c;教育培训行业正经历着前所未有的变革。随着在线教育的兴起和个性化学习需求的增长&#xff0c;构建一个高效、易用的知识库已成为教培机构提升教学质量、优化学习体验、增强竞争力的关键一步。本文将深入探讨构建高效知识库的重要性&#xff0c;以及如…

简站wordpress主题产品多图ACF插件设置方法

此教程仅适用于演示站有产品多图的主题&#xff0c;演示站没有产品多图的主题&#xff0c;就别往下看了&#xff0c;省得浪费时间。 1、给产品添加轮播图 简站wordpress主题有多个产品图的主题&#xff0c;添加产品轮播图的具体方法如下&#xff1a; 1.2、选择产品分类 添加…

【管理】销售管理到底应该怎么管?

销售是个数字游戏&#xff0c;销售管理的最终目的就是完成销售业绩。有人说销售管理是门艺术&#xff0c;有人说销售管理是科学。销售是一门艺术&#xff0c;但是可以通过科学的方式将这些艺术固化很多人对销售管理的认识存在很多不同&#xff0c;我们尝试用最为平时的语言总结…

黑马程序员pink前端查漏补缺笔记,耗时6天,针对必要案例进行练习

HTML 1&#xff09;插件 自动闭合标签&#xff0c;修改开标签时闭标签跟着变&#xff08;微信开发者工具没有这个功能&#xff09; 主题 保存格式化 浏览器打开 实时刷新&#xff0c;不用按浏览器的刷新按钮 win←/→ 快速分屏 2&#xff09;初始结构标签 文档类型声明标签…

在已安装的openresty上添加安装upstream模块报错的解决以及使用Consul服务发现时定时变更nginx的upstream的shell脚本

一、在已经安装好的openresty环境上添加安装upstream模块报错&#xff1a; 在已经安装好的openresty环境上添加安装upstream模块报错&#xff1a;http upstream check module can not find any check server, make sure you ve added the check 的问题解决。 服务器上已经安装好…

Unity3D入门(四) : Android和Unity3D交互 - Unity调用Android

1. 前言 上篇文章&#xff0c;我们讲了如何通过Android调用Unity3D。这篇文章&#xff0c;我们来讲一下Unity3D怎么调用Android。 1.1 unity和Android的三种通信方式 Unity官方提供的接口 : 有一个弊端&#xff0c;它有一个传输内容量的一个限制&#xff0c;传输内容过大或过…

详解JavaScript中的数组

第7章 数组 JavaScript数组索引基于32位数值&#xff0c;以0开头&#xff0c;最大索引2^32-2&#xff0c;最大容纳4294967295&#xff0c;大约42亿个。 JavaScript数组是动态的&#xff0c;根据需要增长或缩减&#xff0c;可能是稀疏的&#xff0c;有length属性。 用数字索引…

Linux下的驱动开发一

设备驱动 设备驱动程序&#xff08;Device Driver&#xff09;是操作系统中的一种软件组件&#xff0c;负责管理和控制计算机硬件设备的工作。驱动程序通过提供操作系统和硬件设备之间的接口&#xff0c;使得操作系统和应用程序能够与硬件设备进行交互&#xff0c;而无需了解硬…

【智能大数据分析 | 实验二】Spark实验:部署Spark集群

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈智能大数据分析 ⌋ ⌋ ⌋ 智能大数据分析是指利用先进的技术和算法对大规模数据进行深入分析和挖掘&#xff0c;以提取有价值的信息和洞察。它结合了大数据技术、人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&a…

网易云多久更新一次ip属地

‌在数字化时代&#xff0c;网络成为了我们日常生活中不可或缺的一部分。无论是社交娱乐还是工作学习&#xff0c;IP地址作为网络身份的象征&#xff0c;都扮演着重要的角色。对于网易云音乐这样的热门应用来说&#xff0c;IP属地的显示不仅关乎用户体验&#xff0c;也涉及用户…

Supervisor进程管理工具安装

Supervisor进程管理工具安装 一、Supervisor概况及作用1.概况2.主要作用1&#xff09;、进程管理(1). 启动与停止进程(2). 自动重启进程(3). 进程状态监控 2&#xff09;、日志管理(1).集中化日志记录 3&#xff09;、资源管理与优化(1). 控制进程资源使用 二.安装 Supervisor1…

小白学大模型RAG:十大步骤分析GraphRAG的工作原理

对于普通的RAG&#xff0c;也就是前面课程讲的RAG&#xff0c;它的原理是通过将文本进行切分和向量化&#xff0c;通过计算文本之间的向量相似度&#xff0c;从而得到两个文本之间的语义相似度&#xff0c;从知识库中找出跟问题语义相似的知识点&#xff0c;再送给LLM得出最终答…

学习Java (五)

1.学习封装 package com.msb.test07; //封装 public class Girl {private int age; // 赋值public void setAge(int age){if(age > 30){this.age 18;}else{this.age age;}} // 读取public int getAge(){return age;} }package com.msb.test07;public class Test {p…

【Linux 报错】“make: ‘xxxx‘ is up to date.” 解决办法

一、报错原因 我们使用 make 命令&#xff0c;想要将 text.c 文件编译形成 可执行文件 text 时&#xff0c;报错如下 make: test is up to date. 中文含义&#xff1a;test 文件已经达到最新状态 意思是&#xff1a; test.c 文件里面的 所有源代码都没有修改过&#xff0c;你…

c++11~c++20 numeric_limits

在c中应该尽量少使用宏&#xff0c;用模板取而代之是明知的选择。我们可以使用numeric_limits来获取最大值和最小值&#xff0c;例如 #include <iostream> #include <limits> #include <iostream> using namespace std;int main() {cout << "int…

Go基础学习04-变量重声明;类型转换;类型断言;Unicode代码点;类型别名;潜在类型

目录 变量重声明 类型断言 类型转换 类型转换注意事项 Unicode代码点 类型别名、潜在类型 类型别名的意义 变量重声明 编写代码&#xff1a; package mainimport "fmt"var container []string{"Beijing", "Shanghai"}func main() {fmt.Pr…

Qt开发技巧(八)自带对话框的美化,内置快捷代码段,巧用匿名槽函数,另类动态换肤,资源动态加载

继续讲一些Qt开发中的技巧操作&#xff1a; 1.自带对话框的美化 Qt中有一些自带的对话框&#xff0c;比如文件选择对话框&#xff0c;颜色选择对话框等等&#xff0c;这些对话框看着跟系统的对话框没太大差别&#xff0c;实际这是Qt有意为之&#xff0c;为的是跟系统保持一致。…

欺诈文本分类检测(十七):支持分类原因训练

1. 引言 前文数据校正与增强进行了数据增强&#xff0c;本文将使用增强后的数据对模型进行进一步训练&#xff0c;以便得到能同时预测出分类标签、欺诈者、分类原因多个信息的模型。 为此&#xff0c;我们需要对整个训练过程进行调整&#xff0c;包括&#xff1a; 交叉训练逻…

苹果端侧AI布局深度分析

苹果 - 国际巨头的端侧 AI布局 深度分析 1.1.1 苹果AI&#xff1a;模型侧&#xff1a;MM1 3月&#xff0c;苹果发布多模态大模型MM1&#xff0c;拥有高达300亿参数。MM1融合密集模型与MoE变体&#xff0c;涵盖300亿、70亿、30亿参数版。MM1预训练指标领先&#xff0c;在多个多…