------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
一、运算符概述
1、运算符的基本概念运算符是告诉编译程序执行特定算术或逻辑操作的符号,用来连接操作数。
2、运算符的分类
1)按照功能划分:
- 算术运算符
- 关系运算符
- 逻辑运算符
- 按位运算符
- 单目运算符:只有一个操作数,如i++,i,sizeof
- 双目运算符:有两个操作数,如a+b
- 三目运算符:C语言中唯一的一个,也称为问号表达式 a > b ? 1 : 0
在一个运算表达式中往往含有多个运算符,为了清晰地知道运算的顺序,我们必须根据运算符的优先级和结合性。
1)C语言中,运算符的优先级共分为15级。1级最高,15级最低。在表达式中,优先级较高的先于优先级较低的进行运算。
2)而在一个运算量两侧的运算符优先级相同时,则按照运算符的结合性所规定的结合方向处理。C语言中各运算符的结合性分为两种,即自左至右的左结合性和自右至左的右结合性。
4、表达式概述
1)概念:将同类型的数据,用运算符按照一定的规则连接起来的、有意义的式子称为表达式。
2)表达式的特点:表达式是一个有意义的式子,所以一定有返回值。
3)表达式可以是常量也可以是变量或算式,在表达式中可分为:算术表达式、逻辑表达式和字符串表达式。
4)表达式语句:表达式后面加上分号,构成表达式语句。
二、算术运算符
1、算术运算符的介绍及基本使用
1)算术运算符有五种,详细介绍如下表所示
2)算术运算符的基本使用
加法示例
int a = 10, b = 3, result = 0;
result = a + b; //result的值为13
减法示例
int a = 10, b = 3, result = 0;
result = a - b; //result的值为7
乘法示例
int a = 10, b = 3, result = 0;
result = a * b; //result的值为30
除法示例
int a = 10,b=3,result=0;
//a、b都是整型,除法的时候,两个操作数如果都是整型的,结果也是整型的
result = a/b; //3
float f1 = 3.0f;
//result是一个int类型的数,如果给他赋值一个小数,那么此时只能保存小数的整数部分
result = a/f1; //3
2、算术运算符的结合性和优先级
1)结合性:左结合,从左到右。
2)优先级:乘法、除法和求余运算符是第3级,高于第4级的加法、减法运算符。
示例
result = ((a*b)/3)-(5*6)+30; // 结果为10
// a*b = 30
// 30/3 = 10
// 5*6=30
// (10-30)+30
// -20
// 10
3、求余运算符使用及注意
1)求余的规则
int m = 10,n = 3;
m%n m除以n之后,取得余数部分
10%3 == 1
m = 0 可以的,0
n = 0 不可以的,无意义
m > n 正常求余数就可以 1
m < n 结果 m
2)求余的注意事项
m和 n都不能为小数,必须是小数
m < 0 结果为负数
result = -3 % 10; // result = -3
n < 0 正负性取决于m,跟n无关
result = 3 % -10; // result = 3
4、算术运算中类型转换的问题
1)隐式类型转换,也称自动类型转换
自动转换发生在不同数据类型的量混合运算时,由编译系统自动完成。
若参与运算量的类型不同,则先转换成同一类型,然后进行计算。
转换按数据长度增加的方向进行,以保证精度不降低。
示例:
float f1 = 23.4f;
int num = 10;
printf("%d\n", f1 + num); //结果显示混乱,这是因为相加后的值不是整型
printf("%f\n", f1 + num); //输出结果为33.400000,这里进行了隐式类型转换
在赋值运算中,右侧表达式的值转换成左边变量的类型;如果右边量的数据类型长度比左边长,将丢失一部分数据,降低精度,丢失的部分按四舍五入向前舍入。
上面示例中的结果也可以这样转换成整型:
float f1 = 23.4f;
int num = 10;
int sum = f1 + num;
printf("%d\n", sum); //输出结果为33,这里进行了隐式类型转换
所有的浮点运算都是以double进行的,即使是只含float的表达式
必定会发生的转换:char,short --------> int; float -------->double
2)显示类型转换,也称强制类型转换
强制类型转换的格式: (要转换的类型)要转换的变量或者表达式;
示例1:
float f1 = 23.4f;
int num = 10;
printf("%d\n",(int)(f1+num)); //输出结果为33,这里进行了强制类型转换
示例2:
float f1 = 23.4f;
int num = 10;
int sum2 = (int)f1 + num;
printf("sum2 = %d\n", sum2)
3)注意事项
用一个大数加上一个特别小的数,如果使用float会有问题(造成数据丢失)
int num3 = 3455;
float f3 = 0.00003;
printf("%f\n",num3+f3); //期望得到3455.00003,但实际结果是3455.000000
强制类型转换是临时转换
printf("f1 d= %d\n",(int)f1); //23 此处是临时转换,不会改变原值
printf("f1 f= %f\n",f1); // 23.400000
三、赋值运算符
1、赋值运算符概述
1)赋值运算符记为“ = ”,由“ = ”连接的式子称为赋值表达式
2)赋值运算符作用:把符号右侧的值给等号左侧的变量
3)使用注意:等号的左侧必须是一个变量
2、赋值运算符的优先级
赋值运算符的等级很低,一般情况下都是最后运算
// = + -
// 7 - 3
// = -
// = 4
result = a+b-3;
printf("result = %d\n",result); //输出结果为4
3、赋值运算符的结合性
右结合:自右至左
int a1,b1,c1;
a1 = b1 = c1 = 10;
// 3 2 1
//(a1 = (b1 = (c1 = 10)));
printf("a1 = %d,b1 = %d,c1 = %d\n",a1,b1,c1); //输出结果为a1 = 10,b1 = 10,c1 = 10
四、复合赋值运算符
在赋值符” = “之前加上其它二目运算符可构成复合赋值运算符。
一次性作两件事情:先运算 再赋值
+= a+=3; ---> a = a + 3;
-= a-=3; ---> a = a - 3;
*=
/=
%=
五、自增自减运算符
1、概念:自增自减运算符++和--是为了简化”i = i + 1“”i = i - 1“这两种操作而设计,它们是单目运算符,从右向左结合的算术运算符。
2、++a和a++的区别
定义变量 int a =3 ;
1)++a(前缀表达式),求值:先让a的值+1,再取出a的值作为表达式的值
a的值: 4
++a表达式的值: 4
口诀:a 先变后用
int a = 3,result=0;
result = (++a); //a本身也要+1 a = 4
printf("result = %d,a = %d\n",result,a); //输出结果为result = 4, a = 4
2)a++(后缀表达式),求值:先取出a的值作为表达式的值,再让a的值+1
a的值: 4
a++表达式的值: 3
口诀:a 先用后变
int a = 3,result=0;
result = (a++); //a本身也要+1 a = 4
printf("result = %d,a = %d\n",result,a); //输出结果为result = 3, a = 4
3、注意:
1)不管是a++还是 ++a,最终执行完了了以后,a的值都会被+1
int a = 3;
(++a)+b+(a++) //a = 5
2) 自增自减运算只能用于单个变量,但不能用于表达式或常量:++5,++(a+3) 错误
4、典型问题分析
int a = 3, b = 5, result = 0;
result = a+++b++;
//即result = (a++)+(b++)
printf("a = %d,b = %d;result = %d",a,b,result); //输出结果是a = 4,b = 6,result = 8
result = a+++++b;
//即result = (a++)+(++b);
printf("a = %d,b = %d;result = %d",a,b,result); //输出结果是a = 4,b = 6,result = 9</span>
六、sizeof运算符
1、概念:
sizeof运算符是一个单目运算符,作用是计算常量、变量、数据类型在内存中占用的字节数
2、使用
1)用sizeof计算常量在内存中占用的字节数
int result = 0;
result = sizeof(1); //计算常量 1 在内存中占用的字节数 4
// 1 默认的事一个10进制的整数(int) 4
result = sizeof(2.3f); //计算 float类型的常量在内存中占用的字节数 4
result = sizeof(2.3); //计算 double 类型的常量在内存中占用的字节数 8
//char 占用1个字节,-128~127
//char 类型的常量存储,97以int类型的数据进行存储
//char 类型的变量以把字符串的ascii码转换为二进制(1给字节)进行存储
result = sizeof('a'); //计算 'a' 字符常量 在内存中占用的字节数 4
2)用sizeof运算符计算变量在内存中占用的字节数
int a = 10;
float f1 = 2.3f;
double d1 = 2.3;
char ch = 'a';
result = sizeof(a); //计算int类型变量a在内存中占用的字节数 //4
result = sizeof(f1); //计算float类型的变量 f1 占用的字节数 //4
result = sizeof(d1); //计算double类型的变量 d1 占用的字节数//8
result = sizeof(ch); //计算char类型的变量 ch 占用的字节数 //1
//注意点:sizeof用在常量和变量的时候,是可以省略括号
result = sizeof 2.3;
result = sizeof d1;
3)sizeof用于计算某一种数据类型在内存中占用的字节数
result = sizeof(int); //表示int类型的数据在内存中占用的字节数 4
result = sizeof(float); //表示float类型的数据在内存中占用的字节数4
result = sizeof(double); //表示double类型的数据在内存中占用的字节数8
result = sizeof(char); //表示char类型的数据在内存中占用的字节数1
//result = sizeof int ; sizeof用在数据类型的时候,不能省略括号
七、逗号运算符
1、基本概念
在C语言中逗号” , “也是一种运算符,称为逗号运算符。其功能是把两个表达式连接起来组成一个表达式,称为逗号表达式。
逗号表达式的一般形式:表达式1,表达式2
2、求值过程
逗号表达式的求值过程:先逐个求表达式的值就,然后把最后一个表达式的值返回(作为整个逗号表达式的值)。
int a = 4,b = 5,result=0;
//a+4,b+3,a+b 用逗号连接的表达式是一个逗号表达式
// 8 , 8 , 9
result = (a+4,b+3,a+b,1+2,10);
printf("result = %d\n",result); //输出结果是result = 9
3、使用注意
1)逗号运算符可以嵌套使用,如(a++,(a+3,b+5,z=a+b))
2)有时候,不太注重逗号表达式的值,因此简化了代码
3)并不是所有出现逗号的地方都能组成逗号表达式,比如定义多个变量的时候
八、关系运算符
1、C语言中的真假性
在C语言中所有数值都有真假性,非零即真,只有0为假
关系运算符返回值只有两个,要么是真(1),要么是假(0)
2、关系运算符概述
在程序中经常需要比较两个量的大小关系,以决定程序下一步的工作。
比较两个量的运算符称为关系运算符,也称为比较运算符。
关系表达式:用关系运算符连接的式子。
关系表达式的值只有两种:1)真(1)2)假(0)
3、关系运算符的使用
1)使用示例:
int a = 3,b = 2,result = -1;
//把a>b的值赋值给result
// 3 2
result = a > b; //1
result = a < b; //0
// 判断 a 是不是大于或者等于 3
result = a >= 3; //1
result = a <= 3; //1
result = a == 3; //1
result = a == b; //0
result = a != b; //1
2)关系运算符的结合性
关系运算符都是双目运算符,其结合性均为左结合。而且,只有在优先级相同的情况下,才谈结合性。
int a = 3,b = 4,result = -1;
//结果
// 0 < 3
result = a>b<3;// 1 result = a>b<3;// 0
3)关系运算符的优先级
int a = 3, b = 2, result = -1;
result = 1==(b>3); // 0
result = 1>a+b<100; // 1
九、逻辑运算符
1、概念
&& 逻辑与(表示多个条件同时成立 “并且” “且” “同时”)
|| 逻辑或 (当有多个条件,只要有一个成立的就可以, “或者”)
! 逻辑非 (取反)
2、使用
1)与运算(&&)
参与运算的两个量都为真时,结果才为假,即:一假则假
int a = 3,b = 4,result = -1;
//a<3和b<3他们都为真, &&的结果才为真
// 1 && 1
result = a<3 && b<3; // 0
result = a<=3 && b>3; // 1
result = a<3 && b>3; // 0
2)或运算(||)
参与运算的两个量只要有一个为真,结果就是真。两个量都为假时,结果为假。即:一真则真
int a = 3,b = 4,result = -1;
// 0 || 1
result = a>3 || b<5; // 1
3)非运算(!)
参与运算量为真时,结果为假;参与运算量为假时,结果为真。即:真变假,假变真
int a = 3,b = 4,result = -1;
// 0 > 3
result = !a>3; // 0
result = !!!a; // 0
3、结合性和优先性
1)结合性
与运算和或运算都是双目运算,具有左结合性
非运算为单目运算,具有右结合性
int a = 3,b = 4,result = 0;
// 1 && 1 && 1
result = a && b && 5; //1
2)优先级
逻辑运算符和其它运算符优先级的关系表示如下:
int a = 3,b = 4,result = 0;
// 0 || 0 || 1
// 0 || 1
result = !a || !b || a; //1
// 1 || 0 && 0
// 1 || (0 && 0)
result = a>2 || b<4 && a>5; // 1
4、短路问题
示例:
int x,y,z;
x = y = z =0;
// ++x || (++y && z++) x = 1,y=1,z=1;
// 1 || 1 && 1
result = ++x || ++y && z++;
// result ? x,y,z
printf("result = %d\n",result); // 输出结果为result = 1
printf("x = %d,y = %d,z = %d\n",x,y,z); // 输出结果为x = 1, y = 0, z = 0,而没有像上面分析得那样,因为这里存在短路问题
1)与运算&& 口诀:一假为假
A && B
如果 A为假(0)结果为假 ,B就不执行了,这就是逻辑与短路
2)或运算|| 口诀:一真为真
A || B
如果 A为真(1)结果为真,B就不执行了,这就是逻辑或的短路
int x,y,z,result=-1;
int a=3,b=4;
x = y = z =0;
// ++x || (++y && z++) x = 1,y=1,z=1;
// 1 || 1 && 1
//实际: 逻辑或短路了
//result = (++x) || ((++y) && (z++));
// result ? x,y,z
//实际: 逻辑与短路了
result = x && y++; //result 0 x = 0 y=0
//result = a<2 && b==4 || a<5; //0
十、三目运算符
1、概念
三目运算符,也称条件运算符,为?和:,它是一个三目运算符,即有三个操作数参与运算的量。
由条件运算符组成条件表达式的一般形式:表达式1?表达式2:表达式3;
2、求值规则
表达式1的值为真时,把表达式2的值作为整个三目运算表达式的值返回;表达式1的值为假时,把表达式3的值作为整个三目运算表达式的值返回。
条件表达式通常用于赋值语句之中。
int a = 3,b = 4 ,result = 0;
// 1
result = a>b?10:100; //把10作为整个条件表达式的值
3、注意事项
1)条件运算符的运算优先级低于关系运算符和算术运算符,但高于赋值符号。
2)条件运算符?和:是一对运算符,不能分开单独使用。
3)条件运算符的结合方向是自右至左。
4、应用实例
思考实现:用户从键盘上输入三个整数,找出最大值,然后输入最大值
//1、定义变量 num1,num2,num3,max
int num1,num2,num3,max=0;
num1 = num2 = num3 = 0;
//2、提示用户输入三个数,以,分隔
printf("请输入三个数,并且以逗号分隔:\n");
//3、接收这三个数,保存到 num1,num2,num3中
scanf("%d,%d,%d",&num1,&num2,&num3);
//4、先比较 num1 和 num2,比较的结果存放到max
max = num1 > num2 ? num1 :num2;
//5、max和第三个数比较
max = max > num3 ? max : num3;
printf("max = %d\n",max);