逻辑类型和运算
bool
bool
类型不是原生类型
#include <stdbool.h>
之后就可以使用
bool
和true
和false
```c int main() { bool b = 6 > 5; bool t = true; t = 2; printf(“%d\n”, b);return 0; }
// 1
<a name="BxLxN"></a>
## 逻辑运算
- 逻辑运算是对逻辑量进行的运算,结果只能有`0`或`1`
- 逻辑量是关系运算或逻辑运算的结果
为什么会出现`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)
- 如何判断一个字符`c`是否是大写字母?
- `c >= 'A' && c <= 'Z'`
- 如何判断一个字符在一个区间?
- `a >= 1 && a <= 4`
<a name="doDOh"></a>
### 理解一下
- `age > 20 && age < 30`
- `index < 0 || index > 99`
- `!age < 20`
- `!age`先运算结果为`1`,该表达式永远成立
- 改正:`!(age < 20)`
<a name="QV3TV"></a>
### 优先级
- `! > && > ||`
- `!done && (count > MAX)`
![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)
<a name="NXhZy"></a>
### 短路
- 逻辑运算是自左向右进行的,如果左边的结果已经能够决定结果了,就不会做右边的计算
- `a == 6 && b == 1`
- `a == 6 && b += 1`
- 对于`&&`,左边是`false`时就不做右边了
- 对于`||`,左边是`true`时就不做右边了
<a name="LObYP"></a>
## 条件运算符
- `count = (count > 20) ? count - 10 : count + 10;`
- 条件、条件满足时的值和条件不满足时的值
相当于:
```c
if (count > 20)
{
count = count - 10;
}
else
{
count = count + 10;
}
优先级
- 条件运算符的优先级高于赋值运算符,但是低于其他运算符
嵌套条件表达式
条件运算符时自右向左结合的
-
逗号运算
逗号用来连接两个表达式,并以其右边的表达式的值作为它的结果。逗号的优先级时所有运算符中最低的,所以它两边的表达式会先计算;逗号的组合关系是自左向右,所以左边的表达式会先计算,而右边的表达式的值就留下来作为逗号运算的结果。 ```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
找三个数中的最大数
如果要求输入三个整数,输出其中最大的,应该怎么做?
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
- 在
if
或else
后面总是用{}
-
级联的
if-else
分段函数
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
值是多少?-
算平均数
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;
代码风格
- 在
if
和else
之后必须加上大括号形成语句块 - 大括号内的语句缩进一个
tab
的位置