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

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的值为6

int 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相同。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值