C++深入学习string类成员函数(4):字符串的操作

news2024/9/28 14:09:37

引言

在c++中,std::string提供了许多字符串操作符函数,让我们能够秦松驾驭文本数据,而与此同时,非成员函数的重载更是为string类增添了别样的魅力,输入输出流的重载让我们像处理基本类型的数据一样方便地读取和输出字符串,连接操作符的重载使得字符串的拼接变得简洁直观。在这篇博客中,我们将一同深入剖析C++中string类的字符串操作符和非成员函数的重载,为大家在编程之旅中增添一份有力的武器。

在开始介绍操作符函数前,我们先来了解一个string类定义的一个静态成员变量npos。

1.npos

npos是std::string中定义的一个静态常量成员,表示“no opsition”(没有位置)。它通常用于返回表示查找操作失败时的返回值  。

static const size_t npos = -1;
#include <iostream>
using namespace std;

int main()
{
	string s1 = "Hello, World";

	size_t pos = s1.find("good");

	if (pos == string::npos);
	{
		cout << "字符串未找到" << endl;
	}

	return 0;
}

 

2.string类的字符串操作函数

2.1. c_str()

c_str用来返回一个指向C风格字符串(以空字符\0结尾)的指针。适用于需要与C语言或库(如printf、文件操作等)进行交互时将std::string转换为C风格字符串

(1)函数原型

const char* c_str() const;

(2)示例代码

#include <iostream>
using namespace std;

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

	const char* cstr = s1.c_str();

	cout << cstr << endl;//Hello
	return 0;
}

 (3)string与C风格字符串的区别

在 C++中, std::string 类型的字符串与 C 风格字符串有以下一些主要区别:
 
一、内存管理
 -  std::string :自动管理内存。当对 std::string 对象进行赋值、拼接等操作时,它会自动处理内存的分配和释放,无需程序员手动管理。
- C 风格字符串:需要手动管理内存。如果是动态分配的字符数组,程序员必须在合适的时候使用 free (C)或 delete[] (C++)释放内存,否则会导致内存泄漏。对于局部的字符数组,其内存会在作用域结束时自动释放,但长度在创建时就固定,难以灵活调整。
 
二、安全性

 -  std::string :通常具有边界检查机制,不容易出现缓冲区溢出等安全问题。例如,在进行字符串拼接时,会自动调整内存大小以容纳新的内容
- C 风格字符串:缺乏内置的安全检查机制。在进行字符串操作时,如复制、连接等,如果不仔细控制长度,很容易导致缓冲区溢出,可能会破坏程序的稳定性甚至被恶意利用。
 
三、功能丰富度
 -  std::string :提供了丰富的成员函数,如 find (查找子串)、 substr (提取子串)、 append (追加字符串)等,使得字符串操作更加方便和直观。
- C 风格字符串:主要依靠 C 标准库中的函数,如 strcpy (复制字符串)、 strcat (连接字符串)、 strstr (查找子串)等,这些函数使用起来相对较为繁琐,且容易出错。
 
四、初始化和赋值
 -  std::string :可以使用多种方式进行初始化和赋值,例如使用字符串常量、另一个 std::string 对象、字符数组的一部分等。初始化和赋值操作通常比较简洁明了。
- C 风格字符串:初始化通常需要使用字符数组初始化语法或者使用 strcpy 等函数进行复制。赋值操作一般使用 strcpy 或 strncpy 等函数,但需要确保目标字符数组有足够的空间容纳源字符串。
 
五、可变性
 -  std::string :可以方便地修改其中的字符内容。例如,可以直接通过下标访问和修改单个字符。
- C 风格字符串:如果是字符数组常量(如 char str[] = "Hello"; ),存储在只读内存区域,不能修改其内容。如果是动态分配的字符数组,可以修改其内容,但需要小心操作以避免越界。

2.2 copy()

copy()用来将字符串的内容复制到字符串数组中,但不自动添加空字符‘\0’。

(1)函数原型 

size_t copy (char* s, size_t len, size_t pos = 0) const;

- s:目标字符数组

- len:要复制的字符数量。

- pos:从字符串的哪个位置开始复制,默认为0.

- const:表示该函数不会修改调用它的字符串对象(即whis指针所指的对象)

(2)示例代码 

#include <iostream>
using namespace std;

