5.2 while语句

while语句进一步扩展了Objective-C语言中的循环功能指令系统。这个经常使用的结构的语法如下:


while(expression)

program statement


圆括号中指定的expression将被求值。如果expression求值的结果为TRUE,则执行随后的program statement。执行完这条语句(或位于花括号中的语句组)后,将再次对expression求值。如果求值的结果为TRUE,将再次执行program statement。继续这个过程直到expression的最终求值结果是FALSE为止,此时循环将终止。然后,程序在program statement之后的语句继续执行。

作为它的用途示例,以下程序设置了一个while循环,它仅仅从1计数到5。

代码清单5-6


//This program introduces the while statement

import<Foundation/Foundation.h>

import<stdio.h>

int main(int argc, char*argv[])

{

NSAutoreleasePool*pool=[[NSAutoreleasePool alloc]init];

int count=1;

while(count<=5){

NSLog(@“i”,count);

++count;

}

[pool drain];

return 0;

}


代码清单5-6输出


1

2

3

4

5


程序最初将count的值设为1;然后开始执行while循环。因为count的值小于或等于5,所以将执行它后面的语句。花括号将NSLog语句和对count执行加1操作的语句定义为while循环。从程序的输出可以看出:这个程序执行了5次,直到count的值是5为止。

从以上程序你可能认识到,使用for语句同样可以方便地完成该任务。事实上,for语句都可转换成等价的while语句,反之亦然。例如,下面这个普通的for语句


for(init_expression;loop_conditon;loop_expression)

program statement


可用while语句的形式等价地表示,如以下所示:


init_expression;

while(loop_condition)

{

program statement

loop_expression;

}


熟悉使用while语句之后,将对何时用while语句更合理以及何时用for语句有更好的认识。一般来说,最先选用for语句来实现执行预定次数的循环。同样,如果初始表达式、循环表达式和循环条件都涉及同一变量,那么for语句很可能是合适的选择。

下一个程序提供了使用while语句的另一个例子。这个程序计算两个整数值的最大公因子(greatest common divisor)。两个整数的最大公因子(此后将其缩写为gcd)是可整除这两个整数的最大整数值。例如,10和15的gcd是5,因为5是可整除10和15的最大整数。

可使用一个过程(或算法)来获得任意两个整数的gcd,它以Euclid于公元前300年左右首次研究出的一个方法为基础。其说明如下:

问题:找出两个非负整数u和v的最大公因子。

步骤1:若v等于0,则结束,gcd等于u。

步骤2:计算temp=u%v, u=v, v=temp并回到步骤1。

不要过分关注上述算法的运行细节,简单地相信它。此处我们更关注开发一个程序来找出最大公因子,而不是分析这一算法的实现方式。

使用算法描述找出最大公因子这一问题的解决方案之后,开发一个计算机程序成了一项十分简单的工作。算法步骤的分析揭示:只要v的值不等于0,就会重复执行步骤2。这一发现导致了该算法在Objective-C中使用while语句的自然实现。

代码清单5-7找出用户键入的两个整数的gcd。

代码清单5-7


//This program finds the greatest common divisor

//of two nonnegative integer values

import<Foundation/Foundation.h>

int main(int argc, char*argv[])

{

NSAutoreleasePool*pool=[[NSAutoreleasePool alloc]init];

unsigned int u, v,temp;

NSLog(@“Please type in two nonnegative integers.”);

scanf(“u%u”,&u,&v);

while(v!=0){

temp=u%v;

u=v;

v=temp;

}

NSLog(@“Their greatest common divisor is%u”,u);

[pool drain];

return 0;

}


代码清单5-7输出


Please type in two nonnegative integers.

150 35

Their greatest common divisor is 5


代码清单5-7输出(重新运行)


Please type in two nonnegative integers.

1026 540

Their greatest common divisor is 54


输入两个整型值并分别存储到变量u和v(使用%u格式字符读入一个无符号的整型值)之后,程序进入一个while循环来计算它们的最大公因子。退出while循环之后,u的值会显示出来,即代表v和u的原始值的gcd,并且显示一条适当的消息。

第7章“类”中,返回处理分数时,将再次使用这个算法来找出最大公因子。

对于下一个说明while语句的程序,设想的任务是翻转从终端输入的整数位。例如,如果用户键入数字1234,该程序将把这个数字的位颠倒过来,并显示结果4321。

注意使用NSLog调用会导致每个数字出现在输出的单独行上。熟悉printf函数的C程序员可以使用该例程,而不是让数字连续地显示。

要编写这样的程序,首先必须提出一个算法来实现所陈述的工作。最常见的情况是,分析自己解决问题的方法可以产生一个算法。对于颠倒数字的位这项工作,解决方案可简单地陈述为“从右到左依次读取数字的位”。通过开发一个过程从数字最右边的位开始依次分离或取出该数字的每个位,计算机程序就可以依次读取数字的各个位。提取的位随后可以作为已颠倒数字的下一位显示在终端上。

通过将整数除以10之后取其余数,可提取整数最右边的数字。例如,1234%10会得出值4,就是1234最右边的数字。也是第一个要颠倒的数字(记住,可以使用模运算符得到一个整数除以另一个整数所得的余数)。通过将数字除以10这个过程,可以获得下一个数字。因此,1234%10的结果为123,而123%10的结果为3,它是颠倒数字的下一个数。

这个过程可一直继续执行,直到计算出最后一个数字为止。一般情况下,如果最后一个整数除以10的结果为0,那么这个数字就是最后一个要提取的数字。

代码清单5-8提示用户输入一个数值,然后从右向左依次显示该数值各个位的数字。

代码清单5-8


//Program to reverse the digits of a number

import<Foundation/Foundation.h>

int main(int argc, char*argv[])

{

NSAutoreleasePool*pool=[[NSAutoreleasePool alloc]init];

int number, right_digit;

NSLog(@“Enter your number.”);

scanf(“i”,&number);

while(number!=0){

right_digit=number%10;

NSLog(@“i”,right_digit);

number/=10;

}

[pool drain];

return 0;

}


代码清单5-8输出


Enter your number.

13579

9

7

5

3

1