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

C语言操作符详解 一针见血!

目录

  1. 算数操作符

  1. 移位操作符

  1. 位操作符

  1. 赋值操作符

  1. 单目操作符

  1. 关系操作符

  1. 逻辑操作符

  1. 条件操作符

  1. 逗号表达式

  1. 下标引用、函数调用和结构成员

  1. 表达式求值

11.1 隐式类型转换

  1. 算数操作符

💭 注意

/ 除法 --得到的是商
% 取模(取余)--得到的是余数
如果除法操作符的两个操作数都是整数,执行的是整数除法
如果除法操作符的两个操作数只只要有一个是浮点数,执行的是小数除法
取模操作符两端必须都是整数

例:

int main()
{printf("%d\n", 10 / 2);//5printf("%d\n", 10 % 2);//0printf("%lf\n", 10 / 3.0);//3.333333printf("%d\n", 10 / 3);//3return 0;
}
  1. 移位操作符

移位操作符移动的是二进制的位。
10进制的数据中:都是0~9的数字组成的。
2进制的数据中:都是0~1的数字组成的。
8进制的数据中:都是0~7的数字组成的。
16进制的数据中:都是0~9 a~f组成的。

数据的二进制表示:

整数的二进制表示形式由3种:原码 反码 补码

注意:正整数的原码、反码、补码是相同的
负整数的原码、反码、补码要计算
整数在内存中存储的是补码。

原码:把一个数按照正负直接翻译成二进制就是原码

反码:原码符号位不变,其他位按位取反

补码:反码+1

2.1左移操作符 <<

左移一位二进制位(补码),后面空出的一位补0

正数进行左移操作

int main()
{int a = 3;int b = a << 1;printf("%d\n", b);return 0;
}

负数进行左移操作:

int main()
{int a = -3;int b = a << 1;printf("%d\n", b);return 0;
}

负数的补码和原码不同,所以在进行负数移位时应先求出该数字的补码,之后在补码的基础上进行移位操作。

-3的补码:

补码进行移位操作:

移位后根据移位后的二进制位进行-1取反得到原码,即为我们所求的b

也可以继续取反,+1。

2.2 右移操作符 >>

右移分为两种:

  1. 逻辑移位:左边用0填充,右边丢弃

  1. 算术移位:左边用原该值的符号位填充,右边丢弃

而右移采用以上哪种,取决于编译器。一般使用算术右移。

int main()
{int a = -5;int b = a >> 1;printf("%d\n", b);return 0;
}

💭 注意:移位操作不要移动负数位。

  1. 位操作符--位指的是二进制位(补码)

& 按位与

| 按位或

^ 按位异或

💭 注意:这里进行的操作数必须都是整数形式

& 按位与:对应的二进制位进行按位与,有0结果为0,全1结果为1。即相同为1,不同为0。

例:

int main()
{int a = 3;int b = -5;int c = a & b;printf("%d\n", c);//000000000000000000000000000000011 3的补码//100000000000000000000000000000101//111111111111111111111111111111010//111111111111111111111111111111011 -5的补码//000000000000000000000000000000011  3
}

| 按位或:对应的二进制位进行按位或,有1则为1,全0为0。

例:

int main()
{int a = 3;int b = -5;int c = a | b;printf("%d\n", c);return 0;//000000000000000000000000000000011 3的补码//111111111111111111111111111111011 -5的补码//111111111111111111111111111111011  -5的补码,原码为-5
}

^ 按位异或:对应的二进制位,相同为0,相异为1

例:

int main()
{int a = 3;int b = -5;int c = a ^ b;printf("%d\n", c);return 0;//000000000000000000000000000000011 3的补码//111111111111111111111111111111011 -5的补码//111111111111111111111111111111000  补码//100000000000000000000000000000111  取反//100000000000000000000000000001000   加1   -8
}
💭:异或支持交换律和结合律

例1:不创建临时变量实现两个数字交换

int main()
{int a = 3;int b = 5;printf("前%d %d\n", a, b);a = a ^ b;b = a ^ b;a = a ^ b;printf("后%d %d\n", a, b);return 0;
}

例2:求一个整数存储在内存中的二进制1的个数

int main()
{int a = 10;int count = 0;int i = 0;while (i < 32){if (a & 1 == 1){count++;}a = a >> 1;i++;}printf("%d\n", count);//000000000000000000000000000001010  2return 0;
}
  1. 赋值操作符

赋值操作符可以进行连续赋值。

  1. 单目操作符

! 逻辑反操作

& 取地址操作符

sizeof 操作数的类型长度

