运算符划分

  • 按照功能划分:

    • 算术运算符
    • 关系运算符
    • 逻辑运算符
    • 按位运算符
  • 按照参与运算的操作个数进行划分

    • 单目运算符

      • 只有一个操作数 如:i++
    • 双目运算符

      • 有两个操作数 如:a+b
    • 三目运算符

      • 有三个操作数 如:a > b ? 1:0 如果a>b时,a = 1,如果a<b时,a = 0

运算符的优先级表

  • 运算符的优先级分为15级别,1级最高,15级最低

  • 在表达式中优先级高的优先于优先级低的先运算

  • 在一个运算量两侧的,优先级一样时按照运算符的结合性所规定的方向进行运算

    优先级 运算符 名称或含义 使用形式 结合方向 说明
    1 [] 数组下标 数组名[常量表达式] 左到右
    () 圆括号 (表达式)/函数名(形参表)
    . 成员选择(对象) 对象.成员名
    -> 成员选择(指针) 对象指针->成员名
    2 - 负号运算符 -表达式 右到左 单目运算符
    (类型) 强制类型转换 (数据类型)表达式
    ++ 自增运算符 ++变量名/变量名++ 单目运算符
    -- 自减运算符 --变量名/变量名-- 单目运算符
    * 取值运算符 *指针变量 单目运算符
    & 取地址运算符 &变量名 单目运算符
    ! 逻辑非运算符 !表达式 单目运算符
    ~ 按位取反运算符 ~表达式 单目运算符
    sizeof 长度运算符 sizeof(表达式)
    3 / 表达式/表达式 左到右 双目运算符
    * 表达式*表达式 双目运算符
    % 余数(取模) 整型表达式/整型表达式 双目运算符
    4 + 表达式+表达式 左到右 双目运算符
    - 表达式-表达式 双目运算符
    5 << 左移 变量<<表达式 左到右 双目运算符
    >> 右移 变量>>表达式 双目运算符
    6 > 大于 表达式>表达式 左到右 双目运算符
    >= 大于等于 表达式>=表达式 双目运算符
    < 小于 表达式<表达式 双目运算符
    <= 小于等于 表达式<=表达式 双目运算符
    7 == 等于 表达式==表达式 左到右 双目运算符
    != 不等于 表达式!= 表达式 双目运算符
    8 & 按位与 表达式&表达式 左到右 双目运算符
    9 ^ 按位异或 表达式^表达式 左到右 双目运算符
    10 | 按位或 表达式|表达式 左到右 双目运算符
    11 && 逻辑与 表达式&&表达式 左到右 双目运算符
    12 || 逻辑或 表达式||表达式 左到右 双目运算符
    13 ?: 条件运算符 表达式1? 表达式2: 表达式3 右到左 三目运算符
    14 = 赋值运算符 变量=表达式 右到左
    /= 除后赋值 变量/=表达式
    *= 乘后赋值 变量*=表达式
    %= 取模后赋值 变量%=表达式
    += 加后赋值 变量+=表达式
    -= 减后赋值 变量-=表达式
    <<= 左移后赋值 变量<<=表达式
    >>= 右移后赋值 变量>>=表达式
    &= 按位与后赋值 变量&=表达式
    ^= 按位异或后赋值 变量^=表达式
    |= 按位或后赋值 变量|=表达式
    15 , 逗号运算符 表达式,表达式,… 左到右 从左向右顺序运算
  • 虽然说运算符有很多,但是不用记住,使用小括号()扩起来就好了

结合性简单介绍

  • c语言中有两种结合性,一种是左结合型,一种是右结合性
  • 左结合性--自左至右运算,右结合性--自右至左运算
  • 左结合性 例如:x + y -z,先计算x+y,计算后的结果再减z
  • 右结合性 例如:x = y = z, 将z的值赋值给y,再将y的值赋值给x

算数运算符表

