for循环
//程序清单5.1
//介绍for循环
#include <iostream>
int main(void)
{
using namespace std;
for (int i = 0;i < 5; i++)
cout << "C++ knows loops.\n";
cout << "C++ knows when to stop.\n";
return 0;
}
- for (initialization; test_expression; update_expression)
- int i = 0;循环初始化
- i < 5;循环测试
- cout << "C++ knows loops.\n"; 循环体
- i++ 循环更新。++运算符——递增运算符
回到for循环
//程序清单5.4
//阶乘
#include <iostream>
const int ArSize = 16;
int main(void)
{
using namespace std;
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++)
cout << i << "! = " << factorials[i] << endl;
return 0;
}
- 修改步长:i = i + by 或 i += by
- 检测不等比检测相等好
使用for循环访问字符串
//程序清单5.6
//将字符串反过来拼写
#include <iostream>
#include <string>
int main(void)
{
using namespace std;
cout << "Enter a word: ";
string word;
cin >> word;
for (int i = word.size() - 1; i >= 0; i--)
cout << word[i];
return 0;
}
- string类的size()获得字符串中的字符数
递增运算符(++)和递减运算符(--)
//程序清单5.7
//递增运算符
#include <iostream>
int main(void)
{
using namespace std;
int a = 20;
int b = 20;
cout << "a = " << a << ": b = " << b << endl; //20, 20
cout << "a++ = " << a++ << ": ++b = " << ++b << endl; //20, 21
cout << "a = " << a << ": b = " << b << endl; //21, 21
return 0;
}
- 递增和递减对操作数的影响是一样的,但影响的时间不同。
- a++意味着使用a的当前值计算表达式,然后将a的值加一。
- ++b意味着先将b的值加一,然后使用新的值来计算表达式。
- 不要在同一条语句对同一个值递增或递减多次。
x = 2 * x++ * (3 - ++x);//可能在不同系统上生成不同的结果
递增/递减运算符和指针(视频链接)
double arr[5] = {21.1, 32.8, 23.4, 45.2, 37.4};
double *pt = arr; //pt指向arr[0],21.1
- 前缀递增,前缀递减和解除引用运算符的优先级相同,以从右到左的方式进行结合。
- 后缀递增和后缀递减的优先级相同,但比前缀运算符的优先级高。这两个用算符以从左到右的方式进行结合。
- *++pt:前缀运算符从右到左结合,先将++应用于pt,然后将*应用于被递增后的pt。32.8
- ++*pt:先取得pt的值,再加1。33.8
- (*pt)++:圆括号优先级高,先对指针解除引用,得到33.8,再后缀++递增,此时值为34.8
- *pt++:后缀比前缀优先级高,指针递增指向23.4,然而后缀意味对原地址解除引用,34.8
复合语句
//程序清单5.8
//语句块
#include <iostream>
int main(void)
{
using namespace std;
cout << "Sum and Average" << endl;
cout << "Enter five values:\n";
double number;
double sum = 0.0;
for (int i = 0; i <= 5; i++)
{
cout << "Value " << i << ": ";
cin >> number;
sum += number;
}
cout << "Sum: " << sum << endl;
cout << "Average: " << sum / 5 << endl;
return 0;
}
- 在语句块中定义一个新的变量,仅当程序执行该语句块中的语句时该变量才存在。执行完该语句块后,变量将被释放。
逗号运算符
//程序清单5.9
//反转字符串
#include <iostream>
#include <cstring>
int main(void)
{
using namespace std;
cout << "Enter a word: ";
string word;
cin >> word; //stressed
char temp;
int i, j;
for (j = 0, i = word.size() - 1; j < i; --i,++j)
{
temp = word[i];
word[i] = word[j];
word[j] = temp;
}
cout << word << endl; //desserts
return 0;
}
- 也可以使用一个生命语句表达式来创建并初始化两个变量,但看上去有点乱:
- int j = 0, i = word.size() - 1;看上去好像只声明了j
- 逗号运算符是一个顺序点。他确保先计算第一个表达式,然后计算第二个表达式。
- 在所有运算符中,逗号运算符的优先级是最低的。
C-风格字符串的比较
//程序清单5.11
//用数组比较字符串
#include <iostream>
#include <cstring>
int main(void)
{
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,words is " << word << endl;
return 0;
}
- 用C库中的strcmp()函数进行比较。
- 该函数接受两个字符串址作为参数,参数可以是指针、字符串常量或字符数组名
- 若两个字符串相同,函数返回0;若第一个字符串顺序在第二个字符串顺序之前,函数返回负值;相反,返回正值
string类字符串比较
//程序清单5.12
//用数组比较字符串
#include <iostream>
#include <string>
int main(void)
{
using namespace std;
string word = "?ate";
for (char ch = 'a'; word != "mate"; ch++)
{
cout << word << endl;
word[0] = ch;
}
cout << "After loop ends,words is " << word << endl;
return 0;
}
while循环
- 确定循环次数——for循环;不确定循环次数——while循环
- while循环是没有初始化和更新部分的for循环,只有测试条件和循环体
while (test_condition)
body
//程序清单5.13
//介绍while循环
#include <iostream>
const int ArSize = 20;
int main(void)
{
using namespace std;
char name[ArSize};
cout << "Your first name: "; //Muffy
cin >> name;
cout << "Here is your name, verticalized and ASCIIized:\n";
int i = 0;
while (name[i] != '\0')
{
cout << name[i] << ": " << int(name[i]) << endl; //类型提升,强制类型转换
i++;
}
return 0;
}
程序运行情况:
Your first name: Muffy
Here is your name, verticalized and ASCIIized:M:77
u:117
f:102
f:102
y:121
- while也可以这样写:while (name[i])
for与while转换
延时循环
//程序清单5.14
#include <iostream>
#include <ctime>
int main(void)
{
using namespace std;
cout << "Enter the delay time, in seconds: ";
float secs;
cin >> secs;
clock_t delay = secs * CLOCKS_PER_SEC; //类型别名
cout << "starting\a\n";
clock_t start = clock(); //当前时钟节拍
while (clock() - start < delay)
; //空循环体
cout << "done\a\n";
return 0;
}
do while循环
- do while 循环:出口条件循环,先执行循环体再判定测试表达式
- 入口条件循环比出口条件循环好,因为入口条件循环在循环开始之前对条件进行检查。但有时do while测试更合理,比如输入密码场景
do
body
while (test_expression); //注意分号
//程序清单5.15
#include <iostream>
int main(void)
{
using namespace std;
int n;
cout << "Enter numbers in the range 1-10 to find my favorite number:\n";
do
{
cin >> n;
}while (n != 7);
cout << "Yes, 7 is my favorite.\n";
return 0;
}
基于范围的for循环
循环和文本输入
哨兵字符:知道何时停止读取
//程序清单5.16
//用while循环读取字符串
#include <iostream>
int main(void)
{
using namespace std;
char ch;
int count = 0;
cout << "Enter characters; enter # to quit:\n"; //see ken run#really fast
cin >> ch;
while (ch != '#')
{
cout << ch;
++count;
cin >> ch;
}
//seekenrun
cout << endl << count << " characters read\n"; //9
return 0;
}
- 为什么程序输出省略空格呢?原因在于cin读取char值时忽略空格和换行符
使用cin.get(char)进行补救
//程序清单5.17
//使用cin.get(char)
#include <iostream>
int main(void)
{
using namespace std;
char ch;
int count = 0;
cout << "Enter characters; enter # to quit:\n"; //Did you use a #2 pencil?
cin.get(ch);
while (ch != '#')
{
cout << ch;
++count;
cin.get(ch);
}
//Did you use a
cout << endl << count << " characters read\n"; //14
return 0;
}
使用哪个cin.get()
文件尾条件
- 有时候定义的哨兵字符是合法输入的组成部分,这怎么办呢?
- 使用检测文件尾(EOF)
- 退出:Windows:<CTRL>+<Z><ENTER>;Linux:<CTRL>+<D>
//程序清单5.18
//使用EOF
#include <iostream>
int main(void)
{
using namespace std;
char ch;
int count = 0;
cout << "Enter characters; enter # to quit:\n"; //Did you use a #2 pencil?
cin.get(ch);
while (cin.fail() == false) //测试EOF
{
cout << ch;
++count;
cin.get(ch);
}
//Did you use a
cout << endl << count << " characters read\n"; //14
return 0;
}
一些更简洁的代码:
cin.get(ch);
while (cin.fail() == false)
{
cout << ch;
++count;
cin.get(ch);
}
while(!cin.fail())
while(cin)
while(cin.get(ch)) //cin.get(ch)只调用一次
{
cout << ch;
++count;
}
嵌套循环和二维数组
//程序清单5.20
//嵌套循环和二维数组
#include <iostream>
const int Cities = 5;
const int Years = 4;
int main(void)
{
using namespace std;
const char * cities[Cities] = //指针数组
{
"Gribble City",
"Gribbletown",
"New Gribble",
"Gribble Vista"
};
int maxtemps[Years][Cities] = //二维数组初始化
{
{95, 100, 87, 101, 105},
{96, 98, 91, 107, 104},
{97, 101, 93, 108, 107},
{98, 103, 95, 109, 108}
};
cout << "Maximum temperature for 2008-2011\n\n";
for (int city = 0; city < Cities; ++city) //for循环嵌套
{
cout << cities[city] << ":\t";
for (int year = 0; year < Years; ++year)
cout << maxtemps[year][city] << '\t' << endl;
}
return 0;
}