news 2026/5/10 23:10:42

快速学C语言——第 4 章:运算符与表达式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
快速学C语言——第 4 章:运算符与表达式

第 4 章:运算符与表达式

​ 在编程中,我们经常需要对数据进行各种计算和比较,就像在数学中一样。C 语言提供了一系列运算符,让我们能够对变量和值进行赋值、计算、比较、逻辑判断等操作。将变量、常量和运算符按照语法规则组合在一起,就形成了表达式。表达式会产生一个具体的值,是构建程序逻辑(如条件判断、循环执行、数据计算)的基础组成部分。

4.1 算术运算符

算术运算符用于执行基本的数学运算,包括加、减、乘、除、取模(求余数),适用于数值类型(整型、浮点型)数据。

运算符描述示例结果
+加法5 + 38
-减法10 - 46
*乘法6 * 742
/除法15 / 43 (整数除法)
%取模 (求余数)15 % 43

​ 关键注意事项:

​ 1、整数除法:两个整型数据相除时,结果会自动舍弃小数部分(仅保留整数),而非四舍五入。

​ 2、浮点数除法:若至少有一个操作数是浮点型(float/double),则结果为浮点型,保留小数部分。

​ 3、取模运算:仅适用于整型数据,用于计算除法后的余数,结果的正负号与被除数一致(如10 % 3 = 1-10 % 3 = -1)。

示例:

#include<stdio.h>intmain(){inta=15,b=4;floatc=15.0f;// 浮点型操作数。intd=-15;printf("15 + 4 = %d\n",a+b);// 输出:19(整数加法)。printf("15 - 4 = %d\n",a-b);// 输出:11(整数减法)。printf("15 * 4 = %d\n",a*b);// 输出:60(整数乘法)。printf("15 / 4 = %d\n",a/b);// 输出:3(整数除法,舍弃小数)。printf("15.0f / 4 = %.2f\n",c/b);// 输出:3.75(浮点数除法)。printf("15 %% 4 = %d\n",a%b);// 输出:3(取模,正数余数)。printf("-15 %% 4 = %d\n",d%b);// 输出:-3(取模,余数与被除数同号)。return0;}

4.2 赋值运算符

​ 赋值运算符用于将右侧的值或表达式结果赋给左侧的变量,最基础的是=,C 语言还提供了复合赋值运算符(结合算术 / 位运算的简化写法),让代码更简洁。

运算符描述示例等价于
=简单赋值x = 5x = 5
+=加后赋值x += 3x = x + 3
-=减后赋值x -= 2x = x - 2
*=乘后赋值x *= 4x = x * 4
/=除后赋值x /= 2x = x / 2
%=取模后赋值x %= 3x = x % 3

​ 关键注意事项:

​ 1、赋值运算符的左侧必须是 “可修改的变量”(如a = 5合法,5 = a非法)。

​ 2、复合赋值运算符会先执行运算,再赋值,优先级低于算术运算符。

​ 3、赋值表达式本身也有值,值为 “赋值后变量的结果”(如a = b = 5等价于b = 5; a = 5,右结合)。

示例:

#include<stdio.h>intmain(){intx=10;x+=5;// 等价于 x = x + 5 → x = 15。printf("x += 5 后,x = %d\n",x);// 输出:15。x*=2;// 等价于 x = x * 2 → x = 30。printf("x *= 2 后,x = %d\n",x);// 输出:30。x%=7;// 等价于 x = x % 7 → 30 ÷ 7 = 4余2 → x = 2。printf("x %%= 7 后,x = %d\n",x);// 输出:2。// 赋值表达式的右结合性。inta,b;a=b=8;// 先执行 b = 8,再执行 a = b。printf("a = %d, b = %d\n",a,b);// 输出:a = 8, b = 8。return0;}

4.3 关系运算符

​ 关系运算符用于比较两个值的大小或相等关系,结果是逻辑值 ——1 表示 “真”(条件成立),0 表示 “假”(条件不成立)。关系运算的结果常用于条件判断(如 if 语句、循环条件)。

