c语言位运算负数的实例_[C语言]你真的了解C语言吗之位运算操作

自C语言盛行以来,豪杰并起,执掌一方者不可胜数,Java比于C++,则年轻而效低,然Java遂能克C++,

以弱为强者,非惟效率,抑亦人和也。今Java已拥亿万之众,移动端后端并行,此诚不可与争锋。

Python揭竿而起,随者之众不可胜数,各方类库亦犹过江之鳞,应天时,人和也。

JavaScript据浏览器,已历n世,国险而源富,此二者可以为援而不可图也。自node出世,Js风生水起,

前后端并行,犹有冲击Java之势。然库多而欠理,npm,webpack一举成名。后React,Vue,Angular等应运而生,

大前端之势浩大,恐怖如斯。然鱼龙混杂,犹互旋之水,难复清明。

至于移动,Android、IOS双足对立。Android本忠Java,然跨平台之势如历史洪流,不可阻也,

外有Hybrid,Weex,ReactNative,Flutter纷涌不绝,内有Kotlin暗刀一击,

Android-Java帝国犹有崩摧之势,然习百技,纳百艺,Coder之能也,此乱世之道,更需多技傍身。

C语言面相过程,年虽老矣,尚有余力,底层之功,莫能与之争,实不可因其老而蔑之。

面相过程之于编程,创现世之基业,劳苦之功,无人能出奇右,实无人可蔑之。

函数式之于编程,新生之思,思之至纯,虽年幼却难掩其芒。实不可因其异而蔑之。

此三者,切不可盲从而身陷,亦不可斥而尊宗,习其思,用于正道,方为上上。

来自《隆中对》----张风捷特烈

依稀还记得大一学C语言的时光,讲真的,那是我对编程的初次认识(本人非计科专业),哪成想几年过去了,现在几乎终日与它为伴~要知道在嵌入式开发当中几乎是离不开C语言的,因为C语言是最接近硬件的一门语言,相比于汇编是更加适合人类开发和阅读的一门语言,虽然现在嵌入式开发也有了别的语言,比如Lua,MicroPython,JS等等,但是相对于C语言的执行效率是远远落后的,所以做嵌入式开发学好C语言是很有必要的。虽然自己每天都有写C代码,可是对于C语言的理解还是远远不够的,就比如有些概念还停留在知道、晓得、懂一点的水平,这是制约自己发展的一大重要因素啊!

是时候重新拾起来,仔细去学习一番了,之前单学C语言的时候,总觉得少一点东西,为什么这么说呢?可能只是为了学而学,并不知道在实际应用中该怎么用,有或者在哪些实际情况中会用到,所以就是缺点东西!现在不一样了,有了一个实际的载体(硬件),知道这一块功能如果去实现该怎么写,如果优化该怎么优化,所以现在对C语言有了很多新的理解。

这两天就对这个C语言中的位运算重新学习了一边,可见当时确实学的浅薄,简单一写,加深下理解~

不知道你在开发单片机的过程中有没有遇到过下面的运算符,又或者你能准确的说出每一个运算符的用法吗?&

|

^

~

>>

<<

我们先来理解下什么是位吧,可能你还记得当时书本中说过的字节和位的区别:位 计算机中最小的存储单位

字节 计算机中最小的数据单位

那我们该怎么理解呢?我们首先要知道计算机中的数据都是0和1的顺序组合,所有的数据最后都是0和1的特定排列,每8个0和1的排列就组成了最小的数据单位->字节,也就是每个字节都是由8位0和1组成的,就比如说数字“0”,在存储器当中是以“00110000”这样的8位连续的0和1排列的,这是我们通过数据在内存中怎么去保存的去理解位和字节的区别。

那在实际开发当中,位运算有什么用呢?我们实际开发中会用到位操作吗?答案当然是肯定的,最常见的例子就是在某些与寄存器打交道的地方,我们需要频繁的进行微操作,因为寄存中的每一位置“1”或者置“0”都是有不同含义的,就拿比较常见的STM32单片机来说吧,我们看一下它寄存器说明:

这是APB1外设复位寄存器的说明。可以看见一共有0~31->32位,STM32的寄存器都是32位的,这个表对此寄存器的每一位是复位哪一个外设的,都做了详细注释,就比如说我们复位DAC(数模转换)吧,我们只需让此寄存器的第29位置“1”就可以让DAC外设复位了。

不闲扯了,来复习我们的C语言吧还是,刚刚给出的6种C语言中的位运算符都知道什么意思了吗?如果还没有,我们来复习一下,下面给出的实际位操作实列都是二进制位模式:& 按位与

00000110 & 00001011 = 00000010| 按位或

00000110 | 00001011 = 00001111^ 按位异或

00000110 ^ 00001011 = 00001101~ 按位取反

~ 00000110 = 11111001>> 向右移位

00000001(结果) = 00000110 >> 2(移动2位)<< 向左移位

00011000(结果) = 00000110 << 2(移动2位)

在移位运算中,有两点需要注意:向左移位的时候,右边多出来的位用0补齐,超出左边边界抛弃。

向右移位的时候,左边多出来的位需要根据有无符号或者是否是负数去处理,无符号或者有符号但非负数,左边多出来的位用0补齐,如果是负数,具体填充位的内容是根据编译器决定的。

思考:int a = 7,将a的第7位置“1”,不改变其它位。

① a |= (0x01 << 7)

② a |= 0x80

2. int a = 7,将a的第1位置“0”,不改变其它位。

① a &= ~ (0x01 << 1)

② a &= ~ 0x02

③ a ^= 0x20

3. int a = 7,将a的第7位置“1”后再清除,不改变其它位。

置“1”:

① x = a | (0x01 << 7)

② x = a | 0x80

清除:

① a = x & (~(0x01 << 7))

② a = x & (~0x80)

③ a = x ^ 0x80

4. int a = 7,将a的第1位置“0”后再置“1”,不改变其它位。

置“0”:

① x = a & (~ (0x01 << 1))

② x = a & (~ 0x20)

③ x = a ^ 0x20

置“1”:

① x = a | (0x01 << 1)

② x = a | 0x20

简单写两个实列,帮助记忆,在嵌入式开发当中置位和清除是比较常见的操作,只有熟练操作才可以运用的更加熟练,一般为了对位操作的方便性和方便移植,都会写成下面的宏定义:

#define setbit(x,y) x |= (0x01 << y)#define clrbit(x,y) x &= ~(0x01 << y)#define reversebit(x,y) x ^= (0x01 << y)#define getbit(x,y) ((x) >> (y) & 0x01)

先写到这里,如果有表述错误,还请指出我好修正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值