1. 算术运算:
- 双目运算:(参与运算的有两个)加减乘除取余,除法运算要注意,如果参与运算的都为整数,那么结果也为整数,若参与运算的有实数,那么结果为实数!如:34/4=8。而取余运算要注意,参与运算必须为整数!如:14%3=2。
- 单目运算:(参与运算的只有一个)自增自减取负,a++或++a等效于a=a+1;a--或—a等效于a=a-1,前置(先操作在取变量值) ++在前 和后置(先取变量值在做操作)++在后 ;-a
- 单目运算的“前置”和“后置”的区别:
“前置”:变量先增值(或先减值),后被引用;
“后置”:变量先被引用,后再增值(或后减值)
2. 赋值运算:<变量> = <表达式>
- 赋值表达式可以嵌套使用,例如:x=(y=(z=100)),相当于x=100,y=100,z=100。
- 赋值运算会把右边表达式的数据类型转换成左边变量的类型。
- 复合运算符=双目+单目,例如加赋值a+=b等效于a=a+b;减赋值a-=b等效于a=a-b;乘赋值a*=b等效于a=a*b;除赋值a/=b等效于a=a/b;取余赋值a%=b等效于a=a%b。
- 算术运算符优先级高于算术赋值运算符,例如x*=10+2等价于x=x*(10+2)。
3. 关系运算符:真(非零),假(为0)
4. 逻辑运算(三种):逻辑与a&&b,逻辑或(a||b),逻辑非(!a)逻辑真为非零,逻辑假为零。
5. 位运算:位逻辑运算、移位运算。
- 变量本身的值不变,左移一位会实现快速乘2,右移一位会实现快速除以2。
- 左移:高位移出,低位补0;右移:低位移出,高位补0;
- 变量名>>右移位数,每右移n位相当于除以2的n次幂;变量名<<左移位数,每左移n位相当于乘以2的n次幂。
- 例如:求X=3+5*2/(4-1)的值。=优先级最低,最后计算;=是右结合,先计算=右边的值;()优先级最高,最先计算;*/优先级高,先计算;同级的是左结合,左边先计算。
6. 运算的优先级和结合性(可以通过加括号来增加可读性)
- 原则:
单目运算符>双目运算符>三目运算符;
算术运算符>关系运算符>逻辑运算符;
移位运算符>关系运算符>位逻辑运算符;
括号最高,逗号最低,赋值和复合赋值仅高于逗号运算符。
- 右结合性:先计算右边再计算左边:三目和赋值运算符
- 左结合性:先计算左边再计算右边:其余运算符。
- 程序1:输入一个正整数,判断它是否是闰年。
思路:闰年的判断条件:能被400整除,或能被4整除但不能被100整除。
/* 输入一个正整数,判断一个年份是否是闰年 */ /* 正确的程序 */ #include<stdio.h> #include<stdlib.h> int main() { int year; printf("input a year:\n"); scanf_s("%d", &year); if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0)) // 我的错误在于if判断语句中==用了=! printf("%d is leap year\n",year); else printf("%d is not leap year\n",year); system("pause"); return 0; }
- 程序2:将扫地机器人控制变量x的第2,4,6位分别进行清零、置一、取反操作。
思路:清零:和0相与;置一:和1相或;取反:和本身异或。
/* 扫地机器人控制变量x=01101111,对第2,4,6位置分别做:清零,置一,取反操作 */ /*正确的程序 */ #include<stdio.h> #include<stdlib.h> int main() { char x = 111, y; // x = 01101111,数据初始化没有二进制数,默认十进制!并且这里是一个字节长度,因此可以用char类型。 printf("开始扫地…\n"); x = x&~2; // 第2位清零(11111101)清零:和0相与。注意:第二位是指从右边的第二位!!! printf("结束扫地,开始拖地…\n"); x = x | 8; // 第4位置置1(00001000),置一:和1相或。 printf("结束拖地,开始吸尘…\n"); x = x ^ 32;// 第6位取反,取反:和本身异或。 printf("当前状态为:"); for (int i = 7; i >= 0; --i) // 从高位进行逐位输出(补位操作) { y = (x >> i) & 01; printf("%d", y); } system("pause"); }
注意:
- 取反:和本身异或;
- 任何数和一相与都是本身,任何数和零相或都是本身;
- 清零:和零相与;
- 计算机输入的数据都是把它当作十进制数来计算的,数据进行初始化的时候也是当作十进制进行初始化的,只不过存储数据存的是二进制;
- 因此,问题产生了:操作之后的数据x怎么输出?输出十进制?八进制?十六进制?二进制?注意:C语言没有二进制输出,因此我们要把十进制转化为二进制输出!
数字按照二进制输出方法(补位操作):
x&01得到最低位;
(x>>1)&01就把次低位移到最低位并取出最低位;
……
(x>>7)&01就把最高位移到最低位并取出。
但这种方法,输出结果是先输出最低位,最后输出最高位,但我们需要先输出最高位!
问题:
- 程序2中,对第六位让它与自身进行异或,其他都为0这样对吗?感觉不太对。。。
- 最后输出二进制的方法中,右移操作为什么是补位操作,移位操作不都是补零吗?
7. 其他运算:三目运算、逗号结合运算、长度运算
- 三目运算(条件语句的简化形式):
基本形式:e1?e2:e3
作用:若e1为真,那么表达式结果取e2,否则取e3,例如:a>b?a:b(实现了找出较大值的功能)
- 逗号结合运算(常用于循环语句中,可以分别对多个变量进行操作):
一般形式:表达式1,表达式2,...,表达式n
求解过程:先求表达式1,最后求表达式n,它是按照顺序从左到右计算的,因此最后整个逗号表达式的值为表达式n的值。例如:x = (a=100,b=10,c=1000); // 最后x的值为1000。
- 长度运算:
一般形式:sizeof(数据类型说明符或者变量名)
作用:求解某种数据类型或者变量名的长度,它是以字节为单位的。例如:sizeof(double)=8。