int main()
{
	string s1 = "Hello, henu";
	char s2[20];

	s1.copy(s2, 5, 7);

	s2[5] = '\0';

	cout << s2 << endl;//henu
	return 0;
}

2.3 substr()

substr()用来提取从指定位置开始的子字符串

(1)函数原型

string substr (size_t pos = 0, size_t len = npos) const;

- pos:字符串起始位置,默认为0

- len:子字符串的长度,默认为字符串的剩余部分 。

- const:表示该函数不会修改调用它的字符串对象(即whis指针所指的对象)

2)示例代码

#include <iostream>
using namespace std;

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

	s2 = s1.substr(1, 3);
	s3 = s1.substr();

	cout << s2 << endl;//ell
	cout << s3 << endl;//Hello
	return 0;
}

2.4 find()与rfind()

2.4.1 find()

- find()用来查找字符串中指定字符串第一次出现的位置。如果未找到,则返回std::string::npos,

- rfind()用于在字符串中查找最后一次出现指定字符串的位置。返回值是找到子串的起始位置如果未找到,则返回npos。 

(1)函数原型

string (1)	
size_t find (const string& str, size_t pos = 0) const noexcept;
c-string (2)	
size_t find (const char* s, size_t pos = 0) const;
buffer (3)	
size_t find (const char* s, size_t pos, size_type n) const;
character (4)	
size_t find (char c, size_t pos = 0) const noexcept;
string (1)	
size_t rfind (const string& str, size_t pos = npos) const;
c-string (2)	
size_t rfind (const char* s, size_t pos = npos) const;
buffer (3)	
size_t rfind (const char* s, size_t pos, size_t n) const;
character (4)	
size_t rfind (char c, size_t pos = npos) const;

find从指定位置往后查找,rfind从指定位置往前查找 

(2)深入解析 

1.查找字符串

size_t find (const string& str, size_t pos = 0) const;
size_t rfind (const string& str, size_t pos = npos) const;
//pos = npos默认查找整个字符串

返回值是size_t,表示找到的位置索引。返回std::string::npos,这是一个特殊值,表示失败。

#include <iostream>
using namespace std;

int main()
{
	string s1 = "Hello, World! World!";
	string s2 = "World!";

	size_t pos1 = s1.find(s2);//查找W第一次出现的位置
	size_t pos2 = s1.rfind(s2);//查找W最后一次出现的位置

	if (pos1 == string::npos)
	{
		cout << "没找到" << endl;
	}
	else
	{
		cout << "找到了, 索引是" << pos1 << endl;//输出7
	}
	if (pos2 == string::npos)
	{
		cout << "没找到" << endl;
	}
	else
	{
		cout << "找到了, 索引是" << pos2 << endl;//输出14
	}

	return 0;
}

 2.查找c风格字符串

size_t find (const char* s, size_t pos = 0) const;
size_t rfind (const char* s, size_t pos = 0) const;
//pos = npos默认查找整个字符串
#include <iostream>
using namespace std;

int main()
{
	string s1 = "Hello, World!World!";

	size_t pos1 = s1.find("World");
	size_t pos2 = s1.rfind("World");
	if (pos1 == string::npos)
	{
		cout << "没找到" << endl;
	}
	else
	{
		cout << "找到了,索引是" << pos1 << endl;//7
	}
	if (pos2 == string::npos)
	{
		cout << "没找到" << endl;
	}
	else
	{
		cout << "找到了,索引是" << pos2 << endl;//13
	}
	return 0;
}

 3.查找字符缓冲区

size_t find (const char* s, size_t pos, size_t n) const;
size_t rfind (const char* s, size_t pos, size_t n) const;
//pos = npos默认查找整个字符串

- s:指向要查找的字符缓冲区的指针,类型为const char*。

- pos:从字符串中的那个位置开始向前查找(可以是npos,表示从末尾查找)。

- n: 要查找的字符缓冲区的前n个字符。

#include <iostream>
using namespace std;

int main()
{
	string s1 = "Hello, World!World!";
	const char* but = "World!";//要查汇的字符缓冲区

	size_t pos1 = s1.find(but, 0, 5);//从位置0开始向后查找缓冲区的前五个字符
	size_t pos2 = s1.rfind(but, string::npos, 5);//从末尾开始向前查找缓冲区的前五个字符
	if (pos1 == string::npos)
	{
		cout << "没找到" << endl;
	}
	else
	{
		cout << "找到了,索引是" << pos1 << endl;//7
	}
	if (pos2 == string::npos)
	{
		cout << "没找到" << endl;
	}
	else
	{
		cout << "找到了,索引是" << pos2 << endl;//13
	}
	return 0;
}

 4.查找单个字符 