~ 对二进制位按位取反

-- 前置、后置--

++ 前置、后置++

*间接引用操作符(解引用操作符)

强制类型转换(类型)

~ 对二进制位按位取反

int main()
{int a = 0;printf("%d\n", ~a);//00000000000000000000000000000000//11111111111111111111111111111111 //11111111111111111111111111111110 //10000000000000000000000000000001  -1return 0;
}
int main()
{int a = 3;//000000000000000000000000000011//000000000000000000000000001000a |= (1 << 3);printf("%d\n", a);//000000000000000000000000001011//111111111111111111111111110111a &= (~(1 << 3));printf("%d\n", a);return 0;
}
  1. 关系操作符

> >= < <= != ==

7.逻辑操作符--只关注真假

&& 逻辑与

|| 逻辑或

&&操作符左边为假右边不再计算
|| 操作符左边为真右边不再计算

8.条件操作符

exp1 ? exp2 : exp3

例:两个表达方式结果是一样的

int main()
{int a = 0;int b = a ? 1 : 2;printf("%d\n", b);/*if (a){b = 1;}else{b = 2;}*/return 0;
}

9.逗号表达式

exp1 , exp2 , exp3 , .......expn

逗号表达式是用逗号隔开的表达式,逗号表达式从左向右依次执行,整个表达式的结果是最后一个表达式的结果。

例:

int main()
{int a = 1;int b = 2;int c = (a > b, a = b + 10, b = a + 1);//13printf("%d\n", c);return 0;
}

10.下标引用、函数调用和结构成员

下标引用:[ ]

int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };printf("%d", arr[5]);return 0;
}

注意:arr和10是[ ]的操作数

函数调用( )

int main()
{int a = strlen("abc");printf("%d", a);return 0;
}
void test()
{}
int main()
{test();return 0;
}

注意:test是()的操作数

访问结构体成员

结构体.成员名

结构体->成员名

struct S
{int num;char c;
};
int main()
{struct S s = { 100,'b' };//结构体的初始化使用{}printf("%d\n", s.num);printf("%c\n", s.c);return 0;
}

注意:.操作符 结构体变量.结构体成员

struct S
{int num;char c;
};
void test(struct S* ps)
{/*printf("%d\n", (*ps).num);printf("%c\n", (*ps).c);*/printf("%d\n", ps->num);printf("%c\n", ps->c);
}
int main()
{struct S s = { 100,'b' };//结构体的初始化使用{}test(&s);return 0;
}

注意:结构体指针->结构体成员

11.表达式求值

表达式求值由操作符的优先级和结合性决定,在一些情况下有些表达式的操作数在求值的过程中可能要转换成其他类型来计算。

11.1隐式类型转换 主要讨论short和char类型

C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换被称为整型提升。

什么意思呢?简单来讲,CPU的通用寄存器长度是整型变量的长度也就是4个字节,(为了获得更高的精度)即使是两个char类型的相加,也要先转换为整型int的长度再进行相加。

char a,b,c;
a=b+c;

b和c的值被提升为普通整型,然后进行加法运算,加法运算完成后,结果被截断,然后再存储于a中。

如何进行整型提升?

