C 语言运算符的优先级和结合性

运算符的结合性和优先级

优先级运算符描述结合性
1()
[]
->
.
函数调用、数组下标、结构体 / 联合体成员通过指针访问、结构体 / 联合体成员访问从左到右
2!
~
++ (前缀)
-- (前缀)
+ (一元)
- (一元)
* (间接寻址)
& (取地址)
sizeof
(type)
逻辑非、按位取反、前缀自增、前缀自减、一元正号、一元负号、间接寻址、取地址、获取操作数的大小、类型转换从右到左
3*
/
%
乘法、除法、取模从左到右
4+
-
加法、减法从左到右
5<<
>>
左移、右移从左到右
6<
<=
>
>=
小于、小于等于、大于、大于等于从左到右
7==
!=
相等、不相等从左到右
8&按位与从左到右
9^按位异或从左到右
10<code>|</code>按位或从左到右
11&&逻辑与从左到右
12<code>||</code>逻辑或从左到右
13? :条件运算符(三元运算符)从右到左
14=
+=
-=
*=
/=
%=
<<=
>>=
&=
^=
<code>|=</code>
赋值、复合赋值运算符从右到左
15,逗号运算符从左到右

上手demo

#include <stdio.h>int main() {int a = 2, b = 3, c = 4;// 乘法优先级高于加法int result1 = a + b * c;  // 先计算 b * c,结果为 12,再加上 a,最终结果为 14printf("result1: %d\n", result1);  // 使用括号改变优先级int result2 = (a + b) * c;  // 先计算 a + b,结果为 5,再乘以 c,最终结果为 20printf("result2: %d\n", result2);  // 后缀自增和前缀自增int d = 5;int result3 = d++ + ++d;  // 先使用 d 的值 5 进行计算,然后 d 自增,再将自增后的 d(此时为 7)加 1,最终结果为 12printf("result3: %d\n", result3);  // 逻辑运算符int result4 = (a < b) && (b < c);  // 先计算 a < b 和 b < c,结果都为真,最终结果为 1printf("result4: %d\n", result4);  // 条件运算符int result5 = (a > b)? a : b;  // a 不大于 b,所以结果为 b 的值,即 3printf("result5: %d\n", result5);  // 复合赋值运算符a += b;  // 等价于 a = a + b,a 的结果为 5printf("a after +=: %d\n", a);  return 0;
}

括号运算符 ()

用于改变运算的优先级,也用于函数调用和类型转换,其在表达式中,括号内的运算总是优先进行。

#include <stdio.h>int main() {int a = 5, b = 3, c = 2;// 改变运算顺序int result1 = (a + b) * c;  // 先计算 a + b,结果为 8,再乘以 c,最终结果为 16printf("result1: %d\n", result1);  // 函数调用int sum(int x, int y) {return x + y;}int result2 = sum(a, b);  // 调用 sum 函数,将 a 和 b 的值传递给函数,结果为 8printf("result2: %d\n", result2);  // 类型转换float f = (float)a;  // 将整型 a 转换为浮点型,结果为 5.0printf("result3: %f\n", f);  return 0;
}

数组下标运算符 []

用于访问数组中的元,其下标必须是整数,可以是常量或变量。

*越界访问数组(使用超出数组长度的下标)会导致未定义行为!!!

#include <stdio.h>int main() {int arr[5] = {10, 20, 30, 40, 50};int index = 2;int element = arr[index];  // 访问数组 arr 中索引为 2 的元素,结果为 30printf("element: %d\n", element);  return 0;
}

结构体和联合体成员访问运算符 . 和 ->

  1. . 用于直接访问结构体或联合体的成员。
  2. -> 用于通过指针访问结构体或联合体的成员。
#include <stdio.h>
#include <stdlib.h>struct Point {int x;int y;
};int main() {struct Point p = {10, 20};// 直接访问成员int x = p.x;  // 访问结构体 p 的成员 x,结果为 10printf("x: %d\n", x);  struct Point *ptr = (struct Point *)malloc(sizeof(struct Point));ptr->x = 30;  // 通过指针访问成员 xptr->y = 40;  // 通过指针访问成员 yprintf("ptr->x: %d\n", ptr->x); printf("ptr->y: %d\n", ptr->y);  free(ptr);  return 0;
}

 一元运算符

逻辑非 !

对操作数取逻辑反,将非零值变为 0,当操作数 0 返回结果为 1。

#include <stdio.h>int main() {int a = 0;int result =!a;  // 结果为 1printf("result: %d\n", result);  return 0;
}

