达内嵌入式课程笔记
day4:运算符
STDC01_day04_01-进制转换06.ts
把二进制数字从右向左每三个数位分成一组,每组用一个0到7之间的数字替换,这个替换结果叫做八进制表示方式
0110 1011 01 101 011 153(八进制)
可以在程序中直接使用八进制方式表示数字,这个时候数字必须以0做开头
在printf
函数调用语句里使用%o
做占位符可以把数字的八进制表示方式显示在屏幕上
/CSD1702/biaoc/day04 01bit.c
/*
八进制和十六进制演示
*/
#include <stdio.h>
int main(){
printf("%d 0%o\n",0153,0153);
return 0;
}
结果:107 0153
把二进制数字从右向左每四个数位分成一组,每组用一个字符替换(用a到f之间的字母替换10到15之间的数字),这个替换结果叫做数字的十六进制表示方式
1100 1011 cb(十六进制)
可以在程序中直接使用十六进制方式表示数字,这个时候数字必须以0x
做开头
可以使用%x
或%X
做占位符把数字的十六进制方式显示在屏幕上
显示结果里不包含0x
开头
补充:要想在显示十六进制的时候输出0x
或者0X
开头,可使用%#x
或者%#X
作为占位符,也可以在%x或者%X前自己加0x
或者0X
用%x
做占位符的时候显示结果里所有字符都是小写的
用%X
做占位符的时候显示结果里所有字符都是大写的
/CSD1702/biaoc/day04 01bit.c
/*
八进制和十六进制演示
*/
#include <stdio.h>
int main(){
printf("%d 0%o\n",0153,0153);
printf("%d 0x%x 0X%X",0xcb,0xcb,0xcb);
return 0;
}
结果:
107 0153
203 0xcb 0XCB
STDC01_day04_02-运算符01.ts
操作符用来表示对数字的处理规则
根据操作符所需要配合的数字个数把操作符分成
单目操作符,双目操作符和三目操作符
加减乘除(+,-,*,/)
都是双目操作符
如果参与除法计算的两个数字都是整数则计算结果保留整数部分
C语言里用%
表示取余操作
赋值操作符用=
表示
赋值语句可以当作数字使用,这个数字就是赋值结束后存储区里的内容
可以在一条语句里使用多个赋值操作符,这个时候优先计算右边的操作符
/CSD1702/biaoc/day04 02opr.c
/*
操作符演示
*/
#include <stdio.h>
int main(){
int num = 0;
char ch = 0;
num = ch = 300;
printf("num是%d\n",num);
return 0;
}
结果:
num是44
STDC01_day04_03-运算符02.ts
绝大多数双目操作符可以和赋值操作符合并成复合赋值操作符,例如+=,*=
等
复合赋值操作符会把双目操作符的计算结果记录到左边的存储区里
/CSD1702/biaoc/day04 02opr.c
/*
操作符演示
*/
#include <stdio.h>
int main(){
int num = 0;
char ch = 0;
num = ch = 300;
printf("num是%d\n",num);
num += 6;
printf("num是%d\n",num);
num *= 2 + 3; //num = num * (2 + 3);
printf("num是%d\n",num);
return 0;
}
结果:
num是44
num是50
num是250
复合赋值操作符的优先级和赋值操作符的优先级一样低
自增操作符(++
)和自减操作符(--
)都是单目操作符
它们都只能和存储区配合使用,它们可以把存储区的内容加一或者减一
它们各自有两种使用方法,一种是前操作(操作符写在存储区前面),另外一种是后操作(操作符写在存储区后面)
/CSD1702/biaoc/day04 02opr.c
/*
操作符演示
*/
#include <stdio.h>
int main(){
int num = 0;
char ch = 0;
num = ch = 300;
printf("num是%d\n",num);
num += 6;
printf("num是%d\n",num);
num *= 2 + 3;
printf("num是%d\n",num);
num = 10;
num++;
printf("num是%d\n",num);
++num;
printf("num是%d\n",num);
return 0;
}
结果:
num是44
num是50
num是250
num是11
num是12
使用自增(自减)操作符编写的表达式也可以当作数字使用,前操作当作数字使用的时候是修改后的数字,后操作当数字使用的时候是修改前的数字
/CSD1702/biaoc/day04 02opr.c
/*
操作符演示
*/
#include <stdio.h>
int num2;
int main(){
int num = 0,num1 = 0;
char ch = 0;
num = ch = 300;
printf("num是%d\n",num);
num += 6;
printf("num是%d\n",num);
num *= 2 + 3;
printf("num是%d\n",num);
num = 10;
num++;
printf("num是%d\n",num);
++num;
printf("num是%d\n",num);
num = 10;
num1 = ++num;
printf("num是%d,num1是%d\n",num,num1);
num1 = num++;
printf("num是%d,num1是%d\n",num,num1);
num = 10;
num1 = num++ + ++num;
printf("num是%d,num1是%d\n",num,num1);
num2 = 10;
num1 = num2++ + ++num2;
printf("num2是%d,num1是%d\n",num2,num1);
return 0;
}
结果:
num是44
num是50
num是250
num是11
num是12
num是11,num1是11
num是12,num1是11
num是12,num1是22 //结果不确定
num2是11,num1是21 //结果不确定
不要在一条语句里对同一个变量多次进行自增或自减计算,因为结果不确定
STDC01_day04_04-运算符03.ts
逻辑操作符用来编写逻辑表达式
逻辑表达式的计算结果只能是布尔值
!
是一个单目逻辑操作符,它可以根据一个布尔值计算出相反的布尔值
它代表的操作叫做求反
/CSD1702/biaoc/day04 03logic.c
/*
逻辑操作符演示
*/
#include <stdio.h>
int main(){
printf("!8是%d\n",!8);
return 0;
}
结果:
!8是0
双目逻辑操作符==
(等于),!=
(不等于),>
(大于),<
(小于),>=
(大于等于)和<=
(小于等于)
3 < 7 <5
/CSD1702/biaoc/day04 03logic.c
/*
逻辑操作符演示
*/
#include <stdio.h>
int main(){
printf("!8是%d\n",!8);
printf("3 < 7 < 5是%d\n",3 < 7 < 5);
return 0;
}
结果:
!8是0
3 < 7 < 5是1
3 < 7 先算出逻辑值1,然后1 < 5也是真
最多只包含一个双目逻辑操作符的表达式叫简单逻辑表达式,简单逻辑表达式在数学里和计算机里的结果一定一样
C语言里包含多个双目逻辑操作符的表达式必须首先拆分成多个简单逻辑表达式然后再合并
可以采用与(&&
)和或(||
)这两个双目逻辑操作符把两个逻辑表达式合并
只要两个逻辑表达式里有一个的结果是假则用与(&&
)合并后结果就是假
只要两个逻辑表达式里有一个的结果是真则用或(||
)合并后结果就是真
3 < 7 < 5改写成计算机能用的表达式 3 < 7 && 7 < 5
/CSD1702/biaoc/day04 03logic.c
/*
逻辑操作符演示
*/
#include <stdio.h>
int main(){
printf("!8是%d\n",!8);
printf("3 < 7 < 5是%d\n",3 < 7 < 5);
printf("3 < 7 && 7 < 5是%d\n",3 < 7 && 7 < 5);
return 0;
}
结果:
!8是0
3 < 7 < 5是1
3 < 7 && 7 < 5是0
与(&&
)和或(||
)都具有短路特征(如果前一个逻辑表达式的结果能决定整个逻辑表达式的结果则后一个逻辑表达式不计算)
STDC01_day04_05-运算符04.ts
/CSD1702/biaoc/day04 03logic.c
/*
逻辑操作符演示
*/
#include <stdio.h>
int main(){
int num = 0;
printf("!8是%d\n",!8);
printf("3 < 7 < 5是%d\n",3 < 7 < 5);
printf("3 < 7 && 7 < 5是%d\n",3 < 7 && 7 < 5);
1 || ++num; //短路特征
printf("num是%d\n",num);
0 && ++num; //短路特征
printf("num是%d\n",num);
return 0;
}
结果:
!8是0
3 < 7 < 5是1
3 < 7 && 7 < 5是0
num是0
num是0
假设有三个变量gender,height和weight分别记录一个人的性别,身高和体重
0代表女人,1代表男人
男人身高减体重小于105算超重
女人身高减体重小于110算超重
要求编写逻辑表达式判断变量所代表的人是否超重
(gender && (height - weight < 105)) || (!gender &&(height - weight < 110))
见STDC01_day04_10-运算符09.ts
gender ? height - weight < 105 : height - weight < 110
STDC01_day04_06-运算符05.ts
位操作符可以直接操作二进制数位
~
是一个单目位操作符
这个符号可以根据一个数字计算出另外一个数字,这两个数字所有二进制数位的内容都不一样
它所代表的操作叫按位求反
/CSD1702/biaoc/day04 04bit.c
/*
位操作符演示
*/
#include <stdio.h>
int main(){
char ch = ~0x93;
int num = ch;
printf("num是0x%x\n",num);
return 0;
}
结果:
num是0x6c
0x93 1001 0011
0x6c 0110 1100
双目位操作符包括按位与(&
),按位或(|
)和按位异或(^
)
它们都可以把两个数字对应数位上的内容做计算
按位与可以把对应数位的内容做与计算
只要一个数位的内容是0则计算结果就是0
3 0000 0011
& 5 0000 0101
0000 0001
/CSD1702/biaoc/day04 04bit.c
/*
位操作符演示
*/
#include <stdio.h>
int main(){
char ch = ~0x93;
int num = ch;
printf("num是0x%x\n",num);
printf("3 & 5是%d\n", 3 & 5);
return 0;
}
结果:
num是0x6c
3 & 5是1
按位或可以把两个数字对应位数的内容做或计算
只要有一个数位的内容是1则计算结果就是1
STDC01_day04_07-运算符06.ts
3 0000 0011
| 5 0000 0101
0000 0111
/CSD1702/biaoc/day04 04bit.c
/*
位操作符演示
*/
#include <stdio.h>
int main(){
char ch = ~0x93;
int num = ch;
printf("num是0x%x\n",num);
printf("3 & 5是%d\n", 3 & 5);
printf("3 | 5是%d\n", 3 | 5);
return 0;
}
结果:
num是0x6c
3 & 5是1
3 | 5是7
按位异或可以把两个数字对应数位的内容做异或计算
如果两个数位的内容一样则结果是0,否则结果是1
3 0000 0011
^ 5 0000 0101
0000 0110
/CSD1702/biaoc/day04 04bit.c
/*
位操作符演示
*/
#include <stdio.h>
int main(){
char ch = ~0x93;
int num = ch;
printf("num是0x%x\n",num);
printf("3 & 5是%d\n", 3 & 5);
printf("3 | 5是%d\n", 3 | 5);
printf("3 ^ 5是%d\n", 3 ^ 5);
return 0;
}
结果:
num是0x6c
3 & 5是1
3 | 5是7
3 ^ 5是6
num % 2 奇数真偶数假
num & 1 二进制最后一位与1进行按位与 奇数真偶数假
移位操作可以把一个数字里的所有二进制位数内容统一向左或向右移动n个位置
>>
表示向右移位操作
<<
表示向左移位操作
它们都是双目位操作符
操作符左边的数字是将要进行移位操作的数字
操作符右边的数字是将要移动的位数
移位操作相当于把数字中每个二进制数位的内容换一个数位放
3 << 2
0000 0011 3
00000 1100 12
/CSD1702/biaoc/day04 04bit.c
/*
位操作符演示
*/
#include <stdio.h>
int main(){
char ch = ~0x93;
int num = ch;
printf("num是0x%x\n",num);
printf("3 & 5是%d\n", 3 & 5);
printf("3 | 5是%d\n", 3 | 5);
printf("3 ^ 5是%d\n", 3 ^ 5);
printf("3 << 2是%d\n", 3 << 2);
return 0;
}
结果:
num是0x6c
3 & 5是1
3 | 5是7
3 ^ 5是6
3 << 2是12
STDC01_day04_08-运算符07.ts
左移的时候右边空出来的位置上一定填充0
/CSD1702/biaoc/day04 04bit.c
/*
位操作符演示
*/
#include <stdio.h>
int main(){
char ch = ~0x93;
int num = ch;
printf("num是0x%x\n",num);
printf("3 & 5是%d\n", 3 & 5);
printf("3 | 5是%d\n", 3 | 5);
printf("3 ^ 5是%d\n", 3 ^ 5);
printf("3 << 2是%d\n", 3 << 2);
num = 0x7fffffff;
printf("num >> 2是0x%x\n", num >> 2);
return 0;
}
结果:
num是0x6c
3 & 5是1
3 | 5是7
3 ^ 5是6
3 << 2是12
num >> 2是0x1fffffff
0111 7 >> 2
0001 1
/CSD1702/biaoc/day04 04bit.c
/*
位操作符演示
*/
#include <stdio.h>
int main(){
char ch = ~0x93;
int num = ch;
printf("num是0x%x\n",num);
printf("3 & 5是%d\n", 3 & 5);
printf("3 | 5是%d\n", 3 | 5);
printf("3 ^ 5是%d\n", 3 ^ 5);
printf("3 << 2是%d\n", 3 << 2);
num = 0x7fffffff;
printf("num >> 2是0x%x\n", num >> 2);
num = 0xbfffffff;
printf("num >> 2是0x%x\n", num >> 2);
printf("0xbfffffff >> 2是0x%x\n", 0xbfffffff >> 2);
return 0;
}
结果:
num是0x6c
3 & 5是1
3 | 5是7
3 ^ 5是6
3 << 2是12
num >> 2是0x1fffffff
num >> 2是0xefffffff
0xbfffffff >> 2是0x2fffffff
解释:
1011 b >> 2 有符号类型 左边填充的是符号位 num定义为有符号类型
1110 e
1011 b >> 2 无符号类型 左边填充的是0 直接将数字移位为无符号类型
0010 2
无符号类型数字右移的时候左边空出来的位置上一定填充0,有符号类型数字右移的时候左边空出来的位置上填充符号位的内容
一般情况下把数字左移n位相当于乘以2的n次方,右移n位相当于除以2的n次方
向左移32位 数变成0
位操作符不会修改任何现有存储区的内容(没有对现有存储区赋值更改存储区)
STDC01_day04_09-运算符08.ts
&
也可以作为单目操作符使用,这个时候它可以用来计算一个存储区的地址 补充:取地址符
使用的时候这个符号应该写在一个存储区的前面
可以使用%p
做占位符把地址数据显示在屏幕上
/CSD1702/biaoc/day04 05addr.c
/*
地址相关操作符演示
*/
#include <stdio.h>
int main(){
int num = 0;
printf("&num是%p\n",&num);
return 0;
}
结果:
&num是0028FF1C
我们的计算机里所有地址都是由32个二进制数位构成的
*
也可以作为单目操作符使用,这个时候它可以根据一个地址找到对应的存储区 补充:取内容
使用的时候要写在一个地址前面
/CSD1702/biaoc/day04 05addr.c
/*
地址相关操作符演示
*/
#include <stdio.h>
int main(){
int num = 0;
printf("&num是%p\n",&num);
*(&num) = 10; //先取变量的地址然后再取变量地址的内容
printf("num是%d\n",num);
return 0;
}
结果:
&num是0xbfde533c
num是10
STDC01_day04_10-运算符09.ts
三目操作符可以从两个计算规则里选择一个进行计算
三目操作符的格式如下
布尔值 ?公式一 : 公式二
如果布尔值为真就用公式一进行计算,否则用公式二进行计算
/CSD1702/biaoc/day04 06tri.c
/*
三目操作符演示
*/
#include <stdio.h>
int main(){
int num = 0;
printf("请输入一个数字:");
scanf("%d",&num);
num = num >= 0 ? num : 0 - num;
printf("绝对值是%d\n",num);
return 0;
}
结果:
请输入一个数字:-1
绝对值是1
/CSD1702/biaoc/day04 06tri.c
/*
三目操作符演示
*/
#include <stdio.h>
int main(){
int num = 0;
printf("请输入一个数字:");
scanf("%d",&num);
num = num >= 0 ? num : 0 - num;
//num >= 0 ? num = num : num = 0 - num; //不要在问号后面使用赋值操作符 num >= 0 ? num = num : num 满足三目操作符
printf("绝对值是%d\n",num);
return 0;
}
不要在问号后面使用赋值操作符
(gender && (height - weight < 105)) || (!gender && (height - weight < 110))
gender ? height - weight < 105 : height - weight < 110
练习:
编写程序从键盘得到一个0到127之间的数字,把它转换成二进制并把结果显示在屏幕上
(先显示左边的数位,后显示右边的数位)
STDC01_day04_11-运算符10.ts
/CSD1702/biaoc/day04 07bit.c
/*
操作符练习
*/
#include <stdio.h>
int main(){
int num = 0;
unsigned char ch = 0x80; //1000 0000
printf("请输入一个数字:");
scanf("%d",&num);
printf("%d",(num & ch) != 0);
ch >>= 1;
printf("%d",(num & ch) != 0);
ch >>= 1;
printf("%d",(num & ch) != 0);
ch >>= 1;
printf("%d",(num & ch) != 0);
ch >>= 1;
printf("%d",(num & ch) != 0);
ch >>= 1;
printf("%d",(num & ch) != 0);
ch >>= 1;
printf("%d",(num & ch) != 0);
ch >>= 1;
printf("%d\n",(num & ch) != 0);
return 0;
}
结果:
请输入一个数字:91
01011011
预习:
1.类型转换
2.分支(if
分支和switch...case
分支)
3.for
循环