运算符描述示例结果
==等于5 == 30 (假)
!=不等于5 != 31 (真)
>大于5 > 31 (真)
<小于5 < 30 (假)
>=大于等于5 >= 51 (真)
<=小于等于5 <= 30 (假)

​ 关键注意事项:

​ 1、区分==(相等判断)和=(赋值):这是最常见的编程错误之一(如if (a == 5)是判断,if (a = 5)是赋值,永远为真)。

​ 2、浮点数比较:由于精度问题,不建议直接用==比较浮点数(如3.14 == 3.1400000001可能为假),应判断两者差值的绝对值是否小于极小值(如fabs(a - b) < 1e-6)。

示例:

#include<stdio.h>#include<math.h>// 用于fabs函数(浮点数绝对值)。intmain(){inta=10,b=20;floatpi1=3.14f,pi2=3.1400001f;printf("%d == %d 的结果是:%d\n",a,b,a==b);// 输出:0(假)。printf("%d != %d 的结果是:%d\n",a,b,a!=b);// 输出:1(真)。printf("%d > %d 的结果是:%d\n",a,b,a>b);// 输出:0(假)。printf("%d < %d 的结果是:%d\n",a,b,a<b);// 输出:1(真)。// 浮点数比较的正确方式。if(fabs(pi1-pi2)<1e-6){// 差值小于10的-6次方,视为相等。printf("pi1 和 pi2 相等\n");}else{printf("pi1 和 pi2 不相等\n");}return0;}

4.4 逻辑运算符

​ 逻辑运算符用于组合多个关系表达式(或逻辑值),形成更复杂的条件判断,结果同样是 1(真)或 0(假)。C 语言支持 “短路求值”,能提高运算效率。

运算符描述示例结果短路求值规则
&&逻辑与 (AND)(5 > 3) && (5 < 10)1 (真)左侧为假则右侧不执行
||逻辑或 (OR)(5 > 3) || (5 < 2)1 (真)左侧为真则右侧不执行
!逻辑非 (NOT)!(5 > 3)0 (假)无(单目运算符)

​ 关键注意事项:

​ 1、逻辑与(&&):所有条件都为真,结果才为真;只要有一个为假,结果为假。

​ 2、逻辑或(||):只要有一个条件为真,结果就为真;所有条件都为假,结果才为假。

​ 3、逻辑非(!):将真变假、假变真(如!0 = 1!5 = 0——C 语言中 “非 0 值都视为真”)。

​ 4、短路求值:逻辑与左侧为假时,右侧表达式不执行;逻辑或左侧为真时,右侧表达式不执行(避免无效计算或副作用)。

示例:

#include<stdio.h>intmain(){intage=20;inthas_license=1;// 1表示真(有驾照),0表示假(无驾照)。intx=5,y=10;// 逻辑与:两个条件都满足才为真。intcan_drive=(age>=18)&&has_license;printf("可以开车:%d\n",can_drive);// 输出:1(真)。// 逻辑或:满足一个条件即为真。intis_young_or_old=(age<18)||(age>65);printf("是年轻人或老年人:%d\n",is_young_or_old);// 输出:0(假)。// 逻辑非:取反。intno_license=!has_license;printf("没有驾照:%d\n",no_license);// 输出:0(假)。// 短路求值示例:逻辑与左侧为假,右侧x++不执行。intresult1=(x>10)&&(x++);printf("result1 = %d, x = %d\n",result1,x);// 输出:0,x = 5(x++未执行)。// 短路求值示例:逻辑或左侧为真,右侧y++不执行。intresult2=(y>5)||(y++);printf("result2 = %d, y = %d\n",result2,y);// 输出:1,y = 10(y++未执行)。return0;}

4.5 自增和自减运算符(⚠️不建议大量使用)

自增(++)自减(–)是单目运算符,用于将变量的值 “直接增加 1” 或 “减少 1”,分为前缀和后缀两种形式,核心区别是 “增减操作” 和 “取值操作” 的执行顺序。

