C++ Primer 学习笔记与思考_4 ---getline&&size_type&&const_iterator混搭

(一)getline的用法

我们在使用string读入字符串的时候,其输入操作符:

* 读取并忽略开头所有空白字符(如空格,换行符,制表符)

* 读取字符直至再次遇到空白字符,读取终止。

所以如果我们输入“hello world”,string将只输出hello。

为了解决这个问题,我们引入getline函数,它接受两个参数:一个输入流对象和一个string对象,但是getline会读取换行符,保存到string中时却忽略换行符,所以string中是空串。

我们通常用getchar()吃掉不应该存在的换行符。

#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main()
{
	int a;
	cin >> a;
	getchar();  //不加的话会导致getline读入回车当作第一次输入
	while (a--)
	{
		string s;
		getline(cin, s);
		cout << s << endl;
	}
	return 0;
}

(二)关于string::size_type

书中提到,string的size()函数返回的是size_type类型(配套类型),使用这些配套类型就能够使库类型的使用与机器无关,它的定义和unsigned类型具有相同的含义,因为unsigned数值范围大于int,所以不要把size的返回类型赋给一个int变量。

并且在进行下标索引取值的使用,最好也是用size_type类型。

string str = "welcome to the icpc world!";
string::size_type len = str.size();
cout << len << endl;
此外vector的size也返回size_type类型
vector<int>::sizetype //ok
vector::size_type //error ,vector只是类模版

具体机器的区别可以参考 http://blog.csdn.net/zhongzhiwei/article/details/8678885

但是,我也有一个疑问,在实际编程中,都要使用size_type定义变量吗?还是在不靠近临界值的时候采用int更方便? 求解答。

(三)为什么推荐c++程序员使用!=而不是<在for循环中

C++程序员习惯于优先使用!=而不是<来编写循环条件,这是安全的泛型编程的要求。

如下代码:

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

C程序员倾向于使用小于,而C++程序员更倾向于使用不等于,这可能出于习惯原因,实际上,C++中有大量的面向迭代器的代码,对于更多的人来说,遍历数据的时候迭代器“不等于”迭代器尾标可能与“小于”迭代器尾标相比可以更形象地描述问题。

此外,把终止条件ivec.size()写在循环里面而不是先定义变量将其记录,在循环中使用变量。是因为我们经常对容器进行增加,删除的操作,size会发生变化,记录一个常量会导致迭代器失效的问题,此外,不必太担心效率问题,size是inline函数,每次调用的代价很小。

(四)const_iterator

我们可以使用迭代器遍历容器,并且可以对迭代器进行解引用改变容器中元素的值(*iter = 5)。但是如果我们不想改变元素的值呢?这里讲解const_iterator.

当我们对const_iterator类型解引用时,得到的是一个指向const对象的引用,该对象不可改变。可以用于const vector或者非const vector均可。

vector<string> text;
for (vector<string>::const_iterator iter = text.begin(); iter != text.end(); ++iter)
{
	cout << *iter << endl;
	*iter = " "; //error,const不可改变
}

另外,要注意const_iterator 对象和const的iterator对象是不一样的,后者是声明一个const迭代器,必须初始化值,并且不能改变。

vector<int> nums(10);
const vector<int>::iterator cit = nums.begin();
*cit = 1; //ok
++cit;  //error
这种应用没什么实际用处。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-24 16:43:10

C++ Primer 学习笔记与思考_4 ---getline&&size_type&&const_iterator混搭的相关文章

C++ Primer学习笔记与思考_1----变量和基本类型

C++ Primer学习笔记与思考_1----变量和基本类型 类型有什么作用? 类型告诉我们数据代表什么意思以及可以对数据执行哪些操作. 一:基本内置类型 C++标准规定了每个算术类型的最小存储空间,但是它并不阻止编译器使用更大的存储空间.对于int,几乎所有的编译器使用的存储空间都比所要求的大. 字符类型有两种char和wchar_t,其中wchar_t用于扩展字符集,比如汉字和日文,这些字符集中的一些字符不能用单个的char表示.  c++ primer第32页      和其他类型不同,c

