C语言运算符优先级如何确定?

99ANYc3cd6
预计阅读时长 12 分钟
位置: 首页 C语言 正文

& 在 C 语言中是一个位运算符,称为按位与(Bitwise AND),它的核心功能是对两个整数的二进制表示形式,逐位进行“与”运算

c语言中 是怎么运算的的
(图片来源网络,侵删)

核心概念:按位与

“与”运算的规则是:对于两个二进制位,只有当两者都为 1 时,结果的对应位才为 1,否则,结果为 0。

可以总结为:

  • 1 & 1 = 1
  • 1 & 0 = 0
  • 0 & 1 = 0
  • 0 & 0 = 0

运算过程: 当对两个整数进行 & 运算时,C 编译器会将它们转换成二进制形式,然后对齐每一位(从最低位到最高位),逐对应用上述规则,最后得到一个新的二进制数,这个数就是运算结果。


运算示例

让我们通过一个具体的例子来理解,假设我们要计算 12 & 10

c语言中 是怎么运算的的
(图片来源网络,侵删)

第一步:将十进制数转换为二进制

  • 12 的二进制是 1100
  • 10 的二进制是 1010

为了方便对齐,我们通常写成相同位数的形式:

  12:  1100
  10:  1010

第二步:逐位进行“与”运算 我们从右到左(从最低位到最高位)逐位计算:

  • 第 0 位 (最右边): 0 & 0 = 0
  • 第 1 位: 0 & 1 = 0
  • 第 2 位: 1 & 0 = 0
  • 第 3 位: 1 & 1 = 1

组合起来,得到的结果二进制是 1000

第三步:将结果二进制转换回十进制

  • 1000 (二进制) = 1 * 2³ + 0 * 2² + 0 * 2¹ + 0 * 2⁰ = 8 + 0 + 0 + 0 = 8

12 & 10 的结果是 8


& 的主要用途

& 运算符在 C 语言中有几个非常重要的用途,远不止简单的数值计算。

位屏蔽

这是 & 最常见的用途,它的作用是从一个数的二进制位中“提取”或“保留”我们想要的某些位,同时忽略(置为0)其他位

原理:

  • 要保留的位,与 1 进行 & 运算。x & 1 的结果永远是 x 本身的值。
  • 要屏蔽(置为0)的位,与 0 进行 & 运算。x & 0 的结果永远是 0

示例: 假设我们有一个 8 位的无符号数 char a = 173,其二进制为 10101101。 我们只想知道它的低4位是什么。

我们可以构造一个“掩码”(Mask)0x0F(十六进制),它的二进制是 00001111

#include <stdio.h>
int main() {
    unsigned char a = 173; // 二进制: 10101101
    unsigned char mask = 0x0F; // 二进制: 00001111
    unsigned char result = a & mask;
    printf("原始值 a: %u (二进制: 10101101)\n", a);
    printf("掩码 mask: %u (二进制: 00001111)\n", mask);
    printf("结果 a & mask: %u (二进制: 00001101)\n", result);
    return 0;
}

运算过程:

  10101101  (a)
& 00001111  (mask)
-----------
  00001101  (result)

结果 00001101 13,成功提取了低4位。

检查某一位是否为 1

这是位屏蔽的一个特例,如果我们想知道一个数的特定位(比如第2位)是否为 1,我们可以用 1 左移到该位置,然后与原数进行 & 运算。

原理:

  • 如果结果的值为 0,说明该位是 0
  • 如果结果的值不为 0(等于那个移位后的值),说明该位是 1

示例: 检查 a 的第 2 位(从0开始计数)是否为 1

#include <stdio.h>
int main() {
    unsigned char a = 12; // 二进制: 1100
    // 我们想检查第2位 (值为 4, 即 1 << 2)
    unsigned char bit_to_check = 1 << 2; // 结果是 4 (二进制 0100)
    if ((a & bit_to_check) != 0) {
        printf("第2位是 1\n");
    } else {
        printf("第2位是 0\n");
    }
    unsigned char b = 13; // 二进制: 1101
    if ((b & bit_to_check) != 0) {
        printf("第2位是 1\n");
    } else {
        printf("第2位是 0\n");
    }
    return 0;
}

对于 a = 12 (1100),1100 & 0100 = 0100 (不为0),所以输出 "第2位是 1"。 对于 b = 13 (1101),1101 & 0100 = 0100 (不为0),所以也输出 "第2位是 1"。

取一个变量的内存地址

重要提示: & 还有一个完全不同的用法,作为取地址运算符

& 用在变量名前面时,它不是进行位运算,而是返回该变量在内存中的地址,这个操作对于指针至关重要。

示例:

#include <stdio.h>
int main() {
    int num = 100;
    int *ptr; // 声明一个整型指针
    ptr = &num; // 将 num 的内存地址赋给 ptr
    printf("变量 num 的值: %d\n", num);
    printf("变量 num 的地址: %p\n", &num);
    printf("指针 ptr 存储的地址: %p\n", ptr);
    printf("通过指针 ptr 访问的值: %d\n", *ptr);
    return 0;
}

在这个例子中:

  • &num 的意思是“获取 num 变量的地址”。
  • %pprintf 中用于打印地址的格式说明符。

用法 名称 作用 示例
a & b 按位与 (Bitwise AND) 对两个整数的二进制位逐位进行“与”运算。 12 & 10 结果是 8
&variable 取地址 (Address-of) 获取一个变量在内存中的地址。 int *p = &x;

如何区分? 非常简单,看 & 后面跟着什么:

  • & 后面是一个变量名,那么它是取地址运算符
  • & 两边是完整的表达式或变量,那么它是按位与运算符

理解 & 的这两种截然不同的用法是掌握 C 语言的关键一步。

-- 展开阅读全文 --
头像
c语言数字字符怎么输入数字
« 上一篇 03-08
dede文章页调用摘要
下一篇 » 03-08

相关文章

取消
微信二维码
支付宝二维码

目录[+]