按位取反 ~

对操作数的二进制表示按位取反,也包括符号位(0为正,1为负)

#include <stdio.h>int main() {int a = 5;  // 二进制: 0101int result = ~a;  // 结果为 -6(二进制: 1010)printf("result: %d\n", result);  return 0;
}

前缀 / 后缀自增 ++ 和前缀 / 后缀自减 --

  1. 前缀:将操作数加 / 减 1,再使用结果。
  2. 后缀:先使用操作数的值,将操作数加 / 减 1。
#include <stdio.h>int main() {int a = 5;int b = ++a;  // 前缀自增,a 先加 1 变为 6,b 为 6int c = a++;  // 后缀自增,使用 a 的值 6,然后 a 加 1 变为 7printf("b: %d, c: %d, a: %d\n", b, c, a);  return 0;
}

一元正号 + 和一元负号 -

  1. +:不改变操作数的值,主要用于明确表示正数
  2. -:对操作数取负
#include <stdio.h>int main() {int a = 5;int b = -a;  // 结果为 -5int c = +a;  // 结果为 5printf("b: %d, c: %d\n", b, c);  return 0;
}

间接寻址 * 和取地址 &

  1. *:解引用指针,获取指针访问所指向的
  2. &:获取变量的地址
#include <stdio.h>int main() {int a = 10;int *ptr = &a;  // 获取 a 的地址存储在 ptr 中int value = *ptr;  // 通过 ptr 访问 a 的值,结果为 10printf("value: %d\n", value);  return 0;
}

sizeof 运算符

获取操作数的大小(以字节为单位)。

#include <stdio.h>int main() {int a;size_t size = sizeof(a);  // 获取 int 类型的大小,通常为 4printf("size: %zu\n", size);  return 0;
}

类型转换 (type)

将操作数转换为指定的数据类型。当是多精度转单精度类型时,可能导致数据丢失(如浮点数转整数)或截断。

#include <stdio.h>int main() {double d = 3.14;int i = (int)d;  // 将双精度浮点数转换为整数,结果为 3printf("i: %d\n", i);  return 0;
}

算术运算符

乘法 * 和除法 /

  1. *:两个操作数相乘。
  2. /:两个操作数相除,对于整数除法,结果会舍去小数部分;对于浮点数除法,使用 float 或 double 类型。
#include <stdio.h>int main() {int a = 10, b = 3;int product = a * b;  // 结果为 30int quotient = a / b;  // 结果为 3(整数除法)printf("product: %d, quotient: %d\n", product, quotient);  return 0;
}

取模 %

计算两个整数相除的余数。操作数必须是整数,否则会导致编译错误!!!

#include <stdio.h>int main() {int a = 10, b = 3;int remainder = a % b;  // 结果为 1printf("remainder: %d\n", remainder);  return 0;
}

加法 + 和减法 -

  1. +:两个操作数相加。
  2. -:两个操作数相减。
#include <stdio.h>int main() {int a = 5, b = 3;int sum = a + b;  // 结果为 8int difference = a - b;  // 结果为 2printf("sum: %d, difference: %d\n", sum, difference);  return 0;
}

移位运算符

左移 <<

将操作数的二进制表示向左移动指定的位数,右边补 0。

#include <stdio.h>int main() {int a = 5;  // 二进制: 0101int result = a << 2;  // 左移 2 位,结果为 20(二进制: 10100)printf("result: %d\n", result);  return 0;
}

右移 >>

将操作数的二进制表示向右移动指定的位数,对于无符号数左边补 0,对于有符号数根据编译器和系统可能补 0 或符号位。

#include <stdio.h>int main() {int a = 10;  // 二进制: 1010int result = a >> 1;  // 右移 1 位,结果为 5(二进制: 0101)printf("result: %d\n", result);  return 0;
}

 关系运算符:<(小于)、<=(小于等于)、>(大于)、>=(大于等于)、==(相等)、!=(不相等)

用于比较两个操作数的大小或相等性,结果为 1(真)或 0(假)。

#include <stdio.h>int main() {int a = 5, b = 3;int less_than = a < b;  // 结果为 0(假)int less_than_or_equal = a <= b;  // 结果为 0(假)int greater_than = a > b;  // 结果为 1(真)int greater_than_or_equal = a >= b;  // 结果为 1(真)int equal = a == b;  // 结果为 0(假)int not_equal = a!= b;  // 结果为 1(真)printf("less_than: %d, less_than_or_equal: %d, greater_than: %d, greater_than_or_equal: %d, equal: %d, not_equal: %d\n", less_than, less_than_or_equal, greater_than, greater_than_or_equal, equal, not_equal);  return 0;
}