运算符 术语 示例 结果
+ 正号 +3 3
- 负号 -3 -3
+ 10 + 5 15
- 10 - 5 5
* 10 * 5 50
/ 10 / 5 2
% 取模(取余) 10 % 3 1
++ 前自增 a=2; b=++a; a=3; b=3;
++ 后自增 a=2; b=a++; a=3; b=2;
-- 前自减 a=2; b=--a; a=1; b=1;
-- 后自减 a=2; b=a--; a=1; b=2;
#include <stdio.h>

int main(int argc, const char * argv[]) {
    /*
     +  加法
     -  减法
     *  乘法
     /  除法
     %  取模(取余)
     */
    int result;
    result = 1 + 1;
    printf("加法结果:result = %i\n",result);
    result = 1 - 1;
    printf("减法结果:result = %i\n",result);
    result = 2 * 3;
    printf("乘法结果:result = %i\n",result);
    result = 10 / 2;
    printf("除法结果:result = %i\n",result); // result = 5
    result = 10 % 3;
    printf("取模结果:result = %i\n",result); // result = 1
  
    return 0;
}


取模运算符的注意点

  • 注意:取模运算只能对整数取模,不能对实数取模
    // 注意取模运算只能是整数取模不能是实数取模
    // result = 10.5 % 3; // 直接报错
  • 注意:取模运算的正负性,取决于左边的操作数
    // 取模运算的正负性,取决于左边的操作数
    result = 10 % -3;
    printf("取模正负性结果:result = %i\n",result); // result = 1
    result = -10 % -3;
    printf("取模正负性结果:result = %i\n",result); // result = -1
    result = -10 % 3;
    printf("取模正负性结果:result = %i\n",result); // result = -1
    result = -0 % -3;
    printf("取模正负性结果:result = %i\n",result); // result = 0
  • 注意:如果取模运算中,左边操作数小于右边操作数,那结果直接就是左边操作数,不会进行计算了
    // 如果取模运算中,左边操作数小于右边操作数,那结果直接就是左边操作数,不会进行计算了
    result = 10 % 100;
    printf("取模结果:result = %i\n",result); // result = 10

算术运算符的结合性

    // 算术运算符的结合性
    result = 3 + 4 + 5 + 6;
    printf("result的值是%i",result);

算术运算符的优先级和结合性同时存在时

  • 先优先级,再按照结合性
    // 优先级+结合性
    result = 2 + 3 * 4 -4;
    printf("result的值是%i\n",result); // 先计算乘法,再从左至右的结合性计算

类型转换

  • 隐式转换
    // 系统自动进行的转换
	int number = 10.8;
    printf("number的值是%i\n",number); // number = 10,
    // 大类型的转换成小类型的,系统会自动进行转换,由大类型转换为小类型,丢失精度
  • 显式转换
    // 显式转换-只需要在值前面加(类型)
    int value = (int)10.8;
    printf("value的值是%i\n",value); // 10;
    // 大类型的转换成小类型的,系统会自动进行转换,由大类型转换为小类型,丢失精度
  • 在算术运算中,类型不一致时,系统会先将类型统一,统一成大类型进行计算
    // 在算术运算中,类型不一致时,系统会先将类型统一,统一成大类型进行计算
    int value2 = 10 + 9.9;
    // 10是int类型,9.9是double类型,int类型占4个字节,9.9占8个字节,所以先将int转为double类型
    // int value2 = 10.0 + 9.9
    // int value2 = 19.9
    // value2 是一个int类型,但是右边的19.9是double类型,这时候系统会做隐式转换,大类型转为小类型,既结果为19
    printf("value2的值是%i\n",value2); // 19;
  • 算术运算符的注意点-参与运算的操作数是什么类型,那么计算出来的结果就是什么类型
    // 算术运算符的注意点-参与运算的操作数是什么类型,那么计算出来的结果就是什么类型
	int value3 = 1 / 2;
	printf("value3的值是%i\n",value3); // 打印出来的是0
    // 此时你会不会觉得是因为定义的变量是int类型导致的呢?那我就换成double类型的看看
    double value3 = 1 / 2;
    printf("value3的值是%lf\n",value3); // 打印出来的是0.000000 此时还是0
    // 是因为右侧参与运算的都是整数,那么计算的结果肯定是整数


	 // 那么如果需要打印出0.5该怎么办呢?
    double value4 = 1.0 / 2; // 此时一个double除以int类型,肯定是都先转换为doublee类型,计算出的结果就是double类型,i定义的变量也是double类型不需要转换所以打印出的是0.500000
    printf("value4的值是%.1lf\n",value4);
    
    int value5 = 1.0 / 2;
    printf("value5的值是%i\n",value5); // 0
    
  • 新手注意常犯的错误
    // 新手注意饭的错误
    double value6 = (double)(1 / 2);
    // 右边先计算括号中的1 / 2,那么两个整数相除,结果肯定是整数,所以是0 ,由强转为double类型,为0.000000
    printf("value6的值是%lf",value6); // 0.000000
  • 在算术运算符中,实数的计算都是double类型,不是float类型

