C语言基础系列【12】运算符

news2025/2/15 13:54:03

博主介绍:程序喵大人

  • 35- 资深C/C++/Rust/Android/iOS客户端开发
  • 10年大厂工作经验
  • 嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手
  • 《C++20高级编程》《C++23高级编程》等多本书籍著译者
  • 更多原创精品文章,首发gzh,见文末
  • 👇👇记得订阅专栏,以防走丢👇👇
    😃C++基础系列专栏
    😃C语言基础系列

运算符是执行各种操作的核心工具,它们定义了如何在程序中对数据进行处理。

C语言提供了一系列丰富的运算符,包括算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符以及杂七杂八的运算符等,下面会详细介绍。

算术运算符

算术运算符用于执行基本的数学运算,包括加法、减法、乘法、除法等。C语言支持的算术运算符如下表所示:

运算符描述示例
+加法a + b
-减法a - b
*乘法a * b
/除法,结果为浮点数(如果操作数中有浮点数)或整数a / b, 10.0 / 3.0
%取模(求余数)a % b
++自增,前置或后置++a 或 a++
自减,前置或后置–a 或 a–

示例代码

#include <stdio.h>

int main() {
    int a = 10, b = 3;
    float c = 5.5, d = 2.0;

    printf("a + b = %d\n", a + b);
    printf("a - b = %d\n", a - b);
    printf("a * b = %d\n", a * b);
    printf("a / b = %d\n", a / b);  // 整数除法,结果为3
    printf("a %% b = %d\n", a % b); // 取模,结果为1
    printf("c / d = %.2f\n", c / d); // 浮点数除法,结果为2.75

    int x = 5;
    printf("前置自增: ++x = %d\n", ++x); // 先增后输出,结果为6
    printf("后置自增: x++ = %d\n", x++); // 先输出后增,结果为6,然后x变为7

    return 0;
}

扩展

  1. 整数除法和浮点数除法:在C语言中,当两个整数进行除法运算时,结果也是整数,小数部分会被舍弃。如果要得到浮点数结果,至少有一个操作数必须是浮点数。
  2. 自增和自减运算符:自增和自减运算符可以前置也可以后置。前置运算符会先改变变量的值,然后再使用改变后的值;而后置运算符会先使用变量的原始值,然后再改变变量的值。

关系运算符

关系运算符用于比较两个值,并返回一个布尔值(真或假)。C语言支持的关系运算符如下表所示:

运算符描述示例
==等于a == b
!=不等于a != b
>大于a > b
<小于a < b
>=大于或等于a >= b
<=小于或等于a <= b

示例代码

#include <stdio.h>

int main() {
    int a = 10, b = 20;

    if (a == b) {
        printf("a 等于 b\n");
    } else {
        printf("a 不等于 b\n");
    }

    if (a < b) {
        printf("a 小于 b\n");
    }

    if (a >= 15) {
        printf("a 大于或等于 15\n");
    }

    return 0;
}

扩展

  1. 关系运算符的返回值:关系运算符返回一个布尔值(在C语言中通常用整数1表示真,0表示假)。这些值常用于条件语句(如if语句)中。
  2. 链式比较:在C语言中,可以链式使用关系运算符进行比较,例如a < b < c。但这种用法并不推荐,代码的可读性太低。

逻辑运算符

逻辑运算符用于组合多个条件表达式,并返回一个布尔值。C语言支持的逻辑运算符如下表所示:
在这里插入图片描述

示例代码

#include <stdio.h>

int main() {
    int a = 10, b = 20, c = 15;

    if (a > 5 && b < 25) {
        printf("a 大于 5 且 b 小于 25\n");
    }

    if (a < 5 || b > 25) {
        printf("a 小于 5 或 b 大于 25\n");
    }

    if (!(a == b)) {
        printf("a 不等于 b\n");
    }

    return 0;
}

扩展

  1. 短路求值:逻辑与运算符&&和逻辑或运算符||具有短路求值的特性。即,如果第一个操作数已经能够确定整个表达式的结果,那么第二个操作数将不会被求值。这可以用于避免除零错误或访问空指针等潜在问题。

位运算符

位运算符用于对整数的二进制位进行操作。C语言支持的位运算符如下表所示:
在这里插入图片描述
示例代码

#include <stdio.h>