C++ Primer 学习笔记与思考_7 void和void*指针的使用方法

(一)void的含义 void的字面意思是"无类型",void差点儿仅仅有"凝视"和限制程序的作用,由于从来没有人会定义一个void变量,让我们试着来定义: void a; 这行语句编译时会出错.提示"illegal use of type 'void'".只是.即使void a的编译不会出错.它也没有不论什么实际意义. void真正发挥的作用在于: (1) 对函数返回的限定: (2) 对函数參数的限定. int f(void); equal t

C++ Primer 学习笔记与思考_9 表达式中过的那些容易忽略的地方

(一)移位操作符用于IO 输入输出标准库分别重载了位操作符>>和<<用于输入和输出.并且像其他的二元操作符一样,移位操作符也是左结合的,这也正好说明了我们为什么可以把多个输入输出操作连接为单个语句: cout<<"hi"<<"there "<<endl; 将其执行为: ( (cout<<"hi")<<"there" )<<endl;

C++ Primer 学习笔记与思考_3 ---头文件那些事儿(extern)

(一)extern在头文件里的使用方法 由于头文件包括在多个源文件里.而且变量的定义仅仅能出现一次,所以在头文件里. 仅仅能够声明不能够出现定义. 我们能够在头文件里用extern声明全局变量,这样在包括此头文件的cpp 中可直接使用 声明过的这个全局变量(例如以下面程序中的变量a). 可是有三个例外: 1.头文件里能够定义类 2.值在编译时就已经知道的const对象 3.能够定义inline函数 extern int ival; // yes extern int ival=1; //erro

C++ Primer 学习笔记与思考_5 bitset你用的正确吗?

bitset类型比整型值上的低级位操作更容易使用,简化了位集的处理.在定义bitset时,要明确bitset含有的位数,在尖括号内给出它的长度值. 注意位集合的编号从0开始,低位存低阶位. 最重要的一个问题:bitset的下标是从右边开始的!!!!很多人的博客都写错了,希望引起大家注意. 1.使用unsigned long值初始化bitset对象 若bitset类型长度大于unsigned long值的二进制位数,则其余的高阶位将置为0:若bitset类型长度小于unsigned long值的二

C++ Primer 学习笔记与思考_10 类型转换易错处大总结

(一)隐式转换 先来看一组样例: int ival=0; ival=3.451+3; 首先做加法操作,操作数分别为int和double类型,c++并没有直接把两个数加在一起,而是提供了一组转换规则,以便在执行算术操作之前,将两个操作数转换为同一种数据类型.在这里是自动执行的,所以他们被成为隐式转换. 因为 C++定义了算术类型之间的内置转换以尽可能防止精度损失,所以这里3转换为double型相加得6.451.但是下一步赋值的时候,右操作数进行截断处理,对此精度会有损失,编译器也会给出警告. 2.

C++ Primer 学习笔记与思考_7 void和void*指针的用法

(一)void的含义 void的字面意思是"无类型",void几乎只有"注释"和限制程序的作用,因为从来没有人会定义一个void变量,让我们试着来定义: void a; 这行语句编译时会出错,提示"illegal use of type 'void'".不过,即使void a的编译不会出错,它也没有任何实际意义. void真正发挥的作用在于: (1) 对函数返回的限定: (2) 对函数参数的限定. int f(void); equal to in

C++ Primer 学习笔记与思考_5 数组和动态数组易错点解读

1. 数组的定义 数组定义中的类型名可以是内置数据类型或者类类型:除了引用之外,数组元素的类型还可以是任意的复合类型.另外,非const变量以及要到运行阶段才知道其值的const变量都不能用于定义数组的维数. #include <iostream> #include <string> #include <cstring> #include <bitset> using namespace std; int main() { const int MAXN1 =

C++ Primer 学习笔记_74_面向对象编程 --再谈文本查询示例[续/习题]

面向对象编程 --再谈文本查询示例[续/习题] //P522 习题15.41 //1 in TextQuery.h #ifndef TEXTQUERY_H_INCLUDED #define TEXTQUERY_H_INCLUDED #include <iostream> #include <fstream> #include <sstream> #include <vector> #include <set> #include <map&g