C++初学者笔记(一)
最近想写一个代码,将未知数量的整形数储存在空间足够大的数组中,然后排序后由小到大输出
写代码时用了这样一段代码:
int arr[80];
int k = 0;
while(cin>>arr[k])
{
if(cin.get() == '\n') break;
k++;
for(int i=0;i<k;i++)
{
cout<<arr[i]<<" ";
}
顺便提一句,运行程序时发现光是靠敲回车结束不能结束此条件下的while循环。故加上了一个判断语句,引入cin.get()函数,方能实现通过敲回车结束while(cin)循环。
然后发现 k++与if判断语句互换位置之后输出,总是少了一个数,由此产生了题目所述的问题。
最初的想法
当时的想法是这样的:输入一串数后,k的值应该比数组中最后一个值的下标大1,故输出时用的判断条件是 i<k。
结果k的值却等于数组中最后一个值的下标,k++与判断语句互换条件后才符合最初的设想。
cin与cin.get()的原理(搬运)
从这看到的: https://blog.csdn.net/dianboliao0344/article/details/102235893
从中摘录了个人认为与本文相关的部分,见下文。
输入原理:
程序的输入都建有一个缓冲区,即输入缓冲区。一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而cin函数直接从输入缓冲区中取数据。正因为cin函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数会直接取得这些残留数据而不会请求键盘输入
一. cin>>
该操作符是根据后面变量的类型读取数据。
输入结束条件 :遇到Enter、Space、Tab键。
对结束符的处理 :丢弃缓冲区中使得输入结束的结束符(Enter、Space、Tab)
二.cin.get(数组名,长度,结束符)
其中结束符为可选参数,读入的字符个数最多为(长度-1)个,结束符规定结束字符串读取的字符,默认为ENTER
若要读取字符,直接cin.get(char ch)或ch=cin.get()即可
读取字符的情况:
输入结束条件:Enter键
对结束符处理:不丢弃缓冲区中的Enter
cin.get() 与 cin.get(char ch)用于读取字符,他们的使用是相似的,
即:ch=cin.get() 与 cin.get(ch)是等价的。
个人理解
当你敲回车,空格,TAB键的时候,这些特殊字符也会储存在输入缓冲区
**
(至于输入缓冲区的储存原理还不太明朗,有了更深的理解后再来补充)**
以输入 3(空格)2(回车) 和文章开头的代码段为例。
①输入3和空格之后,cin部分判断输入结束,忽略空格这一特殊符号。向前发现缓存区中有整形数3,将3赋给arr[0],while判断为真,执行循环体中的if语句。
②此时cin.get()读到的却不是3,而是空格,不满足条件,执行k++。
当再输入2与回车的时候,①部分同理,arr[1]=2。 但是在②中,cin.get()读到的却是储存在缓冲区中的回车(’\n’),跳出循环,不执行k++,故k比预想中的要小1。但庆幸的是,第二个值也存进了数组中。
个人总结与反思
cin与cin.get()的区别在于是否保留缓冲区中的特殊字符,读取缓冲区内的数据时只能读取到当前缓冲区中留存的最后一个数据。