前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言位操作

C语言位操作

作者头像
WuShF
发布2023-03-11 10:00:04
1.7K0
发布2023-03-11 10:00:04
举报
文章被收录于专栏:笔记分享

深入到字节的内部,讨论如何直接操作字节内部的二进制位

十进制转二进制

短除法&位权法

先读高位、后读低位从下往上逆序读右侧的余数101010。这就是十进制数42所对应的二进制。

将二进制转换为十进制,可以把二进制中的各位乘以其所在位的位权,再将所有乘法的积累加起来,即可得到转换后的十进制结果。 例如: 二进制101010,高位在左,低位在右

十进制转二进制函数

代码语言:javascript
复制
#include<stdio.h>
void printBinary(unsigned char dec) {
	// 若dec为0,输出0并返回
	if (dec == 0)
	{
		printf("0\n"); return;
	}
	// 若dec非0,短除计算余数,逆序输出
	char bits[8];
	int count = 0;
	int quotient;
	int remainder;
	while (dec > 0)
	{
		remainder = dec % 2;
		quotient = dec / 2;
		dec = quotient;
		bits[count] = remainder;
		count++;
	}
	for (int i = count - 1; i >= 0; i--)
		printf("%d", bits[i]);
	putchar('\n');
}
int main() {
	printBinary(42);//以42为例
}

正确输出

代码语言:javascript
复制
101010

对于unsigned char类型的变量dec来说,它拥有8个二进制位。而十进制数42,只占6个二进制位,还有两个二进制位为0。若需要把8个二进制位全部输出,可以将bits数组初始化为0。计算完余数后,从数组的最后一个元素开始,逆序输出直到数组第一个元素。此时,无需对dec为0做特殊处理了。由于数组bits初始化为0,dec为0时,不进入while循环,直接输出8个0。

代码语言:javascript
复制
#include<stdio.h>
void printBinary(unsigned char dec) {
	char bits[8] = {0};
	int count = 0;
	int quotient;
	int remainder;
	while (dec > 0)
	{
		remainder = dec % 2;
		quotient = dec / 2;
		dec = quotient;
		bits[count] = remainder;
		count++;
	}
	for (int i = 8 - 1; i >= 0; i--)
		printf("%d", bits[i]);
	putchar('\n');
}
int main() {
	printBinary(42);
}

补齐0

代码语言:javascript
复制
00101010

逻辑运算符

逻辑运算符会把运算对象的数值,看做真或假进行逻辑运算。若运算对象的数值为非0值,则看做真。若数值为0值,则看做假。 下面分别复习一下这3种逻辑运算符。

逻辑与&&

逻辑与&&运算符会对左右两边,两个运算对象进行运算。

  1. 若两个运算对象同时为真时,运算结果为真,用数值1表示。
  2. 否则,运算结果为假,用数值0表示。

12345 && 67890 左右有两个运算对象,分别为1234567890。左边的运算对象12345为非0值,看做真。右边运算对象67890为非0值,看做真。两个运算对象同时为真,运算结果为真,即1。 若将其中一边变为0,表达式如下: 12345 && 0 左边的运算对象12345为非0值,看做真。右边运算对象0为0值,看做假。两个运算对象不同时为真,运算结果为假,即0。

逻辑或||

逻辑或||运算符会对左右两边,两个运算对象进行运算。

  1. 若两个运算对象同时为假时,运算结果为假,用数值0表示。
  2. 否则,运算结果为真,用数值1表示。

12345 || 0 左边的运算对象12345为非0值,看做真。右边运算对象0为0值,看做假。两个运算对象不同时为假,运算结果为真,即1。 0 && 0 左边的运算对象0为0值,看做假。右边运算对象0为0值,看做假。两个运算对象同时为假,运算结果为假,即0。

逻辑非!

逻辑与!运算符会对右边一个运算对象进行运算:

  1. 若运算对象为真,运算结果为假。
  2. 若运算对象为假,运算结果为真。

