1.位操作符可以直接操作二进制数位的内容
位操作符的本质是先把操作数都转换为二进制数,然后再开始运算,最后的运算结果转换为十进制数。
2.~(鳄化符号)是一个单目位操作符。
它可以根据一个数字计算出另外一个数字,这两个数字的所有二进制数位的内容都不同(按位取反)运算规则:0变1,1变0
使用的时候这个符号应该写在数字的前面
输出结果:num是0x6d
char类型有1字节就是8bit,int类型有4字节就是32bit
char 类型0x92转换成int类型~0x92过程:
3.双目位操作符包括按位与(&),按位或(|)以及按位异或(^)
它们都可以把两个数字对应的二进制的内容做计算。
4.按位与(&)可以把两个数字对应数位的内容做与计算。
只要一个数位的内容是0,则与计算以后得到的结果就是0
例子:3 & 5 = 1
3 0000 0011
& 5 0000 0101
= 1 0000 0001
任何数位内容和0做按位与(&)结果一定是0,任何数位内容和1做按位与(&)结果保持不变。
按位与(&)可以用来获得某些数位的内容。
按位与(&)用途判断奇偶:判断随机输入的一个整数num的奇偶
num % 2
num & 1
两个表达式都可以用来判断奇偶。位操作符按位与(&)优与求余(%),用位操作符更好。
按位与(&)还可以把某些数位的内容设置成0
按位与(&)用途:字母小写换成大写
'a' 97 0110 0001
'A' 65 0100 0001
32 0010 0000
输入一个小写字母到ch变量里,输出ch对应的大写字母:
ch &= ~32;
5.按位或(|)可以把两个数字对应数位的内容做或计算。
只要一个数位的内容是1,则或计算以后结果就是1
例子:3 | 5 = 7
3 0000 0011
| 5 0000 0101
= 7 0000 0111
任何数位内容和0做按位或(|)结果保持不变,任何数位内容和1做按位或(|)结果就是1
按位或可(|)以把某些数位的内容变成1。
按位或(|)用途:字母大写换成小写
'a' 97 0110 0001
'A' 65 0100 0001
32 0010 0000
输入一个大写字母到ch变量里,输出ch对应的小写字母:
ch |= 32;
6.按位异或(^)可以把两个数字对应的数位内容做异或计算。
如果两个数位的内容一样则异或结果是0,否则结果是1
例子:3 ^ 5 = 6
3 0000 0011
^ 5 0000 0101
= 6 0000 0110
任何数位内容和0做按位异或(^)保持不变,任何数位内容和1做按位异或(^)一定改变
按位异或(^)可以把某些数位的内容变成相反内容。就是0变1,1变0
例子:变量ch里放了一个不知道大小写的英文字母,如果ch里面的字母是大写把它变成小写,如果ch里面的字母是小写把它变成大写
'a' 97 0110 0001
'A' 65 0100 0001
32 0010 0000
ch ^= 32;
7.移位操作可以把一个数字里所有的二进制数位的内容统一向左或向右移动n个位置
例子:把一个八位二进制数位相左移动两位
* * * * * * * *
0 0 0 0 0 0 1 1
变成: 0 0 0 0 1 1 0 0
>>表示向右移位
<<表示向左移位
它们都是双目位操作符
操作符左边是将要进行移位操作的数字
操作符右边是将要移动的位数
移位操作符本质上就是要把每个数位的内容放到另外一个数位里。
例子:3 << 2;
3 0000 0011 向左移动两位变成
12 0000 1100
向左移位的时候右边空出来的数位里必须填充0
无符号类型的数字右移的时候左边空出来的数位里填充0
有符号类型的数字右移的时候左边空出来的数位里填充符号位的内容,也就是1
(在32位情况下)一般情况下向左移动n个位置相当于乘以2的n次方,向右移动n个位置相当与除以2的n次方。
所有位操作符都不会修改存储区的内容。
8.&也可以做为单目操作符使用,这个时候它可以用来计算一个存储区的地址。
使用的时候应该把这个操作符写在一个存储区的前面。
可以使用%p占位符把地址数据显示在终端窗口里
输出结果:&num是0xbf8dbbac
我们计算机里所有地址数据都是由32个二进制数位构成的。
9.*也可以作为单目操作符使用,这个时候它可以根据一个地址找到对应的存储区。
这个操作符应该写在一个地址数据前面。
输出结果:num是10
10.三目操符符号可以从两套计算规则里选择一套进行计算。
三目操作符的格式如下:
布尔值 ? 公式一 :公式二
如果布尔值为真就采用公式一计算,否则采用公式二计算
例子:判断一个数到0的距离,正整数输出他本身,负数输出他的相反数
不要在问号后使用赋值操作符。
例子: 用三目运算符表示
gender ? height -weight < 105 : height - weight <110
例子:
思路:
11.如果表达式里包含多个不同类型的数字就必须首先把他们转换成同一个类型,然后再计算,这个转换过程叫做隐式类型转换。
隐式类型转换完全由计算机完成。
隐式类型转换的时候必须把占地小的类型转换成占地大的类型
例子:
输出结果:sizeof(1 ?1 : 0.9)是 8
分析: 1是int整型占4个字节,0.9是double类型双精度占8个字节
如果不同类型数字大小一样就把整数类型转换成单精度浮点类型,把有符号类型转换成无符号类型。
例子:
运行结果:加u是无符号类型
12.C语言程序里可以临时给数字指定一个类型,这叫做强制类型转换
强制类型转换格式如下:
printf("%d",(char)300); 输出的是44
分析:char类型范围是0~255,300超出了255,就会从0重新开始,所以是300-255-1=44
强制类型转换有可能导致数据内容丢失
类型转换不会修改存储区内容
13.分支语句可以从几组语句中选择一组执行而忽略其它组
如果在编写程序的时候遇到多种可能性,每种可能性需要专门的语句处理就需要使用分支。
14.if关键字可以用来编写分支语句
if分支里需要为每种可能性编写专门的语句进行处理
if分支里需要为每组语句编写配对的逻辑表达式,当某个逻辑表达式结果为真的时候就执行它配对的那一组语句。
if分支里的任何两组语句都不可能同时执行(可能同时执行的语句不可以被包含在一个if分支里)
编写if分支的时候最好先把所有可能性的个数确定下来。
如果if分支里必然有一组语句会执行就可以省略最后一组语句的逻辑表达式和if关键字
例子:
if () {
}
else if () {
}
else if () {
}
else {
}
如果if分支里多个逻辑表达式同时为真就执行第一个为真的逻辑表达式,所对应的语句而忽略后面的语句。
可以利用这一点简化if分支里的逻辑表达式
例子:
修改后:
if分支里的某一组语句不仅仅和它配对的逻辑表达式有关,只有当前面的所有逻辑表达式都为假而配对逻辑表达式为真的时候才会执行这组语句。
编写if分支的时候尽量把逻辑表达式简单的写在前面。
练习:
方法一:普通if语句
#include <stdio.h>
int main() {
int num1=0, num2=0, num3=0;
printf("请输入三个数字:");
scanf("%d%d%d",&num1,&num2,&num3);
if(num1<num2 && num1<num3){
printf("三个数字中最小的数字是:%d\n",num1);
}
else if(num2<num1 && num2<num3)
{
printf("三个数字中最小的数字是:%d\n",num2);
}
else {
printf("三个数字中最小的数字是:%d\n",num3);
}
return 0;
}
方法二:if嵌套if语句
#include <stdio.h>
int main() {
int num1=0, num2=0, num3=0;
printf("请输入三个数字:");
scanf("%d%d%d",&num1,&num2,&num3);
if(num1>num2){
if(num2>num3){
printf("三个数字中最小的数字是:%d",num3);
}
else{
printf("三个数字中最小的数字是:%d",num2);
}
}
else
{
if(num1>num3){
printf("三个数字中最小的数字是:%d",num3);
}
else{
printf("三个数字中最小的数字是:%d",num1);
}
}
return 0;
}
15.switch...case格式也可以用来编写分支。
如果一个分支里每一个可能性都可以用唯一的整数表示,这个分支才可以用switch...case格式实现
例子:break语句结束case语句
default语句处理不存在的case语句