赋值运算符

  • 最简单的赋值运算符,将等号右边的值赋值给等号左边的变量
    • 赋值运算符的结合性是右结合性
int main(int argc, const char * argv[]) {
    // 最简单的赋值运算符,将等号右边的值赋值给等号左边的变量
    // 赋值运算符的结合性是右结合性
    int number = 10;
    int a;
    int b;
    a = b = 5;
    printf("a的值是%i,b的值是%i\n",a,b);
    return 0;
}
  • 符合赋值运算符
    • 定义:在赋值符“=”加上其他的二目运算符可构成复合赋值运算符

赋值运算符的作用是将常量、变量或表达式的值赋给某一个变量。

运算符 术语 示例 结果
= 赋值 a=2; b=3; a=2; b=3;
+= 加等于 a=0; a+=2; a = a + 2 a=2;
-= 减等于 a=5; a-=3; a = a - 3 a=2;
*= 乘等于 a=2; a*=2; a = a * 2 a=4;
/= 除等于 a=4; a/=2; a = a / 2 a=2;
%= 模等于 a=3; a%2; a = a % 2 a=1;
    int a = 0;
    a += 3; // 这种是直接进行赋值,运算效率要好
    a = a +3; // 这一种是不是先计算再赋值给a
    printf("a的结果是%i\n",a);
// 复合赋值运算,会先进行右边的表达式得到的值在赋值给左边的变量

自增,自减运算符

  • 自增自减的第一种写法: 变量++,变量--
    int result = 10;
    result++;
    result++;
    printf("变量++,自增后的result值为:%i\n",result); // 12
    // 如果想让某一个数减1,可以使用变量--,--变量
    int value = 5;
    value--;
    printf("变量--,自增后的value值为:%i\n",value); // 4
  • 自增自减的第二种写法: --变量,++变量
    // 第二种写法:++变量,--变量
    int result1 = 10;
    ++result1;
    printf("++变量,自增后的result1值为:%i\n",result1); // 11
    
    int result2 = 5;
    --result2;
    printf("++变量,自增后的result1值为:%i\n",result2); // 4
  • ​ ++,-- 在变量前面和++,-- 在变量后面的区别(在变量之前先运算再自增,在变量之后先自增再运算)
    // ++,-- 在变量前面和++,-- 在变量后面的区别
    // ++ , -- 在后面时,先参与运算然后再自增
    int a = 10;
    int b = a++;
    printf("a的值是%i,b的值是%i\n",a,b);// a的值是11,b的值是10 注意看b的值是10,而不是11,这里是a先赋值给b,然后再自增的
    
    // ++ --在变量之前时,是先自增再赋值
    int c = 10;
    int d = ++c;
    printf("c的值是%i,d的值是%i\n",c,d); // c的值是11,d的值是11 注意看这里d的值同样是11,所以c是先自增再赋值给d
    
  • 自增,自减练习
    // 练习
    /*
    int a = 10;
    int b = (a++) + (++a);
    //  b = a++ ,此时a++的结果是11, 后面++a在a=11的基础上再自增,那么a的值就是12了,10+12
    //  a =12
    printf("b的值是%i,a的值是%i\n",b,a);
    */
    /*
    int a = 10;
    int b = (a++) + (a++);
    printf("b的值是%i,a的值是%i\n",b,a); // b = 10 + 11 , a = 12
    */
    /*
    int a = 10;
    int b = (++a) + (++a);
    printf("b的值是%i,a的值是%i\n",b,a); // b = 11 + 12 ,a = 12
    */
    /*
    int a = 10;
    int b = (++a) + (a++);
    printf("b的值是%i,a的值是%i\n",b,a); // b = 11 + 11, a = 12
    */
    int a = 10;
    int b = (a++) + (a--);
    printf("b的值是%i,a的值是%i\n",b,a); // b = 10 + 11 , a = 10
  • 自增的拆分
    // 自增的拆分
    int a = 10;
    int b = a++;
    // 拆分:
    // 1, int b = a;
    // 2, int a = a+1;
    printf("b的值是%i,a的值是%i\n",b,a); // b = 10,a = 11
    
    int c = 10;
    int d = ++c;
    // 拆分
    // 1,int c = c + 1;
    // 2,int d = c;
    printf("d的值是%i,c的值是%i\n",d,c);
    // 拆分之后,只是两个表达式的顺序反了. 如果有时确实难懂的话不妨拆分一下

