当前位置:首页 > 技术 > 正文内容

C语言运算符与表达式

访客 技术 2026年9月9日 11

一、运算符概述

在C语言中,运算符用于对变量和常量进行操作。C语言提供了多种运算符,可以执行数学运算、逻辑判断、位操作等任务。

运算符分类

  1. 算术运算符:执行基本数学运算
  2. 关系运算符:比较两个值的大小
  3. 逻辑运算符:组合多个条件
  4. 位运算符:对整数的二进制位进行操作
  5. 赋值运算符:给变量赋值
  6. 其他运算符:包括条件运算符、逗号运算符、sizeof运算符等

二、算术运算符

算术运算符用于执行数学运算。

运算符 描述 示例
+ 加法 x + y
- 减法 x - y
* 乘法 x * y
/ 除法 x / y
% 取模 x % y
++ 前缀/后缀自增 ++x 或 x++
-- 前缀/后缀自减 --x 或 x--
#include <stdio.h>
int main_function() {
    int x = 10, y = 3;
    
    printf("x + y = %d\n", x + y);      // 13
    printf("x - y = %d\n", x - y);      // 7
    printf("x * y = %d\n", x * y);      // 30
    printf("x / y = %d\n", x / y);      // 3 (整数除法)
    printf("x %% y = %d\n", x % y);     // 1
    
    // 自增运算符示例
    int a = 5;
    printf("a++ = %d\n", a++);          // 先使用a的值5,然后a变为6
    printf("++a = %d\n", ++a);           // a先变为7,然后使用a的值7
    
    // 浮点数除法示例
    float m = 10.0, n = 3.0;
    printf("m / n = %f\n", m / n);      // 3.333333
    
    return 0;
}

三、关系运算符

关系运算符用于比较两个值,返回布尔值(0或1)。

运算符 描述 示例
== 等于 a == b
!= 不等于 a != b
> 大于 a > b
< 小于 a < b
>= 大于等于 a >= b
<= 小于等于 a <= b
#include <stdio.h>
int main_function() {
    int x = 10, y = 20;
    printf("%d == %d: %d\n", x, y, x == y); // 0
    printf("%d != %d: %d\n", x, y, x != y); // 1
    printf("%d > %d: %d\n", x, y, x > y);    // 0
    printf("%d < %d: %d\n", x, y, x < y);    // 1
    printf("%d >= %d: %d\n", x, y, x >= y); // 0
    printf("%d <= %d: %d\n", x, y, x <= y); // 1
    
    return 0;
}

四、逻辑运算符

逻辑运算符用于组合多个条件。

运算符 描述 示例
&& 逻辑与 p && q
! 逻辑非 !p
#include <stdio.h>
int main_function() {
    int p = 1, q = 0;
    
    printf("%d && %d: %d\n", p, q, p && q); // 0
    printf("%d || %d: %d\n", p, q, p || q);  // 1
    printf("!%d: %d\n", p, !p);              // 0
    printf("!%d: %d\n", q, !q);              // 1
    
    // 短路求值示例
    int m = 0, n = 1;
    if(m != 0 && n/m > 1) {  
        printf("This won't be printed\n");
    }
    
    return 0;
}

五、位运算符

位运算符直接操作整数的二进制位。

运算符 描述 示例
& 按位与 a & b
按位或
^ 按位异或 a ^ b
~ 按位取反 ~a
<< 左移 a << n
>> 右移 a >> n
#include <stdio.h>
int main_function() {
    unsigned char p = 0b0011, q = 0b0101; // 3和5的二进制表示
    
    printf("p & q: %d\n", p & q); // 0001 (1)
    printf("p | q: %d\n", p | q); // 0111 (7)
    printf("p ^ q: %d\n", p ^ q); // 0110 (6)
    printf("~p: %d\n", ~p & 0xFF); // 11111100 (252), 只取低8位
    
    printf("p << 1: %d\n", p << 1); // 0110 (6)
    printf("p >> 1: %d\n", p >> 1); // 0001 (1)
    
    // 使用位运算实现快速乘除
    int w = 10;
    printf("w * 8 = %d\n", w << 3); // 左移3位相当于乘以8
    printf("w / 4 = %d\n", w >> 2); // 右移2位相当于除以4
    
    return 0;
}

