C++命名空间/string类型/vector类型

命名空间using声明

c++标准库定义了许多更高级的抽象数据类型
两种最重要的标准库类型 string 和vector。
string类型支持长度可变的字符串,vector可用于保存一组指定类型的对象。
另一种标准库类型提供了更方便和合理有效的语言级的抽象设施,他就是bitset类。//通过这个类可以把某个值当做位集合来处理。

标准string 类型

string标准库支持几个构造函数

//string s1;
//string s2(s1);
//string s3("value");
//int n = 0;
//string s4(n, 'c');

string类型的读写
可以用iostream 与 int,double等。使用标准输入输出操作符来读写string对象

int main(int argc, char** argv) {
    string s;
    cin >> s;
    cout << s << endl;
    return 0;
}

string 类型的输入操作符:
读取并忽略开头所有的空白字符(如:空格,换行符,制表符)。
读取字符直至再次遇到空白字符,读取中止。

读入未知数目的string对象
和内置类型的输入操作符一样,string的输入操作符也会返回所读取的数据流。因此,可以把输入操作符作为判定条件。

int main() {
    string word;
    cin >> word;
    cout << word << endl;
    return 0;
}

上例中,用输入操作符来读取string对象。该操作符所读的istream对象,并在读取结束后,作为while的判断条件。如果输入流是有效的,即还未达到文件尾
使用getline读取整行文本。
getline函数从输入流的下一行读取,并保存读取的内容到string中,但不包括换行符。
和输入操作符不一样的是getline并不忽略开头的换行符。只要getline遇到换行符,即便是输入的第一个字符,getline也将停止读入并返回。//如果第一个字符就是换行符,则 string参数将被置空string。

int main() {
    string line;
    while (getline(cin, line)) {
        cout << line << endl;
    }
}
s.empty();//判断字符串是否为空
s.size();//返回s中字符的个数
s[n];//返回位置为n的字符
s1 + s2;//把s1和s2连接成一个新串,并返回新生成的字符串。
s1 = s2 //把s1内容替换为s2内容
v1 == v2 //比较v1与v2内容相等则返回true,否则返回false。
!=,<,<=,>和>= //保持操作符惯有的含义。

string::size_type类型

从逻辑上讲,size()成员函数似乎应该返回整型数值。但事实上,size操作返回的是string::size_type类型的值。我们需要对这种类型作一些解释。
string类类型和许多其他库类型都定义了一些配套类型。通过这些配套类型,库类型的使用就能与机器无关。
为了使用由string类型定义的size_type类型,程序员必须加上作用域操作符来说明所使用的size_type类型是由string类定义的。
任何存储string的size操作结果的变量必须为string::size类型。特别重要的是,不要把size的返回值赋给一个int变量。
对于任意一种给定的数据类型,他的unsigned型所能表示的最大整数比对应的signed型要大一倍。
这个事实表明size_type存储的string长度是int所能存储的两倍。
使用int型的另一个问题是,有些机器上int变量的表示范围太小,甚至无法存储实际并不长的string对象。
为了避免溢出,保存一个string对象size的最安全的方法就是使用标准库类型string::size_type。
3.string 关系操作符
string类定义了几种关系操作符用来比较两个string值的大小。这些操作符实际上是比较每个string对象字符。
string 对象比较操作是区分大小写的,即同一个字符的大小写形式被认为是两个不同的字符。在多数计算机上,大写的字母位于小写字母前:任何一个大写字母都小于任意的小写字母。
== 操作符比较两个string对象,如果他们相等,则返回true。两个string对象相等是指它们的长度相同,且含有相同的字符。标准库还定义了!=来则是两个string对象是否不等。
关系操作符比较两个string对象时采用了和字典排序相同的策略。
如果两个string对象的字符不同,则比较第一个不匹配的字符。
4.string 对象赋值
总体上说,标准库类型尽量设计得和基本数据类型一样方便易用。
因此大多数数据类型支持赋值操作
大多数string库类型的赋值操作的实现都会遇到一些效率上的问题,从概念上讲赋值操作确实需要一些工作。他必须把st1占用的相关内存释放掉,然后再分配给st1足够存放st2副本的内存空间。
最后把st2中的所有字符复制到新分配的内存空间。
5.两个string对象的加法定义为连接
6.和字符串字面值的链接
7.从string对象获取字符
string 类型通过下标操作符([])来访问string对象中的单个字符。下标操作符需要取一个size_type类型的值,来表明要访问字符的位置。这个下标的值通常被称为“下标”或“索引”。
string 对象的下标从0开始。
如果s是一个string对象且s不空,s[0]就是字符串的第一个字符,s[s.size()-1]。
可用下标分别取出string对象的每个字符