位运算符

  1. 位运算符用于对二进制位进行操作,常用于底层编程、硬件控制和性能优化。
  2. 按位与 & 常用于清除某些位或检查特定位是否置位。
  3. 按位或 | 常用于设置某些位。
  4. 按位异或 ^ 常用于反转某些位或交换两个数的值(不使用临时变量)。

按位与 &

对操作数的每一位进行逻辑与操作,都为 1 时结果为 1,否则为 0。

#include <stdio.h>int main() {int a = 5;  // 二进制: 0101int b = 3;  // 二进制: 0011int result = a & b;  // 结果为 1(二进制: 0001)printf("result: %d\n", result);  return 0;
}

按位异或 ^

对操作数的每一位进行逻辑异或操作,不同为 1,相同为 0。

#include <stdio.h>int main() {int a = 5;  // 二进制: 0101int b = 3;  // 二进制: 0011int result = a ^ b;  // 结果为 6(二进制: 0110)printf("result: %d\n", result);  return 0;
}

按位或 |

对操作数的每一位进行逻辑或操作,有一个为 1 时结果为 1,否则为 0。

#include <stdio.h>int a = 5;  // 二进制: 0101int b = 3;  // 二进制: 0011int result = a | b;  // 结果为 7(二进制: 0111)printf("result: %d\n", result);  return 0;
}

逻辑运算符

逻辑与 && 和逻辑或 || 具有短路特性,即对于 &&,如果第一个操作数为假,则不计算第二个操作数;对于 ||,如果第一个操作数为真,则不计算第二个操作数。

逻辑与 &&

当且仅当两个操作数都为真(非零)时,结果为真。

#include <stdio.h>int main() {int a = 5, b = 0;int result = (a > 0) && (b > 0);  // 结果为 0(假)printf("result: %d\n", result);  return 0;
}

逻辑或 ||

当两个操作数中至少有一个为真时,结果为真。

#include <stdio.h>int main() {int a = 5, b = 0;int result = (a > 0) || (b > 0);  // 结果为 1(真)printf("result: %d\n", result);  return 0;
}

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

根据条件表达式的结果选择两个表达式中的一个,condition? expression1 : expression2,如果 condition 为真,结果为 expression1,否则为 expression2

#include <stdio.h>int main() {int a = 5, b = 3;int max = (a > b)? a : b;  // 结果为 5printf("max: %d\n", max);  return 0;
}

赋值运算符:=+=-=*=/=%=<<=>>=&=^=|=

将右侧表达式的值赋给左侧的变量。赋值表达式的值就是被赋的值。例如,int b = (a = 5); 中,先将 5 赋给 a,然后将 a 的值赋给 b

#include <stdio.h>int main() {int a;a = 10;  // 将 10 赋值给 aprintf("a: %d\n", a);  return 0;
}

复合赋值运算符

结合了算术、移位或位运算与赋值操作,提高代码的简洁性,先进行算术、移位或位运算,然后将结果赋给左侧变量。

#include <stdio.h>int main() {int a = 5;a += 3;  // 等价于 a = a + 3,结果为 8a -= 2;  // 等价于 a = a - 2,结果为 6a *= 4;  // 等价于 a = a * 4,结果为 24a /= 3;  // 等价于 a = a / 3,结果为 8a %= 5;  // 等价于 a = a % 5,结果为 3a <<= 1;  // 等价于 a = a << 1,结果为 6(二进制:110)a >>= 1;  // 等价于 a = a >> 1,结果为 3(二进制:011)a &= 2;  // 等价于 a = a & 2,结果为 2(二进制:010)a ^= 1;  // 等价于 a = a ^ 1,结果为 3(二进制:011)a |= 4;  // 等价于 a = a | 4,结果为 7(二进制:111)printf("a: %d\n", a);  return 0;
}

逗号运算符 ,

从左到右依次计算操作数,并返回最后一个操作数的值。

#include <stdio.h>int main() {int a = (1, 2, 3);  // 结果为 3int b = 5, c = 10;int d = (b++, c++, b + c);  // 先执行 b++ 和 c++,然后计算 b + c,结果为 17printf("a: %d, d: %d\n", a, d);  return 0;
}

常用于在 for 循环的初始化或更新部分中执行多个操作

