逻辑类型和运算

bool

bool类型不是原生类型

为什么会出现bool类型

  • #include <stdbool.h>
  • 之后就可以使用booltruefalse ```c int main() { bool b = 6 > 5; bool t = true; t = 2; printf(“%d\n”, b);

    return 0; }

// 1

  1. <a name="BxLxN"></a>
  2. ## 逻辑运算
  3. - 逻辑运算是对逻辑量进行的运算,结果只能有`0`或`1`
  4. - 逻辑量是关系运算或逻辑运算的结果
  5. 为什么会出现`bool`类型?<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/1557552/1641213168457-d4d43300-e0a4-4b56-a02b-54534663ce58.png#clientId=u2bde0dd3-285a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=243&id=u1fcd8ef7&margin=%5Bobject%20Object%5D&name=image.png&originHeight=486&originWidth=1290&originalType=binary&ratio=1&rotation=0&showTitle=false&size=122625&status=done&style=none&taskId=ub34aa25f-902b-41bb-9860-aaa32e1f99a&title=&width=645)
  6. - 如何判断一个字符`c`是否是大写字母?
  7. - `c >= 'A' && c <= 'Z'`
  8. - 如何判断一个字符在一个区间?
  9. - `a >= 1 && a <= 4`
  10. <a name="doDOh"></a>
  11. ### 理解一下
  12. - `age > 20 && age < 30`
  13. - `index < 0 || index > 99`
  14. - `!age < 20`
  15. - `!age`先运算结果为`1`,该表达式永远成立
  16. - 改正:`!(age < 20)`
  17. <a name="QV3TV"></a>
  18. ### 优先级
  19. - `! > && > ||`
  20. - `!done && (count > MAX)`
  21. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/1557552/1641213733547-39e5b572-e4e9-4b17-a97e-9289a1c69d65.png#clientId=u2bde0dd3-285a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=174&id=u3da10360&margin=%5Bobject%20Object%5D&name=image.png&originHeight=347&originWidth=553&originalType=binary&ratio=1&rotation=0&showTitle=false&size=50339&status=done&style=none&taskId=u187ee6b4-8064-4b8f-921c-806d4701898&title=&width=276.5)
  22. <a name="NXhZy"></a>
  23. ### 短路
  24. - 逻辑运算是自左向右进行的,如果左边的结果已经能够决定结果了,就不会做右边的计算
  25. - `a == 6 && b == 1`
  26. - `a == 6 && b += 1`
  27. - 对于`&&`,左边是`false`时就不做右边了
  28. - 对于`||`,左边是`true`时就不做右边了
  29. <a name="LObYP"></a>
  30. ## 条件运算符
  31. - `count = (count > 20) ? count - 10 : count + 10;`
  32. - 条件、条件满足时的值和条件不满足时的值
  33. 相当于:
  34. ```c
  35. if (count > 20)
  36. {
  37. count = count - 10;
  38. }
  39. else
  40. {
  41. count = count + 10;
  42. }

优先级

  • 条件运算符的优先级高于赋值运算符,但是低于其他运算符

image.png

嵌套条件表达式

条件运算符时自右向左结合的

  • w < x ? x + w : x < y ? x : y

    逗号运算

  • 逗号用来连接两个表达式,并以其右边的表达式的值作为它的结果。逗号的优先级时所有运算符中最低的,所以它两边的表达式会先计算;逗号的组合关系是自左向右,所以左边的表达式会先计算,而右边的表达式的值就留下来作为逗号运算的结果。 ```c int main() { int a; printf(“%d”, a = (3 + 4, 5 + 6)); return a; }

// 11

<a name="WwPbn"></a>
### 逗号表达式的用处
在for循环中使用
```c
for (i = 0, j =10; i < j; i++, j--)
// 多个赋值操作

级联和嵌套的判断

嵌套的if-else

找三个数中的最大数

如果要求输入三个整数,输出其中最大的,应该怎么做?

image.png

int main()
{
    int a, b, c;
    int max = 0;

    printf("请输入abc的值:");
    scanf("%d %d %d", &a, &b, &c);

    if (a > b) // a比较大,则比较a与c
    {
        if (a > c)
        {
            max = a;
        }
        else
        {
            max = c;
        }
    }
    else // b比较大,则比较b与c
    {
        if (b > c)
        {
            max = b;
        }
        else
        {
            max = c;
        }
    }

    printf("The max is %d", max);
}

注意:嵌套加上大括号

int main()
{
    if (gameover == 0)
        if (player2move == 2)
            printf("Your turn\n");
    else // 与上面一个if相匹配
        printf("GAME OVER\n");
}

正确的做法是加上大括号

int main()
{
    if (gameover == 0)
    {
        if (player2move == 2)
            printf("Your turn\n");
    }
    else
        printf("GAME OVER\n");
}