int main() {
    string str("some string");
    for (string::size_type ix = 0; ix != str.size(); ix++) {
        cout << str[ix] << endl;
    }
    system("pause");
    return 0;
}

8.下标操作可用作左值
和变量一样,string对象的下标操作返回值也是左值。因此下标操作数可以防御赋值操作符的左边或右边。通过下标循环把str对象的每一个字符置为’*’:
虽然任何整形数值都可作为索引,但索引的实际数据类型确是unsigned类型string::size_type。
但在下方的尝试中似乎索引值为int类型时也被允许通过?那会有什么样的隐患,或是可能在那方面会产生问题?

int main() {
    string str = "str";
    int i = 1;
    for (string::size_type ix; ix != str.size(); ++ix) {
        str[ix] = '*';
    }
    str[i];
}

string对象中字符处理
我们经常需要对string对象的单个字符进行处理,例如通常需要知道某个特殊字符是否为空白字符、字母、或数字。
大部分函数测试一个给定的字符是否符合条件,返回一个int值作为真值。如果测试失败,则该函数返回0,否则返回一个非0值,表示被测字符返回0值,否则返回一个非0值,表示被测字符返回条件。
表中显示函数,可打印的字符是指哪些可以显示表示的字符。
空白字符则是空格、制表符、垂直制表符、回车符、换行符、和进纸符中的一种;标点符号则是除了数字,字母或空白字符以外的其他可打印字符。

建议:采用c标准库头文件的c++版本

c++标准库除了定义了一些特定于c++的设施外,还包括c标准库。c++头文件cctype其实就是利用了c标准库函数,这些库函数九鼎意在c标准库ctype.h头文件中。
c标准库头文件命名形式为name.h,而C++版本则命名为cname。少了后缀.h。而在头文件名前加了c。c表示这个头文件源自c标准库。因此,cctype与ctype.h文件的内容是一样的。只是采用了更是个c++程序的形式。特别的,cname头文件中定义的名字都在命名空间std内,
而.h版本中的名字却不是这样的。

通常,c++程序中应采用cname这种头文件的版本,而不采用name.h版本,这样命名库中的名字在命名空间std中保持一致。
使用.h版本会给程序员带来负担,因为他们必须记得哪些标准库名字是从c继承来的。

标准库vector类型

vector 是一种类型的对象的集合,每个对象都有一个对应的整数索引值。和string对象一样,标准库将负责管理与存储元素相关的内存。
我们把vector成为容器,是因为他可以包含其他对象。一个容器中的所有对象都必须是同一种类型的。
使用vector之前,必须包含相应的头文件。并假设已做了相应的using声明:

#include<vector>
using std::vector

声明从类模板产生的某种类型对象,需要提供附加信息,信息的种类取决于模板。以vector为例,必须说明保存何种对象的类型,通过将类型放在类模板名称后面的尖括号里来指定类型;

vector<int> ivec; //类型是vector<int>
vector<Sales_item> Sales_vec;vector<Sales_item>

和其他变量定义一样,定义vector对象要指定类型和一个变量列表。
vector不是一种数据类型,而是一个类模板,可用来定义任意多种数据类型。vector类型的每一种都指定了其保存元素的类型。因此,vector 和vector都是数据类型