#include <stdio.h>int main() {for (int i = 0, j = 10; i < 5; i++, j--) {printf("i: %d, j: %d\n", i, j);}return 0;
}
运算符优先级和结合性
  1. 优先级
    1. 运算符的优先级决定了表达式中运算的顺序,在复杂表达式中可能导致混淆。例如,在 a + b * c 中,先计算乘法 b * c,再计算加法。为避免混淆,可使用括号明确运算顺序,如 (a + b) * c
  2. 结合性
    1. 从左到右结合性:大多数二元运算符是从左到右结合的,如 a + b + c 先计算 a + b,再加上 c
    2. 从右到左结合性:一元运算符和赋值运算符通常是从右到左结合的,如 a = b = c 先将 c 赋给 b,再将 b 的值赋给 a

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

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

相关文章

centos 7 Mysql服务

将此服务器配置为 MySQL 服务器&#xff0c;创建数据库为 hubeidatabase&#xff0c;将登录的root密码设置为Qwer1234。在库中创建表为 mytable&#xff0c;在表中创建 2 个用户&#xff0c;分别为&#xff08;xiaoming&#xff0c;2010-4-1&#xff0c;女&#xff0c;male&…

紫光无人机AI飞控平台介绍

随着无人机技术的迅猛发展&#xff0c;无人机飞控平台的智能化需求不断提升。紫光无人机AI飞控平台作为一款创新型产品&#xff0c;为用户提供了从飞行控制到任务管理的一站式解决方案&#xff0c;尤其在AI实时识别和事件分析方面具有显著优势。本文将介绍平台的核心功能、技术…

【机器学习实战入门】有趣的Python项目:使用OpenCV进行性别和年龄检测

Gender and Age Detection Python 项目 首先,向您介绍用于此高级 Python 项目的性别和年龄检测中的术语: 什么是计算机视觉? 计算机视觉是一门让计算机能够像人类一样观察和识别数字图像和视频的学科。它面临的挑战大多源于对生物视觉有限的了解。计算机视觉涉及获取、处…

AutoAlign实体对齐方法的详细工作原理和在大规模知识图谱中的应用

AutoAlign是一种全自动且高效的知识图谱对齐方法&#xff0c;其工作原理主要基于大型语言模型&#xff08;LLM&#xff09;&#xff0c;如ChatGPT和Claude&#xff0c;通过构建谓词邻近图和实体嵌入模块来实现实体和谓词的自动对齐。这种方法不需要人工标注种子对齐&#xff0c…

【2025最新】国内中文版 ChatGPT镜像网站整理合集,GPT最新模型4o1,4o,4o-mini分类区别,镜像站是什么

1.快速导航 原生中转型镜像站点 立即Chat支持GPT4、4o以及o1,canvs等&#xff0c;同步官网功能 AIChat.com 支持最新4O 2.两者对比 官网立即Chat访问难度需要魔法直接访问支付手段国际支付国内支付封禁策略检测节点&#xff0c;随时封禁不会封禁价格每月140元订阅费用每年70元…

事务机制及Spring事务管理

事务概览 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位。 事务会将所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;换句话说&#xff1a;这些操作要么同时成功、要么同时失败。 具体案例 我们先看一个需求&#xff1a;现在有两张数据库表&…

CCLINKIE转ModbusTCP网关,助机器人“掀起”工业智能的“惊涛骇浪”

以下是一个稳联技术CCLINKIE转ModbusTCP网关&#xff08;WL-CCL-MTCP&#xff09;连接三菱PLC与机器人的配置案例&#xff1a;设备与软件准备设备&#xff1a;稳联技术WL-CCL-MTCP网关、三菱FX5UPLC、支持ModbusTCP协议的机器人、网线等。 稳联技术ModbusTCP转CCLINKIE网关&…

python管理工具:conda部署+使用

python管理工具&#xff1a;conda部署使用 一、安装部署 1、 下载 - 官网下载&#xff1a; https://repo.anaconda.com/archive/index.html - wget方式&#xff1a; wget -c https://repo.anaconda.com/archive/Anaconda3-2023.03-1-Linux-x86_64.sh2、 安装 在conda文件的…

python爬虫入门(理论)

python爬虫 学习网站 一、准备 环境搭建 requests beautifulsoup4 selenium 爬虫架构 URL管理器&#xff1a;管理URL&#xff0c;存储已爬取或待爬取的URL 网页下载器&#xff1a;破解网页&#xff0c;进行下载 网页解析器&#xff1a;对网页的HTML样式、连接的URL等进…

