C++

C Plus Plus

6. 循环语句 A

  • for语句
  • 表达式与语句
  • 自增运算符和逗号运算符
  • while语句

精英王子-2012.11.14

CC BY-NC-SA(署名-非商业性使用-以相同方式共享) 3.0

有时我们需要不断执行某个操作一定的次数,或者执行某个操作直到某种情况出现。

这时就用到了循环语句。

for语句

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

{

cout<<"这句话会输出十次"<<endl;

}

初始化表达式

条件表达式

更新表达式

这是一个简单的for语句,在C++中for语句用来进行循环。

循环即按照某些条件,执行相同的代码,但代码中变量的值可能不同,所以可能每次循环都会呈现出不同的结果。

循环必须有终止条件,否则就成了死循环(当然,死循环在某些情况下是故意设计的),所以在每一次循环的时候都要更新一些变量的值,并判断是否达到了终止的条件。

初始化表达式(语句)会在循环开始前执行一次,通常用来定义与循环有关的变量,并赋初值。

条件表达式即用于判断是否循环,当条件表达式为真时,循环会继续进行,每次循环开始前都会重新对条件表达式进行判断。

更新表达式用于更新循环中的变量,使之可以在一定次数的循环后达到终止条件,更新表达式会在每次循环之后执行。

在这里,我在初始化表达式里面定义了一个变量i,并将它的值设置为0.

条件表达式是i<10,即只有i小于10时才继续循环。

更新表达式是i++. 它的作用是每次循环后把i加一,这个我们稍后介绍。

如此一来,循环中的语句便可以执行十次,十次后将等于10, 不满足条件i<10, 循环将结束。

流程图

int i=0;

i<10?

结束

输出“这句话会输出十次”

false

true

i=i+1;

如果用流程图表示前面那个程序,将会是这样。

自增运算符

int i=1;

i++; // i=2 (i=i+1)

++i; // i=3 (i=i+1)

i--; // i=2 (i=i-1)

int a=i++; // a=i,i=i+1

int a=++i; // i=i+1,a=i

i++ 后缀自增

++i 前缀自增

i-- 后缀自减

--i 前缀自减

自增、自减运算符。如i++,i--,是i=i+1,i=i-1的简写形式。

前缀和后缀的区别就是,前缀形式先将变量的值作为整个表达式的值,再对变量进行自增、自减运算。

后缀形式先对变量进行自增、自减运算,再将这个变量的值作为整个表达式的值。

自增、自减运算符只能用于变量,不能用于字面值。比如1++,因为1=1+1这样的表达式是错误的。

表达式

//下面都是表达式

1

1+1

a*b

sqrt(4)*5

"精英王子"

i++

12 字面值

a 变量

sqrt(2) 函数返回值

3+4-5 表达式

表达式:

值(表达式、字面值、变量、函数返回值等)和运算符组成。

之前我们不止一次提到表达式和语句的概念,现在我们来讨论一下什么是表达式,什么是语句。

一般来讲,表达式由值和运算符组成,值是一个很宽的概念,可以是表达式、字面值、变量、函数返回值等。

运算符就是上节课我们提到的那些运算符,以及这节课新学到的自增/自减运算符,当然,还有很多运算符我们没有学习。

单个的值(单个的字面值、变量)也是表达式。

说了这么多,表达式的特点就是,所有表达式都具有一个值。

语句

//下面都是语句

int i=10;

c=a+b;

1;

if(1)

2;

语句:

语句是特殊的语言结构,如if、return、变量定义等。

所有表达式加上一个分号,

就是语句;但反之不成立。

语句是特殊的语法结构,比如之前学到过的for、if、return、switch、变量定义语句等等。

所有表达式加上一个分号,就可以成为一个语句,功能是对这个表达式进行求值。求值是计算表达式的值的过程,如果表达式中含有具有副作用的运算符(如自增运算符),就会在求值时体现出副作用。

对于1这样一个字面值,加上一个分号可以成为一个语句,功能是对1进行求值,结果还是1,而且结果没有被储存到任何地方。这个语句对整个程序完全没有任何影响(通常会被编译器优化功能删除掉),我们称这个表达式没有副作用。

反之,a=b+c这个表达式在求值过程中(没错,记住赋值号也是一个普通的运算符),会把b+c的结果赋值给a,求值前后a的值发生了变化,我们称这个表达式有副作用

