【C++】学习笔记十五——for循环

来源:互联网 发布:仪器信息网 网络讲堂 编辑:程序博客网 时间:2024/05/18 17:41

for循环

程序5.1

#include<iostream>int main(){    using namespace std;    int i;    for (i = 0; i < 5; i++)        cout << "C++ knows loops.\n";    cout << "C++ knows when to stop.\n";    cin.get();    return 0;}

运行结果:
这里写图片描述


1.for循环的组成部分

  1. 设置初始值;
  2. 执行测试条件,判断循环是否应当继续;
  3. 执行循环操作;
  4. 更新用于测试的值。
for(initialization;test-expression;update-expression)    body;       //循环体

C++将整个for看作一条语句。

C++并没有将test-expression的值限制为只能为真或假,可以使用任意表达式,C++将把结果强制转换为bool类型。值为0的表达式将被转换为false,导致循环结束;值为非零的表达式将被转换为true。

程序5.2

#include<iostream>int main(){    using namespace std;    cout << "Enter the starting countdown value: ";    int limit;    cin >> limit;    int i;    for (i = limit; i; i--)        cout << "i = " << i << endl;    cout << "Done now that i = " << i << "\n";    cin.get();    cin.get();    return 0;}

这里写图片描述

for循环是入口条件(entry-condition)循环。在每轮循环之前,都将计算测试条件表达式(test-expression)的值,当测试表达式值为false时,将不会执行循环体。

update-expression(更新表达式)在每轮循环结束时执行,此时循环体已执行完毕。

C++的常用方式是,在for和()之间加上一个空格,而省略函数名与括号之间的空格。

1.1表达式和语句

任何值或任何有效的值和运算符的组合都是表达式。例如,10是值为10的表达式,28*20是值为560的表达式。

赋值表达式也有值,C++将赋值表达式的值定义为左侧成员的值,例如,x=20的值为20。maids = { cooks = 4 } + 3;的值为7。虽然C++允许这样做,但并不鼓励这样做。

程序5.3

#include<iostream>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);                         //一个新的C++特征    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();    return 0;}

这里写图片描述

通常,cout在显示bool值之前将它们转换为int,但cout.setf(ios_base::boolalpha)函数调用设置了一个标记,该标记命令cout显示true和false,而不是0和1。

表达式加上分号就变成了语句。

1.2非表达式和语句

语句去掉分号并不一定是表达式。返回语句、声明语句和for语句去掉分号并不是表达式。

例如,语句int toad;去掉分号得到的int toad并不是表达式,因为它没有值。

1.3修改规则

C++可以在for循环的初始化部分中声明变量:

for (int i = 0; i < 5; i++)

注意,这种声明得到的变量i只存在于for语句中,当程序离开循环后,这种变量将消失。


2.for循环

程序5.4

#include<iostream>const int ArSize = 16;        //外部声明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();    return 0;}


3.修改步长

程序5.5

#include<iostream>int main(){    using std::cout;    using std::cin;    using std::endl;    cout << "Enter an interger: ";    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();    return 0;}

这里写图片描述


4.使用for循环访问字符串

程序5.6

#include<iostream>#include<string>int main(){    using namespace std;    cout << "Enter a word: ";    string word;    cin >> word;    //倒序显示输入的字符串    for (int i = word.size() -1; i >= 0; i--)        cout << word[i];    cout << "\nBye.\n";    cin.get();    cin.get();    return 0;}

这里写图片描述


5.递增运算符(++)和递减运算符(–)

程序5.7

#include<iostream>int main(){    using namespace std;    int a = 20;    int b = 20;    cout << "a   = " << a << ":   b = " << b << endl;    cout << "a++ = " << a++ << ": ++b = " << ++b << endl;    cout << "a   = " << a << ":   b = " << b << endl;    cin.get();    return 0;}

这里写图片描述

a++意味着使用a的当前值计算表达式,然后将a的值加1;
++b意味着先将b的值加1,然后使用新的值计算表达式。

int x = 5;int y = ++x;    //先x=x+1,再y=x;y的值为6,x的值为6int z = 5;int y = z++;    //先y=z,再z=z+1;y的值为5,z的值为6

6.副作用和顺序点

副作用:在计算表达式时对某些东西(如存储在变量中的值)进行了修改;

顺序点:程序执行过程中的一个点。语句中的分号就是一个顺序点。

完整表达式:不是另一个更大表达式的子表达式。

while (guests++ < 10)          //先判断guests<10,再将guests加1     cout << guests <<endl;     //guests的值为11
y = (4 + x++) + (6 + x++);  

表达式4 + x++不是一个完整表达式,因此,C++不保证x的值在计算子表达式4 + x++后立刻加1。整条赋值语句是一个完整表达式,而分号标示了顺序点,因此C++只保证程序执行到西一条语句之前,x的值被递增两次。因此,应避免使用这样的表达式。


7.前缀格式和后缀格式

x++;++x;        //这两条语句作用是否相同?
for (n = lim; n > 0; --n)    ...;for (n = lim; n > 0; --n)    ...;                     //这两条语句作用是否相同?

