文章目录
一、for循环
1.for循环的组成部分
for循环的步骤
a)设置初始值
b)执行测试,看看循环是否应当继续进行
c)执行循环操作
d)更新用于测试的值
说明:
a)每部分都是一个表达式,彼此用分号隔开,只要测试表达式为true,便会执行循环体body
b)循环只执行一次初始化;
c)test-expression(测试表达式),这个表达式是关系表达式,可以采用任意表达式,C++把结果强制转换为bool类型,so:0->bool的false,1->bool的true;
d)for循环是入口条件(entry-condition)循环,当测试表达式为false时,将不会执行循环体;
e)update-expression(更新表达式)在每轮循环结束的时候执行,此时循环体已经执行完毕;
f)写for语句的习惯:
eg:
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
// num_test.cpp -- use numeric test in for loop
int main()
{
using namespace std;
cout << "Enter the starting countdown value: ";
int limit;
cin >> limit;
int i;
for (i = limit; i; i--) // quits when i is 0
cout << "i = " << i << "\n";
cout << "Done now that i = " << i << "\n";
system("pause");
return 0;
}
解释:
一张图说明一切:
说明:
1)表达式和语句
C++中每个表达式都有值。C++优先级表明,赋值运算符是从右向左结合的。
只要加上分号,所有表达式都可以成为语句,但是不一定有编程意义;
eg:下面的是表达式的有:
下面的是语句的有:
有效但无意义的有:
eg:
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
// num_test.cpp -- use numeric test in for loop
int main()
{
using namespace std;
int x;
cout << "The expression x = 100 has the value ";
cout << (x = 100) << endl;
cout << "Now x = " << x << endl;
cout << "The expression x < 3 has the value ";
cout << (x < 3) << endl;
cout << "The expression x > 3 has the value ";
cout << (x > 3) << endl;
cout.setf(ios_base::boolalpha); //a newer C++ feature
cout << "The expression x < 3 has the value ";
cout << (x < 3) << endl;
cout << "The expression x > 3 has the value ";
cout << (x > 3) << endl;
/// cin.get();
system("pause");
return 0;
}
说明 :
2)非表达式和语句
从语句中删除分号,并不一定能转换为表达式。
3)修改规则
C++可以在for循环初始化部分中申明和初始化变量,这种变量只存在于for中,当程序离开循环后,这种变量将消失。
2.回到for循环
eg:计算并存储16个阶乘
方法:通过观察规律发现
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
const int ArSize = 16; // example of external declaration
int main()
{
long long factorials[ArSize];
factorials[1] = factorials[0] = 1LL;
for (int i = 2; i < ArSize; i++)
factorials[i] = i * factorials[i-1];
for (int i = 0; i < ArSize; i++)
std::cout << i << "! = " << factorials[i] << std::endl;
// std::cin.get();
system("pause");
return 0;
}
说明:
a)
b)数组在何处停止?
c)const的作用
d)标准名称的使用
3.修改步长
可以通过修改更新表达式来修改步长
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
int main()
{
using std::cout; // a using declaration
using std::cin;
using std::endl;;
cout << "Enter an integer: ";
int by;
cin >> by;
cout << "Counting by " << by << "s:\n";
for (int i = 0; i < 100; i = i + by)
cout << i << endl;
// cin.get();
// cin.get();
system("pause");
return 0;
}
说明:
a)更新表达式可以是任何有效的表达式
b)检测不等常比检测相同要好
c)
4.使用for循环访问字符串
1)可以使用string对象,也可以使用char数组,都可以使用数组表示法来访问字符串中的字符
2)string类的size()获得字符串中的字符数(使用这个不考虑空值字符);
3)反向计数用了递减运算符–
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
int main()
{
using namespace std;
cout << "Enter a word: ";
string word;
cin >> word;
cout<<word.size()<<endl;
// display letters in reverse order
for (int i = word.size() - 1; i >= 0; i--)
cout << word[i];
cout << "\nBye.\n";
// cin.get();
// cin.get();
system("pause");
return 0;
}
5.递增运算符++和递减运算符–
前缀,++x;
后缀,x++;
两个版本对操作数的影响是一样的,但是影响的时间是不一样的
eg:
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
int main()
{
using std::cout;
int a = 20;
int b = 20;
cout << "a = " << a << ": b = " << b << "\n";
cout << "a++ = " << a++ << ": ++b = " << ++b << "\n";
cout << "a = " << a << ": b = " << b << "\n";
// std::cin.get();
system("pause");
return 0;
}
说明:
1)
a++意味着使用a的当前值计算表达式,然后再将a的值加1;
++b的意思是先将b的值加1,然后使用新的值来计算表达式;
2)eg:
6.副作用和顺序点
副作用side effect指的是:计算表达式时对某些东西(eg:存储在变量中的值)进行了修改;
顺序点sequence point指的是:程序执行过程中一个点,在C++中,分号就是一个顺序点,另外,任何完整的表达式末尾都是一个顺序点。
顺序点的作用:能够有助于阐明后缀递增何时进行。
eg:
说明:
表达式guests++<10是一个完整表达式,因为他是一个while循环的测试条件,因此该表达式的末尾是一个顺序点。所以,C++确保副作用(将guests加1)在程序进入cout之前完成。
eg:
说明:
7.前缀格式和后缀格式
eg:
说明:
1)
2)
8.递增/递减运算符和指针
可将递增运算符用于指针和基本变量,将递增运算符用于指针时,将把指针的值增加其指向的数据类型占用的字节数。
前缀递增(递减)和解除引用*的优先级相同,以从右到左的方向进行结合;
后缀递增和递减的优先级相同,但比前缀运算符的优先级高,这俩运算符是从左到右的方式进行结合。
不理解上述的话,就看例子就懂了!
前置和后置运算符的使用举例(注意最终的值以及pt指向哪里)
eg:
说明:++*pt意味着:先取地pt指向的值,然后将这个值加1
说明:pt仍然指向arr[2]
说明:圆括号指出先对指针解除引用,得到24.4。然后运算符++将这个值递增到25.4,pt仍然指向arr[2]。
说明:注意x最终的值以及pt指向哪里
9.组合赋值运算符
组合赋值运算符的表格
10.复合语句(语句块)
C++可以在循环体中包含任意多条语句,方法是用两个花括号来构造一条复合语句(代码块)。
eg:
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
int main()
{
using namespace std;
cout << "The Amazing Accounto will sum and average ";
cout << "five numbers for you.\n";
cout << "Please enter five values:\n";
double number;
double sum = 0.0;
for (int i = 1; i <= 5; i++)
{ // block starts here
cout << "Value " << i << ": ";
cin >> number;
sum += number;
} // block ends here
cout << "Five exquisite choices indeed! ";
cout << "They sum to " << sum << endl;
cout << "and average to " << sum / 5 << ".\n";
cout << "The Amazing Accounto bids you adieu!\n";
// cin.get();
// cin.get();
system("pause");
return 0;
}
说明:
1)
2)若在语句块中定义一个新的变量,则仅当程序执行该语句块中的语句时,该变量才存在,执行完该语句块后,变量将被释放。
3)若在一个语句块中申明一个变量,而在外部语句中也有一个这种名称的变量,情况?
在申明位置到内部语句块结束的范围之内,新变量将隐藏旧变量,然后旧变量再次可见
eg:
11.其它语法技巧——逗号运算符
逗号运算符对表达式完成同样的任务,允许将两个表达式放到C++语法只允许放一个表达式的地方。
eg:for循环的更新部分可将两个表达式合并为一个
eg:申明中的逗号将变量列表中相邻的名称分开
eg:该程序将数组中的字符顺序反转,还用了语句块(将几条语句合成一条)
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
int main()
{
using namespace std;
cout << "Enter a word: ";
string word;
cin >> word;
// physically modify string object
char temp;
int i, j;
for (j = 0, i = word.size() - 1; j < i; --i, ++j)
{ // start block
temp = word[i];
word[i] = word[j];
word[j] = temp;
} // end block
cout << word << "\nDone\n";
// cin.get();
// cin.get();
system("pause");
return 0;
}
说明:
1)初始化和更新部分
2)循环体
测试条件j<i使得到达数组的中间,循环将终止。
用一个图来说明反转字符串
3)也可以使用一个申明语句表达式来创建并初始化两个变量。
eg:
4)也可以在for循环内部声明temp
eg:
4)逗号运算符最常见的用途是将两个或更多的表达式放到一个for循环表达式中;
首先,它确保计算第一个表达式,然后计算第二个表达式;
其次,C++规定,逗号表达式的值是第二部分的值。
在所有运算符中,逗号运算符的优先级是最低的。
eg:
12.关系表达式
在C++中,关系运算符可以对值进行比较;
关系运算符不能用于C风格的字符串,但是可以用于string类对象。
对于所有的关系表达式,如果比较结果为真,则其值将为true,否则为false,因此可将其用于循环测试的表达式。
eg:
13.赋值、比较和可能犯的错误
不要混淆等于运算符(==)与赋值运算符。
eg:
下面的程序指出了可能出现这种错误的情况。
该程序的作用是:检查一个存储了测验成绩的数组,在遇到第一个不为20的成绩时停止。
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
int main()
{
using namespace std;
int quizscores[10] =
{ 20, 20, 20, 20, 20, 19, 20, 18, 20, 20};
cout << "Doing it right:\n";
int i;
for (i = 0; quizscores[i] == 20; i++)
cout << "quiz " << i << " is a 20\n";
// Warning: you may prefer reading about this program
// to actually running it.
cout << "Doing it dangerously wrong:\n";
for (i = 0; quizscores[i] = 20; i++)
cout << "quiz " << i << " is a 20\n";
// cin.get();
system("pause");
return 0;
}
说明:
1)错误的地方始终是true
对于C++类,可以设计一种保护数组类型来防止这种错误,如果所有的成绩都是20,“好”的循环也会超出数组边界。总之,循环需要测试数组的值和索引的值。
2)注意:不要使用=来比较两个量是否相等,而要使用==
14.C风格字符串的比较
1)数组名是数组的地址
2)如果word是数组名,eg:
用括号括起来的字符串常量也是其地址。
因此,上面的关系表达式不是判断两个字符串是否相同,而是查看它们是否存储在相同的地址上。两个字符串的地址是否相同呢??答案是否定的,虽然他们包含相同的字符串。
C++将C风格的字符串视为地址,如果使用关系运算符来比较它们,将无法得到满意的结果。
3)应该使用C风格字符串库中的strcmp()函数来比较。
该函数接受两个字符串地址作为参数,这些参数可以是指针、字符串常量或者字符串数组名。
若两个字符串相同,该函数将返回0;
如果第一个字符串按字母顺序排在第二个字符串之前,则strcmp()将返回一个负数值;
如果第一个字符串按字母顺序排在第二个字符串之后,则strcmp()将返回一个正数值;
4)对于存储在不同长度的数组中的字符串而言,C风格字符串是通过结尾的空值字符定义的,而不是由其所在数组的长度定义的。
也就是说,两个字符串即使被存储在长度不同的数组中,也有可能是相同的
eg:
说明:虽然不能用关系运算符来比较字符串,但是却可以用它们来比较字符,因为字符实际上是整型。
5)
eg:
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
int main()
{
using namespace std;
char word[5] = "?ate";
for (char ch = 'a'; strcmp(word, "mate"); ch++)
{
cout << word << endl;
word[0] = ch;
}
cout << "After loop ends, word is " << word << endl;
// cin.get();
system("pause");
return 0;
}
说明:
1)我们希望只要word不是mate,循环就可以继续进行
使用strcmp(word,“mate”),若字符串不相等,则它的值为非0(true);
若字符串相等,则它的值为0(false);
2)strcmp()的其它用法
15.比较string类字符串
string类字符串可以直接使用关系运算符进行比较,这是因为类函数重载(重新定义)了这些运算符。
eg:
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
int main()
{
using namespace std;
string word = "?ate";
for (char ch = 'a'; word != "mate"; ch++)
{
cout << word << endl;
word[0] = ch;
}
cout << "After loop ends, word is " << word << endl;
// cin.get();
system("pause");
return 0;
}
说明:
1)
2)进一步,如果不对语句块执行指定的次数做出要求的话,对于这种测试,C++通常使用while循环。
二、while循环
while介绍
1)while循环是没有初始化和更新部分的for循环,它只有测试条件和循环体:
说明:
a)
b)若希望循环体最终能够结束,循环体中的代码必须完成某种影响测试条件表达式的操作;
c)和for循环一样,while循环也是一种入口条件循环。因此,如果测试条件一开始为false,则程序将不会执行循环体;
2)一张图搞定while如何循环
例子:关于循环遍历字符串
说明:
a)循环遇到空值字符时停止,由于字符串中包含了结尾标记,所以程序通常不需要知道字符串的长度;
b)逐字符遍历字符串直到遇到空值字符的技术是C++处理C风格字符串的标准方法;
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
const int ArSize = 20;
int main()
{
using namespace std;
char name[ArSize];
cout << "Your first name, please: ";
cin >> name;
cout << "Here is your name, verticalized and ASCIIized:\n";
int i = 0; // start at beginning of string
while (name[i] != '\0') // process to end of string
{
cout << name[i] << ": " << int(name[i]) << endl;
i++; // don't forget this step
}
system("pause");
return 0;
}
说明:
1)循环体结尾将i+1使得该测试能够成功,若省略这一步,是导致死循环的常见问题直以;
通常,不要忘记在循环体中更新某个值
2)可将while条件:
while(name[i]!=’\0’)
->
while(name[i])
经过这种修改后,程序的工作方式不变。(强烈推荐上述的写法,简洁且常用)
由于name[i]是常规字符,其值为该字符的编码,为非0或true;
当name[i]为空值字符时,其编码为0或false;
3)要打印ASCII码,必须通过强制类型转换,将name[i]转换为整型
4)不同于C风格字符串,string对象不适用空字符来标记字符串末尾
1.for与while
1)在C++中,for和while循环本质上是相同的
可将for循环->while循环
->
while循环->改写成for循环
->
说明:只有两个分号是必须的。
2)省略for循环中的测试表达式时,测试结果将为true,因此,下面的循环将一直运行下去。
3)由于for循环和while循环几乎是等效的。
所以,for和while循环的区别主要在于:
a)for循环中省略了测试条件时,将认为条件为true;
b)在for循环中,可使用初始化语句申明一个局部变量,但是在while中不能这么做;
c)如果循环体中包括continue,情况将稍有不同;
so,程序员使用for循环来为循环计数;再无法预知循环执行的次数时,使用while
4)在设计for和while循环的时候,应该记住下面的几条指导原则:
a)在首次测试之前初始化条件
b)指定循环终止的条件
c)在条件被再次测试之前更新条件
补充:写循环的时候,错误的标点符号
a)语句块是由花括号,而不是由缩进定义的
eg:
b)while后面直接加分号,会造成一种死循环
2.等待一段时间:编写延时循环
C和C++都一个函数名为clock()的一个函数,返回程序开始执行后所用的系统时间;
在头文件ctime提供了这些问题的解决方案:
a)它定义了一个符号常量CLOCKS_PER_SEC,该常量=每秒钟包含的系统时间的单位数。
所以,将系统时间除以这个值,可以得到秒数;将秒数乘以这个值,可以得到以系统时间为单位的时间。
b)ctime将clock_t作为clock()返回类型的别名,意思是可将变量申明为clock_t类型。
eg:
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
#include <ctime> // describes clock() function, clock_t type
int main()
{
using namespace std;
cout << "Enter the delay time, in seconds: ";
float secs;
cin >> secs;
clock_t delay = secs * CLOCKS_PER_SEC; // convert to clock ticks
cout << "starting\a\n";
clock_t start = clock();
while (clock() - start < delay ) // wait until time elapses,为啥这么写?
; // note the semicolon注意分号
cout << "done \a\n";
system("pause");
return 0;
}
说明:
补充:类型别名typedef和define
C++为类型建立别名的方式有两种
a)使用预处理器define
b)使用C++和C的关键字typedef来创建
typedef的通用格式是:
eg:
eg:
3.do while循环
1)for和while是入口循环,do while是出口循环。
2)do while循环的程序流程
首先执行循环体,然后再判定测试表达式,若false,则循环终止;否则,进入新的一轮进行执行和测试。
3)循环至少被执行一次;
入口条件循环比出口条件循环好,因为入口条件循环在循环开始之前对条件进行检查。
eg:
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
#include <ctime> // describes clock() function, clock_t type
int main()
{
using namespace std;
int n;
cout << "Enter numbers in the range 1-10 to find ";
cout << "my favorite number\n";
do
{
cin >> n; // execute body
} while (n != 7); // then test
cout << "Yes, 7 is my favorite.\n" ;
// cin.get();
// cin.get();
system("pause");
return 0;
}
补充:编写清晰、容易理解的代码比使用语言的晦涩特性来显示自己的能力更为有用。
例如以下的三个等价的循环的使用:for,while,do while
a)for循环中的空测试条件被视为true
<=>
b)while循环
c)do while循环
4.基于范围的for循环(C++):目前作为了解即可
eg:
说明:
1)x最初表示数组prices的第一个元素,会不断执行循环,x以此表示数组的其他元素,最终会循环显示数组中的每个值。
2)如果要修改数组的元素
符号&表明x是一个引用变量,这种申明让接下来的代码能够修改数组的内容。
3)初始化列表的方法:
5.循环和文本输入:逐字符地读取来自文件或键盘的文本
cin对象支持3种不同模式的单字符输入,其用户接口各不相同。
1.使用原始cin输入:逐字符读-空格不可算
如果程序要使用循环来读取来自键盘的文本输入,则必须有办法知道何时停止读取。
eg:(最原始的方法)
哨兵字符sentinel character:用来标记停止。
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
#include <ctime> // describes clock() function, clock_t type
int main()
{
using namespace std;
char ch;
int count = 0; // use basic input
cout << "Enter characters; enter # to quit:\n";
cin >> ch; // get a character
while (ch != '#') // test the character
{
cout << ch; // echo the character
++count; // count the character
cin >> ch; // get the next character
}
cout << endl << count << " characters read\n";
// cin.get();
// cin.get();
system("pause");
return 0;
}
说明:
1)对于循环设计而言,结束循环的条件是最后读取的一个字符是#,该条件是通过在循环之前,读取一个字符进行初始化,并通过循环体结尾读取下一个字符进行更新。
具体解释如下:
对于下面画红圈的代码而言的,解释如下:
2)在运行程序的时候,可以在#后面输入字符的原因是,即
说明:
发送cin的输入被缓冲,这意味着,只有用户按下回车键以后,输入的内容才会被发送给程序。
3)从最终的结果,我们可以看到:cin忽略空格和换行符,so,输入中的空格没有被回显,也没有被包括在计数内。
2.使用cin.get(char)进行补救:逐字符读-空格可算
cin属于istream,成员函数**cin.get(ch)**读取输入中的下一个字符(即使它是空格),并将其赋给变量ch。用其代替cin>>ch。
eg:
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
#include <ctime> // describes clock() function, clock_t type
int main()
{
using namespace std;
char ch;
int count = 0;
cout << "Enter characters; enter # to quit:\n";
cin.get(ch); // use the cin.get(ch) function
while (ch != '#')
{
cout << ch;
++count;
cin.get(ch); // use it again
}
cout << endl << count << " characters read\n";
// get rid of rest of line
// while (cin.get() != '\n')
// ;
//cin.get();
system("pause");
return 0;
}
说明:
1)该程序回显了每个字符,并将全部字符计算在内,其中包括空格,输入仍被缓冲
2)重点理解一下C与CPP的区别
通常,在CPP中传递参数的工作方式与在C语言中相同,但是除了cin.get(ch)。
在C语言中,要修改变量的值,必须将变量的地址传递给函数。
但是在CPP中,函数只需将参数申明为引用即可。头文件iostream将cin.get(ch)的参数申明为引用类型,因此,该函数可以修改其参数的值。
3.使用哪一个cin.get()
eg:看看我们前面用的cin.get()的用法
说明:
1)cin.get(name,ArSize),可以接受两个参数:数组名(char *类型的字符串的地址)和ArSize(int类型的整数)。
注:数组名是其第一个元素的地址,so,字符数组名的类型为char * 。
2)cin.get(ch)
在C语言中,如果函数接受char指针和int参数,则使用该函数时,不能只传递一个参数,因为类型不同。
但是在CPP中,支持函数重载的OOP特性。函数重载允许创建多个同名函数,条件是它们的参数列表不同。
函数重载允许对多个相关的函数使用相同的名称,这些函数以不同方式或针对不同类型执行相同的基本任务。
所以:
如果在CPP中使用cin.get(name,ArSize),则编译器将找到使用char *和int作为参数的cin.get()版本;
如果使用cin.get(ch),则编译器将使用接受一个char参数的版本;
如果使用cin.get(),则编译器将使用不接受任何参数的cin.get()版本。
6.文件尾条件:逐字符读-常用的方法
1)如果输入来自文件,可以使用EOF检测文件尾。
很多操作系统都支持重定向,允许用文件替换键盘输入。
eg:
2)很多操作系统允许通过键盘来模拟文件尾条件。很多PC编程环境都将Ctrl+Z视为模拟的EOF。
eg:
对下面cin.fail()提前的说明
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
#include <ctime> // describes clock() function, clock_t type
int main()
{
using namespace std;
char ch;
int count = 0;
cin.get(ch); // attempt to read a char
while (cin.fail() == false) // test for EOF
{
cout << ch; // echo character
++count;
cin.get(ch); // attempt to read another char
}
cout << endl << count << " characters read\n";
system("pause");
return 0;
}
说明:
1)cin.get()可以用来锁住屏幕,直到可以读取为止。但在这里不行,因为检测到EOF的时候,会关闭对输入的进一步读取。
2)~Z指的是Ctrl+Z,我们用Ctrl+Z和回车键来模拟EOF条件。
3)小小的补充:
1.EOF结束输入
2.常见的字符输入做法
1)每次读取一个字符,直到遇到EOF的输入循环的基本设计如下:
<=>
说明:
进一步,可以将1)改为2)的while式子:
2)
说明:
这比 !cin.fail()或者!cin.eof()更加通用 ,因为他可以检测如磁盘故障等失败原因。
进一步,可以将2)精简为下面3)的式子
3)
说明:
1)cin.get(char)只被调用一次
2)写的话,如果要简化的去写,只有上面的一种方法
7.cin.get()的另一个版本:现在写代码最常用的了
1)ch=cin.get();
2)cout.put(ch)
3)为了成功地使用cin.get(),需要知道其如何处理EOF条件。当函数到达EOF时,将没有可返回的字符,而是用一个符号常量EOF表示的特殊值,被定义为 -1。
eg:
说明:
4)对于判断EOF而言:
对于显示char而言:
eg:
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
#include <ctime> // describes clock() function, clock_t type
int main(void)
{
using namespace std;
int ch; // should be int, not char
int count = 0;
while ((ch = cin.get()) != EOF) // test for end-of-file
{
cout.put(char(ch));
++count;
}
cout << endl << count << " characters read\n";
system("pause");
return 0;
}
说明:
1)
2)如果上述的括号没写对
3)
4)cin.get()与cin.get(char)的对比
三、循环嵌套和二维数组:for的再使用
eg:假设要存储5个城市在4年间的最高温度,可以这样申明数组
如何去认识和使用这样的数组呢?
1)由数组组成的数组
2)使用下标访问数组—用的多
如果要打印数组所有的内容,那么可用一个for循环来改变行,用另一个嵌套的for循环来改变列,所以,最终的代码可以写成:
1.初始化二维数组
1)一维数组是用逗号分割的,用花括号括起来的值列表
2)对于二维数组而言,由于每个元素本身就是一个数组,因此,同样可由一系列逗号分割的一维数组初始化组成:
同样也得用花括号括起来
说明:可将数组maxtemps包含4行,每行包含5个数字。
2.使用二维数组
eg:
该程序的意思是:在输出的时候,将列循环(城市索引)放在外面,将行循环(年份索引)放在内面。
// choices.cpp -- array variations
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <vector> // STL C++98
#include <array> // C++0x
#include <string>
#include <ctime> // describes clock() function, clock_t type
#include <iostream>
const int Cities = 5;
const int Years = 4;
int main()
{
using namespace std;
const char * cities[Cities] = // array of pointers
{ // to 5 strings
"Gribble City",
"Gribbletown",
"New Gribble",
"San Gribble",
"Gribble Vista"
};
int maxtemps[Years][Cities] = // 2-D array
{
{96, 100, 87, 101, 105}, // values for maxtemps[0]
{96, 98, 91, 107, 104}, // values for maxtemps[1]
{97, 101, 93, 108, 107}, // values for maxtemps[2]
{98, 103, 95, 109, 108} // values for maxtemps[3]
};
cout << "Maximum temperatures for 2008 - 2011\n\n";
for (int city = 0; city < Cities; ++city)
{
cout << cities[city] << ":\t";
for (int year = 0; year < Years; ++year)
cout << maxtemps[year][city] << "\t";
cout << endl;
}
system("pause");
return 0;
}
说明:
1)C++中一个常用做法:将一个指针数组初始化为一组字符串常量。
对比的话,eg1:
可以使用char数组的数组,而不是字符串指针数组,
说明:
a)使用char数组的数组时,将5个字符串分别复制到5个包含25个元素的char数组中。
b)从存储的角度讲,使用指针数组更为经济,然而缺点是:如果要修改其中的任何一个字符串,则二维数组是更好的选择。
相同点是:这两种方法使用相同的初始化列表,显示字符串的for循环代码页相同。
对比的话,eg2:
使用string对象数组
说明:
a)如希望字符串是可修改的,则应该省略const
b)string对象数组的初始化列表和显示字符串的for循环代码与前两者方法一致
c)在希望是可修改的情况下,string类自动调整大小的特性使得使用二维数组更为方便
七、总结咯——依然总结的非常好