string类函数--深入浅出了解

目录

  • 1.为什么学习string类
    • 1.1C语言中的字符串
    • 1.2OJ题中的优势
  • 2.标准库中的string类
  • 3.string类的常用接口函数
    • 3.1string类对象的常见构造
    • 3.2string类对象的容量操作
    • 3.3string类对象的访问及遍历操作
    • 3.4string类的修改操作
    • 3.5string类的非成员函数
  • 总结

1.为什么学习string类

1.1C语言中的字符串

C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

1.2OJ题中的优势

OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、快捷,基本都使用string类,很少有人去使用C库中的字符串操作函数。

2.标准库中的string类

  1. 字符串是表示字符序列的类
  2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
  3. string类是使用char作为它的字符类型,即使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。
  4. string类basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traitsallocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
  5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码字符)来操作。

总结:

string是表示字符串的字符串类 ② 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
string在底层实际是:basic_string模板类别名,typedefbasic_string<charchar_traits,
allocator>string; ④不能操作多字节或者变长字符的序列。
⑤在使用string类时,必须包含#include头文件以及using namespace std

3.string类的常用接口函数

3.1string类对象的常见构造

string类的构造函数如下:
在这里插入图片描述
介绍经常使用的构造函数:

string();//用空字符串构造一个空string类对象,长度为0
string (const char* s);//用C语言字符串构造string类对象
string (size_t n, char c);//用n个字符c构造string类对象
string (const string& str);//用一个string类str拷贝构造string类对象
string (const string& str, size_t pos, size_t len = npos);
//从str对象pos位置拷贝len字节内容构造string类对象,如果str对象很短或len=npos,则拷贝str对象末尾
static const size_t npos = -1;
//npos为静态成员变量,-1存储在无符号整型中会发生整型提升,为整型的最大值

栗子:

void Test1()
{
	string str1;
	cout << str1 << endl;
	string str2("hello world");
	cout << str2 << endl;
	string str3(10, 'x');
	cout << str3 << endl;
	string str4(str2);
	cout << str4 << endl;
	string str5(str2, 6);
	cout << str5 << endl;
}

代码编译运行的结果为:
在这里插入图片描述
string类赋值运算符重载

和内置类型赋值运算符一样,string类赋值运算符重载,会将赋值对象原有的数据进行覆盖赋值!

string (1)	
string& operator= (const string& str);
//用string类str对象进行赋值
c-string (2)	
string& operator= (const char* s);
//用C字符串进行赋值
character (3)	
string& operator= (char c);
//用C字符进行赋值

eg:

void Test2()
{
	string str1("hello world");
	cout << str1 << endl;
	string str2;
	str2 = str1;
	cout << str2 << endl;
	str2 = "xxxxx";
	cout << str2 << endl;
	str2 = 'y';
	cout << str2 << endl;
}

代码编译运行的结果为:
在这里插入图片描述

3.2string类对象的容量操作

size_t size() const;//以字节为单位返回字符串的有效长度
size_t length() const;//以字节为单位返回字符串的有效长度
size_t capacity() const;//以字节形式返回string类存储的容量大小
bool empty() const;//检测字符串是否为空串,是返回true,否则返回false

eg1:

void Test3()
{
	string str1("hello world");
	printf("string类的大小为:");
	cout << str1.size() << endl;
	printf("string类的大小为:");
	cout << str1.length() << endl;
	printf("string类的存储容量为:");
	cout << str1.capacity() << endl;
	printf("string类的判空值为:");
	cout << str1.empty() << endl;
}

代码编译运行的结果为:
在这里插入图片描述

  1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()
void clear();//清空有效字符串的内容,使string类对象变为空字符串
void resize (size_t n);
void resize (size_t n, char c);
//将string类有效字符数调整为n,多出的空间为用指定的字符c进行初始化,如果不指定则用'\0'进行初始化
void reserve (size_t n = 0);//为string类预留n字节存储空间大小

eg2:

void Test4()
{
	string str1("hello world");
	printf("string对象的内容为:");
	cout << str1 << endl;
	printf("string类的字符串大小为:");
	cout << str1.size() << endl;
	printf("string类当前的存储容量为:");
	cout << str1.capacity() << endl;
	cout << endl;
	str1.resize(20, 'x');//调整有效字符的个数--调大
	printf("string对象的内容为:");
	cout << str1 << endl;
	printf("string类的字符串大小为:");
	cout << str1.size() << endl;
	printf("string类当前的存储容量为:");
	cout << str1.capacity() << endl;
	cout << endl;
	str1.reserve(50);//调整存储空间的大小--调大
	printf("string对象的内容为:");
	cout << str1 << endl;
	printf("string类的字符串大小为:");
	cout << str1.size() << endl;
	printf("string类当前的存储容量为:");
	cout << str1.capacity() << endl;
	cout << endl;
	str1.clear();//清除有效字符大小
	printf("string对象的内容为:");
	cout << str1 << endl;
	printf("string类的字符串大小为:");
	cout << str1.size() << endl;
	printf("string类当前的存储容量为:");
	cout << str1.capacity() << endl;
}

代码编译运行的结果为:
在这里插入图片描述

  1. clear()只是将string中有效字符清空,不改变底层空间大小。
  2. resize(size_t n)resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)'\0'来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。

eg3:

void Test5()
{
	string str1("hello world");
	printf("string对象的内容为:");
	cout << str1 << endl;
	printf("string类的字符串大小为:");
	cout << str1.size() << endl;
	printf("string类当前的存储容量为:");
	cout << str1.capacity() << endl;
	cout << endl;
	str1.resize(6);//调整有效字符的个数--调小
	printf("string对象的内容为:");
	cout << str1 << endl;
	printf("string类的字符串大小为:");
	cout << str1.size() << endl;
	printf("string类当前的存储容量为:");
	cout << str1.capacity() << endl;
	cout << endl;
	str1.reserve(6);//调整存储空间的大小--调小
	printf("string对象的内容为:");
	cout << str1 << endl;
	printf("string类的字符串大小为:");
	cout << str1.size() << endl;
	printf("string类当前的存储容量为:");
	cout << str1.capacity() << endl;
	cout << endl;
}

代码编译运行的结果为:
加粗样式
注意:

4.resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
5. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好
6. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserve不会改变容量大小

eg4:

void Test6()
{
	string str1("hello world");
	size_t old = str1.capacity();
	cout << "初始容量为:" << str1.capacity() << endl;
	for (int i = 0; i <= 100; i++)
	{
		str1 += 'x';
		if (old != str1.capacity())
		{
			cout << "扩容:" << str1.capacity() << endl;
			old = str1.capacity();
		}
	}
}

代码编译运行的结果为:
在这里插入图片描述

6.在VS2019编译器下,string类以原有容量的1.5倍进行扩容。

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

函数名称:

char& operator[] (size_t pos);
//可以对返回string类对象pos位置的字符进行读写
const char& operator[] (size_t pos) const;
//只能对const string类对象pos位置的字符读取操作,不饿进行修改

eg1:

void Test8()
{
	string str1("hello world");
	//对修改前的str1对象进行读取操作
	for (int i = 0; i < str1.size(); i++)
	{
		cout << str1[i];
	}
	cout << endl;
	//对str1对象进行修改操作
	for (int i = 0; i < str1.size(); i++)
	{
		str1[i]++;//等价于str.operator[i]++
		cout << str1[i];
	}
	cout << endl;
}

代码编译运行的结果为:
在这里插入图片描述
函数名称:

char& at (size_t pos);
//可以对返回string类对象pos位置的字符进行读写
const char& at (size_t pos) const;
//只能对const string类对象pos位置的字符读取操作,不饿进行修改

eg2:

void Test9()
{
	string str1("hello world");
	//对修改前的str1对象进行读取操作
	for (int i = 0; i < str1.size(); i++)
	{
		cout << str1.at(i);
	}
	cout << endl;
	//对str1对象进行修改操作
	for (int i = 0; i < str1.size(); i++)
	{
		str1.at(i)++;
		cout << str1.at(i);
	}
	cout << endl;
}

代码编译运行的结果为:
在这里插入图片描述
函数operator[]与函数at的区别:
eg3:

void Test10()
{
	//operator[]越界访问
	string str1("hello world");
	str1[12]++;
}

代码编译运行的结果为:
在这里插入图片描述
eg4:

void Test11()
{
	//函数at越界访问
	string str1("hello world");
	try//捕获异常
	{
		str1.at(12)++;
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}
}

代码编译运行的结果为:
在这里插入图片描述

string类对象越界访问的时候,函数operator[]通过断言assert报错,函数at通过抛异常报错误。

函数名称:

iterator begin();
const_iterator begin() const;
//begin获取string类第一个字符的迭代器(从左到右)
iterator end();
const_iterator end() const;
//end为获取最后一个字符下一个位置的迭代器(从左到右)

图形理解:
在这里插入图片描述
eg5:

void Test12()
{
	string str1("hello world");
	string::iterator it = str1.begin();
	while (it != str1.end())
	{
		cout << (*it);
		it++;
	}
	cout << endl;
}

代码编译运行的结果为:
在这里插入图片描述
汇编代码:
在这里插入图片描述
eg6:

void Test13()
{
	string str1("hello world");
	for (auto& ch:str1)
	{
		cout << ch;
	}
	cout << endl;
}

代码编译运行的结果为:
在这里插入图片描述
汇编代码:
在这里插入图片描述

①迭代器是像指针一样的类型,可能是指针;②iterator(迭代器)提供一种统一的方式访问和修改容器的数据,使算法可以通过迭代器去处理容器中的数据;③范围for的底层是通过迭代器实现的。

eg7:

void Test14()
{
	//string类使用迭代器
	string str1("hello world");
	cout << "string类使用迭代器遍历的结果:" << endl;
	string::iterator it = str1.begin();
	while (it != str1.end())
	{
		cout << *it;
		it++;
	}
	cout << endl;
	vector<int> v;
	v.push_back(10);
	v.push_back(20);
	v.push_back(30);
	v.push_back(40);
	v.push_back(50);
	cout << "vector使用迭代器遍历的结果:" << endl;
	vector<int>::iterator vit = v.begin();
	while (vit != v.end())
	{
		cout << *vit << " ";
		++vit;
	}
	cout << endl;

	list<int> lt;
	lt.push_back(10);
	lt.push_back(20);
	lt.push_back(30);
	lt.push_back(40);
	lt.push_back(50);
	cout << "list使用迭代器遍历的结果:" << endl;
	list<int>::iterator lit = lt.begin();
	while (lit != lt.end())
	{
		cout << *lit << " ";
		++lit;
	}
	cout << endl;
}

代码编译运行的结果为:
在这里插入图片描述

①任何容器都支持迭代器,并且用法类似;②迭代器跟算法进行配合。

函数名称:

reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
//string类逆置字符串的第一个字符的迭代器(即指向string类从右向左的第一个字符)
reverse_iterator rend();
const_reverse_iterator rend() const;
//string类逆置字符串的最后一个字符下一个位置的迭代器(即指向string类从右向左的最后一个字符的下一个位置)

图形理解
eg8:

void Test15()
{
	string str1("hello world");
	string::reverse_iterator it = str1.rbegin();
	while (it != str1.rend())
	{
		cout << *it;
		it++;
	}
	cout << endl;
}

代码编译运行的结果为:
在这里插入图片描述

①使用反向迭代器,从string类后面向前遍历;②范围for不支持反向迭代器。

3.4string类的修改操作

函数名称:

void push_back (char c);//在字符串后尾插字符c
string (1)	
string& operator+= (const string& str);
//在字符串后追加类对象str
c-string (2)	
string& operator+= (const char* s);
//在字符串后追加一个字符串s
character (3)	
string& operator+= (char c);
//在字符串后追加一个字符c

