Chinaunix首页 | 论坛 | 博客
  • 博客访问: 84333
  • 博文数量: 21
  • 博客积分: 371
  • 博客等级: 一等列兵
  • 技术积分: 225
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-15 21:32
文章分类

全部博文(21)

文章存档

2013年(5)

2012年(16)

我的朋友

分类: C/C++

2012-12-11 22:24:38

1.使用string类型的对象时须包含的头文件:

  1. #include <string>

  2. using std::string;

  3. istream& getline(istream input,string line);

//注意,这里直接是把常用的写出来,其实该函数的原型并不是这样子,具体的使用和声明看查看.

该函数的参数不用多说,主要是用途:他是从输入流下一行读取,并保存读取的内容到line

2. string的主要操作说明:

a).size:返回string对象中字符的个数.(返回类型是string:size_type,不要把它赋值给int)

   b).empty:判断string是否为空

注意:当进行string对象和字符串字面值混合连接操作时,+操作符的左右操作数必须至少有一个是string.

点击(此处)折叠或打开

  1. string strTest = "i am a man";
  2. int iSize = strTest.size();
  3. int iLen = strTest.length();
  4. cout<<"size = "<<iSize<<" iLen = "<<iLen<<endl;
  5. strTest = "wsygb";

  6. iSize = strTest.size();
  7. iLen = strTest.length();

  8. cout<<"size = "<<iSize<<" iLen = "<<iLen<<endl;

这里主要说明的是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::size_type)

   c).push_back(t):增加值为t的元素

注意:下标操作不添加元素(下标只能获取已存在的元素)

5.迭代器

a).beginend操作: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位为0

3.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类型可以用于标准输入输出。

string line;
 
cin >> line;

while(getline(cin, line))
{
    cout << line << endl;
}

    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值一定要在有效范围内,负值或者超过串大小会引发严重异常

string a("aaaa");

a[1] = 'b' ; // 字符一定要用单引号,双引号表示字符串


cout << a << endl; // 输出 "abaa"

       

    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。

    可以举个简单的例子

string line("a1 B,");

isalpah(line[0]); // true

isdigit(line[1]); // true
ispunct(line[4]); // true
tolower(line[0]); // 返回A对应的ascii 65

3.3 标准vector类型 

    C++标准库容器有好几类,后面会详细介绍。为什么在这里单单要先介绍vector容器呢?这个容器最常用。对于大部分应用来说用它足以满足你的要求。

    vector是个类模板,泛型最大的好处是只需定义一个类或函数就可以提供不同类型版本的操作。

    它的初始化有如下几种方式:

    Vector v1 ;         // 默认构造函数v1为空
    Vector v2(v1) ;  // v2是v1的一个副本
    Vector v3(n, i) ; // v3包含n个值为i的元素 参数 T 如果是类类型则一定要有拷贝构造函数(未定义的情况下系统会自动分配一个) 
    Vector v4(n) ;    // v4含值初始化的元素个副本 参数 T 如果是类类型则一定要有默认构造函数(未定义的情况下系统会自动分配一个) 如果是内置类型则分配n个0

    对于类类型如果不能满足红色标示的要求编译会失败。 关于类类型的拷贝构造函数和默认构造函数后续章节有介绍

    Vector对象有几种最重要的操作

    v.push_back(t) ;          // 在数组的最后添加一个值为t的数据
    v.size() ;                      // 当前使用数据的大小 返回vector::size_type类型的长度值,其意义类似上面讲过的string::size_type
    v.empty() ;                  // 判断vector是否为空
    v[n] ;                           // 返回v中位置为n的元素 和string类型下标操作类似 是个左值操作
    v1=v2 ;                        // 把v1的元素替换为v2元素的副本
    v1==v2 ;                     // 判断v1与v2是否相等
    !=、<、<=、>、>= ;  // 保持这些操作符惯有含义

 

    关于vector需要注意的是下标不能用来添加元素操作。

