C语言之位运算

一、什么是位运算

所谓位运算是指进行二进制位的运算
在系统软件中,常要处理二进位的问题
例如,将一个存储单元中的各二进位左移或右移一位,两个数按位相加等

二、位运算符和位运算

1、按位与 运算符(&)

参加运算的两个数据,按二进位进行“与”运算。如果两个相应的二进位都为1,则该位的结果值为1,否则为0

即0&0=0;0&1=0;1&0=0;&1=1;

例如: 3&5 并不等于8,应该是按位与。

在这里插入图片描述
如果参加&运算的是负数(如-3 & -5),则以补码形式表示为二进制数,然后按位进行“与”运算

按位与有一些特殊的用途:

  • 清零
  • 取一个数中某些指定位

实例:

#include <stdio.h>int main(int argc, char *argv[])
{int num1 = 3;int num2 = 5;int res = num1 & num2;printf("res = %d\n", res);return 0;
}
[root@localhost 10_bits]# gcc test1.c -o test1
[root@localhost 10_bits]# ./test1
res = 1

负数在内存中是使用的补码表示的
负数的补码表示规则:最高位表示符号(0表示正数,1表示负数),数据值采用反码加1来表示
一个负数在内存中的表示:先看符号位,如果符号位负,最高位就为1,对于数据值,将负数的绝对值取反用二进制表示,在此基础上加1,就是负数的补码表示
-1在内存中存储的时候存储的是1111…11(32个1)

#include <stdio.h>int main(int argc, char *argv[])
{int num1 = -1;int num2 = -3;int res = num1 & num2;printf("res = %d\n", res);return 0;
}
[root@localhost 10_bits]# gcc test1.c -o test1
[root@localhost 10_bits]# ./test1
res = -3

2、按位或运算符(|)

两个相应的二进位中只要有一个为1,该位的结果值为1

0|0=0; 0|1=1; 1|0=1; 1|1=1。

例如:060|017
将八进制数60与八进制数17进行按位或运算。
在这里插入图片描述
实例:

#include <stdio.h>int main(int argc, char *argv[])
{int num1 = 3;int num2 = 5;int res = num1 | num2;   //011 | 101 == 111  == 7printf("res = %d\n", res);printf("num1 = %x\n", num1);return 0;
}
[root@localhost 10_bits]# gcc test1.c -o test1
[root@localhost 10_bits]# ./test1
res = 7
num1 = 3

3、“异或”运算符(∧)

异或运算符∧也称XOR运算符。它的规则是若参加运算的两个二进位同号,则结果为0(假);异号则为1(真)

0∧0=0; 0∧1=1; 1∧0=1; 1∧1=0;

如:
在这里插入图片描述
下面举例说明∧运算符的应用:

  • 使特定位翻转
    假设有01111010,想使其低4位翻转,即1变为0,0变为1。可以将它与00001111进行∧运算,即
    在这里插入图片描述

  • 与0相∧,保留原值
    如: 012∧00=012
    在这里插入图片描述
    因为原数中的1与0进行∧运算得1,0∧0得0,故保留原数。

  • 交换两个值,不用临时变量
    假如a=3,b=4。想将a和b的值互换,可以用以下赋值语句实现:

a=a∧b;
b=b∧a;
a=a∧b;

4、“取反”运算符(~)

~是一个单目(元)运算符,用来对一个二进制数按位取反,即将0变1,1变0。
例如~025是对八进制数25(即二进制数00010101)按位求反。

5、左移运算符(<<)

用来将一个数的各二进位全部左移若干位。例如

a=a<<2

将a的二进制数左移2位,右补0。
若a=15,即二进制数00001111,左移2位得00111100,即十进制数60。
高位左移后溢出,舍弃不起作用。
左移1位相当于该数乘以2,左移2位相当于该数乘以22=4。。
但此结论只适用于该数左移时被溢出舍弃的高位中不包含1的情况。
左移比乘法运算快得多,有些C编译程序自动将乘2的运算用左移一位来实现,将乘2n的幂运算处理为左移n位

实例:

#include <stdio.h>int main(int argc, char *argv[])
{int num1 = 3;int num2 = 5;int res = num1 | num2;   //011 | 101 == 111  == 7res = num1 << 3;printf("res = %d\n", res);printf("num1 = %x\n", num1);res = num2 >> 2;  //101 >>2 printf("res = %d\n", res);num2 = -23;   //10111-->11...01001res = num2 >> 3;   //11...01001>>3  --> 111...01  --> -3printf("res = %d\n", res);num2 =0x83fffff3;res = num2 << 3;printf("res = %d\n", res);return 0;
}
[root@localhost 10_bits]# gcc test1.c -o test1
[root@localhost 10_bits]# ./test1
res = 24
num1 = 3
res = 1
res = -3
res = 536870808   //说明左移的时候符号位是会丢弃的

6、右移运算符(>>)

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

右移一位相当于除以2,右移n位相当于除以2n。
在右移时,需要注意符号位问题。
对无符号数,右移时左边高位移入0。
对于有符号的值,如果原来符号位为0(该数为正),则左边也是移入0
如果符号位原来为1(即负数),则左边移入0还是1,要取决于所用的计算机系统。有的系统移入0,有的移入1。移入0的称为“逻辑右移”,即简单右移。移入1的称为“算术右移”

实例:

#include <stdio.h>int main(int argc, char *argv[])
{int num1 = 3;int num2 = 5;int res = num1 | num2;   //011 | 101 == 111  == 7res = num1 << 3;printf("res = %d\n", res);printf("num1 = %x\n", num1);res = num2 >> 2;  //101 >>2 printf("res = %d\n", res);num2 = -23;   //10111-->11...01001res = num2 >> 3;   //11...01001>>3  --> 111...01  --> -3printf("res = %d\n", res);return 0;
}
[root@localhost 10_bits]# gcc test1.c -o test1
[root@localhost 10_bits]# ./test1
res = 24
num1 = 3
res = 1
res = -3

7、位运算赋值运算符

位运算符与赋值运算符可以组成复合赋值运算符如:&=, |=, >>=, <<=, ∧=
例如,a & = b相当于 a = a & b
a << =2相当于:a = a << 2

8、不同长度的数据进行位运算

如果两个数据长度不同(例如long型和int型)进行位运算时(如a & b,而a为long型,b为int型),系统会将二者按右端对齐
如果b为正数,则左侧16位补满0
若b为负数,左端应补满1
如果b为无符号整数型,则左侧添满0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/63922.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】实现通讯录(动态+文件)

目录 前言&#xff1a;一.创建多文件二.保存人的通讯录信息三.构建菜单 - test.c四.函数的声明五.函数的实现1.初始化通讯录2.增加指定联系人3.删除指定联系人4.查找指定联系人5.修改指定联系人6.排序联系人信息&#xff08;排序名字&#xff09;7.清理通讯录8.文件存盘 六.全部…

IoTDB在springboot2中的(二) 查询

上一章我们处理的基本的构建接入&#xff0c;以及插入的处理&#xff0c;那么接下来我们进行查询的操作处理。 我们继续在IoTDBSessionConfig工具类中加入查询的方法处理 /*** description: 根据SQL查询最新一条数据* author:zgy* param sql sql查询语句&#xff0c;count查询…

【设计模式——学习笔记】23种设计模式——中介者模式Mediator(原理讲解+应用场景介绍+案例介绍+Java代码实现)

文章目录 案例引入案例一普通实现中介者模式 案例二 介绍基础介绍登场角色尚硅谷 《图解设计模式》 案例实现案例一&#xff1a;智能家庭类图实现 案例二&#xff1a;登录页面逻辑实现说明类图实现 总结文章说明 案例引入 案例一 普通实现 在租房过程中&#xff0c;客户可能…

LeetCode[164]最大间距

难度&#xff1a;Hard 题目&#xff1a; 给定一个无序的数组 nums&#xff0c;返回 数组在排序之后&#xff0c;相邻元素之间最大的差值 。如果数组元素个数小于 2&#xff0c;则返回 0 。 您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。 示例 1: 输入: …

中心极限定理例题

关于大数定律的两个题目。 例1 注意牢记公式&#xff1a; P { X } P { ∑ i 1 n x i − n μ n σ < x } ∫ − ∞ x e − x 2 2 d x 2 π P\{ X\} P \{\frac { \sum_{i1}^{n} x_i - n \mu}{\sqrt {n} \sigma} < x \} \frac {\int _{-\infty} ^{x} e ^{- \frac {x^…

【Freertos基础入门】freertos任务的优先级

文章目录 前言一、任务优先级1.Tick2.修改任务优先级 总结 前言 本系列基于stm32系列单片机来使用freerots 任务管理是实时操作系统&#xff08;RTOS&#xff09;的核心功能之一&#xff0c;它允许开发者以并发的方式组织和管理多个任务。FreeRTOS 是一个流行的开源RTOS&…

使用JavaScript实现页面滑动切换效果

使用JavaScript实现页面滑动切换效果 在现代Web页面设计中&#xff0c;页面滑动切换效果已经成为了一种常见的设计要求&#xff0c;能够提升用户体验&#xff0c;增加页面的交互性。本文将通过JavaScript来实现这一效果。 首先&#xff0c;我们需要在HTML中添加一些基础结构和…

进销存管理系统(小杨国贸)springboot采购仓库财务java jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 进销存管理系统&#xff08;小杨国贸&#xff09;spri…

openGauss学习笔记-37 openGauss 高级数据管理-事务

文章目录 openGauss学习笔记-37 openGauss 高级数据管理-事务37.1 语法格式37.2 参数说明37.3 示例 openGauss学习笔记-37 openGauss 高级数据管理-事务 事务是用户定义的一个数据库操作序列&#xff0c;这些操作要么全做要么全不做&#xff0c;是一个不可分割的工作单位。ope…

【积水成渊】9 个CSS 伪元素

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人_python人工智能视觉&#xff08;opencv&#xff09;从入门到实战,前端,微信小程序-CSDN博客 最新的uniapp毕业设计专栏也放在下方了&#xff1a; https://blog.csdn.net/lbcy…

利用三维内容编辑器制作VR交互课件,简单好用易上手

随着虚拟现实技术的不断发展&#xff0c;越来越多的教育机构开始尝试将其应用于教育教学中。然而&#xff0c;要实现这一目标并不容易&#xff0c;需要专业的技术支持和开发团队。 为了解决这一问题&#xff0c;广州华锐互动研发了三维内容编辑器&#xff0c;它是一种基于虚拟现…

Linux 发行版 Debian 12.1 发布

导读在今年 6 月初&#xff0c;Debian 12“bookworm”发布&#xff0c;而日前 Debian 迎来了 12.1 版本&#xff0c;主要修复系统用户创建等多个安全问题。 Debian 是最古老的 GNU / Linux 发行版之一&#xff0c;也是许多其他基于 Linux 的操作系统的基础&#xff0c;包括 Ub…