打印
[技术问答]

C 语言位运算技巧

[复制链接]
1735|34
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
claretttt|  楼主 | 2025-3-23 17:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

生成了一段初始化定时器/计时器相关的代码,代码如下:

void Timer0Init(void)  //10毫秒@11.0592MHz
{
 AUXR &= 0x7F;  //定时器时钟12T模式
 TMOD &= 0xF0;  //设置定时器模式
 TMOD |= 0x01;  //设置定时器模式
 TL0 = 0x00;  //设置定时初值
 TH0 = 0xDC;  //设置定时初值
 TF0 = 0;  //清除TF0标志
 TR0 = 1;  //定时器0开始计时
}

上面的这段代码,和我们写的初始化的代码略有不同,看下我们的代码:

TMOD = 1;
TL0 = 0;
TH0 = 0xDC;
TR0 = 1;

从两段代码可以看出 TMOD 寄存器的赋值是有差别的。STC-ISP 生成的使用了 按位与 和 按位或 操作对 TMOD 进行了赋值;而我们的代码则直接使用的是赋值操作。

0x02:按位操作的意义

对于我们写的代码和 STC-ISP 生成的代码有何区别呢?对于我们的代码而言,没有啥区别。但是,对于 STC-ISP 生成的代码应该算是更标准化和工程化吧(这话说得很油腻啊!)。

按位与操作(就是 & 这个符号),很多语言都有这个运算符,意义也都一样。& 操作的特性是对指定位进行清 0,其他位保持不变。那 TMOD &= 0xF0 来说,这条语句是把 TMOD 的低 4 位清 0,高 4 位则保持不变。因为我们要使用 T0 定时器/计数器,使用 T0 需要设置 TMOD 的低 4 位,所以先给低 4 位清 0,然后再对低 4 位进行设置。而高 4 位是用来设置 T1 的,我们不使用 T1 ,所以让 T1 的设置保持不变。

按位或操作(就是 | 这个符号),很多语言也都有这个运算符。| 操作的特性是对指定位进行置位操作,而其余位保持不变。对于 TMOD |= 0x01 来说,这条语句是让 TMOD 的高 4 位保持不变,然后把最低位设置为 1。

很多时候一个字节是拆成很多个位来使用的,比如 TMOD 就是这样。在操作这些位的时候,就要尽可能地只操作我们需要操作的位,而其他我们不操作的位要保持不变。甚至在有些情况下要把整个字节或者标志位都保存了,操作后再进行恢复,以保持上下文环境不被我们的操作所破坏。

使用特权

评论回复
沙发
youtome| | 2025-4-6 07:18 | 只看该作者
位运算直接操作二进制位,是C语言中高效处理数据的核心工具

使用特权

评论回复
板凳
yorkbarney| | 2025-4-8 09:54 | 只看该作者
通过与1进行按位与运算,可以判断一个数是奇数还是偶数。

使用特权

评论回复
地板
lzmm| | 2025-4-8 12:09 | 只看该作者
可以使用循环和按位与运算符 & 统计一个数中 1 的个数。

使用特权

评论回复
5
juliestephen| | 2025-4-8 15:09 | 只看该作者
在进行位运算时,操作数是无符号的,以避免意外的符号扩展。

使用特权

评论回复
6
bartonalfred| | 2025-4-9 20:18 | 只看该作者
在不需要的情况下,不要将简单的算术运算转换为位运算。

使用特权

评论回复
7
kkzz| | 2025-4-9 23:22 | 只看该作者
位运算符优先级低于算术运算符,需用括号明确顺序。

使用特权

评论回复
8
chenci2013| | 2025-4-10 02:26 | 只看该作者
使用按位异或运算可以不使用临时变量交换两个整数。void swap(int *a, int *b) {
    *a = *a ^ *b;
    *b = *a ^ *b;
    *a = *a ^ *b;
}

使用特权

评论回复
9
alvpeg| | 2025-4-12 20:19 | 只看该作者
通过或运算可以设置某一位为1,通过与运算并取反可以清除某一位。

使用特权

评论回复
10
jkl21| | 2025-4-12 21:15 | 只看该作者
对于乘以2的幂次方或除以2的幂次方的操作,可以使用左移或右移运算来代替乘法或除法运算,以提高计算效率。

使用特权

评论回复
11
abotomson| | 2025-4-13 15:03 | 只看该作者
移位位数不能超过变量的位数              

使用特权

评论回复
12
weifeng90| | 2025-4-13 18:53 | 只看该作者
位运算算法设计好了可以提高效率

使用特权

评论回复
13
sdlls| | 2025-4-13 21:35 | 只看该作者
位运算通常比其他常规运算(如加减乘除)更高效,因为它们直接在硬件层面进行操作,不需要通过软件进行复杂的计算过程。

使用特权

评论回复
14
adolphcocker| | 2025-4-14 13:05 | 只看该作者
位运算虽然高效,但代码可读性较差,建议添加注释。

使用特权

评论回复
15
bestwell| | 2025-4-14 14:27 | 只看该作者
在进行位运算时,要注意边界情况,避免出现错误的结果。

使用特权

评论回复
16
uytyu| | 2025-4-14 14:48 | 只看该作者
不使用临时变量,通过按位异或运算符 ^ 可以交换两个变量的值。

使用特权

评论回复
17
burgessmaggie| | 2025-4-14 16:11 | 只看该作者
过度使用位运算可能会降低代码的可读性

使用特权

评论回复
18
kkzz| | 2025-4-14 17:11 | 只看该作者
位运算依赖于字的大小和字节序              

使用特权

评论回复
19
cashrwood| | 2025-4-14 17:44 | 只看该作者
使用特定的位掩码可以方便地对一组位进行操作。

使用特权

评论回复
20
hearstnorman323| | 2025-4-14 18:11 | 只看该作者
对于有符号数,右移操作会保留符号位,可能会导致意外的结果。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

69

主题

1529

帖子

0

粉丝