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

news2024/12/23 19:48:04

目录

  • 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类有些许帮助,感谢大家阅读,若有不对欢迎纠正!🎠🎠🎠

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

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

相关文章

【《深入浅出计算机网络》学习笔记】第1章 概述

内容来自b站湖科大教书匠《深入浅出计算机网络》视频和《深入浅出计算机网络》书籍 目录 1.1 信息时代的计算机网络 1.1.1 计算机网络的各类应用 1.1.2 计算机网络带来的负面问题 1.2 因特网概述 1.2.1 网络、互联网与因特网的区别与关系 1.2.1.1 网络 1.2.1.2 互联网 …

[LitCTF 2023]Http pro max plus

打开环境后提示说&#xff0c;只允许在本地访问&#xff0c;本地访问&#xff0c;还是想到了XFF字段 好家伙的&#xff0c;直接被嘲讽&#xff0c;还是了解太少了&#xff0c;都不知道还有没有其他方式可以控制ip地址信息 经过查看wp&#xff0c;得知一种新的方式 Client-IP …

【flink】Checkpoint expired before completing.

使用flink同步数据出现错误Checkpoint expired before completing. 11:32:34,455 WARN org.apache.flink.runtime.checkpoint.CheckpointFailureManager [Checkpoint Timer] - Failed to trigger or complete checkpoint 4 for job 1b1d41031ea45d15bdb3324004c2d749. (2 con…

Spring Boot集成EasyExcel实现excel导入导出操作

文章目录 Spring Boot集成EasyExcel实现excel导入导出操作0 简要说明简单使用读操作excel源文件实体类监听器业务代码 写操作*实体类*excel示例业务代码根据参数指定列导出指定哪几列导出复杂头导出 关于数值型&#xff0c;日期型&#xff0c;浮点型数据解决方案实体类接收字符…

ElasticSearch:全文检索及倒排索引原理

1.从全文检索说起 首先介绍一下结构化与非结构化数据&#xff1a; 结构化数据将数据具有的特征事先以结构化的形式定义好&#xff0c;数据有固定的格式或有限的长度。典型的结构化数据就是传统关系型数据库的表结构&#xff0c;数据特征直接体现在表结构的字段上&#xff0c;…

【数据结构OJ题】消失的数字

原题链接&#xff1a;https://leetcode.cn/problems/missing-number-lcci/ 目录 1. 题目描述 2. 思路分析 3.代码实现 1. 题目描述 2. 思路分析 方法一&#xff1a;排序遍历&#xff08;下一个数不等于上一个数1&#xff0c;这个下一个数就是消失的数字&#xff09;。 时…

吃透这款最流行的数据库,技术生涯就稳了

名字&#xff1a;阿玥的小东东 学习&#xff1a;Python、C/C 主页链接&#xff1a;阿玥的小东东的博客_CSDN博客-python&&c高级知识,过年必备,C/C知识讲解领域博主 目录 用好 MySQL 是技术人的基本盘 打稳底盘&#xff1a;学会使用 MySQL 成为高手&#xff1a;摸透底…

GraphGT: Machine Learning Datasets for Graph Generation and Transformation

一、文章来源 > Du Y, Wang S, Guo X, et al. Graphgt: Machine learning datasets for graph generation and transformation[C]//Thirty-fifth Conference on Neural Information Processing Systems Datasets and Benchmarks Track (Round 2). 2021.二、概述 1、文章提出…

使用docker搭建GPT服务

不用ChatGPT账号,不用API,直接免费使用上官方原版的GPT4.0! 这个操作主要使用的是GitHub上的一个开源项目freegpt。 通过docker把这个项目打包到本地电脑上,直接就能使用上原版GPT4.0。 第一步:下载Docker 下载网址:docker.com 根据自己的电脑系统下载对应的版本即可 下…

03微服务到底是什么

一句话导读 微服务是一种架构模式&#xff0c;英文翻译 microservice&#xff0c;微服务架构的核心理念是将大型、复杂的单体应用拆分成更小的、自治的组件&#xff0c;每个组件即为一个微服务 目录 一句话导读 一、微服务的定义 二、微服务的特点 1.独立性 2.松耦合 3.可伸…

第三章 图论 No.5最小生成树之虚拟源点,完全图与次小生成树

文章目录 虚拟源点&#xff1a;1146. 新的开始贪心或kruskal性质&#xff1a;1145. 北极通讯网络最小生成树与完全图&#xff1a;346. 走廊泼水节次小生成树&#xff1a;1148. 秘密的牛奶运输 虚拟源点&#xff1a;1146. 新的开始 1146. 新的开始 - AcWing题库 与一般的最小…

鸿蒙边缘计算网关正式开售

IDO-IPC3528鸿蒙边缘计算网关基于RK3568研发设计&#xff0c;采用22nm先进工艺制程&#xff0c;四核A55 CPU&#xff0c;主频高达2.0GHz&#xff0c;支持高达8GB高速LPDDR4&#xff0c;1T算力NPU&#xff0c;4K H.265/H264硬解码&#xff1b;视频输出接口HDMI2.0&#xff0c;双…

JAVA SE -- 第十六天

&#xff08;全部来自“韩顺平教育”&#xff09; IO流 一、文件 是保存数据的地方 2、文件流 文件在程序中是以流的形式来操作 流&#xff1a;数据在数据源&#xff08;文件&#xff09;和程序&#xff08;内存&#xff09;之间经历的路径 输入流&#xff1a;数据从数据…

UltraToolBars Crack,动画菜单和多种显示样式

UltraToolBars Crack,动画菜单和多种显示样式 创建模仿Microsoft Office 2000外观的健壮应用程序。 UltraToolBars包括11个用于创建可自定义工具栏的界面增强控件&#xff0c;包括&#xff1a;个性化菜单、弹出型工具栏、集成选项卡控件等。PictureRegion技术使表单和组件能够采…

基于Java的新闻全文搜索引擎的设计与实现

中文摘要 本文以学术研究为目的&#xff0c;针对新闻行业迫切需求和全文搜索引擎技术的优越性&#xff0c;设计并实现了一个针对新闻领域的全文搜索引擎。该搜索引擎通过Scrapy网络爬虫工具获取新闻页面&#xff0c;将新闻内容存储在分布式存储系统HBase中&#xff0c;并利用倒…

Go 语言面试题(一):基础语法

文章目录 Q1 和 : 的区别&#xff1f;Q2 指针的作用&#xff1f;Q3 Go 允许多个返回值吗&#xff1f;Q4 Go 有异常类型吗&#xff1f;Q5 什么是协程&#xff08;Goroutine&#xff09;Q6 如何高效地拼接字符串Q7 什么是 rune 类型Q8 如何判断 map 中是否包含某个 key &#xf…

STM32--GPIO

文章目录 GPIO简介GPIO的基本结构GPIO位结构GPIO模式LED和蜂鸣器LED闪烁工程及程序原码代码&#xff1a; 蜂鸣器工程和程序原码代码 传感器光敏传感器控制蜂鸣器工程代码 GPIO简介 GPIO&#xff08;General Purpose Input Output&#xff09;是通用输入/输出口的简称。它是一种…

利用el-button 画圆 ,通过border-radius >50% 就成圆形

<el-button type"danger" style"border-radius: 100%; height: 100px;width: 100px;" plain><span style"font-weight: bold;">工艺分析</span></el-button>通过border-radius >50% 就成圆形。 border-radius: 50% …

STM32基础入门学习笔记:面包板 配件包扩展模块与编程

文章目录&#xff1a; 一&#xff1a;阵列键盘 1.阵列键盘测试程序 KEYPAD4x4.h KEYPAD4x4.c main.c 2.键盘中断测试程序 NVIC.h NVIC.c main.c 二&#xff1a;舵机控制 1.延时函数驱动舵机程序 SG90.h SG90.c main.c 2.PWM(脉冲宽度调制 脉宽调制/占空比)驱动…

极海APM32F003F6P6烧写问题解决记录

工作中遇到的&#xff0c;折腾了好久&#xff0c;因为电脑重装过一遍系统&#xff0c;软件也都重新安装了&#xff0c;所以不知道之前的配置是什么&#xff0c;旧项目代码编译没问题&#xff0c;烧写时疯狂报错&#xff0c;用的是JLink。 keil版本v5.14 win10版本 JLink版本…