sizeof运算符

  • 介绍:sizeof运算符可以用来计算一个变量或一个常量,一种数据类型所占的内存节数

  • 格式:sizeof(变量/常量/数据类型)

  • 注意:sizeof 不是一个函数而是一个运算符(只要是运算符就会有一个返回值)

  • 计算常量的内存字节

    // 使用 sizeof 计算常量的内存字节
    int number = sizeof(10.9);
    printf("10.9的e内存字节是%i\n",number); // 8
  • 计算变量的内存字节
    int a = 10;
    // int number = sizeof(a); // 只要是运算符就会有返回值
    int number = sizeof a; // 不加s括号e也可以
    printf("a的内存字节是%i\n",number);
  • 计算数据类型的内存字节(sizeof的括号不能省略)
    // 使用 sizeof 计算数据类型的内存字节
    int numChar = sizeof(char);
    printf("char 数据类型占用%i个字节\n",numChar); // 1
    int numInt = sizeof(int);
    printf("int 数据类型占用%i个字节\n",numInt); // 4
    int numDouble = sizeof(double);
    printf("double 数据类型占用%i个字节\n",numDouble); // 8
    int numFloat = sizeof(float);
    printf("float 数据类型占用%i个字节\n",numFloat); // 8

逗号运算符

  • 在 C 语言中逗号也是一个运算符,称之为逗号运算符,其功能是把多个表达式连接起来组成一个表达式,成为逗号表达式

  • 格式: 表达式 1,表达式 2,表达式....表达式 n;

  • 例如:a = a + 1,b = 3*4;

  • 结合性:从左到右结合性

    // 逗号运算符,从左到右依次计算表达式的结果,只要是运算符就会有结果,逗号运算符也不例外
    int a = 10;
    int b = 5;
    int result;
    a = a + 10,b = b - 1,result = a + b;
    printf("a的值是%i,b的值是%i,result 的值是%i\n",a,b,result);
  • 逗号表达式的结果是最后一个表达式的结果
// 定一个一个变量 number 来接收逗号表达式的结果,每个表达式用括号括起来,整体再括起来,逗号表达式的结果是最后一个逗号表达式的结果
    int number =  ((a = a + 10),(b = b - 1),(result = a + b));
    printf("a 的值是%i,b 的值是%i,result 的值是%i,number 的值是%i\n",a,b,result,number);