!12345 右边运算对象12345为非0值,看做真。运算结果为假,即0。 !0 右边运算对象0为0值,看做假。运算结果为真,即1。

位运算符

在上面的逻辑运算中,会把运算对象的数值根据非0值或0值,看做真或假,再进行逻辑运算。 还有另外一类运算符,它将深入运算对象的内部,把运算对象内部的二进制位,根据非0值或0值,看做真或假,再进行逻辑运算。

位逻辑运算符:

  1. 位逻辑与&
  2. 位逻辑或|
  3. 位逻辑异或^
  4. 位逻辑非~

将十进制170作为函数printBinary的参数,它将打印出十进制170的二进制10101010。 将十进制102作为函数printBinary的参数,它将打印出十进制102 的二进制01100110。 接下来,我们让这两个数值分别做各种位逻辑运算,看看它们都有什么现象。

位逻辑与&

代码语言:javascript
复制
printf("%hhu\n", 170 & 102);
printBinary(170 & 102);

位逻辑与&它将深入字节内部,对二进制位进行逻辑与运算。

  1. 若两个位同时为真,运算结果为真,用数值1表示。
  2. 否则,运算结果为假,用数值0表示。

前四位为例

位逻辑或|

  1. 若两个位同时为假时,运算结果为假,用数值0表示。
  2. 否则,运算结果为真,用数值1表示。

位逻辑异或^

  1. 若两个位不同时,运算结果为真,用数值1表示。
  2. 否则,运算结果为假,用数值0表示。

位逻辑非~

位逻辑非~它将深入字节内部,对二进制位进行逻辑非运算。

  1. 若二进制位为真时,运算结果为假,用数值0表示。
  2. 二进制位为假时,运算结果为真,用数值1表示。

换句话说,位逻辑非运算会翻转运算对象的所有二进制位。二进制位1变为0,0变为1。

左移右移

左移运算符<<

左移运算符将数据对象内部的二进制全部向左移动指定位,空出来的位置用0填充。

代码语言:javascript
复制
#include<stdio.h>
void printBinary(unsigned char dec) {
	char bits[8] = {0};
	int count = 0;
	int quotient;
	int remainder;
	while (dec > 0)
	{
		remainder = dec % 2;
		quotient = dec / 2;
		dec = quotient;
		bits[count] = remainder;
		count++;
	}
	for (int i = 8 - 1; i >= 0; i--)
		printf("%d", bits[i]);
	putchar('\n');
}
int main() {
	printBinary(231);
	printBinary(231 << 1);
	printBinary(231 << 2);
	printBinary(231 << 3);
}

输出结果

代码语言:javascript
复制
11100111
11001110
10011100
00111000

右移运算符

右移运算符将数据对象内部的二进制全部向右移动指定位,对于无符号类型,空出来的位置用0填充。 对于有符号类型,空出来的位置用0或1填充取决于编译器。

代码语言:javascript
复制
#include<stdio.h>
void printBinary(unsigned char dec) {
	char bits[8] = {0};
	int count = 0;
	int quotient;
	int remainder;
	while (dec > 0)
	{
		remainder = dec % 2;
		quotient = dec / 2;
		dec = quotient;
		bits[count] = remainder;
		count++;
	}
	for (int i = 8 - 1; i >= 0; i--)
		printf("%d", bits[i]);
	putchar('\n');
}
int main() {
	printBinary(231);
	printBinary(231 >> 1);
	printBinary(231 >> 2);
	printBinary(231 >> 3);
}

输出结果

代码语言:javascript
复制
11100111
01110011
00111001
00011100
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-03-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 十进制转二进制
    • 短除法&位权法
      • 十进制转二进制函数
      • 逻辑运算符
        • 逻辑与&&
          • 逻辑或||
            • 逻辑非!
            • 位运算符
              • 位逻辑运算符:
                • 位逻辑与&
                  • 位逻辑或|
                    • 位逻辑异或^
                      • 位逻辑非~
                      • 左移右移
                        • 左移运算符<<
                          • 右移运算符
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档