size_t find (char c, size_t pos = 0) const;
size_t rfind (char c, size_t pos = 0) const;
//pos = npos默认查找整个字符串
#include <iostream>
using namespace std;

int main()
{
	string s1 = "Hello, World!World!";

	size_t pos1 = s1.find('W');
	size_t pos2 = s1.rfind('W');
	if (pos1 == string::npos)
	{
		cout << "没找到" << endl;
	}
	else
	{
		cout << "找到了,索引是" << pos1 << endl;//7
	}
	if (pos2 == string::npos)
	{
		cout << "没找到" << endl;
	}
	else
	{
		cout << "找到了,索引是" << pos2 << endl;//13
	}
	return 0;
}

2.6 其它成员函数

(1)data()

data用来返回指向存储字符串内容的字符数组的指针。与c_str的不同是返回的指针不是以 `\0` 结尾的。

const char* data() const noexcept;
#include <iostream>
using namespace std;

int main() {
	string str = "Hello, World!";

	// 使用 data() 获取字符串的字符数组
	const char* ptr = str.data();

	cout << ptr << endl;// 输出 "Hello, World!"

	return 0;
}

(2)compare

compare用于比较两个字符串或子字符串的内容。

string (1)	
int compare (const string& str) const noexcept;
substrings (2)	
int compare (size_t pos, size_t len, const string& str) const;
int compare (size_t pos, size_t len, const string& str,
             size_t subpos, size_t sublen) const;
c-string (3)	
int compare (const char* s) const;
int compare (size_t pos, size_t len, const char* s) const;
buffer (4)	
int compare (size_t pos, size_t len, const char* s, size_t n) const;

返回一个整数值,负值表示当前字符串小于str,0表示当前字符串等于str,正值表示当前字符串大于str。

#include <iostream>
using namespace std;
int main()
{
    string str1("green apple");
    string str2("red apple");
    string str3("apple");

    if (str1.compare(str2) != 0)//比较两个字符串
        cout << str1 << " is not " << str2 << endl;

    if (str1.compare(6, 5, str3) == 0)//索引6之后的五个字符串与s3相比
        cout << str1 << " is an apple\n";


    if (str2.compare(str2.size() - 5, 5, "apple") == 0)
        cout << "and " << str2 << " is also an apple\n";

    if (str1.compare(6, 5, str2, 4, 5) == 0)
        //索引6之后的五个字符串与s2索引为4后的五个字符串相比
        cout << "therefore, both are apples\n";

    return 0;
}

 

(3)get_aooocator

std::string::get_allocator用于返回 std::allocator<char> 类型的对象。这个对象是用于管理字符串分配和释放内存的分配器。

​allocator_type get_allocator() const noexcept;
#include <iostream>
using namespace std;

int main() {
	string str = "Hello, World!";
	allocator<char> alloc = str.get_allocator();

	// 使用返回的 allocator 分配内存
	char* buffer = alloc.allocate(20);

	// 分配的内存可以用于存储数据
	for (int i = 0; i < 12; ++i) 
	{
		buffer[i] = str[i];
	}

	buffer[12] = '\0'; // 添加字符串终止符

	cout << buffer << endl;

	// 使用 allocator 释放内存
	alloc.deallocate(buffer, 20);

	return 0;
}

在这个示例中,get_allocator 返回的 allocator 对象被用来分配和释放字符数组的内存,这与字符串的内存管理方式相同。

(4)find_first_of与find_last_of

它用于在字符串中查找指定字符中任意一个字符第一次出现的位置

string (1)	
size_t find_first_of (const string& str, size_t pos = 0) const noexcept;
c-string (2)	
size_t find_first_of (const char* s, size_t pos = 0) const;
buffer (3)	
size_t find_first_of (const char* s, size_t pos, size_t n) const;
character (4)	
size_t find_first_of (char c, size_t pos = 0) const noexcept;

 - pos:从字符串中开始查找的起始位置(默认为 0)。该函数返回找到的第一个字符的索引。如果没有找到任何指定的字符,则返回std::string::npos,这是一个常量,表示没有有效位置。 

