您的位置:首页 > 编程语言 > C语言/C++

C++复习 03 标准库类型

2007-10-21 22:36 393 查看
声明,所有的朋友,如果要转我的帖子,务必注明"作者:黑啤 来源:CSDN博客"和具体的网络地址http://blog.csdn.net/nx500/archive/2007/10/21/1836173.aspx,并且我的所有博客内容,禁止任何形式的 商业用途,请大家尊重我的劳动.谢谢!

目 录

三.标准库类型.
001 两种重要的标准库类型是string和vector.说他们重要,是因为它们在C++定义的基本类型基础上作了一些改进.
string类型支持长度可变的字符串,vector可用于保存一组指定类型的对象.
002 命名空间.
std::cin 通过域操作符,说明cin是命名空间std中定义的.
使用using声明可以在不需要加前缀namespace_name::的情况下访问命名空间的名字.
using namespace::name;


// 03002.cpp


#include <iostream>


#include <string>




// 一个using声明一次只能作用于一个命名空间成员.必须要为每个用到的名字都提供using声明.


using std::cout;


using std::endl;


using std::string;






int main()...{


string s("hello heipi");


cout << s << endl;




return 0;


}



在头文件中必须总是使用完全限定的标准库名字(std::cin).因为头文件的内容会被预处理器复制到程序中.
如果在头文件中放置using声明,就相当于在包含该头文件的每个程序中都放置这些using声明,而有些文件很可能不能有这样的声明.
003 标准库string类型.构造函数(初始化方法).
#include <string>
using std::string;
string s1;
string s2(s1);
string s3("value");
string s4(n, 'c');
字符串字面值与string类型不是同一种类型,注意区分.
string对像的读写
string s;
cin >> s;
读取并忽略开头所有的空白字符,读取字符直到再次遇到空白字符,读取终止. 输入" Hello heipi ", s=="Hello"
返回左操作数作为运算结果,所以可以连续读入. cin >> s1 >> s2;
和内置类型的输入操作符一样,string的输入操作符也会返回所读的数据流,因此,可以把输入操作作为判断条件.


// 03003.cpp


#include <iostream>


#include <string>




using std::cin;


using std::cout;


using std::endl;


using std::string;






int main()...{


string s;


while(cin >> s) // linux下,循环直到读入^d,遇到回车并不会使cin产生错误状态


cout << s << endl;


return 0;


}



// 下面是编译和运行的结果
Nan@linux-g4n6:~/Documents> g++ 03003.cpp
Nan@linux-g4n6:~/Documents> ./a.out
abc -123 234 95.5 s2 0xff34
abc
-123
234
95.5
s2
0xff34
^d
Nan@linux-g4n6:~/Documents>
004 getline读取整行文本.从输入流的下一行读取,并保存内容到s中,但不包含换行符.
和输入操作(cin>>)不一样的是,getline并不忽略行开头的换行符.
如果换行符是输入的第一个字符,getline也将停止读入并返回,此时s被置为空string.getline是string头文件中定义的函数.


// 03004.cpp


#include <iostream>


#include <string>




using std::cin;


using std::cout;


using std::endl;


using std::string;






int main()...{


string s;


while(getline(cin, s))


cout << s << endl; // getline不读入换行符,所以人为的加上一个换行符.


return 0;


}



