操作符用来描述对数字的处理规则根据操作符所需要配合的数字个数把操作符分为单目操作符,双目操作符和三目操作符
C语言里用+,-,*和/表示加减乘除四则运算,它们都是双目操作符,如果参与除法计算的两个数字都是整数则计算结果保留整数部分
C语言里用%表示取余操作
赋值操作符用=表示它可以把一个数字记录到一个存储区里,赋值语句可以当作数字使用,这个数字就是赋值完成后左边存储区里的数字,可以在一条语句里使用多个赋值操作符,这个时候先计算右边的赋值操作符
C语言里绝大多数双目操作符可以和赋值操作符合并形成复合赋值操作符(例如+=,/=等)复合赋值操作符要求左边的内容必须代表存储区,右边的内容必须代表数字,复合赋值操作符可以把双目操作符的计算结果记录到左边的存储区里,复合赋值操作符的优先级和赋值操作符优先级一样低
/* * 操作符演示 * */ #include <stdio.h> int num2; int main() { char ch = 0; int num = 0, num1 = 0; printf("15 / 6是%d ", 15 / 6); printf("15 %% 6是%d ", 15 % 6); num = ch = 300; printf("num是%d ", num); num += 6; printf("num是%d ", num); num *= 2 + 3; printf("num是%d ", num); num = 10; num++; printf("num是%d ", num); ++num; printf("num是%d ", num); num = 10; num1 = num++; printf("num是%d,num1是%d ", num, num1); num1 = ++num; printf("num是%d,num1是%d ", num, num1); num = 10; num1 = num++ + ++num; printf("num是%d,num1是%d ", num, num1); num2 = 10; num1 = num2++ + ++num2; printf("num2是%d,num1是%d ", num2, num1); return 0; }
自增操作符(++)和自减操作符(--)都是单目操作符,这两个操作符必须和存储区配合使用,它们可以把存储区里的内容做加一或减一操作,它们都有两种使用方法,一种是前操作(把操作符写在存储区的前面),另外一种是后操作(把操作符写在存储区的后面)这两个操作符编写的表达式本身也可以当作数字使用,前操作当数字使用的时候是修改后的数字,后操作当数字使用的时候是修改前的数字不要在一条语句里对同一个变量多次进行自增或自减计算,因为结果不确定
逻辑表达式的结果只能是布尔值,逻辑操作符用来编写逻辑表达式
!是一个单目逻辑操作符,它可以根据一个布尔值计算相反的布尔值(求反),这个操作符使用的时候应该写在一个布尔值的前面
双目逻辑操作符包括等于(==),不等于(!=),大于(>),小于(<),大于等于(>=)和小于等于(<=)
/* * 逻辑操作符演示 * */ #include <stdio.h> int main() { int num = 0; printf("!8是%d ", !8); printf("3 < 7 < 5是%d ", 3 < 7 < 5); printf("3 < 7 && 7 < 5是%d ", 3 < 7 && 7 < 5); 1 || ++num; printf("num是%d ", num); 0 && ++num; printf("num是%d ", num); return 0; }
最多包含一个双目逻辑操作符的表达式叫简单逻辑表达式,这种表达式的结果在数学里和计算机里一定是一样的,计算机里所有复杂逻辑表达式必须首先拆分成多个简单逻辑表达式然后再合并
可以使用与(&&)和或(||)操作符把两个逻辑表达式合并成一个
只有两个逻辑表达式的结果都是真的时候用与(&&)合并,以后结果才是真,否则结果是假,只要两个逻辑表达式里有一个的结果是真则用或(||)合并后的结果就是真
与(&&)和或(||)都具有短路特征(如果前一个逻辑,表达式的结果可以决定合并后整个逻辑表达式的结果就忽略后一个逻辑表达式)
位操作符可以直接操作二进制数位的内容
~是一个单目位操作符,这个操作符可以根据一个数字计算出另外一个数字,这两个数字的所有二进制数位内容都不一样,这种操作叫按位求反,这个操作符应该写在一个数字的前面
双目位操作符包括按位与(&),按位或(|)和按位异或(^),它们可以把两个数字对应二进制数位的内容进行计算
按位与(&)可以把两个数字对应数位的内容做与计算,只要一个数位的内容是0则与计算以后结果就是0
3 0000 0011
& 5 0000 0101
0000 0001
任何数位的内容和0做按位与结果一定是0,任何数位的内容和1做按位与结果不变,可以使用按位与获得一个数字里某些二进制数位的内容
按位或(|)可以把两个数字对应数位的内容做或计算,只要一个数位里的内容是1则或计算以后结果就是1
3 0000 0011
| 5 0000 0101
0000 0111
任何数位内容和1做按位或结果一定是1,任何数位内容和0做按位或结果保持不变,可以用按位或把一个数字的某些二进制数位内容设置成1
按位异或可以把对应二进制数位的内容做异或计算,如果两个数位的内容一样则异或计算以后结果是0,否则结果是1
3 0000 0011
^ 5 0000 0101
0000 0110
任何数位内容和0做按位异或结果保持不变,任何数位内容和1做按位异或结果变成相反内容,使用按位异或可以把一个数字里某些二进制数位的内容变成相反内容
移位操作可以把一个数字里所有二进制数位的内容统一向左或向右移动n个位置,>>表示向右移位,<<表示向左移位,它们都是双目位操作符,操作符左边的数字是将要进行移位操作的数字,操作符的右边是移动的位数,移位操作会把每个数位的内容换一个数位放
/* * 位操作符演示 * */ #include <stdio.h> int main() { unsigned int unum = 0x8fffffff; int val = 0x8fffffff; char ch = ~0x93; int num = ch; printf("num是0x%x ", num); printf("3 & 5是%d ", 3 & 5); printf("3 | 5是%d ", 3 | 5); printf("3 ^ 5是%d ", 3 ^ 5); printf("3 << 2是%d ", 3 << 2); printf("unum >> 2是0x%x ", unum >> 2); printf("val >> 2是0x%x ", val >> 2); val = 0x4fffffff; printf("val >> 2是0x%x ", val >> 2); return 0; }
/* * 二进制练习 * */ #include <stdio.h> int main() { int num = 0; unsigned char ch = 0x80; 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 ", (num & ch) != 0); return 0; }
向左移位的时候右边空出来的数位里填充0
无符号类型数字右移后左边空出来的数位里一定填充0,有符号类型数字右移后左边空出来的数位里填充符号位的内容
一般情况下把数字向左移动n位相当于乘以2的n次方,向右移动n位相当于除以2的n次方
位操作符不会修改现有存储区的内容
&也可以作为单目操作符使用,这个时候它可以用来计算一个存储区的地址,这个操作符应该写在一个存储区的前面可以使用%p作为占位符把地址数据显示在终端窗口里,我们的计算机里所有地址数据都是由32个二进制数位构成的
*也可以作为单目操作符使用,这个时候它可以根据地址找到对应的存储区,使用的时候应该把这个操作符写在一个地址数据的前面
/* * 地址数据演示 * */ #include <stdio.h> int main() { int num = 0; printf("&num是%p ", &num); *(&num) = 10; printf("num是%d ", num); return 0; }
三目操作符可以从两种不同的计算规则里选择一个进行计算,三目操作符格式如 布尔值 ? 公式一 : 公式二,这种格式表示如果布尔值为真就采用公式一进行计算,否则采用公式二进行计算,不要在问号后使用赋值操作符
/* * 三目表达式演示 * */ #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; 错误 printf("绝对值是%d ", num); return 0; }
如果一个表达式里包含多个不同类型的数字就必须首先把这些数字转换成同一个类型然后才能计算,这个转换过程叫隐式类型转换,完全由计算机执行
隐式类型转换过程中一定把占地小的类型转换成占地大的类型
如果不同类型的大小一样就把整数类型转换成浮点类型,把有符号类型转换成无符号类型
可以在C语言程序里临时给数字指定一个类型,这叫做强制类型转换,强制类型转换格式如 (char)300,强制类型转换有可能造成数据内容丢失
/* * 类型转换演示 * */ #include <stdio.h> int main() { printf("sizeof(1 ? 1 : 0.9)是%d ", sizeof(1 ? 1 : 0.9)); printf("-7 + 3 < 0是%d ", -7 + 3 < 0); printf("-7 + 3u < 0是%d ", -7 + 3u < 0); printf("%d %d ", 300, (char)300); return 0; }
类型转换不会修改现有存储区的内容,计算机会用一个新的存储区记录转换后的结果