六、赋值运算符

赋值运算符用于给变量赋值。

运算符 描述 示例
= 简单赋值 a = b
+= 加后赋值 a += b
-= 减后赋值 a -= b
*= 乘后赋值 a *= b
/= 除后赋值 a /= b
%= 取模后赋值 a %= b
<<= 左移后赋值 a <<= b
>>= 右移后赋值 a >>= b
&= 按位与后赋值 a &= b
^= 按位异或后赋值 a ^= b
= 按位或后赋值
#include <stdio.h>
int main_function() {
    int a = 10;
    
    a += 5;  // 等价于 a = a + 5
    printf("a += 5: %d\n", a); // 15
    
    a -= 3;  // 等价于 a = a - 3
    printf("a -= 3: %d\n", a); // 12
    
    a *= 2;  // 等价于 a = a * 2
    printf("a *= 2: %d\n", a); // 24
    
    a /= 4;  // 等价于 a = a / 4
    printf("a /= 4: %d\n", a); // 6
    
    a %= 4;  // 等价于 a = a % 4
    printf("a %%= 4: %d\n", a); // 2
    
    a <<= 2; // 等价于 a = a << 2
    printf("a <<= 2: %d\n", a); // 8
    
    a |= 1;  // 等价于 a = a | 1
    printf("a |= 1: %d\n", a); // 9  
    return 0;
}

七、其他运算符

1. 条件运算符(三元运算符)

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

2. 逗号运算符

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

3. sizeof运算符

返回变量或类型的大小(以字节为单位)

4. 地址运算符

&:取地址运算符 *:指针运算符

#include <stdio.h>
int main_function() {
    // 条件运算符示例
    int x = 10, y = 20;
    int max_val = (x > y) ? x : y;
    printf("较大的数是: %d\n", max_val); // 20
    
    // 逗号运算符示例
    int a = 5, b = 10, c = (a++, b++, a + b);
    printf("c = %d, a = %d, b = %d\n", c, a, b); // c=15, a=6, b=11
    
    // sizeof运算符示例
    printf("int 类型大小: %zu 字节\n", sizeof(int));
    printf("double 类型大小: %zu 字节\n", sizeof(double));
    printf("变量x大小: %zu 字节\n", sizeof(x));
    
    // 地址运算符示例
    int val = 30;
    int *ptr = &val;
    printf("val的值: %d\n", val);
    printf("val的地址: %p\n", &val);
    printf("ptr指向的值: %d\n", *ptr);
    
    return 0;
}

八、运算符优先级和结合性

当表达式中有多个运算符时,C语言会根据运算符的优先级和结合性来决定运算顺序。

运算符优先级表(从高到低)

类别 运算符 结合性
后缀 () [] -> ++ -- 从左到右
一元 + - ! ~ ++ -- (type)* & sizeof 从右到左
乘除 * / % 从左到右
加减 + - 从左到右
移位 << >> 从左到右
关系 < <= > >= 从左到右
相等 == != 从左到右
位与 & 从左到右
位异或 ^ 从左到右
位或
逻辑与 && 从左到右
逻辑或
条件 ?: 从右到左
赋值 = += -= *= /= %= <<= >>= &= ^= =
逗号 , 从左到右
#include <stdio.h>

