C Primer Plus学习_16 while循环和关系运算符

继续昨天的。。。

-------------------------------------------分割线---------------------------------------------------

【C风格读取循环】

上一篇中的例子还可以再次改写,本来的代码是这样:

	while(status == 1)
	{
		sum = sum + num;
		printf("Please enter next integer (q to quit):");
		status = scanf("%ld",&num);
	}

经过改写,还可以更加简洁,就像这样:

	while(scanf("%ld",&num) == 1)
	{
		sum = sum + num;
		printf("Please enter next integer (q to quit):");
	}

改写后的形式同时使用了scanf()的两种不同的特性。首先,如果函数调用成功,scanf()会吧一个值存入num。然后,利用scanf()的返回值控制循环。这样的用法可以让程序看上去更简洁,而且技术含量(相比之前)会比较高。


while循环

在之前的文章里,总是零零散散的讲了while循环的使用,这次是要彻底的将while循环说完。

while循环的通用形式如下:

while(expression表达式)

        statement语句

statement部分可以是以分号结尾的简单语句,也可以是以花括号结尾的复合语句。

expression部分都使用关系表达式,也就是说expression是值之间比较,可以使用任何表达式。如果expression为真(非零),就会执行statement一次,然后再回头判断expression,直到expression为假(零)。每一次循环都称为一次迭代。

终止while循环

在前面的例子中,我们经常使用到while循环,在使用时都有一个共同点,就是都必须让expression表达式的值有所变化。不妨去试一试,如果expression表达式的值始终不变,很明显while循环会一直运行下去,直到你强制关闭窗口。

while入口条件循环

while循环是使用入口条件的有条件循环。所谓的有条件指的是测试表达式部分,因为必须满足条件才能进入循环体。如果不满足条件,就不会进入循环体,就像上面说的while循环执行到expression为假(零)一样。

(书上还有好长一段,我觉得挺简单的,前面也有讲过,就不水字数了)

用关系运算符和表达式比较大小

while循环依赖测试表达式作比较,这样的表达式被称作关系表达式,其中的运算符被称为关系运算符

关系运算符包含运算符:<, >, <=, >=, !=(不等于), ==(等于)这六种

关系运算符除了可以比较整数,还可以比较字符和浮点数。比较字符是使用的是机器字符码(假定ASCII)。比较浮点数时要尽量只使用< 和 >,因为浮点数的舍入误差会导致逻辑上两个相等的数却不相等。例如3乘1/3的积是1.0,如果把1/3表示成0.333333,那么原式结果就会是0.999999,而不是1 。在这里,使用fabs函数(声明在math.h头文件中)可以方便的比较浮点数,该函数返回浮点数的绝对值。下面给出一个该函数的应用。

/*cmpflt.c -- 浮点数比较*/
#include <stdio.h>
#include <math.h>
int main (void)
{
	const double ANSWER = 3.14159;
	double response;
	
	printf("what is the value of pi?\n");
	scanf("%lf",&response);
	while(fabs(response - ANSWER) > 0.001)
	{
		printf("Try again!\n");
		scanf("%lf",&response);
	}
	printf("Close enough!\n");
	
	return 0;
 } 

来试试结果:

what is the value of pi?
3.1
Try again!
3.14
Try again!
3.141
Close enough!

这个函数还挺好玩的。。。

真值问题

在C中,表达式有一个定值,关系表达式也不例外。下面来打印出关系表达式的值

/* t_and_f.c -- C中的真值和假值*/
#include <stdio.h>
int main (void)
{
	int true_val, false_val;
	
	true_val = (10 > 2);
	false_val = (10 == 2);
	printf("true_val = %d, false_val = %d\n", true_val, false_val);
	
	return 0;
 } 

输出结果为:

true_val = 1, false_val = 0

我们可以看到在程序中,两个表达式一个对一个错,将其赋给变量后打印变量,得到的值是1和0,分别对应真和假。

一般来说,我们将1作为真,将0作为假,但实际上在C中所有非0的值都被值为真。

/* truth.c -- 真值?*/
#include <stdio.h>
int main (void)
{
	int n = 3;
	
	while(n){
		printf("%2d is true\n", n--);
	}
	printf("%2d is false\n", n);
	
	n = -3;
	while(n){
		printf("%2d is true\n", n++);
	}
	printf("%2d is false\n", n);
	
	return 0;
 } 

运行结果为:

 3 is true
 2 is true
 1 is true
 0 is false
-3 is true
-2 is true
-1 is true
 0 is false

事实证明了一切。也同时说明了只要测试条件的值不是0,while循环就会执行下去。

但真值太过宽泛也未必就是好事,下面改动一下上一篇博文中的summing.c,看看一点点改动会造成什么

/*trouble.c -- 改动的summing.c*/
#include <stdio.h>
int main (void)
{
	long num;
	long sum = 0L;//sum初始化为0 
	int status;
	
	printf("Please enter an integer to be summed ");
	printf("(q to quit):");
	status = scanf("%ld",&num);
	while(status = 1)
	{
		sum = sum + num;
		printf("Please enter next integer (q to quit):");
		status = scanf("%ld",&num);
	}
	printf("Those integers sum to %ld.\n", sum);
	
	return 0;
 } 

细心的一定会很快发现,只是删去了一个=,这个结果我不想运行了,有兴趣可以自己试一试。。。

当输入q时,status确实被设置为0,但本来应该结束的循环在这里开始无限输出"Please enter next integer (q to quit):",原因在于循环的测试条件又把status设置为1了。

但是这里又有一个问题,就算该程序执行继续执行循环,也应该有一个输入的过程,而不是无限循环。

如果scanf()读取指定形式的输入失败了,就会把无法读取的输入留在输入列表中,供下一次读取。当scanf()把q作为整数读取失败时,把q留下了,接下来会无限读取q。 所以这是一个非常糟糕的循环。

再回到真值问题上来。总之关系运算符用来构成关系表达式,关系表达式为真,值就是1,为假,值就是0 。通常用关系表达式作为测试条件的语句(如if 和while),可以用任何表达式作为测试条件,非0为真0为假。


优先级和关系运算符

关系运算符的优先级比算术运算符的优先级低,比赋值运算法的优先级高。

然而关系运算符中又有两种不同的优先级

高优先级组:<, >, <=, >=;

低优先级组: !=(不等于), ==(等于)。

(这里运算符还没有介绍完,等到全部介绍完,会给出一张表格。。。)

OVER!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值