C++全系列学习(基础篇)
RechoYit 2024-10-25 10:35:02 阅读 90
一、基础语法
1、数据类型
基本数据类型:
int | 用于表示整数 |
float | 用于表示单精度浮点数 |
double | 用于表示双精度浮点数 |
char | 用于表示字符 |
bool | 用于表示布尔值,只能取 <code>true 或 false |
void | 表示无类型,通常用于函数返回类型或指针类型 |
复合数据类型:
数组 | 由相同类型的元素组成的集合 |
结构体(<code>struct) | 由不同类型的成员组成的复合类型 |
枚举(enum ) | 一组具有命名值的常量 |
类(class ) | 一种封装数据和操作的方式,支持面向对象编程 |
指针(pointer ) | 存储内存地址的变量,用于间接访问内存中的数据 |
引用(reference ) | 提供现有变量的别名,用于简化代码和避免复制 |
引例:
int a = 10;
cout<<sizeof(a)<<endl; //统计该变量所占内存大小
//科学计数法
float a = 3e2; //表示3*10^2
float a = 3e-2; //表示3*10^-2
//字符串
a = 'b'
a = "b"
a = "hello" //单个字符时可用''或"",字符串只能用""
//转义字符
cout<<"hello\n"<<endl; \n为换行符
cout<<"aa\thello"<<endl;
cout<<"aaaa\thello"<<endl;
cout<<"a\thello"<<endl; //\t为水平制表符,可整齐输出数据
2、运算符
算数运算符
/可以是两个小数相除,若是两个整数相除则结果向下取整
%为取模
递增递减
++ | 前置递增 | a=2,b=++a | a=3,b=3 |
++ | 后置递增 | a=2,b=a++ | a=3,b=2 |
-- | 前置递减 | a=2,b=--a | a=1,b=1 |
-- | 后置递减 | a=2,b=a-- | a=1,b=2 |
所谓前置就是先加1,后置就是先运算
逻辑运算符
运算符 | 术语 | 示例 | 结果 |
! | 非 | !a | 若a为假则!a为真 |
&& | 与 | a&&b | 若a与b都为真则为真,否则为假 |
|| | 或 | a||b | 若a与b有一个为真则为真,否则为假 |
3、数组
一维数组
3种定义方式:
1)数据类型 数组名[数组长度];
2)数据类型 数组名[数组长度] = {值1,值2,……}
注意:若实际值与长度不同时,自动用0补足
3)数据类型 数组名[] = {值1,值2,……}
arr[0] = 1;
int arr2[4] = {1,2,3,4};
int arr3[] = {1,2,3};
获取首地址
两种方式:arr或&arr[0]
数组长度统计
数组占用内存空间大小:sizeof(arr)
数组单个元素占用内存空间大小:sizeof(arr[0])
数组长度:sizeof(arr) / sizeof(arr[0])
冒泡排序(后文具体介绍)
比较相邻元素: 从第一个元素开始,比较相邻的两个元素,如果它们的顺序不正确(比如在升序排序中,前一个元素大于后一个元素),则交换它们。
一次遍历完成: 经过一次遍历,最大(或最小)的元素会被移到序列的最后位置。
重复步骤1和2: 重复进行上述步骤,直到序列完全有序。在每次遍历中,待排序序列的长度减一,因为每次遍历都会将一个元素放置到了正确的位置上
二维数组
定义方式
二维数组定义的4种方式:
1)数据类型 数组名[ 行数 ][ 列数 ];
2)数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2} ,{数据3,数据4} };
3)数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
4)数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4}
注意:常用第二种,可读性较强
int array2D[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
cout << "Array elements:" << endl;
for(int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j) {
cout << array2D[i][j] << " ";
}
cout << endl;
}
Array elements:
1 2 3
4 5 6
7 8 9
计算行数与列数
二维数组的行数:sizeof(arr) / sizeof(arr[0])
二维数组的列数:sizeof(arr[0]) / sizeof(arr[0][0])
地址
二维数组首地址:arr[0]
或 &arr[0][0]
二维数组第1个元素的地址: arr[0]
或 &arr[0][0]
二维数组第 0 行的地址: arr
或arr[0]
或arr + 0
二维数组第 i 行的地址:arr[i]
或arr + i
二维数组第 i 行首元素的地址:arr[i]
或arr + i
或*(arr + i)
或&a[0] + i
二维数组第 i 行第 j 列元素的地址:&arr[i][j]
或*(arr + i) + j
4、循环
for循环
<code>#include<bits/stdc++.h>
using namespace std;
int main ()
{ int sum=0;
for (int i=1; i<=100 ; ++i)
sum+=i;
cout<<sum;
return 0;
}
while循环
while(表达式)语句;
while(表达式){
语句1;
语句2;
}
例:用while打印数组
#include <iostream>
using namespace std;
int main() {
int array[] = {1, 2, 3, 4, 5};
int length = sizeof(array) / sizeof(array[0]); // 计算数组的长度
cout << "Array elements: ";
int i = 0; // 初始化计数器
while (i < length) {
cout << array[i] << " ";
i++; // 更新计数器
}
cout << endl;
return 0;
}
do-while循环
do{
语句1;
语句2;
}
while(条件表达式)
示例:获取输入,直到输入的值为正数为止
#include <iostream>
using namespace std;
int main() {
int num;
do {
cout << "请输入一个正数:";
cin >> num;
} while (num <= 0);
cout << "你输入的正数是:" << num << endl;
return 0;
}
while和do-while的区别:
while 循环:
在 while
循环中,循环条件会在每次循环开始之前被检查。如果条件为真,循环体会执行,然后再次检查条件。如果条件为假,循环终止。这意味着,如果条件一开始就为假,循环体可能一次都不会执行。
do-while 循环:
在 do-while
循环中,循环体会先执行一次,然后再检查循环条件。只要条件为真,循环体会继续执行,否则循环终止。这意味着,do-while
循环至少会执行一次循环体,即使条件一开始就为假。
嵌套循环
示例:水仙花数字
#include<bits/stdc++.h>
using namespace std;
int main()
{ for (int a=1; a<=9; ++a)
for (int b=0; b<=9; ++b)
for (int c=0; c<=9; ++c)
{ if (a*a*a+b*b*b+c*c*c==a*100+b*10+c)
cout<<setw(6)<<a*100+b*10+c; //setw函数控制输出场宽
}
return 0;
}
5、条件语句(if)
单行格式if
#include <iostream>
using namespace std;
int main() {
int num;
cout << "请输入一个整数:";
cin >> num;
if (num > 0) {
cout << "这是一个正数。" << endl;
}
return 0;
}
多行格式if
#include <iostream>
using namespace std;
int main() {
int num;
cout << "请输入一个整数:";
cin >> num;
if (num > 0) {
cout << "这是一个正数" << endl;
}
else if (num == 0){
cout << "0" << endl;
}
else{
cout << "这是一个负数" << endl;
}
return 0;
}
6、结构体
语法
struct 结构体名 { 结构体成员列表 };
结构体创建变量
#include <iostream>
using namespace std;
// 定义一个名为 Person 的结构体
struct Person {
string name;
int age;
double height;
};
int main() {
// 创建一个 Person 类型的对象
struct Person person1;
// 给结构体成员赋值
person1.name = "Alice";
person1.age = 30;
person1.height = 5.6;
// 输出结构体成员的值
cout << "Name: " << person1.name << endl;
cout << "Age: " << person1.age << endl;
cout << "Height: " << person1.height << endl;
struct Person person2 = {"BEN",40,4.4};
return 0;
}
结构体数组
#include <iostream>
#include <string>
using namespace std;
// 定义一个名为 Person 的结构体
struct Person {
string name;
int age;
double height;
};
int main() {
// 使用大括号初始化结构体数组
Person people[3] = {
{"Alice", 30, 5.6},
{"Bob", 25, 6.0},
{"Charlie", 35, 5.9}
};
// 输出结构体数组中每个结构体的成员值
for (int i = 0; i < 3; ++i) {
cout << "Person " << i+1 << ":" << endl;
cout << "Name: " << people[i].name << endl;
cout << "Age: " << people[i].age << endl;
cout << "Height: " << people[i].height << endl;
cout << endl;
}
return 0;
}
结构体指针
#include <iostream>
using namespace std;
// 定义一个名为 Person 的结构体
struct Person {
string name;
int age;
double height;
};
int main() {
// 创建一个 Person 类型的结构体指针
struct Person* p = new Person;
// 使用 -> 运算符给结构体成员赋值
p->name = "Alice";
p->age = 30;
p->height = 5.6;
// 使用 -> 运算符访问结构体成员并输出
cout << "Name: " << p->name << endl;
cout << "Age: " << p->age << endl;
cout << "Height: " << p->height << endl;
// 记得释放动态分配的内存
delete p;
return 0;
}
结构体嵌套
结构体中成员是另一个结构体
7、函数
主函数为main(),但可以创作其他函数进行运算,只需在主函数中调用即可,以下以阶乘为例
#include <iostream>
using namespace std;
int factorial(int n){
if(n==1)
return n;
else
return n*factorial(n-1);
}
int main()
{
int n;
cout << "请输入整数:" << endl;
cin >> n;
cout << "整数:" << n << "的阶乘为:" << factorial(n) << endl;
cout << "\n" << endl;
return 0;
}
二、STL库
STL(Standard Template Library)是 C++ 标准库的一部分,它提供了一组通用的模板类和函数,用于实现常见的数据结构和算法。STL 的设计旨在提供一种高效、灵活和可重用的方法来处理数据结构和算法问题。总的来说,STL库装了许多算法和组件,包含多种函数,可用于开发各类应用程序
1、快速排序(Sort)
基本用法
格式:
void sort(起始地址,结束地址,比较函数);
#include<algorithm>
#include<iostream>
using namespace std;
int main(){
int a[] = {2,3,5,4,1,8,6,9};
sort(a,a+8);//a为数组的开头,a+8就等于排序到数组的第8个元素
for(int i=0;i<6;i++)
cout<<a[i]<<" ";
}
cmp用法
在sort比较函数中传入排序函数,>为降序,<为升序
#include<algorithm>
#include<iostream>
using namespace std;
bool cmp(int x,int y)
{
if(x>y)return true;//降序
return false;
}
int main(){
int a[] = {2,3,5,4,1,8,6,9};
sort(a,a+8,cmp);//a为数组的开头,a+8就等于排序到数组的第8个元素
for(int i=0;i<6;i++)
cout<<a[i]<<" ";
}
2、关联容器(Map)
map是一个关联容器,它提供了一种将键与值关联起来的方式,map中的每个元素都是一个键(key-value pair),其中键(key)是唯一的,值(value)则可以不唯一。它基于红黑树(Red-Black Tree)实现。
注意:map不允许容器中有重复的key值,multimap允许容器中有重复的key
格式:
map(数据类型,数据类型)一个自定义的名称;
#include <iostream>
#include <map>
int main() {
map<string, int> phonebook;
phonebook["Alice"] = 123456;
phonebook["Bob"] = 789012;
phonebook["Charlie"] = 345678;
cout << "Bob's phone number: " << phonebook["Bob"] << endl;
phonebook["Alice"] = 111111;
phonebook.erase("Charlie");
// 遍历元素
for (const auto& pair : phonebook) {
cout << pair.first << "'s phone number: " << pair.second <<endl;
}
return 0;
}
1)构造
map<T1,T2> mp; | map对象默认构造形式 |
map(const map &qmp); | 拷贝构造函数 |
2)赋值
map& operator=(const map &mp); | 重载等号操作符 |
3)大小和交换
size();
| 返回容器中元素数目 |
empty(); | 判断容器是否为空 |
swap(st); | 交换两个集合容器 |
4)插入和删除
insert(elem); | 在容器中插入元素 |
clear(); | 清除所有元素 |
erase(pos); | 删除pos迭代器所指的元素,返回下一个元素的选代器 |
erase(beg,end); | 删除区间[beg,end)的所有元素,返回下一个元素的迭代器 |
erase(elem); | 删除容器中值为elem的元素。 |
5)查找和统计
find(key); | 查找是否存在key,若存在返回该键的元素的迭代器,若不存在,返回set.end() |
count(key); | 统计key的元素的个数 |
3、栈(stack)
相当于是一个小箱子,每次向箱子顶部塞入数据,遵循先进后出(Last In, First Out,LIFO)的原则。栈可以被看作是一种容器,其中元素按照后进先出的顺序进行插入和删除。
格式:
<code>#include<stack>
stack<数据类型>一个自定义的名字;
或:
stack 一个自定义的名字;
栈的成员函数
.empty() | 判断栈是否为空,空则返回true |
.push(…) | 在栈顶增加元素 |
.pop() | 在栈顶移除元素 |
.top() | 返回栈顶元素 |
.size() | 返回栈的元素数量 |
代码示例:
<code>#include<stack>
#include<iostream>
using namespace std;
stack<int> st;
int main(){
st.push(1);
st.push(2);
st.push(3);
cout<<st.top();
return 0;
}
输出:
3
4、动态数组容器(Vector)
使用的时候可以看作数组,但他相对于数组来说可以动态扩展,增加长度
1)构造
头文件:#include<vector>
构造:vector<T> v ;
放入数据:v.push_back(…);
迭代器:vector<int>::iterator
将[v.begin(),v.end())区间中的元素拷贝给本身:vector(v.begin(),v.end());
将n个elem拷贝给本身:vextor(n,elem);
拷贝构造函数:vector(const vector &v) ;
void printVector(vector<int>& v)
{//利用迭代器打印 v
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
void text01()
{
vector<int> v1;
for (int i = 0; i < 5; ++i)
{
v1.push_back(i);//向v1末尾添加数据
}
vector<int> v2(v1.begin(), v1.end()); //构造2
vector<int> v3(5, 5); //构造3
vector<int> v4(v3); //构造4
cout << "打印v2: ";
printVector(v2);
cout << "打印v3: ";
printVector(v3);
cout << "打印v4: ";
printVector(v4);
}
2)遍历
v.begin() | 返回迭代器,这个迭代器指向容器中第一个数据 |
v.end() | 返回迭代器,这个迭代器指向容器元素的最后元素的下一个位置 |
vector<int>::iterator | 拿到这种容器的迭代器类型 |
第一种遍历方式
<code>vector<int>::iterator pBegin = v.begin();
vector<int>::iterator pEnd = v.end();
while(pBegin != pEnd){
cout<<*pBegin<<endl;
pBegin++;
}
第二种遍历方式
for (vector<int>::iterator it = v.begin();it != v.end();it++){
cout<<*it<<endl;
}
3)赋值
vector& operator=(const vector &v); | 重载赋值运算符 |
assign(v.begin(),v.end()); | 将[v.begin(),v.end())区间中的元素赋值给本身 |
assign(n,elem); | 将n个elem赋值给本身 |
<code>void printVector(vector<int>& v)
{//利用迭代器打印 v
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
void text02()
{
vector<int> v1,v2;
for (int i = 0; i < 5; ++i)
{
v1.push_back(i);
}
v2 = v1;
vector<int> v3,v4;
v3.assign(v1.begin(), v1.end());
v4.assign(10,100);
cout << "打印v2: ";
printVector(v2);
cout << "打印v3: ";
printVector(v3);
cout << "打印v4: ";
printVector(v4);
}
4)容量和大小
empty(); | 判断容器是否为空 |
capacity(); | 容器容量 |
size(); | 容器中元素个数 |
resize(int num); | 重新指定长度num,变短删末尾元素,变长以默认值填充新位置 |
resize(int num,elem); | 重新指定长度num,变短删末尾元素,变长以elem填充新位置 |
5)插入和删除
push_back(elem); | 尾部插入元素elem |
pop_back(); | 删除最后一个元素 |
insert(const_iterator pos,elem); | 指向的位置pos处插入一个元素elem |
insert(const_iterator pos,int count,elem); | 指向的位置pos处count元素elem |
erase(const_iterator pos); | 指向的位置pos处删除元素 |
erase(const_iterator start,const_iterator end); | 删除start到end之间的元素
|
clear(); | 清空所有元素 |
6)数据存取
at(int id); | 返回id处数据 |
operator[];
| 返回[]处数据 |
front(); | 返回第一个数据 |
back(); | 返回最后一个数据 |
7)互换容器
swap(vec); | 将vec与本身元素互换 |
<code>v1.swap(v2)
8)预留空间
reserve(int len); | 预留len个元素长度 |
当数据量较大时可以一开始就利用reserve预留空间
5、String
string内部封装了许多成员方法,如find,copy,delete,insert,replace等
头文件:#include<string>
1)构造
string(); | 构造空字符串 |
string(const char* s); | 拷贝s所指向的字符串序列,使字符串s初始化 |
string(const char* s, size_t n); | 拷贝s所指向的字符串序列的第n个到结尾的字符 |
string(size_t n, char c); | 将字符c复制n次 |
string(const string& str); | 拷贝构造函数。使用一个string对象初始化另一个对象 |
string(const string& str, size_t pos, size_t n = npos); | 拷贝s中从pos位置起的n个字符,若npos>字符串长度,就拷贝到字符串结尾结束 |
<code>#include<string>
void test1(){
string s1; //创建空字符串,使用无参构造函数
const char*str = "hello";
string s2(str);
string s3(s2); //调用拷贝构造函数
string s4(10,'a'); //将字符a复制10次
string s5(s2,1);//拷贝s2所指向的字符串序列的第1个到结尾的字符
}
2)赋值
string& operator=(const char* s); | char*类型字符串赋值给当前的字符串 |
string& operator=(const string &s); | 把字符串s赋给当前的字符串 |
string& operator=(char c); | 字符赋值给当前的字符串 |
string& assign(const char *s); | 把字符串s赋给当前的字符串 |
string& assign(const char *s, int n); | 把字符串s的前n个字符赋给当前的字符串 |
string& assign(const string &s); | 把字符串s赋给当前字符串 |
string& assign(int n, char c); | 用n个字符c赋给当前字符串 |
3)字符串插入、拼接和删除
插入:
void push_back (char c); | 向字符串末尾追加一个字符 |
string& insert(size_t pos, const string& str);
| 插入字符串拷贝 |
string& insert (size_t pos, const char* s); | 插入c形式的字符串 |
string& insert (size_t pos, const char* s, size_t n); | 将字符串s的前n个字符插到pos位置 |
<code>#include<iostream>
#include<string>
using namespace std;
int main()
{
string s0("");
s0.push_back('a');//s0尾插入a
string s1("b");
s0.insert(1, s1);//在下标为1的位置插入s1的拷贝
s0.insert(4, "c");//在下标为4的位置插入字符串o
s0.insert(0, "hello",2);//在下标为0的位置插入"hello"的前2个字符
return 0;
}
拼接:
string& operator+=(const char* str); | 重载+=操作符 |
string& operator+=(const char c); | 重载+=操作符 |
string& operator+=(const string& str); | 重载+=操作符 |
string& append(const char *s); | 把字符串s连接到当前字符串结尾 |
string& append(const char *s, int n); | 把字符串s的前n个字符连接到当前字符串结尾 |
string& append(const string &s); | 同operator+"(const string& str) |
string& append(const string &s,int pos,int n); | 字符用s中从pos开始的n个字符连接到字符串结尾
|
删除:
string& erase(int pos, int n = npos); | 删除从pos开始的第n个字符 |
<code>str.erase(1,3); //从1号位置开始删除3个字符
4)查找和替换
int find(const string& str, int pos = 0) const; | 查找str最后一次位置,从pos开始查找 |
int find(const char*s, int pos =0)const; | 查线s第一次出现位置,从pos开始查找 |
int find(const char* s, int pos, int n) const; | 从pos位置查找s的前n个字符第一次位置 |
int find(const char c, int pos=0) const; | 查找字符c第一次出现位置 |
int rfind(const string& str, int pos = npos) const; | 查找str最后一次位置,从pos开始查找 |
int rfind(const char* s, int pos = npos) const; | 查找s最后一次出现位置.从pos开始查找 |
int rfind(const char* s, int pos, int n) const; | 从pos查找s的前n个字符最后一次位置 |
int rfind(const char c, int pos = 0) const; | 查找李符c最后一次出现位置 |
string& replace(int pos, int n, const string& str); | 替换从pos开始n个字符为字符串str |
string& replace(int pos, int n, const char* s); | 替换从pos开始的n个字符为字符串s |
注意:
find是从左往右查找,rfind是从右往左查找
find找到字符串后返回查找的第一个字符位置,找不到就返回-1
replace在替换时,要指定从哪个位置起,替换多少个字符,替换成什么
5)字符串的比较
int compare(const string &s) const; | 与字符串s比较 |
int compare(const char *s) const: | 与字符串s比较 |
注意:若=则返回0,>返回1,<返回-1
string s1="hello";code>
string s2="hhllo";code>
int ret = s1.compare(s2);
……
return 0;
}
6)字符串存取
char& operator[](int n); | 通过[]方式取字符 |
char& at(int n); | 通过at方式取字符 |
string str = "hello world"
for (int i = 0;i < str.size();i++){
cout << str[i] << " ";
cout << str.at(i) << " ";
}
cout<<endl;
}
//字符修改:
str[0] = "x";
str.at(1) = "x";
return 0;
}
7)子串
string substr(int pos=0,int n = npos) const; | 返回由pos开始的n个字符组成的字符串 |
<code>void teste1(){
string str ="abcdefg";
string substr = str.substr(1,3)
cout<<"substr ="<< substr << endl;
string email="hello@sina.com";code>
int pos = email.find("@");
string username =email.substr(0, pos);
cout<<"username:"<<username<< endl
}
int main(){
teste1();
system("pause");
return0;
}
6、Set
基本概念:以有序的方式存储一组唯一的元素。具体来说,std::set
使用红黑树(Red-Black Tree)实现,这使得元素在插入时就会按照特定的顺序进行排序,并且保证了查找、插入和删除操作的高效性能。
注意:set不允许容器出现重复元素,multiset允许容器出现重复元素
头文件:#include<set>
遍历:
#include <set>
void printSet(set<int> &s){
for(set<int>::iterator it=s.begin();it!=s.end;it++){
cout<<*it<<" ";
}
cout<<endl;
}
1)构造和赋值
set<T> st; | 默认构造函数 |
set(sonst set &st); | 拷贝构造函数 |
set& operator=(const set &st); | 重载等号操作符 |
s1.insert(10);
s1.insert(10);
set<int>s2(s1); //拷贝构造
set<int> s3;
s3=s2; //赋值
2)大小和交换
size();
| 返回容器中元素数目 |
empty(); | 判断容器是否为空 |
swap(st); | 交换两个集合容器 |
s1.insert(10);
s1.insert(20);
s1.insert(30);
set<int> s2;
s1.insert(40);
s1.insert(50);
s1.insert(60);
s1.swap(s2);
3)插入和删除
insert(elem); | 在容器中插入元素 |
clear(); | 清除所有元素 |
erase(pos); | 删除pos迭代器所指的元素,返回下一个元素的选代器 |
erase(beg,end); | 删除区间[beg,end)的所有元素,返回下一个元素的迭代器 |
erase(elem); | 删除容器中值为elem的元素。 |
s1.insert(10);
s1.insert(20);
s1.insert(30);
s1.erase(s1.begin()); //删除
s1.erase(10);
s1.clear(); //清空
4)查找和统计
find(key); | 查找是否存在key,若存在返回该键的元素的迭代器,若不存在,返回set.end() |
count(key); | 统计key的元素的个数 |
7、Queue
先进先出的数据结果,有两个出口,只有队头和队尾能被外界访问,因此不存在遍历的行为
1)构造函数
queue<T> que; | queue对象默认构造形式 |
queue(const queue &que); | 拷贝构造函数 |
2)赋值
queue& operator=(const queue &que); | 重载等号操作符 |
3)数据存取
push(elem); | 往队尾添加元素 |
pop(); | 从队头移除一个元素 |
back(); | 返回最后一个元素 |
front(); | 返回第一个元素 |
4)大小
empty(); | 判断堆栈是否为空 |
size(); | 返回栈的大小 |
三、字符串
1、简介
C语言风格:
<code>char a[5] = {'1','2','3','4','5'}; //字符数组
char b[5] = {'1','2','3','4','\0'}; //字符串
char greeting['h','e','l','l','o','\0'}; //字符串
char greeting[]="hello";
//输出结果为 hello
C++引入的string类类型(函数及其目的)
Strcpy(s1,s2) | 复制字符串s2到字符串s1
|
Strcat(s1,s2)
| 连接字符串s2到s1的末尾
|
Strlen(s1) | 返回字符串s1的长度 |
Strcmp(s1,s2) | 若s1=s2,返回0
若s1<s2,返回值小于0
若s1>s2,返回值大于0
|
Strchr(s1,s2) | 返回一个指针,指向s1中字符ch第一次出现的位置 |
Strstr(s1,s2) | 返回一个指针,指向s1中s2第一次出现的位置 |
2、字符串的读入
1)对字符数组得输入方法
1.1cin使用空白字符作为一次输入的结尾,并忽略该空字
<code>char word[10];
cin >> word;
cout<<word;
//若输入123 456,只会输出123
该情况下只能输入一个单词,若输入了多个单词,只会取第一个单词,其余单词被忽略掉
1.2使用getline()/get()函数完成面向行的输入
区别:主要区别在于它们处理输入流的方式:getline()
用于读取整行并丢弃定界符,而 get()
则用于逐字符读取,并保留定界符在输入流中。
#cin.getline()
cin.getline(line,nums,(optional)delim)
nums:代表从该队列中获取nums-1个字符到line中(最后一个字符为\0)若超出nums-1,后面的都无法取到。
delim:指定分界符,表示遇到分界符后当前字符串的输入将停止,其后的会保留在输入队列中作为下一个字符串的开始。
int main(){
char line1[10];
char line2[10];
cin.getline(line1,10,'s');
cin.getline(line2,10);
cout<<line1<<endl;
cout<<line2<<endl;
return 0;
}
//测试:123s456
//结果:
line1:123
line2:456
#cin.get()
cin.get(line,nums,(optional)delim)
get会在输入队列中保留最后的换行符,若不做处理可能出现问题,以下方式可以避免:
cin.get(line2,10).get();
cin.get(line2,10);
get();
1.3数字与字符串混合输入
int a,b;
char s[7];
cin>>a;
(cin>>b).get();
cin.getline(s,7);
cout<<a<<" "<<b<<" "<<s;
//测试:123 456 hello
结果:
123
456
hello
123 456 hello
2)对string对象的输入方法
string a
getline(cin,a);
cout<<a<<endl;
3、常见操作
1)常用函数
2)读写string
<code>string s1,s2,s3;
cin>>s1;
cin>>s2>>s3;
//结果:
nice to meet
nice
to
meet
若要保留输入时的空格,可以使用getline
string s1;
getline(cin,s1);
//结果:
nice to meet
nice to meet
3)cctype头文件
4)用for循环完成cctype各项
<code>#include<iostream>
#include<string>
#include<cctype>
using namespace std;
int main(void){
string s1 = "hello world";
for(auto &c : s1)
c=toupper(c);
cout<<s1<<endl;
return 0;
}
//结果
HELLO WORLD
四、排序
1、冒泡排序
原理:比较前后两个数字的大小,大的放在后面,依次遍历所有数字
#include <iostream>
#define N 1010
using namespace std;
int n = 6; //待排序的元素个数为6
int a[N] = {0,2,3,2,11,7,6}; //待排序元素
int main(){
for(int i = 1;i<n;i++){ //连续交换过程
//一共n-1个阶段,在第i个阶段,未排序序列长度从n-i+1到n-i
for (int j = 1;j<=n-i;++j) //将序列从1到n-i+1的最大值移到n-i+1的位置
if (a[j] > a[j+1]) // 将序列从1到n-i+1的最大值,移到n-i+1的位置
swap(a[j],a[j+1]); // 其中j枚举的是前后交换元素的前一个元素序号
}
//输出
for (int i=1;i<=n;++i)
cout<<a[i]<<' ';
cout<<endl;
return 0;
}
2、选择排序
原理:
遍历数组,找到最小(或最大)的元素。将找到的最小(或最大)元素与数组的第一个元素交换位置。排除第一个元素,对剩余的元素进行相同的操作,即在剩余的未排序部分中找到最小(或最大)的元素,并与该部分的第一个元素交换位置。重复以上步骤,直到整个数组排序完成。
缺点:平均时间复杂度为O(n^2),空间复杂度为O(1),性能通常比较差。
#include <iostream>
#include <vector>
using namespace std;
// 选择排序函数
void selectionSort(vector<int>& arr) {
int n = arr.size();
for (int i = 0; i < n - 1; ++i) { // 外层循环遍历数组
int minIndex = i; // 假设当前元素为最小值的索引
// 内层循环寻找最小值的索引
for (int j = i + 1; j < n; ++j) {
if (arr[j] < arr[minIndex]) { // 如果找到更小的元素,则更新最小值的索引
minIndex = j;
}
}
swap(arr[i], arr[minIndex]); // 将最小值与当前位置的元素交换位置
}
}
int main() {
// 测试选择排序函数
vector<int> arr = {64, 25, 12, 22, 11};
cout << "Original array: ";
for (int num : arr) {
cout << num << " ";
}
cout << endl;
selectionSort(arr); // 调用选择排序函数
cout << "Sorted array: ";
for (int num : arr) {
cout << num << " ";
}
cout << endl;
return 0;
}
3、插入排序
原理:
将数组视为两部分,一部分是已排序的部分,一部分是未排序的部分。从未排序部分取出第一个元素,在已排序部分中从后往前逐个比较,找到合适的位置插入该元素,使得插入后的部分仍然保持有序。重复上述过程,直到未排序部分为空,整个数组就排好序了。
优点:适合小型数据集或部分有序的数据。
#include<iostream>
using namespace std;
int main() {
int a[6] = { 2, 6, 5, 3, 4, 1}; // 待排序序列
int temp, i, j;
int n = 6; // 待排序元素个数
// 开始插入排序
for (i = 1; i < 6; i++) {
// 假定第一个数是有序的,从第二个数开始枚举
temp = a[i]; // 临时储存每一次需要排序的数
j = i; // j用于记录当前待排序元素的位置
// 在有序部分从后往前比较,将比当前元素大的元素往后移动
while (j >= 1 && temp < a[j - 1]) {
a[j] = a[j - 1]; // 元素往后移动
j--; // 继续向前搜索
}
a[j] = temp; // 将待排序元素插入到合适的位置
}
// 输出排序后的结果
for (i = 0; i < 6; i++) {
cout << a[i] << " ";
}
cout << endl;
return 0;
}
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。