运算符描述示例核心区别
++自增++x(前缀)先自增,再取值
++自增x++(后缀)先取值,再自增
自减–x(前缀)先自减,再取值
自减x–(后缀)先取值,再自减

​ 关键注意事项:

​ 1、仅适用于变量(如++5非法,x++合法),因为需要修改变量的值。

​ 2、避免在同一表达式中多次使用(如x++ + ++x),结果依赖编译器实现,无统一标准,易出错。

示例:

#include<stdio.h>intmain(){intx=5,y,z;// 后缀自增:先赋值(y = x=5),再自增(x=6)。y=x++;printf("x = %d, y = %d\n",x,y);// 输出:x = 6, y = 5。x=5;// 重置x。// 前缀自增:先自增(x=6),再赋值(y=6)。y=++x;printf("x = %d, y = %d\n",x,y);// 输出:x = 6, y = 6。// 自减示例。z=10;printf("z-- = %d\n",z--);// 后缀:先取值(10),再自减(z=9)。printf("z = %d\n",z);// 输出:9。printf("--z = %d\n",--z);// 前缀:先自减(z=8),再取值(8)。return0;}

4.6 条件运算符(三元运算符,⚠️了解即可)

​ 条件运算符是 C 语言中唯一的三目运算符,语法简洁,用于简化二选一的条件判断,等价于简单的if-else语句。

​ 语法格式:条件表达式 ? 表达式1 : 表达式2

​ ● 执行逻辑:先判断 “条件表达式” 的真假。

​ ● 若为真(非 0),整个表达式的值为 “表达式 1” 的值。

​ ● 若为假(0),整个表达式的值为 “表达式 2” 的值。

​ 关键注意事项:

​ 1、优先级低于关系运算符和算术运算符,高于赋值运算符。

​ 2、结合性为 “右结合”(如a ? b : c ? d : e等价于a ? b : (c ? d : e))。

​ 3、表达式 1 和表达式 2 的类型应一致(或可隐式转换),避免类型不匹配。

示例:

#include<stdio.h>intmain(){inta=10,b=20;intmax,min;intnumber=15;// 求两个数的最大值(等价于 if(a>b) max=a; else max=b;) 。max=(a>b)?a:b;printf("较大的数是:%d\n",max);// 输出:20。// 求两个数的最小值。min=(a<b)?a:b;printf("较小的数是:%d\n",min);// 输出:10。// 判断奇偶数。printf("%d是%s\n",number,(number%2==0)?"偶数":"奇数");// 输出:15是奇数。// 右结合示例:a=10为真,直接返回b=20,不执行后续判断。intresult=(a>5)?b:(b>15)?30:40;printf("result = %d\n",result);// 输出:20。return0;}

4.7 逗号运算符(⚠️了解即可)

​ 逗号运算符用于将多个表达式分隔开,按从左到右的顺序依次执行,整个逗号表达式的值为 “最后一个表达式” 的值。

​ 语法格式:表达式1, 表达式2, ..., 表达式n

​ ● 执行逻辑:先执行表达式 1,再执行表达式 2,…,最后执行表达式 n,最终结果为表达式 n 的值。

​ ● 优先级:所有运算符中最低,低于赋值运算符(如需改变优先级,需加括号)。

​ 适用场景:在允许单个表达式的位置(如 for 循环的初始化 / 更新部分)执行多个操作。

示例:

#include<stdio.h>intmain(){inta=1,b=2,c,d;// 逗号表达式:先执行a++,再执行b++,最终值为b++后的结果(3)。c=(a++,b++,b+1);printf("a = %d, b = %d, c = %d\n",a,b,c);// 输出:a=2, b=3, c=4。// 无括号时:赋值运算符优先级更高,先执行c = a++,再执行b++,逗号表达式值为b++(3)。a=1,b=2;// 重置。d=a++,b++,b+1;printf("a = %d, b = %d, d = %d\n",a,b,d);// 输出:a=2, b=3, d=1(d = a++的结果)。// for循环中使用:初始化a=0、b=5,更新时a++、b--。for(inti=0;i<3;i++,a++,b--){printf("i = %d, a = %d, b = %d\n",i,a,b);}// 输出:// i = 0, a = 2, b = 3// i = 1, a = 3, b = 2// i = 2, a = 4, b = 1return0;}