vector<int> list;

list[0] = 1// 错误 list没有任何数据,下标操作只针对存在的元素

list.push_back(2) ; // 增加了一个值为2的元素

list[0] = 1 ; // ok 将第一个元素由2更改成1

3.4 迭代器简介

    迭代器是用于对容器做遍历操作的类型。 迭代器和后面要说到的指针非常类似。但它侧重列表的迭代遍历,所有有一些快捷属性可用。

vector<string>::iterator iter // 就是定义一个迭代器变量
list.begin()  // 表示容器的第一项迭代器,如果容器有值指向list[0]
list.end()    // 表示容器的哨兵位,也就是最后一项后面的一项,只是用来表示迭代器已遍历到容器末端
iter++        // 迭代器自增表示向后移一位,指向下一个项

vector<string> list(10,"value");

for(vector<string>::iterator iter = list.begin(); iter != list.end(); iter++)
{
    cout << *iter << endl;  // 要访问迭代器当前值必须解引 *  

    *iter = "new value";    // 也可以解引后更改其值,可以看出解引是左值操作
}

// 如果想遍历容器又不想使用迭代器可以用下标操作

for(vector<string>::size_type ix = 0; ix != list.size(); ix)
{
    cout << list[ix] << endl;  
    list[ix] = "new value";
}

    当容器为空时 list.begin() == list.end()

    上面定义的是常规迭代器,还有一种叫常量迭代器的迭代器类型。 我们也能定义迭代器常量,要弄清楚这些拗口的概念可以看下面代码示例

vector<string>::const_iterator iter  // 定义一个代表常量的迭代器,和普通迭代器唯一不同的就是不能通过解引赋值
*iter = "new value";                 // 这是不允许的,因为const_iterator告诉编译器我代表的是一个常量,所以不能通过任何手段改变其值

const vector<string>::iterator iter  // 定义一个常迭代器,迭代器代表的变量,但迭代器本身是常量,所以可以更改代表的内容但无法更改迭代器

*iter = "new value";                 // 没问题
iter ++                              // 不允许,迭代器是常量所以无法让他指向其他项

const vector<string>::const_iterator iter  // 这样定义的迭代器只能读取初始化指向的列表项内容,既无法向后移动迭代器也无法更改项值内容

    最后一个定义很有意思:迭代器指向了常量,所以不能通过解引更改常量值,同时迭代器本省也是常量所以无法更改迭代器的指向

    迭代器不是每次只能向后移动一位,可以通过迭代器与一个整形字面值相加向后移动多位

    iter + n // 迭代器向后移动n位并产生一个指向移位后新位置的迭代器

    两个迭代器可以做相减运算结果是类型为difference_type的两个迭代器之间的距离(两个操作数一定要指向同一容器否则报错)

 

3.5 标准bitset类型

    标准库中bitset类型用来处理二进制位的有序集,bitset类型简化了位集的处理,使用bitset时需要包含头文件#include

    bitset对象的定义和初始化   

   bitset也是类模板,不过bitset类型对象之间的区别在于长度而不是类型,因此bitset模板的参数是长度类型

初始化方法

说明

bitset b;

bn位,每位都为0

bitset b(u);

bunsigned longu的一个副本

bitset b(s);

bstring对象s中含有的位串的副本,s是01串

bitset b(s, pos, n);

bs中从位置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)

bpos位置的位置1

b.reset()

b所有位置置0

b.reset(pos)

bpos位置的位置0

b.flip()

b中所有位翻转

b.flip(pos)

bpos位置上的位翻转

b.to_ulong()

b转化为unsigned long

os << b

b的位集合直接输出到os

注:

Ø b.coutb.size()返回的是size_t类型,该类型定义在cstddef头文件中(C标准头文件stddef.hC++版本)

Ø b[pos]可以作为左值,即可以用来改变pos位置的值


阅读(1231) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~