windows-本地部署Git仓库-安装Gitea

windows-本地部署Git仓库-安装Gitea 初始化MysQL数据库下载运行后关闭配置服务初始化打开防火墙指定端口入站规则 初始化MysQL数据库 create database gitea character set utf8mb4; 下载 运行后关闭 配置服务 初始化 打开防火墙指定端口入站规则

CV 图像处理基础笔记大全(超全版哦~)!!!

一、图像的数字化表示 像素 数字图像由众多像素组成&#xff0c;是图像的基本构成单位。在灰度图像中&#xff0c;一个像素用一个数值表示其亮度&#xff0c;通常 8 位存储&#xff0c;取值范围 0 - 255&#xff0c;0 为纯黑&#xff0c;255 为纯白。例如&#xff0c;一幅简单的…

Android-目前最稳定和高效的UI适配方案

谈到适配&#xff0c;首先需要介绍几个基本单位&#xff1a; 1、密度无关像素&#xff08;dp&#xff09;&#xff1a; 含义&#xff1a;density-independent pixel&#xff0c;叫dp或dip&#xff0c;与终端上的实际物理像素点无关 单位&#xff1a;dp&#xff0c;可以保证在…

Leetcode 91. 解码方法 动态规划

原题链接&#xff1a;Leetcode 91. 解码方法 自己写的代码&#xff1a; class Solution { public:int numDecodings(string s) {int ns.size();vector<int> dp(n,1);if(s[n-1]0) dp[n-1]0;for(int in-2;i>0;i--){if(s[i]!0){string ts.substr(i,2);int tmpatoi(t.c…

【算法】枚举

枚举 普通枚举1.铺地毯2.回文日期3.扫雷 二进制枚举1.子集2.费解的开关3.Even Parity 顾名思义&#xff0c;就是把所有情况全都罗列出来&#xff0c;然后找出符合题目要求的那一个。因此&#xff0c;枚举是一种纯暴力的算法。一般情况下&#xff0c;枚举策略都是会超时的。此时…

网络分析仪测试S参数

S参数的测试 一&#xff1a;S参数的定义 S参数&#xff08;Scattering Parameters&#xff0c;散射参数&#xff09;是一个表征器件在射频信号激励下的电气行为的工具&#xff0c;它以输入信号、输出信号为元素的矩阵来表现DUT的“传输”和“散射”效应&#xff0c;输入、输出…

联通用户管理系统(一)

#联通用户管理系统&#xff08;一&#xff09; 1.新建项目 如果你是windows的话&#xff0c;界面应该是如下的&#xff1a; 2.创建app python manage.py startapp app01一般情况下&#xff1a;我们是在pycharm的终端中运行上述指令&#xff0c;但是pychrm中为我们提供了工具…

迅为RK3576开发板Android 多屏显示

迅为iTOP-3576开发板采用瑞芯微RK3576高性能、低功耗的应用处理芯片&#xff0c;集成了4个Cortex-A72和4个Cortex-A53核心&#xff0c;以及独立的NEON协处理器。它适用于ARM PC、边缘计算、个人移动互联网设备及其他多媒体产品。 1.1 Android 多屏同显 iTOP-RK3576 开发板支持…

【Axure】配色库

配色库是一个专为设计师和创意工作者打造的在线资源平台&#xff0c;旨在提供丰富的色彩解决方案&#xff0c;帮助用户轻松找到或创造美观和谐的色彩搭配。其中&#xff0c;一个典型的配色库包含了以下几个核心元素&#xff1a; 渐变色&#xff1a;提供多样化的渐变色方案&…

港科夜闻 | 香港科大与微软亚洲研究院签署战略合作备忘录,推动医学健康教育及科研协作...

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大与微软亚洲研究院签署战略合作备忘录&#xff0c;推动医学健康教育及科研协作。根据备忘录&#xff0c;双方将结合各自于科研领域的优势&#xff0c;携手推动医学健康领域的交流与合作。合作方向将涵盖人才培训、…

机器学习第一道菜(一):线性回归的理论模型

机器学习第一道菜&#xff08;一&#xff09;&#xff1a;线性回归的理论模型 一、问题&#xff1a;千金买笑1.1 散点图1.2 机器学习能搞啥 二、模型的建立2.1 线性回归2.2 回归模型 前面讲了机器学习的“四大绝技”&#xff0c;今天&#xff0c;开始研究第一绝技“回归”&…