day02:判断、循环
一、基础语法
1.1 位运算符(!!重点)
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
& | 按位与 | 011 & 101 | 2个都为1才为1,结果为001 |
| | 按位或 | 011 & 101 | 有1个为1就为1,结果为111 |
^ | 按位异或 | 011 ^ 101 | 不同的为1,结果为110 |
~ | 取反 | 011 | 100 |
<< | 左移 | 1010 << 1 | 10100 |
>> | 右移 | 1010 >> 1 | 0101 |
& 按位与运算
011 3
101 5
----
001
结论:按位与计算 相同为为1 结果为1
| 按位或运算
011 3
101 5
-----
111
结论 :按位或运算 只要有一个为1 结果就为1
^ 按位异或运算
011 3
101 5
-----
110
结论: 按位异或运算 不同的为1 相同为0
~ 取反运算
~ 011
100
结论: 取反运算 1为0 0为1
左移
1010 <<1 1010
结论:左移 就是所有位 向左移动 后面补0
右移
1010 >>1 101
结论:右移 就是所有位 向右移动
置位案例:
置1 按位或运算
推导过程:
验证结果:
// 将变量a的第2位设置为1,其他位保持不变
// 0b10110011 0xb3
// 0b00000100 0x4 | 按位或运算
// 0b10110111
// uint8_t a = 0b1011 0011; // 0xb3;
uint8_t a = 0xb3; // 0xb3;
printf("置位结果:%0x\n", a | 0x4);
printf("结果为:%0x\n", a | (1 << 2));
// printf("置位结果:%0x\n", a | 0b00000100);
// 将变量b的第2位、第6位设置为1,其他位保持不变
// 0b10110011 0xb3
// 0b01000100 0x44
// 0b11110111 0xF7
uint8_t b = 0xb3; // 0xb3;
printf("结果为:%#X\n", b | 0x44);
printf("结果为:%#X\n", b | (1 << 2 | 1 << 6));
置0 按位与运算
推导过程:
验证结果:
// 将变量c的第5位设置为0,其他位保持不变
// 将变量c的第5位设置为0,其他位保持不变
// 按位与 &
// 0b10110011 0xb3
// 0b11011111 0xdf
// 0b10010011
uint8_t c = 0b10110011; // 0xb3;
// printf("结果为:%#X\n", c & 0b11011111);
printf("结果为:%#X\n", c & 0xdf);
printf("结果为:%#X\n", c & ~(1 << 5));
// 将变量d的第0~3位设置为0,其他位保持不变
// 11111111 0xff
// 11110000 0xf0
// 11110000
uint8_t d = 0xff; // 0xff;
printf("结果为%#x\n", d & 0xf0);
// printf("=====%d\n", (1 << 0 | 1 << 1 | 1 << 2 | 1 << 3));
printf("---结果是%#x\n", d & ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3));
将某位取反
推导过程:
验证结果:
// 将变量e的第2位取反,其他位保持不变
// 10110011
// 00000100 ^ 0x4
// 10110111
uint8_t e = 0xb3; // 0xb3;
printf("***结果是%#x\n", e ^ 0x4);
printf("***结果是%#x\n", e ^ (1 << 2));
取出某些位
推导过程:
结果验证:
// 将变量f取出8-15位
uint32_t f = 0x12345678; //16进制 0x56
//① f 十六进制 对应的事32位二进制
//②怎么获取56 这8位数 & 运算
//③ 和谁与运算 1111 1111 )0xff00 ---> 0x0000ff00 --->0x5600
//④右移 8位 0x56;
// 0000 0000 0000 0000 0000 0000 0000 0000 0x12345678
// 0x00000ff00
printf("%#x\n", (f & 0x00000ff00) >> 8);
1.2 类型转换
-
类型转换的原则:
-
- 占用内存字节数少(值域小)的类型,向占用内存字节数多(值域大)的类型转换,以保证精度不降低。
二、判断
2.1 if 语句
2.2 if…else 语句(重点)
2.3 三目运算符
2.4 if…else if…else语句(重点)
2.5 switch语句
-
switch可以支持数据类型:
-
-
int
- 枚举类型
- char类型
-
2.6 分支综合案例
#include <stdio.h>
// 1.定义变量保存年份、月份、天数
// 2.输入年份和月份
// 3.根据月份输出天数
// 1、3、5、7、8、10、12月 31天
// 4、6、9、11月 30天
// 2月 非闰年 28天 闰年 29天
// 闰年判断:能被4整除,但不能被100整除的;或者能被400整除的年份
int main() {
int year, month, day;
printf("请输入年月");
scanf("%d %d", &year, &month);
switch (month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
day = 31;
break;
case 4:
case 6:
case 9:
case 11:
day = 30;
break;
case 2:
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
day = 29;
}
else {
day = 28;
}
default:
break;
}
printf("年=%d 月= %d 天数=%d\n", year, month, day);
return 0;
}
三、循环
3.1 while语句(重点)
3.2 do…while语句
3.3 for语句(重点)
3.4 死循环
3.5 循环案例
3.5.1 实现1+2+3……100所有数字的累加
3.5.2 循环嵌套
四、跳转关键字
- 循环和switch专属的跳转:break
- 循环专属的跳转:continue
- 无条件跳转:goto
4.1 break(重点)
- 循环中break,某一条件满足时,不再执行循环体中后续重复的代码,并退出循环
4.2 continue
-
某一条件满足时,不再执行本次循环体中后续重复的代码,但进入下一次循环判断
-
- while循环,continue 之前一定要修改计数器(条件变量),否则,导致死循环
4.3 goto
-
goto用于无条件跳转,尽量少用
-
- 在一种情况下可以使用goto语句:从一组嵌套的循环中跳出