C Primer Plus(6) 中文版 第6章 C控制语句:循环 6.3 用关系运算符和表达式比较大小

发布于:2023-01-15 ⋅ 阅读:(394) ⋅ 点赞:(0)

6.3 用关系运算符和表达式比较大小
while循环经常依赖测试表达式作比较,这样的表达式被称为关系表达式(relational expression),出现在关系表达式中间的运算符叫作关系运算符(relational operator)。表6.1列出了C语言的所有关系运算符。
            表6.1 关系运算符
运算符        含义
<              小于
<=            小于或等于
==            等于 
>=            大于或等于
>              大于
!=             不等于
关系运算符常用于构造while语句和其他C语句中用到的关系表达式。这些语句都会检查表达式为真还是为假。
不能用关系运算符比较字符串。
虽然关系运算符也可用来比较浮点数,但是要注意:比较浮点数时,尽量只使用<和>。因为浮点数的舍入误差会导致在逻辑上应该相等的两数却不相等。使用fabs()函数(声明在math.h头文件中)可以方便比较浮点数,该函数返回一个浮点数的绝对值(即,没有代数符号的值)。
判断一个数是否接近预期效果。
// cmpflt.c -- floating-point comparisons
#include <math.h>
#include <stdio.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.0001)
    {
        printf("Try again!\n");
        scanf("%lf", &response);
    }
    printf("Close enough!\n");
    
    return 0;
}

/* 输出:

*/ 

6.3.1 什么是真
在C中,表达式一定有一个值,关系表达式也不例外。
打印两个关系表达式的值,一个为真,一个为假。
/* t_and_f.c -- true and false values in C */
#include <stdio.h>
int main(void)
{
    int true_val, false_val;
    
    true_val = (10 > 2);    // value of a true relationship
    false_val = (10 == 2);  // value of a false relationship 
    printf("true = %d; false = %d \n", true_val, false_val);
    
    return 0;

/* 输出:

*/ 

对C而言,表达式为真的值是1,表达式为假的值是0。
6.3.2 其他真值
// truth.c -- what values are true?
#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;
}

/* 输出:

*/

一般而言,所有的非零值都视为真,只有0视为假。在C中,真的概念是真宽!
也就是说,只要测试条件的值为非零,就会执行while循环。这是从数值方面而不是从真/假方面来看待测试条件。要牢记:关系表达式为真,求值得1;关系表达式为假,求值得0。因此,这些表达式实际上相当于数值。
许多C程序员都会很好地利用测试条件的这一特性。
用while( goats )代替while( goats != 0 )。
6.3.3 真值的问题
C对真的概念约束太少会带来一些麻烦。
// trouble.c -- misuse of =
// will cause infinite loop
#include <stdio.h>
int main(void)
{
    long num;
    long sum = 0L;
    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;

屏幕上会一直显示最后的提示内容,除非强行关闭程序。这里,while( status = 1 )实际上相当于while( 1 ),也就是说,循环不会退出。
程序的循环一直运行着,用户输入q后就完全没机会输入。这是因为scanf()读取指定形式的输入失败,就会把无法读取的输入留在输入队列中,供下次读取。
不要在本应使用==的地方使用=。
如果带比较的一个值是常量,可以把该常量放在左侧有助于编译器捕获错误。例如:
5 == canoes; //检查canoes的值是否为5
可以这样做是因为C语言不允许给常量赋值,编译器会把赋值运算符的这种用法作为语法错误标记出来。
总之,关系运算符用于构成关系表达式。通常用关系表达式作为测试条件的语句(如while和if)可以使用任何表达式作为测试条件,非零为真,零为假。
4.3.4 新的_Bool类型
在C语言中,一直用int类型的变量表示真/假值。C99专门针对这种类型的变量新增了_Bool类型。该类型是以英国数学家George Boole的名字命名的,他开发了用代数表示逻辑和解决逻辑问题。在编程中,表示真或假的变量被称为布尔变量(Boolean variable),所以_Bool是C语言中布尔变量的类型名。_Bool类型的变量只能存储1(真)或0(假)。如果把其他非零值赋给_Bool类型的变量,该变量会被设置为1。这反映了C把所有的非零值都视为真。
把int类型的变量status替换为_Bool类型的变量input_is_good。给布尔类型取一个能表示真或假值的变量名是一种常见的做法。
// boolean.c -- using a _Bool variable
#include <stdio.h>
int main(void)
{
    long num;
    long sum = 0L;
    _Bool input_is_good;
    
    printf("Please enter an integer to be summed ");
    printf("(q to quit): ");
    input_is_good = (scanf("%ld", &num) == 1);
    while (input_is_good)
    {
        sum = sum + num;
        printf("Please enter next integer (q to quit): ");
        input_is_good = (scanf("%ld", &num) == 1);
    }
    printf("Those integers sum to %ld.\n", sum);
    
    return 0;

/* 输出:

*/

使用括号和使用有意义的变量名可以提高代码可读性。
C99提供了stdbool.h头文件,该头文件让bool成为_Bool的别名,而且还把true和false分别定义为1或0的符号常量。包含该头文件后,写出的代码可以与C++兼容,因为C++把bool、true和false定义为关键字。
如果系统不支持_Bool类型,把_Bool替换成int即可。
6.3.5 优先级和关系运算符
关系运算符的优先级比算术运算符低,比赋值运算符高。
关系运算符之间有两种不同的优先级。
高优先级:< <= > >=
低优先级:== !=
关系运算符的结合律也是从左往右。
ex != wye == zee与(ex != wye) == zee相同 //不推荐这些写 
            表6.2 运算符优先级
运算符(优先级从高到低)    结合律
()                                 从左往右
- + ++ -- sizeof            从右往左
* / %                            从左往右
+ -                               从左往右
< <= > >=                    从左往右
== !=                           从左往右
=                                 从右往左
小结:while语句
while语句是一种入口条件循环,也就是说,在执行多次循环之前已决定是否执行循环。因此,循环有可能不执行。 
 
 

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到