但反之不成立,语句去掉分号不一定能成为表达式。

if、for等结构被视为一条语句,虽然其中可能包含多条语句。

回到之前的for语句,你是否发现,被标注为“初始化表达式”的地方被写了一个语句——int i=0; 一个变量定义语句。

这是一个例外,C++规定for的初始化表达式可以是变量定义语句,定义的变量仅在这个for结构之内有效。

习题

//判断下面每行,是不是表达式、是不是语句

i++;

int a,b;

cout<<a

5 && 3

a = 1+1==2

if(1+1==2) "1+1=2";

5<3

因为现在学习的内容越来越复杂,我会随时穿插习题。

for - 更多例子

int sum=0;

for(int i=1 ; i<=10 ; i++)

{

sum+=i;

}

cout<<sum<<endl;

再来看一个例子,它的功能是计算1+2+3+4+5+6+7+8+9+10的和。

首先我们定义了一个变量sum,用来储存它们的和。之前我们都在使用单个字母做变量的名字,这是因为那些变量实在没什么意义,起不出什么好名字。

大家应该尽可能使用有意义的英文单词作为变量名以增加代码的可读性,sum是和的意思。

初始化表达式中我将i(index)的初值设置为了1,因为我们要从1开始相加;条件表达式是i<=10,因为我们要计算10和10以下的整数的和,更新表达式依旧是i++.

sum+=i;的意思是sum=sum+i;即把sum和i相加,赋值给sum. 这句话会循环执行十次,每次i的值都是不同的,分别是1、2、3、4......10.

这样每次循环都将i加到sum上,循环结束时,sum中的数就是我们要的结果了。

最后输出sum.

组合赋值运算符

int i=1;

i+=5; // i=6 (i=i+5)

i*=3; // i=18(i=i*3)

+=

-=

*=

/=

%=

这个就很好理解了,不再详细讲解。

组合赋值运算符除了列出的五个还有一些。它们的优先级和赋值运算符相同,结合性也相同(向右结合)

逗号运算符

int d=(a=1,b=2,c=3); // d=3

int a,b; //不是逗号运算符

表达式1,表达式2

按顺序对表达式逐个求值,并将最后一个表达式作为整个表达式的值

逗号运算符连接两个表达式,(从左到右)逐个计算表达式的值,并将最后一个表达式的值作为整个表达式的值。

利用逗号运算符我们可以在一个语句(表达式)中完成多个表达式的求值。

比如for的条件表达式,只能提供一个表达式,但我们可以通过逗号运算符,将两个表达式连接成为一个表达式,作为for的条件表达式。

看下面的例子,将逐个计算a=1、b=2,c=3,并将c=3(即3)作为整个表达式的值,所以d=3.

值得注意的是逗号表达式的优先级非常低,几乎是优先级最低的运算符,在很多情况下,我们都需要加括号。

并非C++代码中所有的逗号都是逗号运算符,比如变量定义语句中的逗号,是变量定义语句中固有的结构,不是逗号运算符。

之前我也强调过,在C++中同一个符号,在不同的上下文,具有不同的含义。

while 语句

int sum=0,i=1;

while(i<=10)

{

sum+=i;

i++;

}

cout<<sum<<endl;

while是C++中另一种循环语句,以while关键字开始,后面括号里直接就是条件表达式,满足这个条件,就会继续循环。

如果用while语句改写上面的程序,将会是这样。

将初始化语句移至循环开始之前,将更新表达式放入循环体。

while 和 for

for(初始化表达式;条件表达式;更新表达式)

{

循环体

}

//等价于:

初始化表达式

while(条件表达式)

{

循环体

更新表达式

}

通过之前的例子,我们可以得出这样一种大致的等价关系。

它们都可以用来进行循环,功能上没有区别,只是表达形式上有区别。

通常for用来进行已知循环次数的循环,而while用来进行需要达到某种条件的循环。

思考题

计算圆周率,下面提供了两个比较简单的公式,任选:

Leibniz定理

Wallis乘积

提示:π是无理数,不可能算尽,且C++中的小数类型有精度限制,你需要在某种条件下终止计算。

建议计算小数点后6位。

有兴趣可自行了解刘徽的割圆术算法,数学必修三、维基百科有详细介绍。

最后

下一节:循环语句B

循环还没讲完,下节课接着讲。

C++-6.循环语句A - Google Slides