// 编译及运行结果
Nan@linux-g4n6:~/Documents> g++ 03004.cpp
Nan@linux-g4n6:~/Documents> ./a.out
abc -123 234 95.5 s2 0xff34
abc -123 234 95.5 s2 0xff34
^d
Nan@linux-g4n6:~/Documents>
005 string对像的操作.
s.empty() 返回bool类型值,如果s为空,则返回true,否则返回false.
s.size() 返回string::size_type类型,返回s中字符的个数,注意:不要把返回值赋给int型变量.
s
返回s中位置为n的字符,起始位置为0.下标必须是一个string::size_type类型.
s1 + s2 把s1和s2链接成一个新的字符串,返回新生成的字符串.
s1 = s2 把s2的内容赋值给s1.
s1 == s2 比较s1和s2的内容,相同则返回true,否则返回false.
!=, <, >, <=, >= 保持这些操作惯有的含义 (还记得么? A的ASCII码是65,a是98,0是48).
当进行string对象和字符串字面值混合链接操作时,"+"操作的左右操作数必须至少有一个是string类型.
string s1 = "hello";
string s2 = s1 + " hei" + " pi"; // ok
string s3 = " hei" + " pi " + s1; // error: 不行对两个字符串字面值进行+操作
用下标方法索引string类型中的字符要注意范围,超出将引起溢出错误.任何可产生整型值的表达式都可以用做下标操作符的索引.
string对像的下标操作返回值也是左值,所以可以对其赋值.
s[someotherval * someval] = someval;
006 string对象中字符的处理. (这些函数都包含在cctype头文件定义中)
isalnum(c) 如果是字母或数字,返回true
isalpha(c) 如果是字母...
iscntrl(c) 如果是控制字符...
isdigit(c) 如果是数字...
isgraph(c) 如果不是空格,但可以打印...
islower(c) 如果是小写字符...
isprint(c) 如果是可以打印字符...
ispunct(c) 如果是标点符号...
isspace(c) 如果是空格...
isupper(c) 如果是大写字母...
isxdigit(c) 如果是十六进制数...
tolower(c) 转换为小写字符
toupper(c) 转换为大写字符
如果测试失败,函数返回0,否则返回一个非零值,表示被测试字符符合条件.空白字符包含空格/制表符/垂直制表/回车符/换行符/进纸符.
007 vector称为容器,是同一种类型的对象的集合,每个对象都有一个对应的整数索引值.
#include <vector>
using std::vector;
vector不是一种数据类型,而只是一个类模板,可以定义任意多种数据类型.
vector<int> ivec; // ivec是一个保存int型数据集合的变量.
vector<string> istr;
vector对象的定义和初始化
vector<T> v1;
vector<T> v2(v1);
vector<T> v3(n, i); // v3包含n个值为i的元素.
vector<T> v4(n); // v4包含值初始化的元素的n个副本,类型T必须要有默认构造函数.
vector<int> ivec1;
vector<int> ivec2(ivec1); // ok
vector<string> ivec3(ivec1); // error, ivec1和ivec3不是相同的数据类型
vector对象的重要属性在于可以"在运行时高效地"添加元素.虽然可以在初始化时预先分配内存,但是更有效的方式还是动态的增加元素.
008 vector对象的操作.
v.empty() // 没有添加注解的操作均与string功能相同.
v.size() // 返回vector<T>::size_type类型.
v.push_back(t) // v的末尾增加一个值为t的元素.
v

v1 = v2
v1 == v2
!=, <, <=, >, >=
009 向vector中添加元素,索引元素.


// 03009.cpp


#include <iostream>


#include <string>


#include <vector>




using std::cin;


using std::cout;


using std::endl;


using std::string;


using std::vector;






int main()...{


string word;


vector<string> texts;






while(cin >> word)...{


texts.push_back(word);


// 每加入一个字符串元素,都将texts中所有的元素输出一遍.


// c++程序员习惯于使用!=而不是<操作符来进行条件测试.


// 因为vector是动态增长的类型,所以应该每次判断时调用size()函数.




for(vector<string>::size_type ix = 0; ix != texts.size(); ++ix)...{


cout << texts[ix] << " ";


}


cout << endl;


}




return 0;


}



