第三章字符串、向量和数组
3.1 命名空间using声明
1.using用法
using用于命名空间有两种用法:
①using namespace std;
包含了整个std命名空间,反效果是编译时间略长。
②using std::cout;
用哪个写那个,上一种写法的简化版。
3.2 标准库类型string
1.string初始化
string是C++特有的字符串,并不是c语言的数组形式。
使用string需要包含<string>头文件,并且要用std::string:
string s2; //默认初始化,s2是一个空串
string s1(s2); //直接初始化,s2与s1相同 推荐使用直接初始化的方式
string s1=s2; //拷贝初始化
string s1 = "abcde"; //拷贝初始化
string s1("abcde"); //直接初始化
string s1(10, 'c'); //直接初始化,相当于十个c都放在s1中;拷贝初始化不能这样使用
2.string的操作
string sum; //不是0,是空的
os<< s; //没懂: 将s写到输出流os中,返回os
is>> s; //没懂: 从is中读取字符串赋给s,字符串以空白分隔,返回is
getline(cin,s); //给s赋值
s.empty(); //s 如果是空的,s.empty()=ture;如果不是空的,s.empty()=false
s.size(); //s.size()表示有多少个字符
cout<< s.size() << endl;
s[n]; //取第n个字符,0是第一个
os+ s; //两个字符连在一起,中间没有空格
s1= s2; //赋值
s1== s2; //判断是否相同
s1!= s2; //判断是否不同
3.string的读入
如果使用cin进行读入,每次遇到 空白(空格、回车、制表符)直接退出
getline( cin, 某字符串),只有遇到回车才会停止读入,空格可以读进去。
string s1,s2;
cout<< "请输入姓名" << endl;
cin>> s1 ; //遇到 空白(空格、回车、制表键)直接退出
//输入文字前输入空格,则自动忽略空格
getline(cin,s2); //将一整行都读入,可以读入空格,遇到回车终止
cout<< "cout " << s1 << endl;
cout<< "getline " << s2 << endl;
4. string::size_type a
专门为string定制的计数器,不论是s1.size()还是 s1[a]都可以使用这个计数器,不使用int型变量做计数。
cout<< "请输入一个字符串:" << endl;
string c1;
getline(cin,c1);
string c2;
for (string::size_type index_c1 = 0;index_c1 != c1.size(); index_c1++)
{
if (isalpha(c1[index_c1]))
{
c2+= c1[index_c1];
//字符串中的某个值不能直接使用赋值的方式改变,要用C++特有的函数
//字符串可以使用加法的方式,将一个一个值连接在它的后边
}
}
c2[3] = ‘c’; //可以使用这种赋值方式
cout<< c2[3]<< endl;
5.字符串操作函数
对字符串进行操作可以使用一些特定的函数,这些函数是从C语言的标准库里继承下来的,名为:
#include <cctype> 在C语言中为 ctype.h 头文件。
C语言库进入C++库,通常将末尾的.h去掉,在开头加上一个c。
isalnum(s1[1]); //是不是字母数字
isalpha(s1[1]); //是不是字母
iscntrl(s1[1]); //是不是控制字符
isdigit(s1[1]); //是不是数字
islower(s1[1]); //是不是小写字母
isupper(s1[1]); //是不是大写字母
ispunct(s1[1]); //是不是标点符号
isspace(s1[1]); //是不是空格
isxdigit(s1[1]);//是不是16进制数
tolower(s1[1]); //所有字符变成小写
toupper(s1[1]); //所有字符变成大写
6.特别的for遍历string
有一种特殊for写法专门给string使用:
for (auto a : s1) { 表达式 }
迭代使用通常有如下两种: 直接赋值 和 引用改变string数据
void run8()
{
string s1("Hello World!!!");
for (auto a : s1)
{
cout<< a << endl; //每次循环都会将s1中对应的值赋给a
}
string s2("KPLKPLKPL!!!");
for (auto &b: s2)
{
b= 'c'; //通过引用可以改变内部的值
}
cout<< s2 << endl;
}
3.3 标准库类型Vector
1.vector基础知识
vector翻译为“向量”,实际是“向量容器”,内部存放的是大量的对象,是一个类模板,常用于调用定义好的类class和struct。
vector类型不能被直接输入,需要有下标或专用输入函数。
vector的头文件有:
#include <vector>
using std::vector;
2.vector对象的初始化
void run_vector3() //笔记程序
{
vector<int> ivec; //这种<>写法叫类模板,未初始化a默认为空,最佳推荐使用方式
vector<string> c{"abchhh","1111","2123hh"}; //string初始化 使用()会出错
vector<dog> dogvec; //保存一个dog类型数据的vector
vector<int> ivec1(10, -1);//10个-1存在ivec1中
vector<int>ivec2(ivec1); //给ivec2中存放ivec1一样的东西
vector<int> v1(10); //v1有10个元素,每个值都是0
vector<int> v2{ 10 }; //v2有1个元素是10
vector<int> v3(10,1); //v3有10个元素,每个值都是1
vector<int> v4{ 10,1 };//v4有2个元素,分别是10和1
vector<string> v5{"hi" }; //列表初始化:v5有一个元素
// vector<string>v6("hi"); //报错
vector<string> v7{ 10 }; //10个默认初始化的元素
vector<string> v8{ 10,"hi" }; //10个hi
}
3.vector常用io
void run_vector1()
{
vector<int> a; //这种<>写法叫类模板,未初始化a默认为空,最佳推荐使用方式
vector<int> b(10,2); //b里边有10个2
vector<string> c;
vector<dog> dogvec; //保存一个dog类型数据的vector
vector<Sales_data> Sales_vec; //保存Sales_item类型数据的变量
a.push_back(100); //依次送数
a.push_back(200);
a.push_back(300);
a[2] = 400; //通过下标操作可以重新赋值,但不可以给未初始化的没有下标的部分进行操作
b.push_back(10); //在向量的后边依次添加10和11
b.push_back(11);
cout<< a.size() << endl;
cout<< b.size() << endl;
//向量有配套的size_type,必须初始化,不要用int计数
for(vector<int>::size_typei=0;i!=a.size();i++)//向量必须按照数组的a.[]形式进行输出
{ cout << a[i]<< endl; }
for (vector<int>::size_type i1=0; i1 !=b.size(); i1++)
{ cout << b[i1]<< endl; }
vector<int> v3(a); //同类型的向量可以通过这种方式赋值
vector<string> v4(10);//没有初始化10个数是什么,会自动设成0
vector<string> v5(10,"Hello World!"); //v5里设定了10个10个字符串
}
4.vector常用io2
void run_vector2()
{
vector<int> ivec;
int k;
// cout << ivec.size() << endl;
cout<< "请输入第一组vector数据(4个整数):" << endl;
for (vector<int>::size_type ix = 0; ix != 4;ix++)
{
cin>> k;
ivec.push_back(k);
}
cout<< "输入的向量容器结果如下:" << endl;
for (vector<int>::size_type iy = 0; iy !=ivec.size(); iy++)
{
cout<< ivec[iy]<< endl;
}
cout<< "请输入第二组vector数据(字符):" << endl;
string word;
vector<string> text;
while (cin >> word)
{
text.push_back(word);
}
//前边是什么类型,iz就必须一致,不能是int型
for (vector<string>::size_type iz = 0; iz !=text.size(); iz++)
{
cout<< text[iz]<< endl;
}
}
3.4 迭代器介绍
1.迭代器
使用vector时,可以使用下标来操作容器中的内容,但是不是所有vector都可以使用下标操作的,因此,C++推出迭代器,专门操作vector中的数据。
迭代器为iterator
void run_diedai1()
{
vector<int> v(10,8);
vector<int>::iterator iter = v.begin();
//begin操作返回一个迭代器,它指向第一个数据元素
//迭代器实际上是一个指针
*iter = 9;
iter++;
*iter = 10;
vector<int>::iterator mid = v.begin()+ v.size() / 2;
*mid +=99 ;
for (vector<int>::iterator i=v.begin(); i!= v.end(); i++)
{ cout << "迭代器: " <<*i<< endl; }
}
2.长迭代器const_iterator
长迭代器定义的时候使用const_iterator进行定义,但是这种定义只能进行读,不能进行写操作。简言之,只能读取但是不能修改它所指的元素值。
vector<int>::const_iterator iter = v.begin();
*iter = 9;
这样写会报错。
3.5 数组
1.数组
数组是C语言的基础,不过有很多缺点。但是在C++中已经完全被vector代替。
缺点:长度固定、长度不清楚、数组没有引用、没有pushback等操作等等。
int a[100];
int b[] = { 0,1,2 };
string c[3] = { "abc","def" };
2.指针和数组
string nums[] = { "one","two","three" };
string *p1 =&nums[0]; //等价于指针p1指向数组num
string *p2 = nums; //等价于指针p2指向数组num
3.6 多维数组
1.多维数组初始化
//如果无数据,将初始化为0
int ia[3][4]; //3行4列
intib[10][20][30]; //10行20列30深度
int a1[3][4] ={{0,1,2,3},{4,5,6,7},{8,9,10,11}}; //初始化数组
int a2[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11 }; //同上初始化一致
int a3[3][4] = {{0},{1},{2} }; //第一行0,第二行1,第三行2
int a4[3][4] = {0,3,6,9 }; //第一行0369,剩下为0初始化