运算符分类
- 1.按照功能划分:
算术运算符;关系运算符与逻辑运算符;按位运算符
2.运算符根据参与运算的操作数的个数分为
单目运算
单目运算:只有一个操作数 如 : i++ ! sizeof
双目运算
双目运算:有两个操作数 如 : a+b
结合性:左结合性(自左至右)和右结合性(自右至左)
1.算术运算符的结合性是自左至右,即先左后右
例如表达式: x-y+z
则y 应先与“-”号结合,执行 x-y 运算,然后再执行+z 的运算。这种自左至右的结合 方向就称为“左结合性”。
2.自右至左 的结合方向称为“右结合性”
最典型的右结合性运算符是赋值运算符例如:如x=y=z
由于“=”的 右结合性,应先执行y=z 再执行x=(y=z)运算。
算术运算符:
1.整数除于整数,求出来的结果依然是整数
2.浮点型赋值给整型会损失小数部分
3.%两侧必须都为整数
4.利用%求出来的余数是正数还是负数,由%左边的被除数决定,被除数是正数,余数就是正数,反之则反
算术运算的注意点:
1.自动类型转换 int a = 10.6; int b = 10.5 + 1.7;
2.自动将大类型转换为了小类型,会丢失精度 自动类型提升 int b = 10.5 + 10;
3.将右边的10提升为了double类型 double b = 1.0 / 2; 解决除法的精度问题
4.强制类型转换 double a = (double)1 / 2; double b = (double)(1 / 2);
求余运算注意事项:
- 参与运算的必须是整数**
- 运算结果的正负性取决于第一个运算数,跟后面的运算数无关
类型转换
1.自动转换(隐式转换): 发生在不同数据类型的量混合运算时,由编译系统自动完成。
2.自动转换遵循以下规则:
• 0)相同数据类型的值才能进行运算(比如加法运算),而且运算结果依然是同一种数据类型。系统会自动对占用内存较少的类型做一个“自动类型提升”的操作
• 1)若参与运算量的类型不同,则先转换成同一类型,然后进行运算。 + 2)转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转 成long型后再进行运算。
• 3)所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成 double型,再作运算。
• 4)char型和short型参与运算时,必须先转换成int型。
5)在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类 型。如果右边量的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度,丢失的部分 按四舍五入向前舍入。
例如:
int i = 1;
i = i + 8.808
printf("%d", i);
输出结果: 9
按照隐式处理方式,在处理i = i + 8.808时
首先i转换为double型,然后进行相加,结果为double 型,再将double型转换为整型赋给i
3.强制类型转换(显示转换): 强制类型转换是通过类型转换运算来实现的
4.一般形式为:(类型说明符) (表达式)
float) a; /* 把a转换为实型 */
(int)(x+y); /* 把x+y的结果转换为整型 */
int i = 1;
i = i + (int)8.808
printf("%d", i);
//输出结果: 9
这时直接将8.808转换成整型,然后与i相加,再把结果赋给i。
其实: 这样可把二次转换简化为一次转换。
int i = 1;
i = (int)(i + 8.808)
printf("%d", i);
//或者让系统隐式转换
int i = 1;
i = i + 8.808
printf("%d", i);
5.强制类型转换注意点
0)将大范围的数据赋值给小范围变量时,系统会自动做一个强制类型转换的操作,这样容易丢失精度
1)类型说明符和表达式都必须加括号(单个变量可以不加括号),如把(int)(x+y)写成(int)x+y 则成了把x转换成int型之后再与y相加了。
2)无论是强制转换或是自动转换,都只是为了本次运算的需要而对变量的数据长度进行的临时性 转换,而不改变数据说明时对该变量定义的类型。
float floatValue = 10.1f;
int sum = 4 + (int)floatValue ;
printf("sum = %d", sum);// 输出14
// floatValue本身的值并没有改变
printf("floatValue = %f", floatValue); // 输出10.100000
赋值运算符
1.表达式:将同类的数据(常数、变量、函数等)用运算符号按一定的规则连接起来的、有意的式子
一定有返回值
// 自增自减写在前面和后面的区别
// 如果++写在变量的前面, 那么会先将变量自增再用自增之后的结果参与运算
// 如果++写在变量的后面, 那么会先将变量的值参与运算再将变量自增
// 总结一句话: ++在前, 先自增再运算, ++在后, 先运算再自增
sizeof
可以用来计算一个变量或一个常量、一种数据类型所占的内存字节数
格式: 用法:sizeof(常量/变量)
注意: sizeof不是一个函数, 是一个运算符. (面试题)
逗号运算符:
1.逗号表达式的运算过程是:先算表达式1,再算表达式2,依次算到表达式n
2.整个逗号表达式的值是最后一个表达式的值
b = (a=4, ++a, a * 7);
// 1.先执行第一个表达式, 将4赋值给a
// 2.再执行第二个表达式, 让a自增变为5
// 3.再执行第三个表达式, 5 * 7
// 4.最后将最后一个表达式的值作为”逗号表达式的值”返回赋值给b, 所以b等于35
关系运算符中==、!=的优先级相等,<、<=、>、>=的优先级相等,且前者的优先级低于后者
关系运算符的优先级小于算术运算符
逻辑运算
C语言中��供了三种逻辑运算符:
• &&(与运算)
• ||(或运算)
• !(非运算)
1. &&(与运算
格式: “条件A && 条件B”
口诀:一假则假
逻辑与运算过程:
总是先判断条件A是否成立
如果条件A成立,接着再判断条件B是否成立:如果条件B成立,“条件A && 条件B”的结果就为1,即“真”,如果条件B不成立,结果就为0,即“假”
如果条件A不成立,就不会再去判断条件B是否成立:因为条件A已经不成立了,不管条件B如何,“条件A && 条件B”的结果肯定是0,也就是“假”
• 2. ||(或运算)
• 格式: “条件A || 条件B”
• 逻辑或运算过程
总是先判断条件A是否成立
如果条件A成立,就不会再去判断条件B是否成立:因为条件A已经成立了,不管条件B如何,“条件A || 条件B”的结果肯定是1,也就是“真”
如果条件A不成立,接着再判断条件B是否成立:如果条件B成立,“条件A || 条件B”的结果就为1,即“真”,如果条件B不成立,结果就为0,即“假”
C语言规定:任何非0值都为“真”,只有0才为“假”。因此逻辑或也适用于数值。比如 5 || 4的结果是1,为“真”;-6 || 0的结果是1,为“真”;0 || 0的结果是0,为“假”
3. !(非运算)
格式: “! 条件A”
运算结果:
• 其实就是对条件A进行取反:若条件A成立,结果就为0,即“假”;若条件A不成立,结果就为1,即“真”。也就是说:真的变假,假的变真。
口诀:真变假,假变真
优先级
!(非) // 注意
↑
算术运算符
↑
关系运算符
↑
&&和|| // 注意
↑
赋值运算符
注意:
1.与短路:&& 只要第一个条件表达为假那么后面的条件表达就不参与运算了
2. 或短路:|| 只要第一个条件表达式为真那么后面的条件表达式就不参与运算了
三目运算
1.格式: 表达式1?表达式2:表达式3
如果表达式1为真,三目运算符的运算结果为表达式2的值,否则为表达式3的值
2.条件运算符的结合方向是自右至左
例如:a>b?a:c>d?c:d;
应理解为:
a>b?a:(c>d?c:d)
// 从键盘输入3个整数, 利用三目运算符取出最大值并输出
// 1.提示用于输出三个整数, 用逗号隔开, 以回车结束
printf("请输入三个整数, 用逗号隔开, 以回车结束\n");
// 2.定义三个变量保存用户输入的数据
int num1, num2, num3;
// 3.利用scanf函数接收用户输入的数据
scanf("%i,%i,%i", &num1, &num2, &num3); // 17, 5, 88
// 4.比较三个数的大小, 取出最大值
// 4.1获取num1和num2中的最大值
// int temp = num1 > num2 ? num1 : num2;// 17 > 5 ? 17 : 5; temp = 17
// 4.2利用num1和num2中的最大值和剩下的num3比较
// int result = temp > num3 ? temp : num3;// 17 > 88 ? 17 : 88; result = 88
// youtube写法 usb写法
// 1.阅读性比较差
// 2.性能也比较差
int result = (num1 > num2 ? num1 : num2) > num3 ? (num1 > num2 ? num1 : num2) : num3;
// 5.输出结果
printf("result= %i\n", result);
if基本概念
/*
第一种格式:
if (条件表达式)
{
语句…
}
只要 条件表达式 为真, 那么就会执行if后面大括号中的内容.
第二种格式:
if (条件表达式)
{
语句…
}else
{
语句…
}
只要 条件表达式 为真,那么就会执行if后面大括号中的内容.
如果 条件表达式 不为真, 那么就会执行else后面大括号中的内容
规律: 两个大括号中的内容, 一定会有一个会被执行
第三种格式:
if (条件表达式1)
{
语句…
}
else if (条件表达式2)
{
语句…
}
else if (条件表达式3)
{
语句…
}
…..
else
{
语句…
}
只要 条件表达式1 为真,那么就会执行if后面大括号中的内容. 而其它大括号不会被执行
如果 条件表达式1 不为真, 那么就会取判断条件表达式2, 如果 条件表达式2 为真就会执行 条件表达式2 后面大括号中的内容
其它的else if一次类推,
当前面所有的if, else if的条件表达式都不为真, 就会执行else后面大括号中的内容
规律:
众多大括号只会执行其中一个
如果执行到后面大括号中的内容, 代表前面的所有条件都不满足
第4种格式:
if (条件表达式)
语句…
如果省略if后面的大括号, 当条件表达式为真时, 只会执行if后面的第一条语句
第5种格式:(if嵌套)
if(添加表达式)
{
if(添加表达式)
{
}
}else
{
if(添加表达式)
{
}else
{
}
}