// 编译及运行结果
Nan@linux-g4n6:~/Documents> g++ -o o 03009.cpp
Nan@linux-g4n6:~/Documents> ./o
abc -123 234 95.5 s2 0xff34
abc
abc -123
abc -123 234
abc -123 234 95.5
abc -123 234 95.5 s2
abc -123 234 95.5 s2 0xff34
^d
Nan@linux-g4n6:~/Documents>
下标操作不能添加元素,应该该使用push_back(t)函数添加元素.
与string一样,只能对已经存在的元素进行下标操作."缓冲区溢出"的错误,就是对不存在的元素进行下标操作的结果.
010 迭代器iterator.是一种检查容器内元素并遍历元素的数据类型.所有的容器都定义了相应的迭代器类型,而少数支持下标操作.
每种容器类型都定义了自己的迭代器,如vector, vector<T>::iterator iter;
每种容器都定义了名为begin()和end()的函数,用于返回迭代器.如果容器中有元素的话,begin()返回的迭代器指向第一个元素.
end()返回的迭代器指向末端元素的下一个,通常称为超出末端迭代器,指向了一个不存在的元素,如果容器为空,begin()==end().
比如02009.cpp中的输出可修改为如下方式,注意迭代器的自增(++)/解引用(*iter)/比较(!=/==)的几个操作.
for(vector<string>::iterator iter = texts.begin(); iter != texts.end(); ++iter){
cout << *iter << " ";
}
每种容器还定义了const_iterator的类型,防止在遍历过程中对元素的修改,02009.cpp中的输出不涉及修改,所以可以修改为如下.
for(vector<string>::const_iterator iter = texts.begin(); iter != texts.end(); ++iter){
cout << *iter << " ";
// *iter = ""; // error! const元素对象不能修改.
}
注意:不要把const_iterator对象与const的iterator对象混淆.const的iterator必须在定义时初始化,而且iterator不能自增操作.
const vector<string>::iterator iter = texts.begin();
*iter = ""; // ok, 可以修改迭代器指向元素的值.
++iter; // error, 不可以修改const迭代器,使之指向其他元素.
迭代器的算数操作.
iter + n;
iter - n;
vector<type>::difference_type diff = iter1 - iter2;
计算位于vector中间的元素的迭代器
vector<string>::iterator mid = texts.begin() + texts.size()/2;
任何改变vector长度的操作都会使已存在的迭代器实效.比如,在调用push_back之后,就不能再信赖指向vector的迭代器的值了.
下边是应用于string类型的迭代器的例子,引用了string类型的begin()和end()操作
string s("Expressions in C++ are composed...");
string::iterator it = s.begin();
while ((it != s.end()) && !isspace(*it)){
*it = toupper(*it);
++it;
}
011 标准库bitset类型.
#include <bitset>
using std::bitset;
构造函数
bitset<n> b; // b有n位,每位都是0.
bitset<n> b(u); // b是unsigned long型u的一个副本.
bitset<n> b(s); // b是string对象s中含有的位串的副本.
bitset<n> b(s, pos, n); // b是s中从位置pos开始的n个位的副本.
使用unsigned long作为bitset对象的初始值时,将该值转化为二进制的位模式.而bitset对象中的位集作为这种位模式的副本.
若bitset长度大于unsigned long的位数,则其余高位将置0,如果biset长度小于位数,则只使用unsigned值中的低阶位,超过长度的高位被抛弃.
下边这段话"本人持保留意见": 要注意机器的unsigned long的字长度,如下边这句代码:
bitset<32> bitvec(0xffff); 对于16位机器,16到31位初始化为0,对于32位机器,全部都初始化为1.
使用string初始化,要使用string类型初始化,而不是字符串值,另外注意位的描述,不要混淆.
std::string strval("1100"); // 对于strval,第0第1位的值是字符1,第2第3位是字符0.
bitset<16> bitvec(strval); // 对于bitvec, 0000 0000 0000 1100, 第2和第3位是1,其他位是0.
bitset对象的操作.
b.any() // 任意位置存在1,就返回true.
b.none() // 所有位置都为0,就返回true.
b.count() // 返回1的个数,返回一个size_t类型的值(size_t定义在cstddef头文件中).
b.size() // 返回b的长度(位数).
b[pos] // 返回b在pos位置的值.
b.test[pos] // 如果b在pos位置的值为1,返回true.
b.set() // 将所有位都重置为1.
b.set(pos) // 将pos位设置位1.
b.reset() // 将所有位都重新设置为0.
b.reset(pos) // 将pos位设置为0.
b.flip() // 将所有位都取反.
b.flip(pos) // 将b中pos位取反,也可以这样用: b[pos].flip().
b.to_ulong // 用b中同样的二进制返回一个unsigned long值,b的长度必须小于unsigned long才可以用.
os<<b // 把b中的位集输出到os流中.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: