[置顶] 黑马程序员——C语言中的运算符

时间:2022-09-20 00:24:43

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

一、运算符概述

1、运算符的基本概念

运算符是告诉编译程序执行特定算术或逻辑操作的符号,用来连接操作数。

[置顶]        黑马程序员——C语言中的运算符

2、运算符的分类

1)按照功能划分:

  • 算术运算符
  • 关系运算符
  • 逻辑运算符
  • 按位运算符
2)根据参与运算的操作数的个数划分:
  • 单目运算符:只有一个操作数,如i++,i,sizeof
  • 双目运算符:有两个操作数,如a+b
  • 三目运算符:C语言中唯一的一个,也称为问号表达式 a > b ? 1 : 0
3、运算符的优先级与结合性

在一个运算表达式中往往含有多个运算符,为了清晰地知道运算的顺序,我们必须根据运算符的优先级和结合性。

1)C语言中,运算符的优先级共分为15级。1级最高,15级最低。在表达式中,优先级较高的先于优先级较低的进行运算。

2)而在一个运算量两侧的运算符优先级相同时,则按照运算符的结合性所规定的结合方向处理。C语言中各运算符的结合性分为两种,即自左至右的左结合性和自右至左的右结合性。

4、表达式概述

1)概念:将同类型的数据,用运算符按照一定的规则连接起来的、有意义的式子称为表达式。

2)表达式的特点:表达式是一个有意义的式子,所以一定有返回值。

3)表达式可以是常量也可以是变量或算式,在表达式中可分为:算术表达式、逻辑表达式和字符串表达式。

4)表达式语句:表达式后面加上分号,构成表达式语句。

二、算术运算符

1、算术运算符的介绍及基本使用

1)算术运算符有五种,详细介绍如下表所示

[置顶]        黑马程序员——C语言中的运算符

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;

3sizeof用于计算某一种数据类型在内存中占用的字节数

    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、关系运算符概述

在程序中经常需要比较两个量的大小关系,以决定程序下一步的工作。

比较两个量的运算符称为关系运算符,也称为比较运算符。

[置顶]        黑马程序员——C语言中的运算符

关系表达式:用关系运算符连接的式子。

关系表达式的值只有两种: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)优先级

逻辑运算符和其它运算符优先级的关系表示如下:

[置顶]        黑马程序员——C语言中的运算符

    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);