从逻辑上说,上述两种情况使用前缀格式和后缀格式没有任何区别。
但从速度上说,这两种情况对执行速度可能有细微的差别。前缀格式:将值加1,然后返回结果;后缀格式:先复制一个副本,将其加1,然后将复制的副本返回。因此,对于类而言,前缀版本的效率比后缀版本高。


8. 递增/递减运算符和指针

可以将递增运算符用于指针和基本变量。

double arr[5] = {21.1, 32.8, 23.4, 45.2, 37.4};double *pt = arr;   //pt指向arr[0]++pt;               //pt指向arr[1]

前缀递增、前缀递减和解除引用运算符(*)的优先级相同,以从右到左的方式进行结合;
后缀递增和后缀递减的优先级相同,但比前缀运算符的优先极高,这两个运算符以从左到右的方式进行结合。

*++pt的含义为:先将++应用于pt,然后将*应用于被递增后的pt;

double x = *++pt;   //pt指向arr[2],x值为arr[2]=23.4

++*pt的含义为:先取得pt指向的值,然后将这个值加1,pt的指向不变;

(*pt)++;   //先取得23.4,然后加1,得24.4;pt仍然指向arr[2]

(*pt)++的含义为:先取得pt指向的值,然后将这个值加1,pt的指向不变;

(*pt)++;    //先取得24.4,然后加1,得25.4,pt仍然指向arr[2]

*pt++的含义为:后缀++的优先级更高,因此先执行pt++,指针递增。然而后缀运算符意味着对原来的地址解除引用,而不是递增后的地址,因此*pt++的值为*pt。但该语句执行完毕后,pt的值将为下一个地址。

x = *pt++;    //x的值仍为arr[2]=25.4,但执行完语句后,pt将指向arr[3]

9. 组合赋值运算符

+=运算符将两个操作数相加,并将结果赋给左边的操作数。

i = i + by   可写为   i += by

左边的操作数必须能够被赋值。

操作符 作用(L为左操作数,R为右操作数) += 将L+R赋给L -= 将L-R赋给L *= 将L*R赋给L /= 将L/R赋给L %= 将L%R赋给L

10.复合语句(语句块)

程序5.8

#include<iostream>int main(){    using namespace std;    cout << "The Amazing Accounto will sum and average ";    cout << "five numbers fir you.\n";    cout << "Please enter five values:\n";    double number;    double sum = 0.0;    for (int i = 1; i <= 5; i++)    {                                                                            //语句块开始        cout << "Value " << i << ": ";        cin >> number;        sum += number;    }                                                                           //语句块结束    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();    return 0;}

这里写图片描述

假如省略了花括号,编译器将忽略缩进,只有第一条语句位于循环中。

复合语句还有一种有趣的特性,如果在语句块中定义了一个新的变量,则仅当程序执行该语句块中的语句时,该变量才存在。执行完该语句块后,变量将被释放。这表明此变量仅在该语句块中才是可用的。


11.其他语法技巧——逗号运算符

语句块将两条或更多条语句放到按C++句法只能放一条语句的地方。

逗号运算符将两个表达式放到按C++句法只允许放一个表达式的地方。

例如,在一个循环中,每轮将一个变量加1,而将另一个变量减1,在for循环的更新部分中完成这两项工作非常简单:++j,--i

程序5.9

#include<iostream>#include<string>int main(){    using namespace std;    cout << "Enter a word: ";    string word;    cin >> word;    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 << "\nDone\n";    cin.get();    cin.get();    return 0;}

这里写图片描述

逗号运算符将两个或更多的表达式放到一个for循环表达式中,它确保先计算第一个表达式,再计算第二个表达式,下面的表达式是安全的:

i=20, j= 2*i;

C++规定,逗号表达式的值是第二部分的值,因此上述表达式的值为40。

在所有运算符中,逗号运算符的优先级最低。例如:
cata = 17,240;将被解释为(cata = 17),240;

下面的表达式将把cats设置为240:

cats = (17,240);

12.赋值、比较和可能犯的错误

程序5.10

#include<iostream>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";    cout << "Doing it dangerously wrong:\n";    for (i = 0; quizscores[i] = 20; i++)        cout << "quiz" << i << "is a 20\n";    cin.get();    return 0;}

13.C-风格字符串的比较

比较两个字符串是否相等,使用strcmp()函数来比较。

该函数接受两个字符串地址作为参数,这意味着参数可以是指针、字符串常量或字符数组名。

  • 如果两个字符串相同,该函数将返回0;
  • 如果第一个字符串按编码(如ASCII)顺序排在第二个字符串之前,该函数返回一个负数;
  • 如果第一个字符串按编码(如ASCII)顺序排在第二个字符串之后,该函数返回一个正数。

不能用关系运算符比较C-风格字符串,但可以用关系运算符来比较字符,因为字符实际上是整型。

程序5.11

#include<iostream>#include<cstring>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();    return 0;}

这里写图片描述


14.比较string类字符串

可以将关系运算符用于string对象

程序5.12

#include<iostream>#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();    return 0;}

输出和程序5.11相同。

0 0