string (1)	
size_t find_last_of (const string& str, size_t pos = npos) const noexcept;
c-string (2)	
size_t find_last_of (const char* s, size_t pos = npos) const;
buffer (3)	
size_t find_last_of (const char* s, size_t pos, size_t n) const;
character (4)	
size_t find_last_of (char c, size_t pos = npos) const noexcept;

pos:从字符串的指定位置开始向前查找(默认为std::string::npos,表示从字符串的末尾开始查找)。该函数返回找到的第一个字符的索引。如果没有找到任何指定的字符,则返回std::string::npos,这是一个常量,表示没有有效位置。 

#include <iostream>
using namespace std;

int main()
{
	string str1 = "Hello, World";
	string str2 = "World";

	size_t pos1 = str1.find_first_of(str2);
	size_t pos2 = str1.find_first_of("Wd");
	size_t pos3 = str1.find_first_of("World", 0, 5);
	size_t pos4 = str1.find_first_of('o');

	cout << pos1 << endl;//2,str2中的'l'第一次出现在索引为2处
	cout << pos2 << endl;//7,'Wd'中的'W'第一次出现在索引为7处
	cout << pos3 << endl;//2
	cout << pos4 << endl;//4

	return 0;
}
#include <iostream>
using namespace std;

int main()
{
	string str1 = "Hello, World";
	string str2 = "World";

	size_t pos1 = str1.find_last_of(str2);
	size_t pos2 = str1.find_last_of("He");
	size_t pos3 = str1.find_last_of("World", 0, 5);
	size_t pos4 = str1.find_last_of('o');

	cout << pos1 << endl;//11,str2中的'd'第一次出现在索引为11处
	cout << pos2 << endl;//1,'He'中的'e'第一次出现在索引为1处
	cout << pos3 << endl;//18446744073709551615没有找到
	cout << pos4 << endl;//6

	return 0;
}

 (5)find_first_not_of与find_last_not_of

find_first_not_of​​​​​​​用于查找字符串中第一个不属于指定字符集合的字符的位置(从前往后查找)。find_last_not_of用于查找字符串中最后一个不属于指定字符集合的字符的位置(从后往前查找)。

string (1)	
size_t find_first_not_of (const string& str, size_t pos = 0) const noexcept;
c-string (2)	
size_t find_first_not_of (const char* s, size_t pos = 0) const;
buffer (3)	
size_t find_first_not_of (const char* s, size_t pos, size_t n) const;
character (4)	
size_t find_first_not_of (char c, size_t pos = 0) const noexcept;
string (1)	
size_t find_last_not_of (const string& str, size_t pos = npos) const noexcept;
c-string (2)	
size_t find_last_not_of (const char* s, size_t pos = npos) const;
buffer (3)	
size_t find_last_not_of (const char* s, size_t pos, size_t n) const;
character (4)	
size_t find_last_not_of (char c, size_t pos = npos) const noexcept;

用法同find_first_of和find_last_of类似,不在赘述。

总结

总结:在 C++ 中,std::string 类提供了多种功能强大的成员函数,使字符串处理变得灵活、高效。通过这些操作函数,开发者能够对字符串进行查找、替换、获取子串、内存管理等多种操作,极大地提升了开发效率。以下是一些重要的操作函数总结:

- c_str:c_str() 和 data() 函数提供了字符串的 C 风格字符数组等效形式。这在需要与 C 风格字符串或其他库进行交互时非常实用。

- initializer list 替换:replace 函数可以使用初始化列表对字符串中的某个范围进行替换。这种操作在处理特定范围的修改时非常有用。
  

- copy:通过 copy 函数可以将字符串的一部分复制到字符数组中,适用于需要操作原始字符数据的场景。

- get_allocator:该函数返回用于管理 std::string 内存的分配器,便于自定义内存管理。

- 查找功能:
  - find:查找字符串中某内容首次出现的位置。
  - rfind:查找字符串中某内容最后一次出现的位置。
  - find_first_of:查找指定字符集中的任意字符第一次出现的位置。
  - find_last_of:从字符串末尾开始查找指定字符集中的任意字符。
  - find_first_not_of:查找第一个不属于指定字符集的字符。
  - find_last_not_of:从末尾开始查找不属于指定字符集的字符。

- 子串操作:substr 函数可以生成字符串的子串,适用于提取特定部分内容。