eg1:

void Test16()
{
	string str1("hello world");
	str1.push_back('x');
	printf("使用push_back追加一个字符后:\n");
	cout << str1 << endl;
	string str2("yyyyy");
	str1 += str2;
	printf("使用operator+=追加str类对象:\n");
	cout << str1 << endl;
	str1 += "abcdef";
	printf("使用operator+=追加字符串:\n");
	cout << str1 << endl;
	str1 += 'u';
	printf("使用operator+=追加一个字符:\n");
	cout << str1 << endl;
}

代码编译运行的结果为:
在这里插入图片描述
函数名称:

string (1)	
string& append (const string& str);
//string类对象追加string类对象的字符串
substring (2)	
string& append (const string& str, size_t subpos, size_t sublen);
//string类对象追加string类subpos位置sublen长度的字符串
c-string (3)	
string& append (const char* s);
//string类对象追加一个常量字符串
buffer (4)	
string& append (const char* s, size_t n);
//string类对象追加常量字符串的前n个字符
fill (5)	
string& append (size_t n, char c);
//string类对象追加n个字符
range (6)	
template <class InputIterator>
   string& append (InputIterator first, InputIterator last);
//string类对象追加一个string类[first,last)区间的字符串

eg2:

void Test17()
{
	string str1("hello world");
	string str2(" fighting");
	str1.append(str2);
	cout << str1 << endl;
}

代码编译运行的结果为:
在这里插入图片描述
注意:

  1. string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。

函数名称:

size_t find (const string& str, size_t pos = 0) const;
size_t find (const char* s, size_t pos = 0) const;
//从stringpos位置往后查找str对象(字符串),并返回第一次出现的位置

eg3:

void Test18()
{
	string str1("hello world");
	size_t ret=str1.find("world");
	cout << ret << endl;
}

代码编译运行的结果为:
在这里插入图片描述
函数名称:

size_t rfind (const string& str, size_t pos = npos) const;
size_t rfind (const char* s, size_t pos = npos) const;
//从stringpos位置往前查找str对象(字符串),并返回第一次出现的位置
//返回的下标是string类的正向下标(从前往后数),而不是逆向的下标(从后往前数)

eg4:

void Test19()
{
	string str1("hello world");
	size_t ret = str1.rfind("world");
	cout << ret << endl;
}

代码编译运行的结果为:
在这里插入图片描述
函数名称:

string substr (size_t pos = 0, size_t len = npos) const;
//返回string类从pos位置len长度的字符串构造的对象

eg5:

void Test20()
{
	string str1("hello world");
	string str2 = str1.substr(6);
	cout << str2 << endl;
}

代码编译运行的结果为:
在这里插入图片描述
函数名称:

const char* c_str() const;
//返回指向string类C语言字符串

eg6:

void Test21()
{
	string str1("hello world");
	cout << str1.c_str() << endl;
}

代码编译运行的结果为:
在这里插入图片描述

3.5string类的非成员函数

函数名称:

string operator+ (const string& lhs, const string& rhs);
string operator+ (const string& lhs, const char*   rhs);
//string类+运算符重载,使用传值返回,深拷贝效率低

eg1:

void Test22()
{
	string str1("hello world");
	string str2(" fighting");
	string str3 = str1 + str2;
	cout << str3 << endl;
	str3 = str1 + " abc";
	cout << str3 << endl;
}

代码编译运行的结果为:
在这里插入图片描述
函数名称:

istream& operator>> (istream& is, string& str);//string类输入运算符重载,遇到空格、'\n',停止读取
ostream& operator<< (ostream& os, const string& str);//string类输出运算符重载

eg2:

void Test23()
{
	string str1;
	cin >> str1;//使用operator>>运算符重载读取(遇到空格、'\n'停止读取)
	cout << str1 << endl;//使用operator<<运算符重载写入
}

代码编译运行的结果为:
在这里插入图片描述
函数名称:

istream& getline (istream& is, string& str, char delim);
istream& getline (istream& is, string& str);
//获取一行字符串给string类对象,可以指定delim终止符,不指定则默认以'\n'为终止符

eg3:

void Test24()
{
	string str1;
	getline(cin, str1);
	cout << str1 << endl;
}

代码编译运行的结果为:
在这里插入图片描述

总结

本章节我们一起学习了string类常用接口函数,希望对大家了解string类有些许帮助,感谢大家阅读,若有不对欢迎纠正!🎠🎠🎠

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

0807|IO进程线程day9 IPC对象概念及示例(消息队列、共享内存、信号灯集)

0 什么是IPC机制 概念&#xff1a; IPC机制&#xff1a;Inter Process Communication&#xff0c;即进程间通信机制。 进程与进程间的用户空间相互独立&#xff0c;内核空间共享。所以如果要实现进程间的通信&#xff0c;需要使用进程间通信机制。 分类&#xff08;3类…

物联网潜在的巨大价值在于大数据分析

物联网潜在的巨大价值在于大数据分析 从数据里去挖掘市场或者用户的精准需求。 往小的说&#xff0c;后台可以统计用户家里各各插座一年甚至更久的用电情况&#xff0c;这些数据也可以通过app或者小程序展现给用户。 用户可以很直观看到自己一年的用电情况&#xff0c;哪个家…

【Grafana】中文界面配置 v10.0.3

比如通过 docker run -d -p 3000:3000 -v /e/code/monitor/grafana/grafana.ini.txt:/etc/grafana/grafana.ini grafana/grafana运行一个容器&#xff08;最新是v10.0.3&#xff09;。 在 /admin/settings 可以看到 users 部分有一个 default_language 配置。 所以在挂载到 …

读取文件和写入文件操作

在java中会涉及到对文件进行读取和写入操作&#xff0c;以下将介绍如何用java对文件进行读取和写入 读取 通过Readr读取字符流文件中的数据 读取字符流文件中的数据表示以字符为单位进行读取 package 文件操作;import java.io.*;/*** Created with IntelliJ IDEA.* Descript…

Docker 容器化学习

文章目录 前言Docker架构 1、 docker安装2、启动docker服务3、设置docker随机器一起启动4、docker体验5、docker常规命令5.1、容器操作docker [run|start|stop|restart|kill|rm|pause|unpause]docker [ps|inspect|exec|logs|export|import] 5.2、镜像操作docker images|rmi|tag…

深入了解 PostgreSQL 扩展插件

深入了解 PostgreSQL 扩展插件 在 PostgreSQL 数据库中&#xff0c;扩展插件是极具价值的工具&#xff0c;它们为我们提供了丰富多样的功能增强。本篇博客将深入介绍几个常用的 PostgreSQL 扩展插件&#xff0c;包括 pg_stat_statements、uuid、postgis 以及 postgis_raster。…

vector模拟实现

vector模拟实现 构造函数拷贝构造函数析构函数赋值运算符重载容量大小相关的函数size()capacity()reserveresize 修改容器内容相关函数push_backpop_backinserteraseswap 访问容器内容相关函数operator[] 与迭代器相关函数begin()和end()关于迭代器失效的问题 构造函数 vector…

【JVM】垃圾回收 ——自问自答2

Q: System.gc() 的理解 System.gc()底层调用的是 Runtime.getRuntime.gc(),会现实出发FullGC。 但是&#xff0c;它的调用附带一个免责声明&#xff0c;无法保证对垃圾收集器的调用。 Q&#xff1a; 内存溢出和内存泄漏&#xff1f; 内存溢出&#xff1a; 简而言之&#xf…

删除这4个文件夹,流畅使用手机无忧

在现代社会中&#xff0c;手机已经成为我们生活中不可或缺的一部分。然而&#xff0c;随着使用时间的增长&#xff0c;我们可能会遇到手机卡顿和内存不足的问题&#xff0c;让我们感到十分困扰。手机卡顿不仅影响使用体验&#xff0c;还可能导致应用程序运行缓慢&#xff0c;甚…