4.8 运算符的优先级与结合性

​ 当一个表达式包含多个运算符时,计算顺序由 “优先级” 和 “结合性” 共同决定 —— 优先级决定 “先执行哪个运算符”,结合性决定 “优先级相同时的执行顺序”。

4.8.1 常见运算符优先级(从高到低)
优先级运算符类别具体运算符
1括号()
2自增 / 自减(单目)++, --(前缀)、!、~(位非)
3算术运算符*, /, %(乘、除、取模)
4算术运算符+, -(加、减)
5关系运算符<, <=, >, >=
6关系运算符==, !=(相等 / 不等)
7逻辑运算符&&(逻辑与)
8逻辑运算符||(逻辑或)
9条件运算符?:
10赋值运算符=, +=, -=, *=, /=, %=
11逗号运算符,
4.8.2 结合性规则
  • 左结合:优先级相同时,从左到右执行(如算术运算符、关系运算符、逗号运算符)。

    • 示例:a + b - c等价于(a + b) - ca = b = 5是例外(赋值运算符右结合)。
  • 右结合:优先级相同时,从右到左执行(如赋值运算符、条件运算符)。

    • 示例:a = b = 5等价于a = (b = 5)a ? b : c ? d : e等价于a ? b : (c ? d : e)

      核心建议:当不确定优先级或结合性时,直接用括号明确执行顺序—— 既避免出错,又让代码更易读(括号优先级最高)。

示例:

#include<stdio.h>intmain(){inta=5,b=3,c=2,result;// 无括号:先乘后加(优先级:* > +)result=a+b*c;printf("a + b * c = %d\n",result);// 输出:11(5 + 3*2)// 有括号:先加后乘(括号改变优先级)result=(a+b)*c;printf("(a + b) * c = %d\n",result);// 输出:16((5+3)*2)// 结合性示例:赋值运算符右结合intx,y;x=y=10;// 等价于 x = (y = 10)printf("x = %d, y = %d\n",x,y);// 输出:10, 10return0;}

4.9 位运算符基础

​ 位运算符用于直接操作二进制位,适用于整型数据(char、int、long 等),底层编程(如硬件操作、数据压缩)中常用,基础阶段需掌握核心用法。

运算符描述示例(二进制)结果(二进制)
&按位与1010 & 0111 =0010
按位或1010 | 0111 =1111
^按位异或1010 ^ 0111 =1101
~按位非(取反)~1010 =0101(假设 4 位)
<<左移1010 << 1 =10100
>>右移1010 >> 1 =0101

关键说明:

  1. 按位与(&):对应位都为 1 时结果为 1,可用于 “清 0 某些位”。
  2. 按位或(|):对应位有一个为 1 时结果为 1,可用于 “置 1 某些位”。
  3. 按位异或(^):对应位不同时结果为 1,可用于 “交换变量”“翻转某些位”。
  4. 左移(<<):二进制位向左移动 n 位,右边补 0,等价于乘以 2^n(如a << 1等价于a * 2)。
  5. 右移(>>):二进制位向右移动 n 位,左边补符号位(正数补 0,负数补 1),等价于除以 2^n(取整)。

示例:

#include<stdio.h>intmain(){inta=10,b=7;// a=1010(二进制),b=0111(二进制)printf("a & b = %d\n",a&b);// 0010 → 2printf("a | b = %d\n",a|b);// 1111 → 15printf("a ^ b = %d\n",a^b);// 1101 → 13printf("~a = %d\n",~a);// 按位取反(依赖系统位数,结果为负数)printf("a << 1 = %d\n",a<<1);// 10100 → 20(10*2)printf("a >> 1 = %d\n",a>>1);// 0101 → 5(10/2)return0;}

