2.2 循坏结构及其应用文本输入

本文详细介绍了C++中的循环结构,包括for、while、do-while和基于范围的for循环,强调了设计循环时的原则。同时,讨论了文本输入的方法,如cin.get()的使用,并解释了如何处理EOF。最后,提到了循环嵌套和二维数组的应用。
摘要由CSDN通过智能技术生成

设计循环时的几条指导原则:1)指定循环终止条件 2)在首次测试前初始化条件 3)在条件被再次测试之前更新条件

1 for循环

c++允许在for循环初始化部分中声明和初始化变量,c不允许,这种变量离开循环后就会消失。

#include <string>

string word;
cin>>word;
for(int i = word.size()-1;i>=0;i--)    // 反向打印字符串
    cout<<word[i];

2 while以及do-while循环

#include <ctime>
// #define clo clock_t 
typedef clock_t clo; // 1)2)

float secs;
cin >> secs;
clo delay = secs * CLOCKS_PER_SEC;  // 3)
cout << "start!" << endl;
clo start = clock();    // 4)
while(clock() - start < delay);  // 时间差,目的等待secs秒
cout << "done!" << endl;

4)处:函数名clock()返回从开始程序到调用clock()函数之间的系统时间,问题是单位不一定是秒,其次他的类型可能是long、unsigned int或其他类型。

1)处:为类型建立别名有两种方式:一种是使用预处理器,格式#define aliasname typeName,缺点有时不适用,如

#define FLOAT_POINT float *
FLOAT_POINT pa,pb;

此时预处理器会将该声明转换为float * pa,pb;,pa是float*类型,而pb是float类型。另一种是关键字typedef来创建别名,格式typedef typeName aliasName;,它能够处理更加复杂的类型别名

2)处:cctime将clock_t作为clock()返回类型的别名,编译器会将它转换为long、unsigned int或适合系统的其他类型

3)处:CLOCKS_PER_SEC为符号常量,等于每秒包含的系统时间单位数,秒数*CLOCKS_PER_SEC,可以得到以系统时间单位为单位的时间。

3 基于范围的for循环(c++11)

int number[5] = {1,2,3,4,5};
for(int x : number)   // 版本1对数组中的元素执行相同的操作
    cout << x << endl;
for(int &x : number)  // 版本2:x是引用变量,能够修改数组中的内容,版本1不可以
    x = 2 * x;
cout << x <<" ";
cout << endl;

4 文本输入与循环

方案一:使用原始的cin进行输入(有问题)

char ch;
int count = 0;	// 计数
cin >> ch;
while (ch != '#'){
	cout << ch;
	count++;
	cin >> ch;  // 1)
}
cout << endl << count << endl;
// 测试示例
ewr fwe#wer
ewrfwe
6

1)问题:cin会忽略空格、制表符和换行符,因此输入中的空格没有被回显,也没有被包括在计数内。

方案二:使用cin.get(char)修改,缺点是#也有可能是合法输入,此时的程序就出错了。

char ch;
int count = 0;	// 计数
cin.get(ch);
while (ch != '#'){
	cout << ch;
	count++;
	cin.get(ch);
}
cout << endl << count << endl; 

// 测试示例
wew     we#   // 这里输入时有tab键
wew     we
6

方案三:检测文件尾条件(EOF,被定义为-1,它不表示字符,而是指出没有字符) windows将ctrl+Z视为模拟的EOF,用户还要按回车键结束。

检测到EOF后,cin将两位(eofbit和failbit)都设置为1,可以通过成员函数eof()查看eofbit是否被设置,如果检测到EOF,则cin.eof()将返回bool值true,否则返回false。同样,如果eofbit或failbit被设置为1,则fail()成员函数返回true,否则返回false。eof()和fail()方法报告最近读取结果,应将cin.eof()或cin.fail()测试放在读取之后。

char ch;
int count = 0;
cin.get(ch);
while(cin.fail() == false)  // while(!cin.fail())
{
	cout << ch;
	count++;
	cin.get(ch);
} 
cout << endl << count << endl; 

// 测试示例
qwe ert
qwe ert
^Z

8   // 在qwe ert后有回车键

最终通用版: cin.get(ch)版本

char ch;
int count = 0;
while(cin.get(ch))  // 1)
{
    cout << ch;
    count++;
} 
cout << endl << count << endl;

// 测试示例
wer zxc
wer zxc
^Z

8

 1)处:方法cin.get(ch)的返回值是一个cin对象,然而istream类提供一个将istream对象转换为bool值的函数,所以当cin出现在需要bool值的地方时,该转换函数将被调用。在判断循环测试条件时,程序必须首先调用cin.get(ch),如果成功,则将值放入ch中。然后,程序获得函数调用的返回值,即cin。接下来,程序对cin进行bool转换,如果输入成功,则结果为true,否则为false。这时的三条指导原则全部放在while的循环测试条件中。

ch = cin.get()版本

int ch;                          // 1)
int count = 0;
while((ch = cin.get()) != EOF)  // 1)
{
	cout.put(char(ch));
	count++;
} 
cout << endl << count << endl;
// 测试示例
we are Chinese.
we are Chinese.
^Z

16

1)处: char类型可能是没有符号的,因此char变量不可能是-1,测试条件永远不会成立。当使用cin.get()并测试EOF,则必须将返回值赋给int变量,而不是char变量。

以上出现的cin和cout的函数可参考如下博客链接,cin对象中的相同函数名,不同参数列表,为函数重载。

https://blog.csdn.net/vinkuan/article/details/104118391

https://blog.csdn.net/vinkuan/article/details/104215308

5 循环嵌套和二维数组

const char * varieties[NUM] =   // 1)2)
{
	"fruit",
	"snacks",
	"drink"
};
double price[NUM][VAL] = {      // 3)
	{ 10,11,12,13,15 },
	{ 21,22,23,24,25},
	{ 7,8,9,10,11}
};
for(int varity = 0; varity < NUM; ++varity)
{
	cout << varieties[varity] << ":\t";
	for(int pri = 0; pri < VAL; ++pri) 
	    cout << price[varity][pri]<<"\t";
	cout << endl;
}

// 测试结果
fruit:  10      11      12      13      15
snacks: 21      22      23      24      25
drink:  7       8       9       10      11

1)字符串字面值是常量,所以在声明中使用const关键字,意味着可以用varieties访问字符串,但不可修改它

2)这是字符串指针数组,也可以用char数组的数组和string对象数组,如下

char varieties[NUM][10] =   // char数组的数组
{
	"fruit",
	"snacks",
	"drink"
};

const string varieties[NUM] =   // string对象数组。可省略const,便可修改字符串
{
	"fruit",
	"snacks",
	"drink"
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vinkuan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值