内容提要
- 运算符
运算符
各类数值型数据间的混合运算
-
整型浮点型、字符型数据间可以进行混合运算,如:
10 - 'a' * 1.5 = 10 - 97 * 1.5 //保证参与运算的都是数字 = 10.0 - 97.0 * 1.5 //保证参与运算的每一个运算数都是同一数据类型(不同数据类型无法参与运算)
解释:整型、浮点型、字符型之间都可以参与混合运算,是因为它们都是数值型,字符是特殊的数值型(字符的数值型使用的是字符的ASCII码)
运算时,参与运算的两个运算数如果类型不同,则首先将其类型转换为一致再与运算。转换规则为隐式转换和显示转换。
隐式转换
将低等级类型自动提升为高等级类型,又被称作自动类型转换。是由编译系统在控制类型的转换。
语法:
高等级类型 变量名 = 低等级类型变量;
转换关系:
①(低等级类型) i n t → u n s i g n e d i n t → l o n g → d o u b l e int → unsigned int → long → double int→unsignedint→long→double(高等级类型)
②(低等级类型) c h a r / s h o r t → i n t char/short → int char/short→int(高等级类型)
③(低等级类型) f l o a t → d o u b l e float → double float→double(高等级类型)
注意:
在混合运算过程中,系统所进行的类型转换并不会改变原数据的类型(不会改变原数据在内存的储存),只是在运算过程中将其值变成同类型后运算,举例:
int a = 10; //a是int
double c = a + 22.5; //此时 a在参与运算的时候临时转换为double类型,就变成了double c = 10.0 + 22.5
a = 21; //a是int
float c2 = a + 21.5f; //此时a在参与运算时临时转换为float类型,就变成了 float c2 = 21.0f + 21.5f
a = 10; //a是int
显示转换
需要我们手动指定转换类型,又被称作强制类型转换。是由程序员自己来控制转换。
语法:
(type)(表达式)
举例:
- (double)a:将a的值转换为double类型。
- (int)(x+y):将x+y的结果转换为int类型。
- (int)x+y:将x的值转换为int类型后与y相加。
double a = 2, b = 3; //a,b都是double类型
double c = (int)a + b; // 首先将a转换为int类型,此时为显示转换;然后a参与运算的时候,a又被隐式转换为double类型
double num1 = 12.25; // num1是double类型
int num2 = (int)num1; // num1原本是doule类型,在赋值运算时,显示转换为int类型
num1 = 12;//num1原本的类型不会发生改变
注意:类型转换只是发生在程序运行中,并不会改变其在内存中的存储形式。在强制类型转换的过程中,并不改变原变量的类型,只是在运算过程中将其转换类型后再运算。
案例:
- 需求:强制类型转换
- 代码:
#include <stdio.h>
int main(int argc,char *argv[])
{
float x;
int i;
x = 3.6f; // float类型的变量,如果赋值是同类型常量,需要跟上f或者F
i = (int)x; // 将x在程序运行阶段,强制转换为int类型
printf("x=%f,i=%d\n",x,i);// x=3.600000,i = 3 浮点型数据转换为整数,会丢失小数部分
return 0;
}
说明:x仍然为float类型,可见强制类型转换并不会改变变量的类型。
c运算符和c表达式
c运算符
c表达式
所谓表达式就是将操作对象用运算符连接起来的符合C语法规则的式子。(表达式 = 运算数 + 运算 符)
C语言规定了运算符的优先级和结核性。在表达式求值时,按运算符的优先级的高低次序执行。如果运算符对象两侧的运算符优先级相同,如a +b +c,则按照规定的“结合方向”处理。
C语言运算符优先级
算数运算符
基本的算数运算符
+、-
正负值运算符(单目/一元运算符:只有一个运算符),举例:+5,-5
+、-、*、/、%
加减乘除取余运算符(双目/二元运算符:有两个运算数)注意:除法运算中,除数不能为0这些算数运算符的运算顺序与数学上的运算顺序是相同。*、/、%
的优先级高于+、-
表达式和运算符的优先级与结核性
算术表达式
定义:指用算数运算符和括号将运算对象连接起来,符合C语言规范的算式,例如:
a * b /c - 1.5 + 'A'
-
表达式中各种运算符的运算顺序,必要时需要添加括号,例如:
(a+b) / (c+d) != a+b / c+d
-
表达式中各种运算对象的数据类型,特别是整型相除,C语言规定,两整型相除,其结果仍为整型,例如:
7/6 值 1 4/7 值 0 1/2 值 0
-
面试题:
1.(1/2) + (1/2) 结果是多少? 正确答案是 0 2.(1.0/2) + (1.0/2) 结果是多少? 正确答案 1.0
优先级与结核性
定义:在表达式求解的时候,先按运算符的优先级级别的高低次序执行。若一个运算对象两侧的运 算符的优先级相同,则按规定的结合方向处理。
各种运算符的结合方向:
① 算术运算符的结合方向: 自左向右,也就是运算对象先与左边的运算符结合,例如:
a - b + c; //先计算 a - b,然后用其减出来的结果 + c
② 特殊运算符的结合方向: 自右向左,也就是运算对象先与右边的运算符结合,例如:
i++
③ 若一个运算符两侧的数据类型不同,会自动转换为同类型后计算
12 + 12.5 + 'A'
=12.0 + 12.5 + 'A'
=24.5 + 65
=24.5 + 65.0
=89.5
自增++、自增–运算符
作用:使变量的值增1或者减1
结合方向:向右向左
++i,–i
表示在使用该运算符对象之前,先让运算数i自身增1或者减1,然后再使用它,也就是使用增1或者减1后的值
先计算后使用
说明:
①先计算:先让计算数+1
②后使用:将计算后的运算数进行赋值、比较等操作
范例:
int i = 1; //i = 1
int x = ++i; //这里的++i整体相当于一个匿名的变量,上面的案例等价于 i = i + 1 ,x = i
printf("i=%d,x=%d\n",i,x);//i=2,x=2
printf("i=%d,x=%d\n",++i,x)//i=3,x=2
int a = 1;
printf("a=%d\n",++a); //a=2
i++,i–
表示在使用该运算符对象之后,先使用它,然后再让运算数自身增1或者减1,也就是使用增1或者减1前的值
先使用,后计算
①先使用:将计算前的运算数进行赋值、比较等操作
②后计算:再让计算数+1
范例:
int i = 1; //i = 1
int x = i++; //这里的i++整体相当于一个匿名的变量,上面的案例等价于x = i,i = i + 1
printf("i=%d,x=%d\n",i,x);//i=2,x=1
printf("i=%d,x=%d\n",i++,x)//i=2,x=1
int a = 1;
printf("a=%d\n",a++); //a=1
总结:不管是++i还是i++,还是i自身都增1;同理不挂是–i还是i–,运算自身都减1.他们的不同之处在于赋值给整体(++i还是i++)的顺序。
注意
①++
与--
运算符只适用于整型变量或字符型变量,而不能用于其他类型的变量。如
int i = 0;
i++; // i = 1
++i; // i = 2
char a = 'A';
a++; //a = 66 这里是字符的ASCII码参与运算
②++
与--
运算符不能用于常量或表达式。如:–5,(ii+j)++都是非法的