vector 对象的定义和初始化
vector对象定义了好几种构造函数,用来定义和初始化vector对象。
几种初始化vector对象的构造方式

vector<T> v1;
vector<T> v2(v1);
vector<T> v3(n, i);
vector<T> v4(n);

创建确定个数的元素
关键概念:vector对象动态增长
vector 对象(以及其他标准库容器)的重要属性就在于可以在运行时高效地添加元素。因为vector增长的效率高,在元素值已知的情况下,最好是动态地添加元素。
这种增长方式不同于c语言中的内置数据类型,也不同于大多数其他编程语言的数据类型。具体而言如果读者习惯了c或java的风格,由于vector元素连续存储,可能希望最好预先分配合适的空间。
。但事实上,为了达到连续性,c++的做法恰好相反。

值初始化
如果没有元素的初始化,name标准库将自行提供一个元素初始值进行值初始化。这个由库生成的初始值将用来初始化容器中的每个元素,具体值为何,取决于存储在vector中元素的数据类型。
如果vector保存内置类型的元素(如:int),那么标准库将用0值创建元素初始化式。
vector fvec(10);
如果vector保存得是含有构造函数的类类型的元素,标准库,将用该类型的默认构造函数创建元素初始化式:
vector svec(10);
后面有介绍一些自定义构造函数但没有默认构造函数类,在初始化这种类型的vector对象时,程序员就不能只提供元素个数,还需要提供元素初始值。
还有第三种可能性:元素类型可能是没有定义任何构造函数的类类型。这种情况下,标准库仍产生一个带初始值的对象,这个对象的成员进行了初始化。
练习中 出现vector

v.empty();//如果v为空,则返回true,否则返回false。
v.size();//返回v中元素的个数。成员函数size返回相应的vector类定义的size_type的值
v.push_back(t);//在v的末尾增加一个值为t的元素。
v[n];//返回v中位置为n的元素。
v1 = v2;//把v1的元素替换为v2中元素的副本。
v1 == v2;//如果v1与v2相等则返回true。
!=,<,<=,>,>=//保持这些操作符惯有的含义。

//vector对象的size
//empty和size操作类似于 string类型的相关操作。成员函数size返回相应的vector类定义的size_type的值
//使用size_type类型时,必须指出该类型是哪里定义的。vector类型总是包括vector的元素类型:

vector<int>::size_type //ok
vector::size_type    //error

vector添加元素值
push_back()操作接受一个元素值,并将他在作为一个新元素添加到vector对象的后面,也就是“插入(push)”到vector对象的“后面(back)”

string word;
vector<string> text;
while (cin >> word) {
    text.push_back(word);
}

vector的下标操作
vector下标操作类似于string类型的下标操作。
vector的下标操作符接受一个值,并返回vector中该对应位置的元素。vector位置的元素从0开始。

for (vector<int>::size_type ix = 0;ix!=ivec.size();++ix) {
    ivec[ix] = 0;
}

关键概念:
c++习惯于优先选用!=而不是<来编写循环条件程序。
调用size()成员函数而不保存它返回的值,这样的例子中不是必须的,但这反映了一种良好的编程习惯在c++中有些数据结构是可以动态增长。
如果循环可以容易的增加新元素的话,那么测试已保存的size值作为循环结束条件就会有问题。

下标操作不添加元素

vector<int> ivec;
for (vector<int>::size_type ix = 0; ix != 10; ++ix) {//   disaster: ivec has no elements.
    ivec[ix] = ix;
}
for (vector<int>::size_type ix = 0; ix != 0; ++ix) {//    ok:adds new elements with value ix
    ivec.push_back(ix);
}

仅能对确知已存在的元素进行下标操作

vector<int> ivec;// no elements
cout << ivec[0];//
vector<int> ivec2(10);//elements 0~9. 
cout << ivec[10];
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值