全部博文(21)
分类: C/C++
2012-12-11 22:24:38
1.使用string类型的对象时须包含的头文件:
//注意,这里直接是把常用的写出来,其实该函数的原型并不是这样子,具体的使用和声明看查看.
该函数的参数不用多说,主要是用途:他是从输入流下一行读取,并保存读取的内容到line里
2. string的主要操作说明:
a).size:返回string对象中字符的个数.(返回类型是string:size_type,不要把它赋值给int型)
b).empty:判断string是否为空
注意:当进行string对象和字符串字面值混合连接操作时,+操作符的左右操作数必须至少有一个是string.
点击(此处)折叠或打开
这里主要说明的是size和length获取的是其所占字节的大小.并且不包括'\0'
这里我想要深一步来了解strlen和sizeof,结果发现:sizeof一直都为16,而strlen则与size和length相等.
还有,我经常用到char来做一些字符处理.顺带也一起总结:
char ch[20] = "yws";
int size = sizeof( ch );
int len = strlen( ch );
cout<<"sizeof = "<
还有测试程序:
char* ch = "leelee";
int size = sizeof( ch );
int len = strlen( ch );
cout<<"sizeof = "<
返回结果:4,6.
因此:sizeof(指针) = 4,也即首地址.
strlen(ch/指针) = 实际占用的字节数.
最后一种:
cout<<"sizeof = "<
结果如下:
如果是字符串常量,sizeof要加上实际占用字节大小加'\0'
(这里说的不是很准确.知道意思就行了.)
这里特别需要指出的是:我们在使用的时候千万不要简单地将两个字符串表示的数字进行比较.这样带来的问题是很严重的.
举例来说吧!
"111111","111112"由于其占用的长度相等,使用比较操作符是没问题,但是如果长度不相等呢?
比如:"99","111111"比较出来的结果肯定不对了.
这个给出的几种解决办法.最容易想到的当然是使用size来先比较大小.相同的话在运用比较操作符.
第二种解决办法是,先不管啥,都转成int类型.在比较大小/
第一种方法可取,第二种方法不可取.(问题有二:1.如果其超过了int表示的范围内的话就悲剧了,2.需要用到atoi来转换,不如直接调用比较操作符来的直接)
3.使用vector类型的对象时须包含的头文件:
#include <vector>
using std:: vector
4.vector的主要操作说明;
a).v.empty():如果为空,则返回true;
b).v.size():返回v中元素的个数.(此时的返回值是vector
c).push_back(t):增加值为t的元素
注意:下标操作不添加元素(下标只能获取已存在的元素)
5.迭代器
a).begin和end操作:begin返回的迭代器指向第一个元素.end返回的迭代器指向vector的”末端元素的下一个”.(即哨兵)
b).const_iterator只能用于读取容器内元素,不能改变其值.
注意:任何改变vector长度的操作都会使已存在的迭代器失效.
6.使用bitset类型的对象时须包含的头文件:
#include
using std::bitset;
利用string对象初始化bitset对象时,从string对象的读入位集的顺序是从右到左.
例如:string strval(“1011”);
bitset<32>bitval(strval);//bitval的第2位为03.1 命名空间的using声明
using声明是对某个命名空间做引入。主要作用是简化代码编写。
3.2 标准string类型
首先要明确类型是类类型,意味着它有构造函数,也类似我们自定义的类一样的其他类对象。
它有几种初始化方式如下
string s1 ; // 调用默认构造函数初始化对象
strng s2(s1) ; // 将S2初始化为S1的一个副本, 赋值构造
string s3("value") ; // 用一个字符串值初始化对象
string s4(n,'c') ; // 用N个字符‘C’组成字符串作为初始化s4的值
特别要注意的是第一种初始化方式,虽然默认构造函数是没有参数的但是不能因此就写成 string s1()
我们可以复习一下内置类型的默认初始化方式和类类型做个比较:
string s1 ; // 调用默认构造函数初始化
int i ; // 要根据定义位置来确定初始化值,全局变量一律初始化为0, 局部变量是一个随机数,称为未初始化
string类型可以用于标准输入输出。
cin >> line 输入内容并保存到变量line,输入时会忽略输入左面的的空格直到非空格字符才开始读取,直到再次读到空格输入结束。
例如如果你输入" zhang san " 实际line保存的是"zhang" 。
getline(cin,line) 是一个系统函数,可以输入标准行内容,这个函数不会忽略任何内容一直读取用户输入并保存到line,直到用户输入换行函数才结束,结束时函数会返回cin的引用。 如果用户刚开始就输入换行符那么line的内容就是"" 。
上文说过string是类类型所有有很多类成员(属性和成员函数),下面就是一些常用的操作
s.empty() ; // 判断s是否为空,相当于s.size()==0
s.size() ; // s的长度
s[n] ; // n位置的字符(左值返回)
s1+s2 ; // 返回s1和s2连接的串
s1=s2 ; // 把s1替换为s2的副本
s1==s2 ; // 判断s1,s2是否相等
!=,<,<=,>,>= // 按字典顺序比较
s.insert(...) ; // 插入字符操作,有多个重载可用
s.size()函数返回一个表示字符串长度大小的值,其类型并不是我们认为的int类型,而是一个叫string::size_type的类型,为什么不用INT而新创造一个类型呢,原因有如下两点:
1. 取值范围不同,int有固定的取值范围,并且可以取负数,但字符串长度是不可能为负的,并且长度的大小很可能会超过int的范围而导致溢出
2. int的范围大小与机器相关,有的机器上范围大些,有点机器小一些。但是字符串长度应该是个不能随机器发生大小改变的值,所以即使用无符号int来表示串大小也是不合适的,为了移植的考虑
s[n]可以作为左值操作,也就是说改操作既可以返回N位置的字符也可以替换N位置的字符。 n值一定要在有效范围内,负值或者超过串大小会引发严重异常
cctype 头文件所包含的函数主要用来测试字符值,以下是一个列表,但是对于初学者来说自己上机操作一下,后两个返回的是int型,确实很意外,强制转换一下,很简单。
isalnum(c) ; // 假如c是字母或数字,则为true
isalpah(c) ; // 假如c是字母,则为true
iscntrl(c) ; // 假如c是控制字符,则为true
isdigit(c) ; // 假如c是数字,则为true
isgraph(c) ; // 假如c不是空格,则为true
islower(c) ; // 假如c是小写字母,则为true
isprint(c) ; // 假如c是可打印的字符,则为true
ispunct(c) ; // 假如c是标点符号,则为true
isspace(c) ; // 假如c是空白字符,则为true
isupper(c) ; // 假如c是大写字母,则为true
isxdigit(c) ; // 假如c是十六进制数,则为true
tolower(c) ; // 假如c是大写字母,则返回小写字母形式(对应的int值),否则返回c。
toupper(c) ;// 假如c是小写字母,则返回大些字母形式(对应的int值),,否则返回c。
可以举个简单的例子
3.3 标准vector类型
C++标准库容器有好几类,后面会详细介绍。为什么在这里单单要先介绍vector容器呢?这个容器最常用。对于大部分应用来说用它足以满足你的要求。
vector是个类模板,泛型最大的好处是只需定义一个类或函数就可以提供不同类型版本的操作。
它的初始化有如下几种方式:
Vector
Vector
Vector
Vector
对于类类型如果不能满足红色标示的要求编译会失败。 关于类类型的拷贝构造函数和默认构造函数后续章节有介绍
Vector对象有几种最重要的操作
v.push_back(t) ; // 在数组的最后添加一个值为t的数据
v.size() ; // 当前使用数据的大小 返回vector
v.empty() ; // 判断vector是否为空
v[n] ; // 返回v中位置为n的元素 和string类型下标操作类似 是个左值操作
v1=v2 ; // 把v1的元素替换为v2元素的副本
v1==v2 ; // 判断v1与v2是否相等
!=、<、<=、>、>= ; // 保持这些操作符惯有含义
关于vector需要注意的是下标不能用来添加元素操作。
3.4 迭代器简介
迭代器是用于对容器做遍历操作的类型。 迭代器和后面要说到的指针非常类似。但它侧重列表的迭代遍历,所有有一些快捷属性可用。
当容器为空时 list.begin() == list.end()
上面定义的是常规迭代器,还有一种叫常量迭代器的迭代器类型。 我们也能定义迭代器常量,要弄清楚这些拗口的概念可以看下面代码示例
最后一个定义很有意思:迭代器指向了常量,所以不能通过解引更改常量值,同时迭代器本省也是常量所以无法更改迭代器的指向
迭代器不是每次只能向后移动一位,可以通过迭代器与一个整形字面值相加向后移动多位
iter + n // 迭代器向后移动n位并产生一个指向移位后新位置的迭代器
两个迭代器可以做相减运算结果是类型为difference_type的两个迭代器之间的距离(两个操作数一定要指向同一容器否则报错)
3.5 标准bitset类型
标准库中bitset类型用来处理二进制位的有序集,bitset类型简化了位集的处理,使用bitset时需要包含头文件#include
bitset对象的定义和初始化
bitset也是类模板,不过bitset类型对象之间的区别在于长度而不是类型,因此bitset模板的参数是长度类型
初始化方法 |
说明 |
bitset |
b有n位,每位都为0 |
bitset |
b是unsigned long型u的一个副本 |
bitset |
b是string对象s中含有的位串的副本,s是01串 |
bitset |
b是s中从位置pos开始的n个位的副本 |
用unsigned long值初始化bitset对象
用unsigned long值初始化bitset对象的时候,将long值转化为二进制模式,然后拷贝到bitset的右方(bitset右边为低阶位,左边为高阶位),string位数多了将被截断,少了bitset将在前面补零。
用string对象初始化bitset对象
从string对象初始化bitset对象,需要注意的是,复制拷贝相当于从string位模式平移到了bitset。
例如:
string str(”11001010”);
bitset<32> bitvec(str);
这个时候,bitvec是这样的:0000 0000 0000 0000 0000 0000 1100 1010最右边是bitset的低阶位,即bitvec[0],bitset[1] …
bitset对象上的操作
操作调用方式 |
操作说明 |
b.any() |
测试b中是否有存在1的位 |
b.none() |
测试b中是否全0 |
b.count() |
测试b中置1的位个数 |
b.size() |
b中所有二进制位个数 |
b[pos] |
访问下标为pos位置的位值 |
b.test(pos) |
测试pos位置的二进制位是否为1 |
b.set() |
将b所有位置1 |
b.set(pos) |
将b中pos位置的位置1 |
b.reset() |
将b所有位置置0 |
b.reset(pos) |
将b中pos位置的位置0 |
b.flip() |
将b中所有位翻转 |
b.flip(pos) |
将b中pos位置上的位翻转 |
b.to_ulong() |
将b转化为unsigned long值 |
os << b |
将b的位集合直接输出到os流 |
注:
Ø b.cout和b.size()返回的是size_t类型,该类型定义在cstddef头文件中(C标准头文件stddef.h的C++版本)
Ø b[pos]可以作为左值,即可以用来改变pos位置的值