C语言入门系列之12.位运算(下)

简介: 位运算是指按二进制位进行的运算,这是因为在系统软件中,常要处理二进制位的问题。

右移运算符>>

右移运算符是a>>2表示将a的各二进制位右移2位,移到右端的低位被舍弃,对无符号数,高位补0。

例如a=017时,a的值用二进制形式表示为00001111, 舍弃低2位11,得到a >> 2 == 00000011。

可以得到:

右移一位相当于除以2,右移n位相当于除以2n。

有关符号位的注意事项如下:

对无符号数,右移时左边高位移入0;

对于有符号的值,如果原来符号位为0(该数为正),则左边也是移入0;

如果符号位原来为1(即负数),则左边移入0还是1,要取决于所用的计算机系统,有的系统移入0,有的系统移入1。

移入0的称为逻辑右移, 即简单右移;

移入1的称为算术右移。

例如,a的值是十进制数-2:

a = 1111 1110(用二进制形式表示);

无符号数:a>>1 = 0111 1111 (逻辑右移时);

有符号数:a>>1 = 1111 1111 (算术右移时)。

练习如下:

#include <stdio.h>
int main(){
  unsigned char a = -2;
  char b = -2;
  a = a >> 1;
  b = b >> 1;
  printf("a = %d\nb = %d\n", a, b);
  return 0;
}

打印:

a = 127
b = -1

显然,C语言对于有符号数和无符号数的处理是不同的。

位运算赋值运算符

位运算符与赋值运算符可以组成复合赋值运算符。

例如: &=、|=、>>=、<<=、^=。

所以,a &= b相当于a = a & ba <<= 2相当于a = a << 2

二、位运算举例

练习:

取一个字符型变量a从右端开始的2-5位。

实现思路:

(1)先使a右移2位a >> 2,目的是使要取出的那几位移到最右端;

(2)设置一个低4位全为1,其余全为0的数,即~(~0 << 4);

(3)将(1)、(2)进行&运算,(a >> 2) & ~(~0 << 4)。

代码如下:

#include <stdio.h>
int main(){
  char a, b, c, d;
  printf("Please input the number:\n");
  scanf("%d", &a);
  b = a >> 2;
  c = ~(~0<<4);
  d = b & c;
  printf("%d\n");
  return 0;
}

打印:

Please input the number:
37
9

练习:

要求将a进行右循环移位,如下:

2345_image_file_copy_88.jpg

代码如下:

#include <stdio.h>
int main(){
  unsigned a, b, c, d;
  int n;
  printf("Please input the number:\n");
  scanf("%d", &a);
  printf("Please enter the number of digits to be moved:\n");
  scanf("%d", &n);
  b = a << (sizeof(char) * 8 - n);
  c = a >> n;
  d = b | c;
  printf("result = %d\n", d);
  return 0;
}

打印:

Please input the number:
25
Please enter the number of digits to be moved:
2
result = 1606

三、位段

信息的存取一般以字节为单位,但有时存储一个信息不必用一个或多个字节。

例如,真或假用0或1表示,只需1位即可。

在计算机用于过程控制、参数检测或数据通信领域时,控制信息往往只占一个字节中的一个或几个二进制位,常常在一个字节中放几个信息。

C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为位段或称位域(bit field),利用位段能够用较少的位数存储数据。

如下:

struct  packed_data{
    unsigned a:2;
    unsigned b:6;
    unsigned c:4;
    unsigned d:4;
    int 1;
} data; 

位段的定义和引用的说明:

(1)位段成员的类型必须指定为unsigned或int类型。

(2)若某一位段要从另一个字开始存放,可用以下形式定义:

unsigned a:1;
unsigned b:2;   // 一个存储单元       
unsigned :0;
unsigned c:3; // 另一存储单元  

a、b、c应连续存放在一个存储单元中,由于用了长度为0的位段,其作用是使下一个位段从下一个存储单元开始存放。因此,只将a、b存储在一个存储单元中,c另存在下一个单元(存储单元可能是一个字节,也可能是2个字节,视不同的编译系统而异)。

(3) 一个位段必须存储在同一存储单元中,不能跨两个单元;

如果第一个单元空间不能容纳下一个位段,则该空间不用,而从下一个单元起存放该位段。

(4) 可以定义无名位段。

(5) 位段的长度不能大于存储单元的长度,也不能定义位段数组。

(6) 位段可以用整型格式符输出。

(7) 位段可以在数值表达式中引用,它会被系统自动地转换成整型数。

相关文章
|
16天前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
28 1
|
2月前
|
安全 编译器 C语言
C++入门1——从C语言到C++的过渡
C++入门1——从C语言到C++的过渡
66 2
|
14天前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
68 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
16天前
|
存储 算法 安全
C 语言中的位运算:挖掘底层计算的高效力量
位运算是C语言中直接操作二进制位的一种技术,能高效处理底层数据,广泛应用于优化算法、硬件编程等领域,是掌握C语言高级特性的关键之一。
|
2月前
|
存储 Java 编译器
初识C语言1——C语言入门介绍
初识C语言1——C语言入门介绍
33 1
|
2月前
|
C语言
回溯入门题,数据所有排列方式(c语言)
回溯入门题,数据所有排列方式(c语言)
|
3月前
|
存储 C语言
C语言程序设计核心详解 第十章:位运算和c语言文件操作详解_文件操作函数
本文详细介绍了C语言中的位运算和文件操作。位运算包括按位与、或、异或、取反、左移和右移等六种运算符及其复合赋值运算符,每种运算符的功能和应用场景都有具体说明。文件操作部分则涵盖了文件的概念、分类、文件类型指针、文件的打开与关闭、读写操作及当前读写位置的调整等内容,提供了丰富的示例帮助理解。通过对本文的学习,读者可以全面掌握C语言中的位运算和文件处理技术。
|
4月前
|
C语言
C语言------程设设计入门
这篇文章是C语言程序设计的入门教程,涵盖了C程序的实现过程、VC集成开发环境的使用、基本数据类型的使用、格式控制字符的作用,以及通过示例代码演示了如何使用printf()函数输出不同类型的数据。
C语言------程设设计入门
|
5月前
|
存储 Java C语言
【C语言入门】初识C语言:掌握编程的基石
【C语言入门】初识C语言:掌握编程的基石
70 4
【C语言入门】初识C语言:掌握编程的基石
|
4月前
|
NoSQL Java 编译器
C语言从入门到精通该怎样学?
持续学习与实践:编程是一门需要不断学习和实践的技能,要保持对新技术和新知识的敏感性,并持续进行编程实践。
65 1