3分钟白话RocketMQ系列—— 核心概念

白话3分钟&#xff0c;快速了解RocketMQ基础&#xff0c;包括适用场景&#xff0c;以及基本概念。 看完如果不了解&#xff0c;欢迎来打我。 关键字摘要 低延迟、高可用、高可靠、高并发 的消息中间件适合在线业务分为producer、consumer、nameserver、broker等角色另外还有主…

第3章 语言基础

引言 任何语言的核心所描述的都是这门语言在最基本的层面上如何工作&#xff0c;涉及语法、操作符、数据类型以及内置功能&#xff0c;在此基础之上才可以构建复杂的解决方案 本章接下来的内容主要基于ECMAScript第6版。ES6 语法 js的语法借鉴了c/c&#xff0c;java。js是相对…

快速消除视频的原声的技巧分享

网络上下载的视频都会有视频原声或者背景音乐&#xff0c;如果不喜欢并且想更换新的BGM要怎么操作呢&#xff1f;今天小编就来教你如何快速给多个视频更换新的BGM&#xff0c;很简单&#xff0c;只需要将原视频的原声快速消音同时添加新的背景音频就行&#xff0c;一起来看看详…

c语言函数作为形参的注意事项

1、c语言数组作为形参会退化成数组指针 #include "stdio.h" #include <stdlib.h>//数组作为函数的形参会退化成指针 void print_arr(int a[5]);// int *b int main() {int arr[5] { 1,2,3,4,5 };print_arr(arr);return 0; }void print_arr(int a[5]) {printf…

UVA1347 旅行 Tour (样例解释 + 思路心得 + 代码)

目录 题目大意 样例解释 第一组样例解释 第二组样例解释 有注释的代码 没有注释的代码 题目大意 样例解释 &#xff08;多组样例&#xff09; 第一组样例解释 第二组样例解释 &#xff08;没有注释的代码实际上很短 在后面&#xff09; 有注释的代码 思路和心得都在代码里, 快…

【Linux】计算机网络的背景和协议分层

文章目录 网络发展协议何为协议网络协议协议分层OSI七层模型TCP/IP五层模型&#xff08;四层&#xff09; 基本通信流程mac地址和ip地址网络通信本质 网络发展 从一开始计算机作为一台台单机使用&#xff0c;到现在网络飞速发展&#xff0c;从局域网Lan建立起局域网&#xff0…

git bash 安装sdkadmin

1.下载相关安装包,复制到git 安装目录 D:\software\Git\mingw64\bin 2. 运行 curl -s "https://get.sdkman.io" | bash

Service not registered 异常导致手机重启分析

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、Service not registered 异常导致手机重启二、Service not registered 解决方案 一、Service not registered 异常导致手机重启 1.重启 的部分Log如…

某大型医院门户网站性能分析案例

故障现象 门户网站近期出现少量的访问体验慢现象&#xff0c;主要是由于服务器响应时间慢。出现慢页面的页面簇为&#xff1a;http://www.xxx.ac.cn/。 分析过程 下面将分析异常原因:页面的URL信息&#xff1f;页面慢的原因&#xff1f; 性能问题分析&#xff0c;定位到慢访…

不可错过的家装服务预约小程序商城开发指南

在当今社会&#xff0c;家装行业发展迅速&#xff0c;越来越多的人开始寻求专业的家装预约和咨询服务。对于不懂技术的新手来说&#xff0c;创建一个自己的家装预约咨询平台可能听起来很困难&#xff0c;但实际上通过一些第三方制作平台和工具&#xff0c;这个过程可以变得简单…

ES6 数组的用法

1. forEach() 用来循环遍历的 for 数组名.forEach(function (item,index,arr) {})item:数组每一项 , index : 数组索引 , arr:原数组作用: 用来遍历数组 let arr [1, 2, 3, 4]; console.log(arr); let arr1 arr.forEach((item, index, arr) > {console.log(item, index…