int main_function() {
    int a = 5, b = 10, c = 15;
    
    // 优先级示例
    int result1 = a + b * c;  // 等价于 a + (b * c)
    printf("a + b * c = %d\n", result1); // 155
    
    int result2 = (a + b) * c;
    printf("(a + b) * c = %d\n", result2); // 225
    
    // 结合性示例
    int d = a = b;  // 从右到左结合,等价于 a = b; d = a;
    printf("d = %d, a = %d\n", d, a); // 都是10
    
    int e = a + b + c;  // 从左到右结合,等价于 (a + b) + c
    printf("e = %d\n", e); // 35
    
    // 复杂表达式示例
    int f = a++ + b * (c - a);
    printf("f = %d, a = %d\n", f, a); // f=60, a=11
    
    return 0;
}

九、表达式

表达式是由运算符和操作数组成的式子,可以计算出一个值。

表达式类型

  1. 算术表达式:由算术运算符组成,如 a + b * c
  2. 关系表达式:由关系运算符组成,如 a > b
  3. 逻辑表达式:由逻辑运算符组成,如 a && b || c
  4. 赋值表达式:由赋值运算符组成,如 a = b + c
  5. 条件表达式:由条件运算符组成,如 a > b ? a : b
  6. 逗号表达式:由逗号运算符组成,如 a = (b++, c--)

表达式求值顺序

  1. 确定运算符的优先级
  2. 相同优先级的运算符根据结合性确定顺序
  3. 注意运算符的副作用(如自增自减)
#include <stdio.h>

int main_function() {
    // 算术表达式示例
    int a = 10, b = 20, c = 30;
    int result = a * b + c / a - b % a;
    printf("算术表达式结果: %d\n", result); // 200 + 3 - 0 = 203
    
    // 关系表达式示例
    if(a < b && b < c) {
        printf("a < b < c 成立\n");
    }
    
    // 逻辑表达式示例
    int flag1 = 1, flag2 = 0;
    if(flag1 || !flag2) {
        printf("逻辑表达式为真\n");
    }
    
    // 赋值表达式示例
    int m, n, o;
    m = n = o = 100;  // 从右到左赋值
    printf("m=%d, n=%d, o=%d\n", m, n, o);
    
    // 条件表达式示例
    int max_num = (a > b) ? a : b;
    printf("较大的数是: %d\n", max_num);
    
    // 逗号表达式示例
    int p = (a++, b++, c++, a + b + c);
    printf("p=%d, a=%d, b=%d, c=%d\n", p, a, b, c); // p=63, a=11, b=21, c=31
    
    return 0;
}

十、常见问题与注意事项

  1. 整数除法:两个整数相除结果仍是整数,小数部分被截断
  2. 运算符优先级混淆:使用括号明确运算顺序
  3. 自增自减的副作用:避免在同一个表达式中多次修改同一个变量
  4. 浮点数比较:由于精度问题,避免直接比较浮点数是否相等
  5. 短路求值:逻辑与和逻辑或运算符的短路特性
  6. 类型溢出:注意数据类型的范围,避免溢出
  7. 未定义行为:如 i = i++ 这样的表达式结果未定义
#include <stdio.h>
#include <math.h>

int main_function() {
    // 整数除法问题
    int x = 5, y = 2;
    float z = x / y;  // 结果是2.0而不是2.5
    printf("错误的除法: %.1f\n", z);
    
    // 正确的做法
    z = (float)x / y;
    printf("正确的除法: %.1f\n", z);
    
    return 0;
}

总结

掌握C语言的运算符和表达式是编写高效、正确程序的关键。以下是本文的要点总结:

  1. 运算符多样性:C语言提供了丰富的运算符类型,满足各种运算需求。
  2. 表达式灵活性:通过组合不同的运算符和操作数,可以构建复杂的表达式。
  3. 优先级与结合性:理解运算符的优先级和结合性是写出正确表达式的基础。
  4. 类型转换:混合类型运算时需要注意类型转换规则。
  5. 效率考量:位运算和复合赋值运算通常效率更高。
  6. 陷阱警示:自增/自减运算、整数除法、浮点数比较等问题需要特别注意。

记住,清晰可读的表达式往往比"聪明"但晦涩的写法更有价值。在保证正确性的前提下,适当考虑效率,这样的代码才是高质量的C语言代码。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。