int main() {
    unsigned int a = 60; // 0011 1100
    unsigned int b = 13; // 0000 1101

    printf("a & b = %u\n", a & b); // 0000 1100 = 12
    printf("a \| b = %u\n", a | b); // 0011 1101 = 61
    printf("a ^ b = %u\n", a ^ b); // 0011 0001 = 49
    printf("~a = %u\n", ~a);       // 1100 0011 = 4294967275(32位无符号整数的补码)
    printf("a << 2 = %u\n", a << 2); // 1111 0000 = 240
    printf("a >> 2 = %u\n", a >> 2); // 0000 1111 = 15

    return 0;
}

扩展

  1. 位运算与掩码:位运算常用于与掩码(mask)结合使用,用来提取或设置特定位。例如,可以使用掩码0x0F(即二进制的00001111)来提取一个字节的低四位。
  2. 位运算的效率:位运算在处理大量数据时通常比普通的算术运算更高效,因为它们直接在二进制层面进行操作,避免了不必要的类型转换和计算。

赋值运算符

赋值运算符用于将值赋给变量。C语言支持的赋值运算符如下表所示:
在这里插入图片描述

示例代码

#include <stdio.h>

int main() {
    int a = 10, b = 5;

    a += b; // a = a + b = 15
    printf("a += b = %d\n", a);

    a -= b; // a = a - b = 10
    printf("a -= b = %d\n", a);

    a *= b; // a = a * b = 50
    printf("a *= b = %d\n", a);

    a /= b; // a = a / b = 10
    printf("a /= b = %d\n", a);

    a %= b; // a = a % b = 0
    printf("a %= b = %d\n", a);

    a = 10;
    a <<= 2; // a = a << 2 = 40
    printf("a <<= 2 = %d\n", a);

    a >>= 2; // a = a >> 2 = 10
    printf("a >>= 2 = %d\n", a);

    a &= 3; // a = a & 3 = 2
    printf("a &= 3 = %d\n", a);

    a |= 5; // a = a | 5 = 7
    printf("a \|= 5 = %d\n", a);

    a ^= 3; // a = a ^ 3 = 4
    printf("a ^= 3 = %d\n", a);

    return 0;
}

扩展

  1. 赋值运算符的复合性:赋值运算符可以结合其他运算符使用,形成复合赋值运算符。这种写法既简洁又高效。
  2. 赋值运算的顺序:在C语言中,赋值运算是从右到左进行的。例如,在表达式a = b = c = 5;中,首先计算c = 5,然后将结果赋给b,最后将b的值赋给a

杂项运算符

除了上述几类运算符外,C语言还支持一些其他重要的运算符,包括sizeof运算符和三元运算符?:

sizeof运算符

sizeof运算符用于获取数据类型或变量在内存中占用的字节数。它的返回值是一个size_t类型的值。

示例代码

#include <stdio.h>

int main() {
    int a = 10;
    double b = 5.5;
    char c = 'A';

    printf("sizeof(int) = %lu\n", sizeof(int));
    printf("sizeof(double) = %lu\n", sizeof(double));
    printf("sizeof(char) = %lu\n", sizeof(char));
    printf("sizeof(a) = %lu\n", sizeof(a));
    printf("sizeof(b) = %lu\n", sizeof(b));
    printf("sizeof(c) = %lu\n", sizeof(c));

    return 0;
}

扩展

  • sizeof运算符在编译时计算,因此不会增加程序的运行时开销。
  • 对于指针类型,sizeof运算符返回的是指针本身的大小,而不是指针所指向的数据的大小。

三元运算符**?:**

三元运算符是一种条件运算符,它根据一个布尔表达式的值来选择两个值中的一个。其语法为条件 ? 表达式1 : 表达式2

示例代码

#include <stdio.h>

int main() {
    int a = 10, b = 20;
    int max;

    max = (a > b) ? a : b;
    printf("max = %d\n", max);

    return 0;
}

扩展

  • 三元运算符常用于简化简单的条件判断语句,使代码更加简洁明了。
  • 三元运算符可以嵌套使用,但过多的嵌套会降低代码的可读性,应谨慎使用。

运算符优先级和结合性

运算符的优先级和结合性决定了在复杂表达式中各个运算符的执行顺序。C语言中的运算符优先级从高到低排列如下(部分运算符):

  1. () 圆括号
  2. ! 逻辑非
  3. */% 乘法、除法、取模
  4. +- 加法、减法
  5. <<>> 左移、右移
  6. <<=>>= 关系运算符
  7. ==!= 等于、不等于
  8. & 按位与
  9. ^ 按位异或
  10. | 按位或
  11. && 逻辑与
  12. || 逻辑或
  13. = 赋值运算符

