C++第四章笔记

2014/10/8 posted in  C++

C++11使得大括号初始化成为通用初始化,可用于所有类型,甚至可以省略等号的赋值。

cin和scanf一样,对字符串不会录入空格,在istream中的类cin提供了一些面向行的类成员函数:getline()和get(),这两个函数都读取一行输入,直到到达换行符,然而,getline将舍弃换行符,而get将换行符保留在输入序列中。

getline输入两个参数,第一个参数是存储输入行的数组名称,第二个参数是要读取的字符数,

cin.getline(name,20);

其实getline还有第3个参数,只不过第4章木有讲~

对于get()来说,一定要注意的是get并不在读取并丢弃换行符,而是将其留在输入队列中,如果连续两次调用get()

cin.get(name,ArSize);
cin.get(dessert,ArSize);

因为当第一行录入成功之后,因为没有把换行符录入进去,而运行到下一行,

但是换行符留在了输入缓冲中,第二行没有获得任何东西便读到了换行符,也就是dessert没有得到任何东西,这样,如果不借助帮助,这条语句就无法被跳过。

所幸,因为函数重载,get还有另外一种使用方法:

cin.get(name,ArSize);
cin.get();
cin.get(dessert,ArSize);

第二行,这样使用可以吃掉一个任意字符,包括换行符。

其实还有一种炫酷的使用方法,

cin.get(name,ArSize).get();

因为get会返回cin,便可以继续“.”下去~~

不光get,getline也可以。炫酷技能get it (⊙v⊙)。

《C++ PP》推荐使用get而不是getline,原因有二:一是getline在老版本中并没有,也就是说老版本编译器支持性不好,二是如果一行文字录入完成之后,怎么判断是因为录入到换行符才结束的还是因为超出固定长度而结束的?用get只需要判断输入缓冲中最前面那个字符是不是换行符即可。

失效位问题,像封装好的类,里面总有各种各样的标记,而istream中有个失效位标记,标记着是否还能被录入进去数据。

get在读取空行的时候,便会设置失效位,导致后面所有的输入语句失效,

当输入的语句比设置长度要长,get和getline都会只录入规定长度的内容,其他的保留在缓冲区中,但不同的是getline还会设置失效位,关闭后续的输入,在一定长度上讲,起到了保护后续数据的作用。

其实非法输入,EOF等都可以引起失效,失效的解决方法就是清除函数

cin.clear();

其实这样讲,我认为getline也可以判断到底是因为输入过长还是确实是行结束,判断失效位就可以了。

换行符问题,如果是这样的代码:

cin >> year;
cin.getline(address,80);

第二行会被录入什么东西呢?其实只会被录入一个换行符,因为录入year之后,换行符留在了缓冲区,最后被address吃掉了。

和之前敲代码的时候在scanf中加%*c的原因相同,这个也要相似处理,当然,又是一个高大上的语句

(cin >> year).get();

灵活的语句,十分炫酷。

因为string类不需要规定长度,因此有个不是cin成员函数的getline,

string str;
getline(cin,str);

他将cin作为参数而不是以cin的成员函数使用,其实就是因为string出现的晚,cin没有支持string 的成员函数,便加声明了getline以支持string。

面向对象编程与传统的过程性编程的区别在于OOP强调的是在运行阶段而不是编译阶段,最好的诠释就是动态分配,用指针等,在运行过程中决定使用多大的空间而不是在编译的时候决定,更加灵活。

C++中添加了vector作为数组的代替品,vector总的来说属于动态数组,功能要比数组强大,但付出的代价是效率低下。

但在C++11标准中,增加了array类,他的长度和数组一样是固定的,可以认为是定长数组,但是存储在栈(静态内存分配)而不是自由存储区,因此和数组一样快,并且同样强大。