负数的整型提升
char c1=-1;
变量c1的二进制位(补码)有8个比特位 11111111
char为有符号的char
所以整型提升的时候,高位补充符号位,即为1
提升后的结果:
11111111111111111111111111111111
正数的整型提升:
char c2=1;
变量c2的二进制位(补码)有8个比特位 00000001
char为有符号的char
所以整型提升的时候,高位补充符号位,即为 0
提升后的结果:
00000000000000000000000000000001
无符号整型提升,高位补0
int main()
{char a = 3;//00000000000000000000000000000011//00000011 截断char b = 127;//00000000000000000000000001111111//01111111 截断char c = a + b;//00000000000000000000000000000011//00000000000000000000000001111111//00000000000000000000000010000010//10000010  c 截断//整型提升printf("%d", c);//因为c是char类型的数据所以又要进行整型提升// //10000010  有符号数用符号位填充//11111111111111111111111100000010   补码//10000000000000000000000011111101   取反//10000000000000000000000011111110   原码return 0;}
int main()
{char c = 1;char d = 2;printf("%u\n", sizeof(c));//1printf("%u\n", sizeof(+c));//4  进行了整型提升printf("%u\n", sizeof(-c));//4  进行了整型提升printf("%u\n",sizeof(c+d));//4  进行了整型提升return 0;
}

11.2算术转换 主要讨论字节大小大于等于int的变量类型

如果某个操作符的各个操作数属于不同类型,除非其中一个操作数转换为另一个操作数的类型,否则操作无法进制,下面层次体系称为寻常算术转换。

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

类型向上转换 例如int 和long int进行表达式求值,将int 转换为long int 进行计算。

复杂表达式的求值有3个影响因素:

操作符的优先级 操作符的结合性 是否控制求值顺序

两个相邻操作符先执行哪一个取决于它们的优先级,如果两者优先级相同取决于它们的结合性

注意控制求值顺序操作符:&& 逻辑与 | |逻辑或 ?:条件操作符 ,逗号表达式控制求值顺序,也就是说可以控制哪些算哪些不算
&&操作符左边为假右边不再计算
|| 操作符左边为真右边不再计算
exp1?exp2:exp3 exp1真则表达式为exp2的值否则为exp3
, 逗号表达式的值为最后一个表达式的值

操作符的属性:

int fun()
{static int count = 1;return ++count;
}
int main()
{int answer;answer = fun() - fun() * fun();printf("%d\n", answer);return 0;
}

函数的调用先后顺序无法通过操作符的优先级决定

int main()
{int i = 1;int ret = (++i) + (++i) + (++i);printf("%d\n", ret);//12printf("%d\n", i);//4return 0;
}

在我们写代码时,还是希望能够写出能表现出操作符优先顺序的代码。

相关文章:

C语言操作符详解 一针见血!

目录算数操作符移位操作符位操作符赋值操作符单目操作符关系操作符逻辑操作符条件操作符逗号表达式下标引用、函数调用和结构成员表达式求值11.1 隐式类型转换算数操作符&#x1f4ad; 注意/ 除法 --得到的是商% 取模&#xff08;取余&#xff09;--得到的是余数如果除法操作符…...

前端面试题汇总

一&#xff1a;JavaScript 1、闭包是什么&#xff1f;利弊&#xff1f;如何解决弊端&#xff1f; 闭包是什么&#xff1a;JS中内层函数可以访问外层函数的变量&#xff0c;外层函数无法操作内存函数的变量的特性。我们把这个特性称作闭包。 闭包的好处&#xff1a; 隔离作用…...

以数据驱动管理场景,低代码助力转型下一站

数据驱动 数据驱动&#xff0c;是通过移动互联网或者其他的相关软件为手段采集海量的数据&#xff0c;将数据进行组织形成信息&#xff0c;之后对相关的信息讲行整合和提炼&#xff0c;在数据的基础上经过训练和拟合形成自动化的决策模型&#xff0c;简单来说&#xff0c;就是…...

2023年全国数据治理DAMA-CDGA/CDGP考试报名到弘博创新

弘博创新是DAMA中国授权的数据治理人才培养基地&#xff0c;贴合市场需求定制教学体系&#xff0c;采用行业资深名师授课&#xff0c;理论与实践案例相结合&#xff0c;快速全面提升个人/企业数据治理专业知识与实践经验&#xff0c;通过考试还能获得数据专业领域证书。 DAMA认…...

流程控制之循环

文章目录五、流程控制之循环5.1 步进循环语句for5.1.1 带列表的for循环语句5.1.2 不带列表的for循环语句5.1.3 类C风格的for循环语句5.2 while循环语句5.2.1 while循环读取文件5.2.2 while循环语句示例5.3 until循环语句5.4 select循环语句5.5 嵌套循环5.4 利用break和continue…...

SpringDataRedis快速入门

SpringDataRedis快速入门1.SpringDataRedis简介2.RedisTemplate快速入门3.RedisSerializer4.StringRedisTemplate1.SpringDataRedis简介 SpringData是Spring中数据操作的模块&#xff0c;包含对各种数据库的集成&#xff0c;其中对Redis的集成模块就叫做SpringDataRedis Spri…...

MySQL 的执行计划 explain 详解

目录 什么是执行计划 执行计划的内容 select子句的类型 访问类型 索引的存在形式...

2023年网络安全比赛--Web综合渗透测试中职组(超详细)

一、竞赛时间 180分钟 共计3小时 二、竞赛阶段 1.通过URL访问http://靶机IP/1,对该页面进行渗透测试,将完成后返回的结果内容作为FLAG值提交; 2.通过URL访问http://靶机IP/2,对该页面进行渗透测试,将完成后返回的结果内容作为FLAG值提交; 3.通过URL访问http://靶机IP/3,对…...

【c++之于c的优化 - 下】

前言 一、inline 概念 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用内联函数的地方展开&#xff0c;没有函数调用建立栈帧的开销&#xff0c;内联函数提升程序运行的效率。 如果在上述函数前增加inline关键字将其改成内联函数&#xff0c;在编译期间编译…...

MySQL事务管理

文章目录MySQL事务管理事务的概念事务的版本支持事务的提交方式事务的相关演示事务的隔离级别查看与设置隔离级别读未提交&#xff08;Read Uncommitted&#xff09;读提交&#xff08;Read Committed&#xff09;可重复读&#xff08;Repeatable Read&#xff09;串行化&#…...

二维计算几何全家桶

参考文章&#xff1a;范神的神仙博客 前置芝士 一些高中数学 向量的叉积&#xff1a;向量的点积为 a⋅b∣a∣∣b∣cos⁡<a,b>a\cdot b|a||b|\cos<a,b>a⋅b∣a∣∣b∣cos<a,b>&#xff0c;向量的叉积为 ab∣a∣∣b∣sin⁡<a,b>a\times b|a||b|\sin<…...

基于图的下一代入侵检测系统

青藤云安全是一家主机安全独角兽公司&#xff0c;看名字就知道当前很大一块方向专注云原生应用安全&#xff0c;目前主营的是主机万相/容器蜂巢产品&#xff0c;行业领先&#xff0c;累计支持 800万 Agent。当前公司基于 NebulaGraph 结合图技术开发的下一代实时入侵检测系统已…...

若依框架---树状层级部门数据库表

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是小童&#xff0c;Java开发工程师&#xff0c;CSDN博客博主&#xff0c;Java领域新星创作者 &#x1f4d5;系列专栏&#xff1a;前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 &#x1f4…...

【Mysql第十期 数据类型】

文章目录1. MySQL中的数据类型2.类型介绍2.2 可选属性2.2.2 UNSIGNED2.2.3 ZEROFILL2.3 适用场景2.4 如何选择&#xff1f;3. 浮点类型3.2 数据精度说明3.3 精度误差说明4. 定点数类型4.1 类型介绍4.2 开发中经验5. 位类型&#xff1a;BIT6. 日期与时间类型6.1 YEAR类型6.2 DAT…...

2023-2-9 刷题情况

删除子文件夹 题目描述 你是一位系统管理员&#xff0c;手里有一份文件夹列表 folder&#xff0c;你的任务是要删除该列表中的所有 子文件夹&#xff0c;并以 任意顺序 返回剩下的文件夹。 如果文件夹 folder[i] 位于另一个文件夹 folder[j] 下&#xff0c;那么 folder[i] 就…...

Homekit智能家居DIY设备-智能通断开关

智能通断器&#xff0c;也叫开关模块&#xff0c;可以非常方便地接入家中原有开关、插座、灯具、电器的线路中&#xff0c;通过手机App或者语音即可控制电路通断&#xff0c;轻松实现原有家居设备的智能化改造。 随着智能家居概念的普及&#xff0c;越来越多的人想将自己的家改…...

【java】EJB(Enterprise Java Bean)概述

EJB概述目录一、什么情况下需要企业Bean需要使用EJB的N个理由二、EJB的基本分类2.1、Enterprise Bean2.2、 Message Driven Bean(MDB)——消息驱动Bean,基于JMS三、定义客户端访问的接口3.1、 远程客户端——客户端与其调用的EJB对象不在同一个JVM进程中3.2、本地客户端——客户…...

Android 10.0 Launcher3桌面禁止左右滑动

1.1概述 在10.0的rom定制化开发中,由于Launcher3有一些功能需要定制,这样的需求也好多的,现在功能需求要求桌面固定在Launcher3的app列表页,不让左右移动,就是禁止左右移动的功能实现,所以需要禁止滑动分析页面滑动部分的功能,然后禁用 2.1Launcher3桌面禁止左右滑动的核…...

日期类的实现

文章目录1. 日期类的具体实现1.查询当前月份的天数2. 构造函数的实现(注意)3.d1d24. d1!d25. d1<d26. d1<d27. d1>d28. d1>d29. 日期天数10.日期天数11.日期-天数12. 日期-天数13. d和 d14. --d 和 d--15.日期日期 返回天数2. 函数的声明——date.h3. 函数的定义—…...

2022年这5款熟悉的软件退出了历史舞台

在过去的一年里&#xff0c;有很多新产品发布&#xff0c;当然也有很多产品与我们就此别过。这些产品曾陪伴我们的生活&#xff0c;给我们带来欢乐&#xff0c;帮助我们成长。所以本文将盘点一下在2022年和我们告别的产品。1.微软IE浏览器IE浏览器1995年8月16日正式上线&#x…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...