- 字符串比较:compare 函数提供了灵活的字符串比较功能,用于按字典顺序比较两个字符串。

这些操作函数使 std::string 成为一个强大的工具,能够处理从简单字符串操作到复杂的字符串匹配、替换等任务。掌握这些函数可以帮助开发者编写出高效、健壮的字符串处理代码。在实际开发中,这些函数的组合应用能够显著提高代码的灵活性和可读性。

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

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

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

相关文章

51单片机系列-串口(UART)通信技术

&#x1f308;个人主页&#xff1a; 羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 并行通信和串行通信 并行方式 并行方式&#xff1a;数据的各位用多条数据线同时发送或者同时接收 并行通信特点&#xff1a;传送速度快&#xff0c;但因需要多根传输线&#xf…

20.指针相关知识点1

指针相关知识点1 1.定义一个指针变量指向数组2.指针偏移遍历数组3.指针偏移的补充4.指针和数组名的见怪不怪5.函数、指针、数组的结合 1.定义一个指针变量指向数组 指向数组首元素的地址 指向数组起始位置&#xff1a;等于数组名 #include <stdio.h>int main(){int ar…

LeetCode 2266. 统计打字方案数

Alice 在给 Bob 用手机打字。数字到字母的 对应 如下图所示。 为了 打出 一个字母&#xff0c;Alice 需要 按 对应字母 i 次&#xff0c;i 是该字母在这个按键上所处的位置。 比方说&#xff0c;为了按出字母 s &#xff0c;Alice 需要按 7 四次。类似的&#xff0c; Alice 需…

Qt --- Qt窗口

一、前言 前面学习的所有代码&#xff0c;都是基于QWidget控件。QWidget更多的是作为别的窗口的一个部分。 Qt中的QMainWindow就是窗口的完全体 Menu Bar菜单栏 Tool Bar Area 工具栏&#xff0c;类似于菜单栏&#xff0c;工具栏本质上就是把菜单中的一些比较常用的选项&…

活动展览棚:灵活多变的展览解决方案—轻空间

在快速变化的市场环境中&#xff0c;活动展览棚作为一种创新的展示空间&#xff0c;正受到越来越多企业和组织的青睐。无论是展览、活动、还是市场推广&#xff0c;活动展览棚都能提供高效、灵活的解决方案&#xff0c;为品牌传播和产品展示带来全新体验。 便捷的搭建与拆卸 活…

C. Cards Partition 【Codeforces Round 975 (Div. 2)】

C. Cards Partition 思路&#xff1a; 可以O(n)直接判断&#xff0c;牌组从大到小依次遍历即可。 不要用二分答案&#xff0c;因为答案不一定是单调的 代码: #include <bits/stdc.h> #define endl \n #define int long long #define pb push_back #define pii pair<…

Angular与Vue的全方位对比分析

一、框架概述 Angular Angular是由Google开发和维护的一款开源JavaScript框架。它采用TypeScript编写&#xff0c;具有一套完整的开发工具和规范。Angular遵循MVC&#xff08;Model - View - Controller&#xff09;或更确切地说是MVVM&#xff08;Model - View - ViewModel&a…

【Python】数据可视化之分布图

分布图主要用来展示某些现象或数据在地理空间、时间或其他维度上的分布情况。它可以清晰地反映出数据的空间位置、数量、密度等特征&#xff0c;帮助人们更好地理解数据的内在规律和相互关系。 目录 单变量分布 变量关系组图 双变量关系 核密度估计 山脊分布图 单变量分布…

超全面的线程编程实战指南

第一部分&#xff1a;线程基本概念 一、线程简介 线程是操作系统能够进行运算调度的最小单位&#xff0c;它是一个进程内的独立控制流。线程之间共享同一进程的资源&#xff0c;如内存空间和其他系统资源。 二、线程的优势 效率高&#xff1a;由于线程共享相同的地址空间&a…

用Python+flask+mysql等开发的Excel数据资产落地工具

话不多说 1)Excel文件上传,列表预览 2)选中要导入结构及数据的Excel文件 约束说明: 2.1)Excel文件的第一行约定为表头名称 2.2)系统自动识别字段列名及数据类型,目前不支持合并表头 3)Excel建表导入数据成功后,可在表源列表中预览查看 4)对数据表源可进行透视图设计管理,可对…

