C语言|C语言——运算符

运算符 一、算术运算符

  1. 加法运算符
    把两个操作数相加
    int c = 21+10; //c = 31

  2. 减法运算符
    第一个操作数减去第二个操作数
    int a = 21-10; //a = 11

  3. * 乘法运算符
    把两个操作数相乘
    int b = 21*10; //b = 210

  4. / 除法运算符
    把两个操作数相除
    / 操作数均为整数,结果为取商并取整
    int d = 16/5; //d = 3

    / 操作数中有一或两个浮点数,结果为取商
    double e = 16/5; //e = 3.200000

  5. % 取模运算符
    整除后的余数操作数都必须为整数,结果取余
    注意:“余数”符号和左边操作数相同
    int b = 7%3; //b = 1 int c = -7%3; //c = -1 int e = 7%-3; //e = 1

  6. ++自增运算符
    • 前缀++a
      i = 5;++i; //i = 6; ++i = 6;

    • 后缀a++
      i = 5; i++; //i = 6; i++ = 5; `

      int a = ++i;
      int b = i++;
      前缀——先自增后赋值,后缀——先赋值后自增
  7. —-自减运算符
    • 前缀—a
      i = 5;—i; //i=4; —i=4;

    • 后缀a—
      i = 5; i—; //i=4; i—=5; `

      int a = --i;
      int b = i–;
      前缀——先自减后赋值,后缀——先赋值后自减
二、关系运算符
关系运算符的结果是逻辑值(真or假)
  1. == 等于
    判断两个操作数是否相等,如果相等,条件表达式为真,不相等则为假。
    例:
    5 == 3; 假
    5 == 5; 真
  2. != 不等于
    判断两个操作数是否不相等,如果不相等,条件表达式为真,相等则为假。
  3. > 大于
    左操作数是否大于右操作数,如果是,条件表达式为真
  4. < 小于
    左操作数是否小于右操作数,如果是,条件表达式为真
  5. >= 大于等于
    左操作数是否大于等于右操作数,如果是,条件表达式为真
  6. <= 小于等于
    左操作数是否小于等于右操作数,如果是,条件表达式为真
三、逻辑运算符
逻辑运算符的操作数只能由逻辑值来充当
0 ——表示逻辑假; 1 (非0值) ——表示逻辑真
  1. && 逻辑与
    如果两个操作数都非零,则结果为真
    短路原则:当&&左边的操作数是假,则右边表达式就不需要进行判断,运算结果为假
    int a = (12==8 && 4/2==2); //a = 0

  2. || 逻辑或
    两个操作数都为0,结果为假
    短路原则:当||左边的操作数是真,则右边表达式就不需要进行判断,运算结果为真
    int x = 1,y = 1; int t = ++x || ++y; /* 结果是t = 1, x = 2, y = 1 因为++x为真,表达式 ++x || ++y 的结果为真,不用计算++y */

  3. 逻辑非
    逆转操作数状态,使真变为假,假变为真。
    a=1; //!a为假

四、位运算符
(计算机先将输入的十进制数,转换成二进制补码,再进行位运算,然后将二进制结果转换成十进制)
在计算机中操作的是补码
作用于位,逐位进行操作()
以3,5与运算为例演示逐位运算:
C语言|C语言——运算符
文章图片

真值表:
C语言|C语言——运算符
文章图片

例:a = 60; b = 13;
二进制补码: a = 00111100; b = 00001101;
正整数的补码与原码相同,负整数的补码是将原码除符号位外的所有位取反后加1
······································································································································
  1. & 与运算符
    按”位与“操作,按二进制位进行”与“运算。
    都1才1 1&1 = 1
    a&b = 00001100

  2. | 或运算符
    按”位或“操作,按二进制位进行”或“运算。
    都0才0 0|0 = 0
    a|b = 00111101

  3. ^异或运算符
    按二进制位进行”异或“运算。
    相同为0,不同为1
    1^0=1; 1^1=0; 0^0=0
    a^b = 00110001

  4. ~ 取反运算符
    按二进制位进行”取反“运算。
    按位取反:二进制每一位取反,0变1,1变0。
    对所有整数取反=本身的相反数-1
    计算步骤:(~b为例)二进制数在内存中以补码的形式存储。
    转二进制:00001101
    计算补码:00001101
    按位取反:11110010
    转为原码:10001110(负整数反码转原码,将反码减1后除符号位外的所有位取反)
    符号位为1是负数,即-14
  5. << 二进制左移运算符
    将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。
    a<<2 00111100 → 11110000

  6. >> 二进制右移运算符
    将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。
    a>>2 00111100 → 00001111

五、赋值运算符
给变量赋值
基本赋值运算符
= 把右边操作数的值赋给左边操作数(符号=的左边该是一个可修改的变量名,而右边是赋给该变量的值。)
int a = 12;

复合赋值运算符
+= 加且赋值运算符
把右边操作数加上左边操作数的结果赋值给左边操作数
a += 12; //→ a = a+12;

-= 减且赋值运算符
把左边操作数减去右边操作数的结果赋值给左边操作数
a-=12; //→ a = a-12;

*= 乘且赋值运算符
把右边操作数乘以左边操作数的结果赋值给左边操作数
a *= 12; //→ a = a*12;

/= 除且赋值运算符
把左边操作数除以右边操作数的结果赋值给左边操作数
a /= 12; //→ a = a/12;

%= 求模且赋值运算符
求两个操作数的模赋值给左边操作数
a %= 12; //→ a = a%12;

<<= 左移且赋值运算符
a <<= 2; //→ a = a<<2;

>>= 右移且赋值运算符
a >>= 2; → a = a>>2;

【C语言|C语言——运算符】&= 按位与且赋值运算符
a &= 2; //→ a = a&2;

^= 按位异或且赋值运算符
a ^= 2; //→ a = a^2;

|= 按位或且赋值运算符
a |= 2; //→ a = a|2;

六、其他运算符
  1. ? :条件运算符(三元运算符)
    先判断?前面的条件表达式的逻辑值,如果为真,结果为?后面的表达式的运算结果;如果为假,则结果是:后面的表达式的运算结果。
    x>y ? x : y
    若x>y,则结果为x
    若x
  2. & 取地址运算符
    返回变量的地址
    求某个变量的地址,如scanf()中的&a表示求a的内存空间地址。
    int a; scanf("%d",&a);

  3. *指针运算符
    指向一个变量
    求某个内存地址中的数据。
    int* a; int var=20; a = &var; printf("%d",*a); //结果为20

  4. ,逗号运算符
    当顺序点用,结合顺序是从左至右按顺序求值,完毕后,整个表达式的值是最后一个表达式的结果。
    a=(12+6,7/8,9+3); //结果:a=12;

  5. sizeof()求字节数运算符
    返回变量的大小,用于求一个对象或者类型所占的内存字节数。
    • 语法:sizeof有两种语法:
      sizeof(type_name); //sizeof(类型);
      sizeof object; //sizeof对象
      例:
      sizeof(int) = 4;

    • 当为数组的时候,sizeof的值=数组元素类型 x 元素个数;
      例:
      int a[2] = {0,1}; sizeof(a); //4x2=8;

    • 总结
      sizeof(数组): 分配的数组空间大小;
      sizeof(指针): 该指针所用的空间大小(在32位系统是4,在64系统是8);
      sizeof(类型): 该类型所占的空间大小;
      sizeof(对象): 对象的实际占用空间大小;
      sizeof(函数): 函数的返回类型所占的空间大小。函数的返回类型不能是void
    • sizeof()和strlen()的区别:
      1. sizeof求的是占用内存的大小,strlen求的是字符串的实际长度;(sizeof统计’\0’,strlen不统计’\0’)
      2. sizeof是运算符,strlen是函数;
      3. sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以’’\0’'结尾的; (sizeof还可以用函数做参数)
      4. 数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,
    • 特点
      1、sizeof是运算符,不是函数。sizeof以byte为单位返回操作数的大小。
      2、sizeof不能求得 void 类型的长度。
      3、sizeof能求得 void * 类型的长度。
      4、sizeof能求得静态分配内存的数组的长度。
      5、sizeof不能求得动态分配的内存的大小!
      6、sizeof不能对不完整的数组求长度!
      7、当表达式作为sizeof的操作数时,它返回表达式的计算结果的类型大小,但是它不对表达式求值!
      8、sizeof可以对函数调用求大小,并且求得的大小等于返回类型的大小,但是不执行函数体。
      9、sizeof求得的结构体(及其对象)的大小并不等于各个数据成员对象的大小之和!
      10、sizeof不能用于求结构体的位域成员的大小,但是可以求得包含位域成员的结构体的大小!
  6. (类型)强制类型转换运算符
    一般形式:(类型名)(表达式\常量\变量)
    例:
    (int)(x+y) //将x+y的值转换为整型(float)(5%3)//将5%3的值转换成单精度型

    注意:
    • (int)(x+y)与(int)x+y 意义不同,前者先做x+y操作再转换,后者先转换x类型再+y
    • 类型转换得一个中间值,原变量类型没有发生变化。
      例:
      double a = 4.6; int b = (int)a; printf("a=%lf,b=%d", a, b); //结果:a=4.600000,b=4`

  7. [] 下标运算符
    具有两个操作数的双目运算符。
    • 指向Type型对象的指针
    • 整数类数据类型下标运算符[ ]的操作数的顺序是随意的。
    • 下标运算符所生成的值的类型是 Type型
    a[5] = 4; int b[10] = {0}; double c[2][2] = {1.0,2.0,3.0,4.0};

  8. () 函数调用运算符
    return_type function_name**(** parameter list )
    void example(); //无返回类型,无形参 int student( int id, char sex ); //int返回类型,有形参

  9. _>间接成员运算符
    _> 用于结构体指针,指向该结构的指针访问结构的成员

    struct Books *struct_pointer; //定义结构体指针 struct_pointer -> title; //指针指向结构体成员title

  10. . 结构体访问成员运算符
    . 用来访问结构体,共用体中的成员
    访问成员的一般形式是: 结构变量名 . 成员名
    student.pwd = 12345; //访问student结构体成员pwd,并赋值

    推荐阅读