IE盒子

搜索
查看: 115|回复: 2

C语言——位运算

[复制链接]

4

主题

6

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2023-3-6 01:30:25 | 显示全部楼层 |阅读模式
C语言有一个重要特点就是可以直接对二进制位进行操作,即位运算
二进制位简称位(bit),其值为0或1。计算机真正执行的正是由0和1构成的机器指令,计算机内数据也是由二进制表示的。
数在计算机内均是以补码的形式存储的 。
1  位运算符



2  位运算

2.1  按位取反运算

取反运算“~”是一个单目运算符,运算量在运算符之后,取反运算的功能是将一个数据中所有位都取其相反值,即1变0,0变1。
运算规则为:      ~1=0   ~0=1
例1   对于无符号的字符型数据
a=(18)10 =(00010010)2 ,
则~a等于(11101101)2 ,即(237)10
C程序如下:
# include <stdio.h>
int main()
{
unsigned char  a=18,b;
   b=~a;
   printf(“~a=%d”,b);
   return 0;
}运行结果为: ~a= 237
注意以下程序与上面程序及运行结果的区别:
#include <stdio.h>
int main()
{
char  a=18,b; b=~a;
  printf(“~a=%d”,b);
  return 0;
}运行结果:-19
注意:
前一个程序结果很好理解,后一个因为a是带符号数据,因此~a=(11101101)2的结果是一负数的补码,转换为原码时,第1位符号位不变,对剩余的部分先减1,再全部取反,因此得到的二进制原码为:10010011,即十进制的-19。
2.2  左移运算

左移运算“<<”是一个双目运算符,左移运算的功能是将一个数据所有位向左移若干位,左边(高位)移出的部分舍去,右边(低位)自动补零。
例2  对于无符号字符型数据
               a=(18)10 =(00010010)2 ,
            a <<3的结果是(10010000)2 ,即(144)10
C程序如下:
#include <stdio.h>
int main()
{
unsigned char  a=18, b;
    b=a<<3;
    printf(“a<<3=%d”,b);
}运行结果为: a<<3=144
注意以下程序与上面程序的区别:
# include <stdio.h>
int main()
{
char  a=18,b;
  b=a<<3;
printf(“a<<3=%d”,b);
return 0;
} 运行结果为: a<<3=-112
原因同前,对于带符号数a,因a<<3得到的(10010000)2, 是一负数的补码,转换为原码时,第1位符号位不变,对剩余的部分先减1,再全部取反,因此得到的二进制原码为:11110000,即十进制的-112。
对于无符号数来说,在左移的过程中如果没有高位的丢失,左移1位相当于乘2,左移2位相当于乘4。
左移运算速度较快,因此有些C编译系统自动将乘2的操作用左移1位来实现,将2的n次幂运算用左移n位来实现。
2.3  右移运算

右移运算“>>”是一个双目运算符,右移运算的功能是将一个数据所有位向右移若干位,右边(低位)移出的部分舍去,左边(高位)移入的二进制数分两种情况:对于无符号数和正整数,高位补0;对于负整数,高位补1(适用于turboc系统)。
例3  对于无符号字符型数据
          a=(18)10 =(00010010)2 ,
则  a >>3的结果是(00000010)2,即(2)10
C程序:
# include <stdio.h>
int main()
{
unsigned char  a=18, b;
   b=a>>3;
   printf(“a>>3=%d”,b);
   return 0;
}运行结果为: a>>3=2
2.4  按位与运算

按位“与”运算符要求有两个运算量,其功能是将两个运算量的各个相应位分别进行“与”运算。
运算规则为: 1&1=1  0&1=0  1&0=0  0&0=0
例4    对于无符号数a=(173)10=(10101101)2,
   b=(203)10=(11001011)2,
则a&b = (10001001)2 =(137)10  


C程序:
# include <stdio.h>
int main()
{
unsigned char  a=173,b=203,c;
    c=a&b;
    printf(“a&b=%d”,c);
   return 0;
}运行结果为: a&b=137
C程序:
# include <stdio.h>
int main()
{ char  a=-83,b=-53,c;
   c=a&b;
   printf(“a&b=%d”,c);
   return 0;
}运行结果为: a&b=-119
例5  对于有符号数a=(-83)10=(10101101)2 ,
  b=(-53)10=(11001011)2 ,
则a&b = (10001001)2 =(-119)10 。
以上二进制形式是负数的补码。C程序如下所示。


2.5  按位或运算   

按位“或”运算符要求有两个运算量,其功能是将两个运算量的各个相应位分别进行“或”运算。
运算规则为: 1|1=1  0|1=1  1|0=1  0&0=0
例6    对于无符号数a=(173)10=(10101101)2,b=(203)10=(11001011)2,则a|b = (11101111)2 =(239)10


C程序:
# include <stdio.h>
int main()
{
unsigned char  a=173,b=203,c;
   c=a|b;
   printf(“a|b=%d”,c);
   return 0;
}                  
   运行结果: a|b=239  例7   对于有符号数
           a=(-83)10=(10101101)2,
           b=(-53)10=(11001011)2,
则a|b = (11101111)2 =(-17)10


C程序:
# include <stdio.h>
int main()
{
char  a=-83,b=-53,c;
  c=a|b;
  printf(“a|b=%d”,c);
  return 0;
}运行结果为: a|b= -17
2.6  按位异或运算

按位“异或”运算符要求有两个运算量,其功能是将两个运算量的各个相应位分别进行“异或”运算。
运算规则为: 1^1=0  0^1=1  1^0=1  0&0=0
例8   对于无符号数
      a=(173)10=(10101101)2,
      b=(203)10=(11001011)2,
则a^b = (11101111)2 =(102)10
    C程序:
# include <stdio.h>
int main()
{
unsigned char  a=173,b=203,c;
c=a^b;   printf(“a^b=%d”,c);
return 0;
}  运行结果: a^b=102

回复

使用道具 举报

0

主题

4

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2023-3-6 01:31:00 | 显示全部楼层
C语言里面,如果我想用96bit的数据类型左移(<<),或者进行其它位运算,怎么操作?
回复

使用道具 举报

3

主题

6

帖子

11

积分

新手上路

Rank: 1

积分
11
发表于 2023-3-6 01:31:44 | 显示全部楼层
假如有一串二进制1010111001011100,怎么快速统计里面1的个数,和0的个数?有什么骚操作 能秒出结果没不?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表