笔记

  1. 算术运算符中,整数除法会舍弃小数,取模仅适用于整型,浮点数比较需用 “差值绝对值” 避免精度问题。
  2. 区分==(相等判断)和=(赋值),这是高频编程错误。
  3. 逻辑运算符支持 “短路求值”,左侧结果可确定时,右侧表达式不执行,需避免依赖右侧副作用(如x++)。
  4. 自增 / 自减的前缀和后缀核心区别:前缀 “先增减再取值”,后缀 “先取值再增减”,避免同一表达式多次使用。
  5. 条件运算符(?:)简化二选一逻辑,结合性为右结合;逗号运算符优先级最低,结果为最后一个表达式的值。
  6. 优先级:括号 > 算术 > 关系 > 逻辑 > 条件 > 赋值 > 逗号,不确定时用括号明确顺序。
  7. 位运算符直接操作二进制位,左移等价于乘 2、右移等价于除 2(取整),仅适用于整型数据。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/10 23:02:39

Rust异步运行时:从Tokio到生产环境实践

Rust异步运行时&#xff1a;从Tokio到生产环境实践 引言 异步编程是现代高性能后端服务的关键技术。Rust通过async/await语法和强大的运行时实现&#xff0c;提供了卓越的异步性能。 本文将深入探讨Rust的异步运行时&#xff0c;包括Tokio、async-std等运行时的原理、使用方法和…

作者头像 李华
网站建设 2026/5/10 22:59:35

PlayCover多语言支持完整指南:让全球用户享受本地化体验

PlayCover多语言支持完整指南&#xff1a;让全球用户享受本地化体验 【免费下载链接】PlayCover Community fork of PlayCover 项目地址: https://gitcode.com/gh_mirrors/pl/PlayCover PlayCover作为一款强大的iOS应用兼容性工具&#xff0c;其多语言支持功能让全球用户…

作者头像 李华
网站建设 2026/5/10 22:58:25

基于微信平台健身小助手小程序(30285)

有需要的同学&#xff0c;源代码和配套文档领取&#xff0c;加文章最下方的名片哦 一、项目演示 项目演示视频 二、资料介绍 完整源代码&#xff08;前后端源代码SQL脚本&#xff09;配套文档&#xff08;LWPPT开题报告/任务书&#xff09;远程调试控屏包运行一键启动项目&…

作者头像 李华
网站建设 2026/5/10 22:55:51

雨天高速公路元胞传输模型可变限速控制方法【附程序】

✨ 本团队擅长数据搜集与处理、建模仿真、程序设计、仿真代码、EI、SCI写作与指导&#xff0c;毕业论文、期刊论文经验交流。 ✅ 专业定制毕设、代码 ✅如需沟通交流&#xff0c;点击《获取方式》 &#xff08;1&#xff09;雨天改进元胞传输模型参数标定与验证&#xff1a; 在…

作者头像 李华
网站建设 2026/5/10 22:55:50

国电智深DCS污水处理自动控制组态与模糊PID优化【附方案】

✨ 本团队擅长数据搜集与处理、建模仿真、程序设计、仿真代码、EI、SCI写作与指导&#xff0c;毕业论文、期刊论文经验交流。 ✅ 专业定制毕设、代码 ✅如需沟通交流&#xff0c;点击《获取方式》 &#xff08;1&#xff09;基于EDPF-NT的三容水箱液位模糊PID控制与改进PSO优化…

作者头像 李华
网站建设 2026/5/10 22:55:49

在多模型聚合调用中体验taotoken的路由容灾能力

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 在多模型聚合调用中体验 Taotoken 的路由容灾能力 在构建面向生产环境的 AI 应用时&#xff0c;服务的稳定性是开发者必须面对的核…

作者头像 李华