关系运算符

  • 在 c 语言中条件成立为真,条件不成立为假,判断条件是否成立就是判断条件的真假
  • 怎么判断条件的真假呢? C 语言中规定任何数值都有自己的真假性,任何非 0 的都为真,也就是说 100,-50,2.3这些都是真,只有 0 是假的
  • 关系运算符的结果只有两个结果,真和假

C 语言的比较运算中, “真”用数字“1”来表示, “假”用数字“0”来表示。

运算符 术语 示例 结果
== 相等于 4 == 3 0
!= 不等于 4 != 3 1
< 小于 4 < 3 0
> 大于 4 > 3 1
<= 小于等于 4 <= 3 0
>= 大于等于 4 >= 1 1
  • 关系运算符的返回值要么真要么假
    // > , < , >= , <= , == , !=
    int a = 10;
    int b = 5; // 怎么知道 a>b 呢? 任何的运算符都有结果
    int c = 20;
    int result = a > b;
    int result1 = a > c;
    printf("result的值是%i\n",result); // 1
    printf("result1的值是%i\n",result1); // 0
  • 关系运算符的优先级: > < >= <=的优先级大于 == , !=
    // 关系运算符的优先级: > < >= <=的优先级大于 == , !=
    int a = 10;
    int b = 5;
    int result = 1 == a > b; // 先计算 a 是否大于 b,再拿这个结果与 1 是否相等,
    printf("result 的值是%i",result); // 1
  • 算术运算符的优先级大于关系运算符(比较运算符)
    // 算术运算符的优先级大于关系运算符
    int result = 1 + 1 > 2+2;
    printf("result 的值是%i\n",result);  // 0,先计算 1+1,在计算 2+2,再拿 2>4?
  • 关系运算符的结合性是左结合性
    // 关系运算符的结合性是左结合性
    int result = 10 > 5 > 20;
    printf("result 的值是%i\n",result); // 0,先计算 10>5,再拿这个值与 20做比较
  • 如果优先级和结合性同时存在,那就先优先级,再结合性
    // 如果优先级和结合性同时存在,那就先优先级,再结合性
    int result = 10 + 1 > 5 + 4 == 3 > 1;
    // 先计算 10+1,再计算 5+4,这两个算术运算符,得出 11 > 9 == 3>1
    // 再计算 11 > 9 ,和 3 > 1 这两个优先级比较高的比较运算符表达式,
    // 最后计算 1 == 1 等于的表达式
    printf("result 的值是%i\n",result); // 11 > 9 == 3 > 1 ---> 1 == 1 ---> 1
  • 开发中没有人会按照上面那么写的
    int result1 = (10+1) > (5+4) == (3>1);
    printf("result1 的值是%i\n",result1); // h实际开发中为了阅读,还是加上括号

