当前位置: 首页 > news >正文

第10讲:操作符详解——掌握C语言的“运算密码”

🧰 第10讲:操作符详解——掌握C语言的“运算密码” 🔐

适合已掌握基本语法的你,深入理解操作符背后的二进制世界!


📚 目录

  1. 操作符分类总览 🗂️
  2. 进制与转换:二进制的奥秘 🔢
  3. 原码、反码、补码:计算机的“负数语言” 📝
  4. 移位操作符:<< 和 >> 的魔法 ✨
  5. 位操作符:&、|、^、~ 的位运算艺术 🎨
  6. 单目操作符回顾 🔍
  7. 逗号表达式:被低估的“顺序执行器” 💬
  8. 下标 [] 与函数调用 () 操作符 🧩
  9. 结构成员访问:.-> 🏗️
  10. 操作符属性:优先级与结合性 ⚖️
  11. 表达式求值的“陷阱”与规则 🕳️

操作符分类总览 🗂️

类别操作符示例
算术+, -, *, /, %5 + 3
移位<<, >>8 << 1
位操作&, `, ^`, `~`
赋值=, +=, -=, *=, /=, %= <<=, >>=, &=, `=, ^=`
单目!, ++, --, &, *, +, -, ~, sizeof, (类型)!flag, ++i
关系>, >=, <, <=, ==, !=a > b
逻辑&&, `
条件? :a > b ? a : b
逗号,a=1, b=2, c=3
下标[]arr[0]
函数调用()func()
结构成员., ->s.name, ptr->age

📌 本讲重点:深入讲解移位、位操作、结构体、优先级、表达式求值等底层机制。


进制与转换:二进制的奥秘 🔢

🌍 什么是进制?

  • 进制是数值的不同表示形式。
  • 常见进制:2进制(0,1)、8进制(0-7)、10进制(0-9)、16进制(0-9, a-f)
✅ 示例:数值15的表示
进制表示前缀
二进制1111-
八进制170
十进制15-
十六进制F0x

🔁 二进制 ↔ 十进制转换

🔄 2进制 → 10进制

方法:按权展开,从右到左,权重为 2^0, 2^1, 2^2, ...

二进制: 1101= 1×2³ + 1×2² + 0×2¹ + 1×2= 8 + 4 + 0 + 1 = 13
🔁 10进制 → 2进制

方法:除2取余,逆序排列

13 ÷ 2 = 61
6  ÷ 2 = 30
3  ÷ 2 = 11
1  ÷ 2 = 01
→ 二进制: 1101

🔀 2进制 ↔ 8进制 / 16进制

🔄 2进制 → 8进制
  • 规则:每3位二进制 → 1位八进制(从右向左)
二进制: 011 010 113   2   3
→ 八进制: 0323
🔄 2进制 → 16进制
  • 规则:每4位二进制 → 1位十六进制
二进制: 0110 10116    b
→ 十六进制: 0x6b

原码、反码、补码:计算机的“负数语言” 📝

计算机中整数以补码形式存储

类型符号位数值位
原码0正1负直接二进制
反码不变原码取反
补码不变反码 + 1

🧮 示例:-3 的表示(8位)

原码:  10000011
反码:  11111100
补码:  11111101

正数:原、反、补码相同
存储:内存中存放的是补码


移位操作符:<< 和 >> 的魔法 ✨

只能用于整数!

⬅️ 左移 <<

  • 规则:左边丢弃,右边补0
  • 效果num << nnum * 2^n
int num = 10; // 1010
int n = num << 1; // 10100 = 20

➡️ 右移 >>

  • 逻辑右移:左边补0(无符号数)
  • 算术右移:左边补符号位(有符号数)
int num = 10; // 1010
int n = num >> 1; // 101 = 5
⚠️ 警告
  • 禁止移位负数位num >> -1 → 未定义行为!

位操作符:&、|、^、~ 的位运算艺术 🎨

操作数必须是整数!

操作符名称规则
&按位与同1为1
``按位或
^按位异或不同为1
~按位取反0变1,1变0

💡 实战案例

🔄 交换两个数(不使用临时变量)
int a = 10, b = 20;
a = a ^ b;
b = a ^ b; // b = (a^b)^b = a
a = a ^ b; // a = (a^b)^a = b
📊 统计二进制中1的个数
// 方法1:循环32次
int count = 0;
for (int i = 0; i < 32; i++) {if (num & (1 << i)) count++;
}// 方法2:优化版(推荐)
int count = 0;
while (num) {count++;num &= (num - 1); // 消除最右边的1
}
🔧 二进制位置0或置1
int a = 13; // 1101
a |= (1 << 4);  // 第5位置1 → 11101
a &= ~(1 << 4); // 第5位置0 → 1101

单目操作符回顾 🔍

操作符说明
!逻辑非
++, --自增/自减
&取地址(指针部分讲解)
*解引用(指针部分讲解)
+, -正负号
~按位取反
sizeof计算大小(字节)
(类型)强制类型转换

逗号表达式:被低估的“顺序执行器” 💬

格式exp1, exp2, ..., expN
规则:从左到右执行,结果为最后一个表达式的值。

int c = (a=1, b=2, a+b); // c = 3

🔄 实际应用:简化循环

// 传统写法
a = get_val();
count_val(a);
while (a > 0) {// 处理a = get_val();count_val(a);
}// 逗号表达式写法
while (a = get_val(), count_val(a), a > 0) {// 处理
}

下标 [] 与函数调用 () 操作符 🧩

🧱 [] 下标访问

  • 操作数:数组名 + 索引
  • 等价arr[i]*(arr + i)
int arr[10];
arr[9] = 10; // 使用下标操作符

🧩 () 函数调用

  • 操作数:函数名 + 参数列表
void test(const char *str) {printf("%s\n", str);
}
test("hello"); // () 是函数调用操作符

结构成员访问:.-> 🏗️

🏗️ 结构体定义

struct Stu {char name[20];int age;char id[20];
};

✅ 成员访问

操作符用法场景
.s.name结构体变量
->ptr->name结构体指针
struct Stu s = {"zhangsan", 20};
struct Stu *ptr = &s;printf("%s\n", s.name);     // .
printf("%d\n", ptr->age);   // ->

📌 更多结构体知识见第19讲


操作符属性:优先级与结合性 ⚖️

决定表达式求值顺序的两大法则!

🔝 10.1 优先级

  • 优先级高的操作符先执行。
3 + 4 * 5; // 先算 4*5,因为 * 优先级 > +

↔️ 10.2 结合性

  • 优先级相同时,按结合性决定顺序。
类别例子执行顺序
左结合5 * 6 / 2(5*6)/2
右结合a = b = 5a=(b=5)

📊 常见操作符优先级(从高到低)

1. ()      // 圆括号
2. ++ --   // 自增/自减
3. + - ~ ! // 单目
4. * / %   // 算术
5. + -     // 算术
6. < <= > >= // 关系
7. == !=   // 相等
8. & ^ |   // 位操作
9. && ||   // 逻辑
10. ?:     // 条件
11. = += -= // 赋值
12. ,      // 逗号

📌 建议:复杂表达式加括号明确优先级!


表达式求值的“陷阱”与规则 🕳️

🔼 11.1 整型提升(Integer Promotion)

  • 规则:小于 int 的类型(如 char)在运算前会提升为 int
  • 目的:CPU运算器通常以 int 长度操作。
char a = 1, b = 2;
char c = a + b; // a,b 提升为int,相加后截断赋值
📌 提升规则
  • 有符号:高位补符号位
  • 无符号:高位补0

🔁 11.2 算术转换(Usual Arithmetic Conversion)

当操作数类型不同时,按以下顺序转换:

long double
double
float
unsigned long int
long int
unsigned int
int

原则:低类型 → 高类型


⚠️ 11.3 问题表达式解析

❌ 表达式1:a*b + c*d + e*f
  • * 优先级高于 +,但无法确定 c*de*f 谁先计算。
  • 结论:依赖编译器优化,但结果确定。
❌ 表达式2:c + --c
  • -- 优先级高,但无法确定 c 的取值时机。
  • 结果:未定义,有歧义 ❌
❌ 表达式3:i = i-- - --i * (i = -3) * i++ + ++i;
  • 包含多个副作用(++, --, =),求值顺序未定义。
  • 不同编译器结果不同非法表达式
❌ 表达式4:answer = fun() - fun() * fun();
  • * 优先级高,但三个 fun() 调用顺序不确定。
  • 副作用:静态变量 count 的结果依赖调用顺序。
❌ 表达式5:ret = (++i) + (++i) + (++i);
  • GCC 和 VS 结果不同!
  • 原因:前置 +++ 的执行顺序未由优先级决定。

✅ 学习收获总结

技能掌握情况
✅ 理解二进制、八进制、十六进制转换✔️
✅ 掌握原码、反码、补码表示✔️
✅ 熟练使用移位和位操作符✔️
✅ 理解结构体与成员访问✔️
✅ 掌握操作符优先级与结合性✔️
✅ 识别危险表达式,避免未定义行为✔️

🎯 操作符是C语言的“底层语言”
你已经掌握了位运算、补码、表达式求值等核心知识,下一步就是深入指针的世界!💪🔥

💬 需要本讲的 位运算可视化工具 / 表达式求值动画 / 源码工程?欢迎继续提问,我可以一键打包给你!

http://www.dtcms.com/a/454332.html

相关文章:

  • 安平县哪家做网站手机站电影
  • 大淘客网站上的推广怎么做网站建设设计风格描述
  • 简述常用的网站开发软件产品设计和工业设计有什么区别
  • 建设网站制作汉狮团队wordpress mysql 挂了
  • 移动端公众号网站开发软文发稿平台有哪些
  • 计算机操作系统:操作系统的目标与作用
  • paypal客户端网站建设评价网页制作收入
  • 重庆做兼职哪个网站网页升级跳转自动刷新
  • 网站 翻页 实现网站集约化建设方案
  • 公司网站管理图片制作ppt的软件是什么
  • Altium Desinger阵列式粘贴使用
  • 临沂seo网站推广曹鹏wordpress教程 下载
  • PyQt批量年龄计算工具:从身份证到指定日期的周岁处理
  • L2TPv2-原理浅谈+报文示例+简易配置-RFC2661
  • 信息系统项目的风险管理
  • hot100-3
  • 网站推广的措施和手段有哪些网站优化顺义案例
  • CompletableDeferred、defer 和 Job 关系
  • 呼市做引产z首大网站网站设计和建设ppt
  • 做面膜的网站如何才能做好品牌网站建设策划
  • 外贸社交网站排名网站搜不出来怎么办
  • 做影视网站规模不大洛阳网站建设哪个好点
  • 《投资-82》价值投资者的认知升级与交易规则重构 - 第二层:五大财务指标的定义、分析方法、误区
  • 做网站哪家强wordpress 不用插件代码高亮
  • string类的理解和使用
  • 做羞羞网站谷歌广告联盟怎么做
  • 网站规划建设与管理维护的论文软件推广
  • 备案的网站名称可以改吗pc网站怎么做适配
  • 用 AI 工具简化西瓜视频用户增长实操教程
  • 滁州市建设工程协会网站免费logo设计在线生成器钙网