示例代码

#include <stdio.h>

int main() {
    int a = 10, b = 20, c = 30;

    int result = a + b * c / (a + b); // 运算符优先级示例
    printf("result = %d\n", result); // 输出结果为 30

    return 0;
}

扩展

  • 圆括号()可以改变运算符的优先级和结合性,因此在使用复杂表达式时应合理使用圆括号来提高代码的可读性和准确性。
  • 运算符的结合性决定了相同优先级的运算符的执行顺序。例如,乘法运算符*和除法运算符/是左结合的,这意味着a * b / c等价于(a * b) / c

码字不易,欢迎大家点赞关注评论,谢谢!


C++训练营

专为校招、社招3年工作经验的同学打造的1V1 C++训练营,量身定制学习计划、每日代码review,简历优化,面试辅导,已帮助多名学员获得offer!训练营介绍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2298671.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

服务器之连接简介(Detailed Explanation of Server Connection)

一台服务器最大能支持多少连接&#xff1f;一台客户端机器最多能发起多少条连接&#xff1f;&#xff1f; 我们知道TCP连接&#xff0c;从根本上看其实就是client和server端在内存中维护的一组【socket内核对象】&#xff08;这里也对应着TCP四元组&#xff1a;源IP、源端口、…

华为2288H V5服务器无法启动问题处理

问题&#xff1a;通电后服务器前面显示888&#xff0c;点击电源键没有反应 一.通过管理口管理服务器硬件设备 华为2288H V5它默认的IP是192.168.2.100 网关是255.255.255.0 2.将网线一头连接服务器的Mgmt口&#xff0c;另一头来连接笔记本的网口&#xff0c;将笔记本的的本地…

华宇TAS应用中间件与因朵科技多款产品完成兼容互认证

在数字化浪潮澎湃向前的当下&#xff0c;信息技术的深度融合与协同发展成为推动各行业创新变革的关键力量。近日&#xff0c;华宇TAS应用中间件携手河北因朵科技有限公司&#xff0c;完成了多项核心产品的兼容互认证。 此次兼容性测试的良好表现&#xff0c;为双方的进一步深入…

第36天:安全开发-JavaEE应用第三方组件Log4j日志FastJson序列化JNDI注入

时间轴&#xff1a; 演示案例&#xff1a; Java-三方组件-Log4J&JNDI Java-三方组件-FastJson&反射 Maven的下载及配置&#xff1a; IDEA配置Maven的超详细步骤_java_脚本之家 Java-三方组件-Log4J&JNDI JNDI 注入&#xff1a; ( 见图 ) Java Naming and Dire…

21爬虫:使用playwright接管本地已经登录淘宝的浏览器并查找python相关店铺信息

1.playwright如何接管本地浏览器 &#xff08;1&#xff09;首先找到电脑上安装的Chrome浏览器可执行程序的完整路径&#xff1a; Mac电脑上可执行程序的完整路径为&#xff1a; /Applications/Google Chrome.app/Contents/MacOS/Google Chrome windows系统的电脑上查找可执行…

Redis——优惠券秒杀问题(分布式id、一人多单超卖、乐悲锁、CAS、分布式锁、Redisson)

#想cry 好想cry 目录 1 全局唯一id 1.1 自增ID存在的问题 1.2 分布式ID的需求 1.3 分布式ID的实现方式 1.4 自定义分布式ID生成器&#xff08;示例&#xff09; 1.5 总结 2 优惠券秒杀接口实现 3 单体系统下一人多单超卖问题及解决方案 3.1 问题背景 3.2 超卖问题的…

【现代深度学习技术】深度学习计算 | GPU

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…

USB Flash闪存驱动器安全分析(第一部分)

翻译原文链接&#xff1a;Hacking Some More Secure USB Flash Drives (Part I) | SySS Tech Blog 文章翻译总结&#xff1a;文章对一些具有AES硬件加密的USB闪存驱动器的网络安全分析研究。研究由SySS的IT安全专家Matthias Deeg进行&#xff0c;他在2022年初发现了几个安全漏…

【Linux】--- 基础开发工具之yum/apt、vim、gcc/g++的使用

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; Linux网络编程 本篇博客我们来认识一下Linux中的一些基础开发工具 --- yum,vim,gcc/g。 &#x1f3e0; yum &#x1f3b8; 什么是yum 当用户想下载软…

Python + WhisperX:解锁语音识别的高效新姿势

