c语言运算符

c语言运算符

按位或

按位或操作使用 | 符号表示。对于两个二进制数,如果对应位上至少有一个是1,则结果的那个位也是1;如果两个对应位都是0,则结果的那个位是0。

0101 (5 in decimal)  
|  
1010 (10 in decimal)  
------  
1111 (15 in decimal)

unsigned char a = 5;  
unsigned char b = 10;  
unsigned char c = a | b; // c 现在是 15

按位与

按位与操作使用 & 符号表示。对于两个二进制数,如果对应位上两个都是1,则结果的那个位也是1;如果至少有一个是0,则结果的那个位是0。

0101 (5 in decimal)  
&  
1010 (10 in decimal)  
------  
0000 (0 in decimal)

unsigned char a = 5;  
unsigned char b = 10;  
unsigned char c = a & b; // c 现在是 0

按位取反

按位取反操作使用 ~ 符号表示。它对单个二进制数进行操作,将其每一位都反转(0变1,1变0)。

~  
0101 (5 in decimal)  
------  
1010 (complement of 5, which is -6 in 2's complement representation)

unsigned char a = 5;  
unsigned char b = ~a; // b 现在是 250 (对于8位无符号字符,因为255 - 5 = 250)

左移操作符

在C语言中,左移操作符(<<)用于将一个整数的所有位向左移动指定的位数。左移操作实际上是将该数乘以2的指定次幂,因为向左移动一位等价于乘以2,向左移动两位等价于乘以4,依此类推。

当我们将一个数左移时,我们实际上是在丢弃该数的最右边的位(即最低位),并在最左边(即最高位)填充0。如果原始数是带符号的(如intchar,并且未明确指定为无符号),并且左移后最高位(符号位)变为1,则结果可能会是一个负数(在二进制补码表示法中)

#include <stdio.h>  
  
int main() {  
    unsigned char a = 4; // 二进制表示为 0100  
    unsigned char b;  
  
    // 将a左移一位  
    b = a << 1; // 现在b是 8,二进制表示为 1000  
  
    printf("a (original): %u\n", a);  // 输出: a (original): 4  
    printf("b (after left shift): %u\n", b); // 输出: b (after left shift): 8  
  
    return 0;  
}

在这个例子中,a的初始值是4,其二进制表示为0100。当我们将a左移一位时,得到的结果是8,其二进制表示为1000

需要注意的是,对于无符号整数类型(如unsigned charunsigned int等),左移操作总是安全的,因为最高位填充的是0,不会改变数的符号。但是,对于带符号整数类型(如charshortintlong等),如果左移操作导致符号位变为1,则结果可能是负数。此外,如果左移的位数超过了该整数类型的位数,那么结果将是未定义的(对于标准C语言)。

按位异或

^ 是一个位运算符,被称为“按位异或

  • 当两个相应的二进制位相异时,结果为1
  • 当两个相应的二进制位相同时,结果为0
a = 0b10101010 (二进制表示,等于十进制的170)  
b = 0b01010101 (二进制表示,等于十进制的85)
a^b结果:
10101010  
^ 01010101  
----------  
  11111111 (二进制表示,等于十进制的255)
  
  
#include <stdio.h>  
int main() {  
    unsigned char a = 170; // 二进制为 10101010  
    unsigned char b = 85;  // 二进制为 01010101  
    unsigned char result = a ^ b;  
    printf("Result of XOR operation: %u\n", result); // 输出应为 255  
    return 0;  
}

例子

需求:

二进制位控制LED灯开关。假定有8盏LED灯的开关由状态字psw控制。Psw的8个二进制位分别控制1个LED灯,将位清0则对应的灯关闭,置1则打开。编一个程序功能是模拟LED灯光跑马灯闪烁效果。即第1盏灯亮1秒后关闭,切换到第2盏灯再亮1秒,一直循环下去。设置按任意键控制跑马灯效果的启停,输出psw的十六进制数形式来模拟循环一个完整周期的灯光控制效果。

提示:通过观察状态字psw值的变化来模拟控制效果。其设计基本思路是:

① 使用getch(函数控制启停,延时调用库函数leep(1000),参数为毫秒数,其头文件在windows.h中。

② 状态字psw为1字节无符号字符(unsigned char),从第0位到第7位共8个二进制位分别控制8个LED灯。每位单独是1其他位是0时的十六进制值依次是:0x1(0位)、0x2(1位)、0x4(2位)、0x8(3位)、0x10(4位)、0x20(5位)、0x40(6位)、0x80(7位)

③ 灯全灭psw-0,开关掩码mask依据上列十六进制值来设定。

④ 由于异或运算同一个数2次,又恢复了原来的值,也就是psw^=mask,灯开,再次做同样运算灯灭。也可以考虑用位左移运算实现开关控制。psw=1,打开0位对应的灯,psw<=1每次左移1位可切换开关的状态。

#include <stdio.h>  
#include <windows.h>   // Sleep()  
#include <conio.h>     // _kbhit() 和 _getch()  
  
int main() {  
    unsigned char psw = 0x00; // 初始状态,所有灯关闭  
    unsigned char mask = 0x01; // 掩码,用于控制每一位的LED  
    int running = 1; // 控制跑马灯是否运行  
  
    while (running) {  
        // 模拟每个LED灯打开并关闭  
        for (int i = 0; i < 8; ++i) {  
            // 打开当前LED灯  
            psw |= mask; // 使用按位或运算设置当前位  
            printf("psw: 0x%X\n", psw); // 输出当前psw的值  
            Sleep(1000); // 等待1秒  
  
            // 关闭当前LED灯  
            psw &= ~mask; // 使用按位取反和按位与运算清除当前位
            //也可以用按位异或运算符 psw=psw^mask;
            printf("psw: 0x%X\n", psw); // 输出当前psw的值  
            Sleep(1000); // 等待1秒  
  
            // 将掩码左移一位,以控制下一个LED灯  
            mask <<= 1;  
  
            // 如果掩码超过了一个字节的界限,重置它回到最低位  
            if (mask == 0) {  
                mask = 0x01;  
            }  
  
            // 检查是否有按键按下以停止跑马灯  
            if (_kbhit()) {  
                int ch = _getch();  
                if (ch != '\0' && ch != EOF) {  
                    running = 0; // 如果有任意键被按下,停止跑马灯  
                }  
            }  
        }  
    }  
  
    printf("跑马灯已停止。\n");  
    return 0;  
}
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值