Vue-Bag-Admin 采用漂亮的 Naive UI 构建的开源中后台系统,基于 Vue3 / Vite / TypeScript 等最新的前端技术栈

这是一款完成度很高、实用性很强的 admin 前端框架&#xff0c;颜值不错&#xff0c;推荐给大家。 Vue-Bag-Admin 在官网上也直接称为 Bag-Admin&#xff0c;这是一款专门为企业项目搭建中后台管理平台的前端框架&#xff0c;基于目前最新的前端技术栈 Vue3、Vite、TypeScript…

双十一儿童耳勺哪款好?双十一儿童专用掏耳神器推荐!

近期收到很多后台私信问儿童应该选择哪款耳勺&#xff0c;现在市面上掏耳神器众多&#xff0c;但要选择一个能适合儿童专用的产品要仔细斟酌。 如果挑选到不符合或者劣质的儿童掏耳工具&#xff0c;不仅清洁不干净不说&#xff0c;还会有损害儿童肌肤的风险&#xff01;那么专为…

Llama 3.2 90B刚开源就被Molmo-72B全面击败!

Meta此次发布的Llama 3.2一个新特性是视觉模型&#xff0c;包括11B和90B&#xff0c;作为首批支持视觉任务的Llama模型&#xff0c;但是allenai开源的多模态Molmo-72B&#xff0c;在视觉评测上全面击败Llama 3.2 90B。 两个新发布的开源LLM之间的基准测试比较&#xff1a;Molm…

leetcode163.缺失的区间,模拟

leetcode163.缺失的区间 给定一个排序的整数数组 nums &#xff0c;其中元素的范围在 闭区间 [lower, upper] 当中&#xff0c;返回不包含在数组中的缺失区间。 示例&#xff1a; 输入: nums [0, 1, 3, 50, 75], lower 0 和 upper 99, 输出: [“2”, “4->49”, “51-&…

OpenSource - 开源WAF_SamWaf

文章目录 PreSafeLine VS SamWaf开发初衷软件介绍架构界面主要功能 使用说明下载最新版本快速启动WindowsLinuxDocker 启动访问升级指南自动升级手动升级 在线文档 代码相关代码托管介绍和编译已测试支持的平台测试效果 安全策略问题反馈许可证书贡献代码 Pre Nginx - 集成Mod…

关系模型与关系代数——数据库原理 总结2

2.1 关系模型 关系数据结构 关系模型的数据结构是二维表&#xff0c;亦称为关系。关系数据库是表的集合&#xff0c;即关系的集合。表是一个实体集&#xff0c;一行就是一个实体&#xff0c;它由有关联的若干属性的值所构成。 关系模型的相关概念 列就是数据项 或 字段 或 属…

C++那些你不得不知道的(2)

C那些你不得不知道的&#xff08;2&#xff09; 1、缺省参数在使用的遍历 &#xff08;1&#xff09;以下是实现顺序表的初始化和检查容量空间的方式&#xff1a; void Init(list* ps) {ps->arr NULL;ps->Capacity ps->size 0; }void CheckCapacity(list* ps) {…

量化系统QTYX使用攻略|“自动交易”篇——ETF量化框架,集成“策略回测仓位风控下单”(更新v2.9.2)...

QTYX系统简介 股票量化交易系统QTYX是一个即可以用于学习&#xff0c;也可以用于实战炒股分析的系统。 分享QTYX系统目的是提供给大家一个搭建量化系统的模版&#xff0c;最终帮助大家搭建属于自己的系统。因此我们提供源码&#xff0c;可以根据自己的风格二次开发。 关于QTYX的…

ABAP版本管理

在开发中ABAP管理有查看&#xff0c;生成&#xff0c;比对&#xff0c;远程比对&#xff0c;回滚&#xff0c;删除等等操作。日常中往往会遇到需要回滚到上一版本的代码&#xff0c;但是ABAP不像git代码管理那么专业&#xff0c;但是也是可以回滚代码的。在此记录一下操作过程。…

大模型时代,2024的传统程序员还需要写代码吗?需要学习大模型吗?

一&#xff0e;引言 随着大模型&#xff08;如GPT等&#xff09;的迅猛发展&#xff0c;软件开发领域中我们的开发方式也在悄然发生变化。当然&#xff0c;我作为一名传统的Java后端开发工程师&#xff0c;在职业生涯的初期主要专注于使用多种数据结构以及算法编写业务代码。 …