C语言操作符上

一、算术操作符

 +     -    *    /    %

1.    / (除号)

int i = 1 / 2;              // i = 0 ; 除号两边都是整形,则得到的结果是自动去掉了小数点后面的数,得到的仅仅是整数部分

float j = 1.0 / 2;        // i = 0.500000 除号两边只要有一个是小数,则结果就是小数(还要注意前面的类型要是浮点型,默认六位小数,要用%f 打印)

2.   % (取模)

这个操作符的两边都要是整数才可以(关于负数取模可以在B站上找单个讲的《C语言深度解刨》


二、移位操作符

<<左移操作符        >>右移操作符
移动的是二进制位,整数的二进制表示有3种:原码、反码、补码
正数的原码、反码、补码相同;
负数的原码、反码、补码需要计算,
原码是用二进制来表示的整数(如果是32位操作系统就是32位,最高位是符号位)
整数在内存中存的是二进制补码的形式
如 7
     原码:00000000000000000000000000000111(第一个0就是符号位,表示是正数,如果是1就是负数)
     反码:00000000000000000000000000000111
     补码:00000000000000000000000000000111
如 -7
     原码:10000000000000000000000000000111
     反码:111111111111111111111111111111111000(原码的符号位不变,其他位按位取反就是反码)
     补码:111111111111111111111111111111111001 (反码+就是补码)
    
左移操作符:左边丢弃,右边补零
下边就是例子:a左移一位   int a = 7; int b = a << 1;b等于多少呢?
    7的补码左移一位,最左边的丢弃,最右边少了一位补0,就得到:                                                              00000000000000000000000000001110(补码)(反码)(原码)
    将此原码转换为十进制数:14    即:b = 14

   -7的补码左移一位,最左边的丢弃,最右边少了一位补0,就得到                                                                  111111111111111111111111111111110010(补码)
                111111111111111111111111111111110001(反码:补码-1)
                10000000000000000000000000001110(原码:反码符号位不变,其他位按位取反)
    将此原码转换为十进制数:-14   即:b = -14
    
 右移操作符:
 1.算术移位:右边丢弃,左边补原符号位(通常编译器都是算术移位)
 2.逻辑移位:右边丢弃,左边补0

 下边是算数移位的例子:a右移一位    int a = 7; int c = a >> 1; c等于多少呢?
    7的补码右移一位,最右边的丢弃,最左边少了一位补原符号位0,就得到:                                                00000000000000000000000000000011(补码)(反码)(原码)
   将此原码转换为十进制数:3   即:c = 3
     
    -7的补码右移一位,最右边的丢弃,最左边少了一位补原符号位1,就得到:                                               111111111111111111111111111111111100(补码)
                111111111111111111111111111111111011(反码:补码-1)
                10000000000000000000000000000100(原码:反码符号位不变,其他位按位取反)
   将此原码转换为十进制数:-4   即:c = -4

三、位操作符

 & 按(2进制)位与
  |  按(2进制)位或
  ^ 按(2进制)位异或

      -5的原码:10000000000000000000000000000101
      -5的反码:111111111111111111111111111111111010
      -5的补码:111111111111111111111111111111111011
       3的补码:00000000000000000000000000000011
       3   &  -5:00000000000000000000000000000011(按位与就是补码对其,两个都是1才是1,否则为0)得到的是补码,转换成原码后,得出结果为:3
       3    |   -5:111111111111111111111111111111111011(按位或就是补码对其,两个都是0才是0,否则为1)得到的是补码,转换成原码后,得出结果为:-5
       3   ^   -5:111111111111111111111111111111111000(按位异或就是补码对其,相同为0,相异为1)             得到的是补码,转换成原码后,得出结果为:-8

 有什么用呢?
 做一下这个题吧:不能创建临时变量(第三个变量),实现两个数的交换
 1.创建临时变量,这种方法用的最多,运算效率最快
    int r1 = 3;
    int t1 = 5;
    int m = 0;
    printf("交换前:r1=%d t1=%d\n", r1, t1);
    m = r1;
    r1 = t1;
    t1 = m;
    printf("交换前:r1=%d t1=%d\n", r1, t1);
  2.不创建临时变量,但可能存在栈溢出
    int r2 = 3;
    int t2 = 5;
    printf("交换前:r2=%d t2=%d\n", r2, t2);
    r2 = r2 + t2;
    t2 = r2 - t2;
    r2 = r2 - t2;
    printf("交换前:r2=%d t2=%d\n", r2, t2);
  3.不创建临时变量,且不用担心栈溢出
  (  //  首先要先了解^的特点
        //    3^3 = 0    可以推出:   a^a = 0
        //  ……011
        //  ……011
        //  ……000
        // 
        //  0^5 = 5    可以推出:   0^a = a  
        //  ……000
        //  ……101
        //  ……101

        //  所以:    3^3^5 = 5
        //  又因为:3^5^3 = 5(说明按位异或支持交换律)

     )

    int r3 = 3;
    int t3 = 5;
    printf("交换前:r3=%d t3=%d\n", r3, t3);
    r3 = r3 ^ t3;
    t3 = r3 ^ t3;
    r3 = r3 ^ t3;
    printf("交换后:r3=%d t3=%d\n", r3, t3);

四、赋值操作符


     一个 =   是赋值操作符;注意两个 == 判断是否相等,一定要小心小心再小心

五、复合操作符
    

  +=  -=  *=  /=  %=  <<=  >>=  &=  |=  ^=

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值