逻辑运算符

  • 有时候我们需要满足多个条件同时成立才能执行代码,比如登录:需要输入正确的用户名,和正确的密码,才能登录.所以c 语言提供了逻辑运算符

  • C 语言中提供了三个逻辑运算符

    • && 逻辑与 表达式 1 && 表达式 2
    • || 逻辑非 表达式 1 || 表达式 2
    • ! 逻辑非 ! 表达式 2
  • 逻辑运算符的运算结果只有两个真和假

  • 逻辑与:只有表达式都为真,结果才是真,其余都是假

    • 结合性:从左至右
    // 逻辑与(一假则假)
    int result = 10 > 7 && 5 > 3; // 10>7为真,5>3 为真
    printf("result = %i\n",result); // 1
    int result1 = 10 > 90 && 8 >1; // 10 > 90为假
    printf("result1 = %i\n",result1); // 0
  • 逻辑或:只要有一个表达式为真,结果就是真,如果表达式都是假,结果才是假
    • 结合性:从左至右
    // 逻辑或 (一真则真)
    int result = 10 > 8 || 9 > 7;
    printf("result = %i\n",result); // 都为真--真
    
    int result1 = 10 > 8 || 9 > 10;
    printf("result1 = %i\n",result1); // 一个为真--真
    
    int result2 = 10 > 11 || 9 > 10;
    printf("result2 = %i\n",result2); // 都为假--假
    
    int result3 = 10 > 11 || 9 > 8;  // 一个为真--真
    printf("result3 = %i\n",result3);
  • 逻辑非(如果表达式为真,则为假,如果表达式为假,则为真)---取反
    • 结合性:从右至左
    // 逻辑非
    int result = ! 10; // 0
    int result1 = ! 0; // 1
    printf("result = %i\n",result);
    printf("result1 = %i\n",result1);
  • 注意点;C 语言规定,任何数值都有真假性,非 0 既真,所有的逻辑运算符可以直接约数值进行计算
  • 逻辑与的特点是一假则假,所以如果前面的表达式是假的话,那么后面的表达式就不会计算了
    int a = 10;
    int result = 10 < 8 && a++ > 5; // a = 10,result = 0
    // 由于 10 < 8 为假,所以后面的表达式就不会计算了,a++ 后,a 的值就没有自增
    int b = 20;
    int result1 = 10 > 8 && b++ >5; // 10 > 8 为真,后面的表达式继续计算,所以 b 的值是 21
    printf("a = %i,result = %i\n",a,result);
    printf("b = %i,result1 = %i\n",b,result1);
  • 逻辑或的特点是一真则真,所以如果前面的表达式是真的话,那么后面的表达式就不会计算了
    int a = 10;
    int result = 10 > 8 || a++ > 5; // a = 10,result = 0
    // 由于 10 > 8 为真,所以后面的表达式就不会计算了,a++ 后,a 的值就没有自增
    int b = 20;
    int result1 = 10 < 8 || b++ >5; // 10 < 8 为假,后面的表达式继续计算,所以 b 的值是 21
    printf("a = %i,result = %i\n",a,result);
    printf("b = %i,result1 = %i\n",b,result1);
  • 以上两个逻辑运算符的特点称之为:逻辑运算符的短路

  • 判断一个数值是否在一个范围内

    int a = 10;
    if (a > 3 && a < 100){
        printf("a在 3-100 之间");
    } else{
        printf("a 不在 3-100 之间");
    }

三目运算符

  • 格式: 条件表达式 ? 结果 A: 结果 B

    • 如果表达式为真,返回结果 A,如果表达式为假,返回结果 B
  • 结合性:左结合性

    // 三目运算符
    int a = 10;
    int b = 20;
    int result = a > b;
    printf("result = %i\n",result);
    // 如果我想获取两个数之间的最大数呢?
    if (a>b){
        printf("a 和 b 之间最大数是%i\n",a);
    }else{
        printf("a 和 b 之间最大数是%i\n",b);
    }
    // 可是上面的办法太麻烦了,x要写这么多行代码
    int maxNum = a > b ? a:b; // 这句话的意思是,如果a> b,那就返回 a,如果 a 不大于 b 的话,那就返回 b
    printf("a 和 b 之间最大数是%i\n",maxNum);
  • 三目运算符练习
    // 从控制台输入三个整数,返回最大的整数
    printf("请输入三个整数以逗号隔开,回车结束\n");
    int num1,num2,num3;
    scanf("%i,%i,%i",&num1,&num2,&num3);
    int temp = num1 > num2 ? num1 : num2; // 比较 num1 和num2 中的最大值
    int maxNum = temp > num3 ? temp : num3; // 拿到 num1 和 num2 的最大值再与 num3 做比较,返回最大值
    printf("num1,num2,num3 之间的最大值是:%i\n",maxNum);
    
    int maxNum1 = (num1 > num2 ? num1 : num2) > num3 ? (num1 > num2 ? num1 : num2) : num3;
    // 不推荐这种写法是因为,问号之前计算了一次num1 和num2 的最大值,问号表达式之后又计算了一次,无疑消耗了性能
    printf("num1,num2,num3 之间的最大值是:%i\n",maxNum1);

哎呀妈呀,运算符终于写完了!

posted on 2020-05-16 16:49  python我学的很菜  阅读(829)  评论(1编辑  收藏  举报