大家好&#xff0c;我是烤鸭&#xff1a; 最近在尝试做视频的质量分析&#xff0c;打算利用asr针对声音判断是否有人声&#xff0c;以及识别出来的文本进行进一步操作。asr看了几个开源的&#xff0c;最终选择了openai的whisper&#xff0c;后来发现性能不行&#xff0c;又换了…

redis 缓存击穿问题与解决方案

前言1. 什么是缓存击穿?2. 如何解决缓存击穿?怎么做?方案1: 定时刷新方案2: 自动续期方案3: 定时续期 如何选? 前言 当我们使用redis做缓存的时候,查询流程一般是先查询redis,如果redis未命中,再查询MySQL,将MySQL查询的数据同步到redis(回源),最后返回数据 流程图 为什…

SAP HCM 批量核算工资报错如何定位错误 (SAT分析错误)

导读 簇目录 (表 RGDIR) 不包含任何记录:今天遇到一个很奇怪的问题&#xff0c;簇目录 (表 RGDIR) 不包含任何记录&#xff0c;而且出现的问题没有具体到员工编号&#xff0c;所以处理问题非常棘手。今天分享下我的处理方式&#xff0c;以便大家遇到这类的问题不知道如何下手。…

服务器被暴力破解的一次小记录

1. 网络架构 家里三台主机&#xff0c;其他一台macmini 启用ollama运行大模型的服务&#xff0c;主机1用来部署一些常用的服务如&#xff1a;mysql, photoprism等&#xff0c;服务器作为网关部署docker, 并且和腾讯云做了内网穿透。服务器部署了1panel用来管理服务并且监控&…

3. 导入官方dashboard

官方dashboard&#xff1a;https://grafana.com/grafana/dashboards 1. 点击仪表板 - 新建 - 导入 注&#xff1a;有网络的情况想可以使用ID&#xff0c;无网络情况下使用仪表板josn文件 2. 在官方dashboard网页上选择符合你现在数据源的dashboard - 点击进入 3. 下拉网页选…

国家队出手!DeepSeek上线国家超算互联网平台!

目前,国家超算互联网平台已推出 DeepSeek – R1 模型的 1.5B、7B、8B、14B 版本,后续还会在近期更新 32B、70B 等版本。 DeepSeek太火爆了!在这个春节档,直接成了全民热议的话题。 DeepSeek也毫无悬念地干到了全球增速最快的AI应用。这几天,国内的云计算厂家都在支持Dee…

第6章 6.4 ASP.NET Core Web API各种技术及选择

6.4.1 控制器父类用哪个 6.2小节和6.3小节所演示的ASP.NET Core Web API 的控制器类都继承自ControllerBase&#xff0c;而6.1中MVC的控制器继承自Controller&#xff0c;Controller又继承自ControllerBase。 所以&#xff0c;一般情况下&#xff0c;编写的WebAPI控制器类继承…

【Linux】Ubuntu Linux 系统——Node.js 开发环境

ℹ️大家好&#xff0c;我是练小杰&#xff0c;今天星期五了&#xff0c;同时也是2025年的情人节&#xff0c;今晚又是一个人的举个爪子&#xff01;&#xff01; &#x1f642; 本文是有关Linux 操作系统中 Node.js 开发环境基础知识&#xff0c;后续我将添加更多相关知识噢&a…

使用pyCharm创建Django项目

使用pyCharm创建Django项目 1. 创建Django项目虚拟环境&#xff08;最新版版本的Django) 使用pyCharm的创建项目功能&#xff0c;选择Django,直接创建。 2. 创建Django项目虚拟环境&#xff08;安装特定版本&#xff09; 2.1创建一个基础的python项目 2.2 安装指定版本的D…

【前端框架】深入Vue 3组件开发:构建高效灵活的前端应用

一、引言 Vue 3作为一款流行的前端框架&#xff0c;其组件化系统是构建大型应用的核心。通过将应用拆分为多个可复用的组件&#xff0c;不仅能提高代码的可维护性与复用性&#xff0c;还能让开发团队进行高效的协作。本文将深入探讨Vue 3组件开发的各个方面&#xff0c;帮助开…

基于Python flask-sqlalchemy的SQLServer数据库管理平台

适应场景&#xff1a; 主要用于帮助DBA自动化很多日常工作&#xff0c;包括&#xff1a; 数据库状态监控 性能问题诊断 日志分析 自动巡检 问题告警 系统截图&#xff1a; main.py from flask import Blueprint, render_template, request, flash, redirect, url_for f…