tips

  • ifelse后面总是用{}
  • 即使只有一条语句的时候

    级联的if-else

    分段函数

    image.png

    int main()
    {
      if (x < 0)
      {
          f = -1;
      }
      else if (x == 0)
      {
          f = 0;
      }
      else
      {
          f = 2 * x;
      }
    
      printf("%d", f); // 单一出口
    }
    

    多路分支

    switch-case

    if-else经常适用于范围的判断,但当程序中某个值的时候,if-else就有些太过于复杂,运气不好的时候,经常要判断到最后一个选项,使程序运行变得缓慢。

int main()
{
    int type;

    if (type == 1)
    {
        printf("你好");
    }
    else if (type == 2)
    {
        printf("早上好");
    }
    else if (type == 3)
    {
        printf("晚上好");
    }
    else if (type == 4)
    {
        printf("再见");
    }
    else
    {
        printf("啊,什么啊?");
    }
}
int main()
{
    int type = 1;

    switch (type)
    {
    case 1:
        printf("你好");
        break;
    case 2:
        printf("早上好");
        break;
    case 3:
        printf("晚上好");
        break;
    case 4:
        printf("再见");
        break;
    default:
        printf("啊,什么啊?");
    }
}
  • 控制表达式只能是整数型的结果
  • 常量可以是常数,也可以是常数计算的表达式

    break

    switch语句可以看作是一种基于计算的跳转,计算控制表达式的值后,程序会跳转到相匹配的case(分支符号处)。分支符号只是说明switch内部位置的路标,在执行完分支中的最后一条语句后,如果后面没有break,就会顺序执行到下面的case里去,直到遇到一个break,或者switch结束为止

循环的例子

循环计算

计数循环

int main()
{
    int count = 100;
    while (count >= 0)
    {
        count--;
        printf("%d\n", count);
    }
    printf("发射!\n");
}
  • 这个循环需要执行多少次?
    • n+1
  • 循环停下来的时候,有没有输出最后的0?
    • 有输出
  • 循环结束的时候,count值是多少?

    • -1

      算平均数

      int main()
      {
      int number;
      int sum = 0;
      int count = 0;
      
      scanf("%d", &number);
      
      while (number != -1)
      {
         sum += number;
         count++;
         scanf("%d", &number);
      }
      
      printf("%d", sum / count);
      }
      

      猜数游戏

      随机数

      int main()
      {
      srand(time(0));
      int a = rand();
      
      printf("%d\n", a);
      return 0;
      }
      
      int main()
      {
      srand(time(NULL));
      int number = rand() % 100 + 1;
      printf("number = %d\n", &number);
      
      int count = 1;
      printf("计算机已经想好了一个数,请猜一下:");
      int choice;
      scanf("%d", &choice);
      
      while (choice != number)
      {
         count++;
      
         if (choice > number)
         {
             printf("你猜的数大了!\n");
         }
         else if (choice < number)
         {
             printf("你猜的数小了!\n");
         }
         printf("请再猜一下:");
         scanf("%d", &choice);
      }
      
      printf("你猜的数正确!");
      }
      

      整数求逆

      整数的分解

  • 一个整数是由1至多位数字组成的,如何分解出整数的各个位上的数字,然后加以计算

  • 对一个整数做%10的操作,就得到了它的个位数
  • 对一个整数做/10的操作,就去掉了它的个位数
  • 然后再对2的结果做%10,就得到了原来数的十位数了
  • 以此类推…

    int main()
    {
      int number;
      int new_number = 0;
      scanf("%d", &number);
      int length = fnGetLength(number);
    
      int digit;
      length--;
    
      while (number > 0)
      {
          digit = number % 10; // 个位
          new_number += digit * pow(10, length);
          number /= 10; // 去掉个位
          length--;
      }
      printf("new_number = %d", new_number);
      return 0;
    }
    

    C语言判断整数有多少位

    int fnGetLength(int num)
    {
      int count = 0;
      while (num != 0)
      {
          num /= 10;
          count++;
      }
      printf("数字是%d位数\n", count);
      return count;
    }
    

    判断循环常见的错误

    忘了大括号

    ```c if (age > 60) salary = xxx; printf();

// printf()不在if语句内部

<a name="IbhZv"></a>
## `if`后面的分号
```c
int main()
{
    double salary = 4000;
    int age = 55;
    if (age > 60); // 会跳过这个语句,直接执行大括号里面的语句
    {
        salary = salary * 1.2;
        printf("%f\n", salary);
    }
}

错误使用===

  • if只要求()里的值是零或非零 ```c int main() { int temp = 1; if (temp = 2) {
      printf("hello world");
      return 0;
    
    } }

// 程序还会打印出”hello world” ```

代码风格

  • ifelse之后必须加上大括号形成语句块
  • 大括号内的语句缩进一个tab的位置