### 操作符 **运算操作符** C语言里采用操作符表示对数字的处理规则。 根据需要配合的数字个数把操作符分成三类,分别是单目操作符,双目操作符和三目操作符。 单目操作符:仅需要一个数字配合使用的操作符,例如:++ --。 双目操作符:需要两个数字配合使用的操作符,例如:+ - * /等。 三目运算符:需要三个数字来配合使用的操作符, 例如: .. ? .. : ..。 双目运算符还有其他的。 % 也是一个双目操作符,它表示取余。 /* 取余操作符 */ #include <stdio.h> int main(){ printf("15 % 6 = %d\n", 15 % 6); return 0; } **赋值操作符** 赋值操作符(=)可以吧一个数字放到存储区里。 赋值语句可以当做数字使用,这个数字就是赋值完成后存储区里的数字。 可以在一条语句里使用多个赋值操作符,这个时候先计算右边的赋值操作符,后计算左边的。 #include <stdio.h> int main(){ char ch = 0; int num = 0; num = ch = 300; printf("num = %d\n", num); return 0; } 双目操作符和赋值操作符合并,形成了复合赋值操作符, 例如: +=, *=等。; 复合赋值操作符要求左边的内容可以代表存储区,右边的内容可以代表数字。 它首先用双目操作符对左右两边的内容做计算,然后把计算结果记录到左边的存储区里。 #include <stdio.h> int main(){ int num = 44; num += 6; printf("num = %d\n", num); return 0; } 复合赋值操作符的优先级和赋值操作符的优先级一样低。 自增操作符(++)和自减操作符(--)都是单目操作符。 它们都应该和存储区配合使用。 它们可以把存储区里的内容加一或者减一。 它们各有两种使用方法,一种是前操作(操作符写在存储区前面),另外一种是后操作符(操作符写在后面)。 前操作语句当作数字使用的时候是修改后的数字,后操作语句当作数字使用的时候是修改前的数字。 #include <stdio.h> int main(){ int num = 10; printf("num = %d\n", num++); printf("num = %d\n", ++num); return 0; } 返回结果: num = 10 num = 11 不要在一条语句里对同一个变量多次进行自增或者自减计算,因为结果是不确定的。 **逻辑表达式** 逻辑表达式的计算结果一定是布尔值。 逻辑操作符就是用来编写逻辑表达式的。 有一个求反的单目逻辑操作符,是 ! ,它可以计算一个布尔值的相反值。 这个操作符应该写在一个布尔值的前面。 /* 逻辑操作符演示 */ #include <stdio.h> int main(){ printf("!8 = %d\n", !8); return 0; } 返回结果: !8 = 0 双目逻辑操作符包括==(等于),不等于(!=),大于(>),小于(<),大于等于(>=),小于等于(<=)。 最多包含一个双目逻辑操作符的表达式在计算机里的结果和数学里的结果一定一样。 可以把最多包含一个双目逻辑操作符的表达式,叫做简单逻辑表达式。 所有逻辑表达式必须拆分成多个简单逻辑表达式然后在我合并,和数学里的方法并不是完全一样的。 /* 逻辑操作符演示 */ #include <stdio.h> int main(){ printf("3 < 7 < 5 = %d\n", 3 < 7 < 5); return 0; } 返回结果: 3 < 7 < 5 = 1 // 1 = True 与(&&)、或(||)也是双目逻辑操作符,它们可以用来合并多个逻辑表达式。 如果两个逻辑表达式中有一个的结果是假则用 与(&&) 合并后的结果一定是假。 如果两个逻辑表达式中有一个的结果是真则用 或(||) 合并后的结果一定是真。 与(&&)、或(||)都有一个短路的特征,如果前面的逻辑表达式可以决定最终结果,则计算机就会忽略后面了逻辑表达式。 ### 位操作符 位操作符是直接操作二进制数位。 ~是一个单目位操作符,这个操作符可以根据一个数字计算出另外一个数字,这两个数字在所有二进制数位上的内容都一样。 ~叫做按位求反操作符。 这个操作符应该写在一个数字前面。 /* 位操作符演示 */ #include <stdio.h> int main(){ char ch = ~0xc3; // 0xc3 | 11000011 int num = ch; printf("ch = 0x%x\n", num); return 0; } 返回结果: 0x3c | 00111100 双目位操作符包括: * 按位与(&) * 按位或(|) * 按位异或(^) 它们可以把两个数字对应二进制数位上的内容进行计算。 **按位与(&)** 按位与(&)可以把数位上的内容做与计算。 只要有一个数位内容是0则计算结果就是0。 /* 按位与 */ #include <stdio.h> int main(){ printf("3 & 5 = %d\n", 3 & 5); return 0; } 返回结果: 3 & 5 = 1 0000 0011 & 0000 0101 = 0000 0001 **按位或(|)** 按位或(|)可以把数位上的内容做或计算。 只要有一个数位内容是1则计算结果就是1。 /* 按位或 */ #include <stdio.h> int main(){ printf("3 | 5 = %d\n", 3 | 5); return 0; } 返回结果: 3 | 5 = 7 0000 0011 | 0000 0101 = 0000 0111 **按位异或(^)** 按位异或(^)可以把数位上的内容做异或计算。 如果两个数位内容一样则异或计算结果是0, 否则结果是1。 /* 按位异或 */ #include <stdio.h> int main(){ printf("3 ^ 5 = %d\n", 3 ^ 5); return 0; } 返回结果: 3 ^ 5 = 6 0000 0011 ^ 0000 0101 = 0000 0110 **移位操作** 移位操作可以把一个数字中所有二进制数位的内容同意向左或向右移动n个位置。 * >> 表示向右移动 * << 表示向左移动 他们都是双目位操作符。 操作符左边的数字是将要进行移位操作的数字。 操作符右边的数字是将要移动的位数。 /* 移位操作练习 */ #include <stdio.h> int main(){ printf("3 << 2 = %d\n", 3 << 2); return 0; } 返回结果: 3 << 2 = 12 0000 0011 << 2 = 0000 1100 向左移动的时候,右边空出来的位置上一定填充0。 无符号类型数字向右移位后左边空出来的位置上一定填充0。 有符号类型数字向右移位后左边空出来的位置上填充符号位。 一般情况下数字向左移动n位相当于乘以2的n次方,向右移动n位相当于除以2的n次方。 位操作符不会修改任何存储区内容,它们只是会计算出一个新数字。 ### 地址相关操作符 **计算一个存储区的地址** &也可以作为单目操作符使用,这个时候它可以用来计算一个存储区的地址。 这个操作符使用的时候,应该写在一个存储区的前面。 可以使用%p做占位符把地址数据显示在屏幕上。 在我们的计算机上所有的地址数据都是32个二进制数位。 /* 地址相关操作符演示 */ #include <stdio.h> int main(){ int num = 0; printf("&num = %p\n", &num); return 0; } **知道对应的存储区** "*" 可以当做单目操作符使用,这个时候它可以根据一个地址找到对应的存储区。 这个时候应该把它写在一个地址数据前面。 /* 地址相关操作符演示 */ #include <stdio.h> int main(){ int num = 0; *(&num) = 10; printf("num = %d\n", num); return 0; } ### 三目操作符 操作符结构 布尔值 ? 公式一 : 公式二 如果布尔值是真就采用公式一进行计算,否则就采用公式二进行计算。 /* 三目表达式演示 */ #include <stdio.h> int main(){ int num = 0; printf("请输入一个数字:"); scanf("%d", &num); num = num >= 0 ? num : 0 - num; printf("绝对值是: %d\n", num); return 0; } 不要在问号后使用赋值操作符,会因为符号优先级问题,造成不正确的计算。