C语言——操作符保姆级教学(含整形提升及算数转换)

操作符

  • 一.操作符的分类
  • 二.原码、反码、补码
  • 三.移位操作符
    • 1.左移操作符:<<
    • 2.右移操作符:>>
  • 四.位操作符
    • 1.按位与—— &
    • 2.按位或—— |
    • 3.按位异或—— ^
    • 4.按位取反—— ~
  • 五.逗号表达式
  • 六.条件操作符
  • 七.操作符的属性:优先级、结合性
    • 1.优先级
    • 2.结合性
  • 八.表达式求值
    • 1.整形提升
    • 2.算数转换

一.操作符的分类

操作符名称操作符符号
算术操作符+,-,*,/,%
移位操作符<<,>>
位操作符&,I,^
赋值操作符=,+=,-= ,*=,/=,%=,<<=,>>=,&=,
单⽬操作符!、++、–、&、*、+、-、~ 、sizeof、(类型) 强制类型转换
关系操作符>,>=,<,<=,==,!=
逻辑操作符&&,II
条件操作符? :
逗号表达式
下标引用操作符[]
函数调用操作符()

二.原码、反码、补码

  • 整数的二进制有三种表示方法——原码,反码,补码

  • 有符号的整形的三种表示方法由符号位和数值位组成,二进制序列中,最高位表示符号位,符号位值分为两种:0表示正数,1表示负数。其余的都是数值位。

  • 无符号的整形的三种表示方法仅有数值位组成,二进制序列中,都是数值位。

  • 正整数:原码,反码,补码都相同

  • 负整数:原码,反码,补码都不相同
    原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
    反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
    补码:反码 + 1就得到补码。

  • 补码得到原码可以由:-1,取反 或 取反,+1的操作

  • 对于整形来说:数据存放内存中其实存放的是补码

为什么计算机存放的是补码呢?
  在计算机系统中,数值⼀律⽤补码来表⽰和存储。原因在于,使用补码,可以将符号位和数值域统⼀处理;同时,加法和减法也可以统⼀处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

例如:计算1-2(本质上:1+(-2),利用补码与补码相加,最后以原码所对应的10进制打印在屏幕上
在这里插入图片描述

三.移位操作符

1.左移操作符:<<

  • 移位规则:左边抛弃、右边补0
  • 左移n位,有乘2的n次方的效果
#include <stdio.h>
int main()
{
 	int num = 10;
	int n = num<<1;
	printf("n= %d\n", n);//n=20
	printf("num= %d\n", num);//num=10,num是不会改变的
 	return 0;
}

在这里插入图片描述

2.右移操作符:>>

移位规则:右移运算分两种

  • 1.逻辑右移:左边用0填充,右边丢弃
  • 2.算术右移:左边用原该值的符号位填充,右边丢弃
  • 右移n位,有除2的n次方的效果
#include <stdio.h>
int main()
{
	int num = -2;
	int n = num >> 1;
	printf("n= %d\n", n);//n=-1
	printf("num= %d\n", num);//num-2
	return 0;
}

在这里插入图片描述

注意:

  • 大部分都是算数右移(例如VS):左边用原该值的符号位填充,右边丢弃
  • 对于移位运算符,不要移动负数位,这个是标准未定义的。
  • 进行移位操作时,移动的是补码的二进制形式,最后以原码所对应的十进制打印在屏幕上
  • 移位操作符的操作数只能是整数

四.位操作符

1.按位与—— &

#include <stdio.h>
int main()
{
 	int num1 = -3;
 	int num2 = 5;
 	printf("%d\n", num1 & num2);//5
 	return 0;
}

在这里插入图片描述
在这里插入图片描述

  • 总结按位与:对应的二进制位,只要有0则为0,两个同时为1,才为1

2.按位或—— |

#include <stdio.h>
int main()
{
 	int num1 = -3;
 	int num2 = 5;
 	printf("%d\n", num1 | num2);//-3
 	return 0;
}

在这里插入图片描述

  • 总结按位或:对应的二进制位,只要有1则为1,两个同时为0,才为0

3.按位异或—— ^

#include <stdio.h>
int main()
{
 	int num1 = -3;
 	int num2 = 5;
 	printf("%d\n", num1 ^ num2);//-8
 	return 0;
}

在这里插入图片描述

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

4.按位取反—— ~

#include <stdio.h>
int main()
{
 	printf("%d\n", ~0);//-1
 	return 0;
}

在这里插入图片描述

  • 总结按位取反:按二进制位取反,0变1,1变0

位操作符都是作用于:补码的二进制位,且操作数必须是整数

五.逗号表达式

exp1, exp2, exp3, …expN

  • 逗号表达式:就是⽤逗号隔开的多个表达式。
  • 逗号表达式:从左向右依次执⾏。整个表达式的结果是最后⼀个表达式的结果。
#include<stdio.h>
int main()
{
	int a = 1;
	int b = 2;
	int c = (a>b, a=b+10, a, b=a+1);
	//a=b+10 —— a=12
	//b=a+1  —— b=13
	//最终c=13
	return 0;
}

六.条件操作符

表达式1?表达式2:表达式3

  • 若表达式1成立,则返回表达式2的结果,否则返回表达式3的结果。

例如:

#include <stdio.h>
int main()
{
	int a = 3;
	int b = 5;
	int ret = a > b ? a : b;//返回的是二者的最大值
	printf("ret=%d", ret);//ret=5
	return 0;
}

七.操作符的属性:优先级、结合性

1.优先级

 优先级:如果⼀个表达式包含多个运算符,哪个运算符应该优先执行。各种运算符的优先级是不⼀样的。

2.结合性

如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符是左结合,还是右结合,决定执行顺序。大部分运算符是左结合(从左到右执⾏),少数运算符是右结合(从右到左执行),⽐如赋值运算符( = )。

运算符的优先级顺序很多,下⾯是部分运算符的优先级顺序(按照优先级从⾼到低排列),建议大概记住这些操作符的优先级就行,其他操作符在使用的时候查看下⾯表格就可以了。

• 圆括号( () )

• ⾃增运算符( ++ ),⾃减运算符( – )

• 单⽬运算符( + 和 - )

• 乘法( * ),除法( / )

• 加法( + ),减法( - )

• 关系运算符( < 、 > 等)

• 赋值运算符( = )

优先级、结合性表

八.表达式求值

1.整形提升

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

整型提升的意义:

  • 表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度⼀般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执⾏时实际上也要先转换为CPU内整型操作数的标准长度。通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送⼊CPU去执行运算。
//实例:伪代码
	char a,b,c;
	a = b + c;
	//b和c的值被提升为普通整型,然后再执行加法运算。
    //加法运算完成之后,结果将被截断,然后再存储于a中。

例如:

#include <stdio.h>
int main()
{
	char a = -1;//-1默认为整形
	char b = 1;
	char c = a + b;
	printf("%d\n", c);//0
	return 0;
}

在这里插入图片描述

2.算数转换

  • 如果某个操作符的各个操作数属于不同的类型,那么除⾮其中⼀个操作数的转换为另⼀个操作数的类型,否则操作就⽆法进⾏。下面的层次体系称为寻常算术转换。
  • 如果某个操作数的类型在上面这个列表中排名靠后,那么首先要转换为另外⼀个操作数的类型后执行运算。
    在这里插入图片描述

例如:

#include <stdio.h>
int main()
{
	int a = 0;
	unsigned int b = -1;
	printf("%u\n", a + b);//4294967295
	return 0;
}

在这里插入图片描述

在这里插入图片描述

对于取地址&,解引用 *,以及结构体成员访问 . 。这三个操作符日后更新。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何配置和使用Apollo的component里的plugin

关于如何使用Apollo的Component里的plugin&#xff0c;在Apollo的文档里只有如果和开发的说明却没有找到一个清楚完整说明怎么把plugin跑起来的说明&#xff0c;例如我想把lidar_detection_filter按我们的需求对目标过滤算法作修改然后编译完后&#xff0c;执行 cyber_launch …

【数据结构】链表专题3

前言 本篇博客我们继续来讨论链表专题&#xff0c;今天的链表算法题是经典中的经典 &#x1f493; 个人主页&#xff1a;小张同学zkf ⏩ 文章专栏&#xff1a;数据结构 若有问题 评论区见&#x1f4dd; &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 目录 1.判断链表是否…

Dom获取属性操作

目录 1. 基本认知 1.1 目的和内容 1.2 什么是DOM 1.3 DOM对象 1.4 DOM树 2. 获取DOM元素对象 2.1 选择匹配到的第一个元素 2.2 选择匹配到的多个元素 2.3 其他获取DOM元素方法 3. 操作元素内容 3.1 元素对象.innerText 属性 3.2 元素对象.innerHTML 属性 4. 操作元…

springcloud微服务搭建多数据源(mysql,oracle,postgres,等等)管理模块,支持通过注解方式切换不同类型的数据库

1.背景 同一套微服务管理系统&#xff0c;业务完全一样&#xff0c;但不同的客户可能要求使用自己熟悉的数据库&#xff0c;比如&#xff0c;mysql&#xff0c;oracle&#xff0c;postgres&#xff0c;还有一些国产数据库。如果能够将数据库模块独立出来&#xff0c;兼容各家的…

IDEA启动项目报错:Error running ‘‘: Command line is too long.

1、在workspace.xml 2、 在标签 <component name"PropertiesComponent"> 添加 <property name"dynamic.classpath" value"true" />

MySQL 运维篇

回顾基本语句&#xff1a; 数据定义语言(DDL) 这类语言用于定义和修改数据库的结构&#xff0c;包括创建、删除和修改数据库、 表、视图和索引等对象。 主要的语句关键字包括 CREATE 、 DROP 、 ALTER 、 RENAME 、 TRUNCATE 等。 create database 数据库 &#xff1b; cr…

【MySQL | 第十一篇】一条SQL语句在MySQL的执行过程

文章目录 11.一条SQL语句在MySQL的执行过程11.1MySQL整体架构11.2SQL语句在Server层执行流程11.3拓展&#xff1a;InnoDB存储引擎的更新操作11.3.1问题&#xff1a;为什么写了redolog日志还要写binlog日志&#xff1f;11.3.2问题&#xff1a;为什么要两阶段提交&#xff1f;11.…

《QT实用小工具·四十七》可交互的创意动态按钮

1、概述 源码放在文章末尾 该项目实现了可交互的创意动态按钮&#xff0c;包含如下功能&#xff1a; 所有颜色自定义 鼠标悬浮渐变 两种点击效果&#xff1a;鼠标点击渐变 / 水波纹动画&#xff08;可多层波纹叠加&#xff09; 额外鼠标移入/移出/按下/弹起的实时/延迟共8种事…

springboot 自动配置源码解读

什么是自动装配 当我们程序依赖第三方功能组件时&#xff0c;不需要手动将这些组件类加载到IOC容器中。例如 当程序需要用到redis时&#xff0c;在pom.xml文件中引入依赖&#xff0c;然后使用依赖注入的方式直接从IOC容器中拿到相应RedisTemplate实例。 SpringBootApplication …

【已解决】json文件太大无法打开怎么办+ijson报错

下载了一个json文档&#xff0c;尝试了全部的编辑器都打不开。。。 搜了搜或许可以使用ijson GitHub - ICRAR/ijson: Iterative JSON parser with Pythonic interfaces "Ijson is an iterative JSON parser with standard Python iterator interfaces." 示例代码&…

【C++ —— 多态】

C —— 多态 多态的概念多态的定义和实现多态的构成条件虚函数虚函数的重写虚函数重写的两个例外协变&#xff1a;析构函数的重写 C11 override和final重载、覆盖(重写)、隐藏(重定义)的对比 抽象类概念接口继承和实现继承 多态的继承虚函数表多态的原理动态绑定和静态绑定 单继…

VTK 的可视化方法:Glyph

VTK 的可视化方法&#xff1a;Glyph VTK 的可视化方法&#xff1a;Glyph标量、向量、张量将多边形数据的采集点法向量标记成锥形符号参考 VTK 的可视化方法&#xff1a;Glyph 模型的法向量数据是向量数据&#xff0c;因此法向量不能像前面讲到的通过颜色映射来显示。但是可以通…

25 JavaScript学习:var let const

JavaScript全局变量 JavaScript中全局变量存在多种情况和定义方式&#xff0c;下面详细解释并提供相应的举例&#xff1a; 使用var关键字声明的全局变量&#xff1a; var globalVar "我是全局变量";未使用var关键字声明的变量会成为全局变量&#xff08;不推荐使用&…

【前端】-【防止接口重复请求】

文章目录 需求实现方案方案一方案二方案三 需求 对整个的项目都做一下接口防止重复请求的处理 实现方案 方案一 思路&#xff1a;通过使用axios拦截器&#xff0c;在请求拦截器中开启全屏Loading&#xff0c;然后在响应拦截器中将Loading关闭。 代码&#xff1a; 问题&…

(刷题记录2)随机链表的复制

[刷题记录2]随机链表的复制 题目信息&#xff1a;题目思路(环境来自力扣OJ的C语言)&#xff1a;复杂度&#xff1a;代码和解释&#xff1a;1.遍历一遍原链表的同时&#xff0c;在每个原节点后面插入一个相同的新节点&#xff0c;共插入 n 个新节点。2.利用两者联系&#xff0c;…

神奇的Vue3 - 组件探索

神奇的Vue3 第一章 神奇的Vue3—基础篇 第二章 神奇的Vue3—Pinia 文章目录 神奇的Vue3了解组件一、注册组件1. 全局注册​2. 局部注册3. 组件命名 二、属性详解1. Props&#xff08;1&#xff09;基础使用方法&#xff08;2&#xff09;数据流向&#xff1a;单项绑定原则&…

ThreeJS:Mesh网格与三维变换

Mesh网格 ThreeJS中&#xff0c;Mesh表示基于以三角形为多边形网格(polygon mesh)的物体的类&#xff0c;同时也作为其它类的基类。 通过Mesh网格&#xff0c;我们可以组合Geometry几何体与Material材质属性&#xff0c;在3D世界中&#xff0c;定义一个物体。例如&#xff1a;之…

vue2(4)之scoped解决样式冲突/组件通信/非父子通信/ref和$refs/异步更新/.sync/事件总线/provide和inject

vue2 一、学习目标1.组件的三大组成部分&#xff08;结构/样式/逻辑&#xff09;2.组件通信3.综合案例&#xff1a;小黑记事本&#xff08;组件版&#xff09;4.进阶语法 二、scoped解决样式冲突**1.默认情况**&#xff1a;2.代码演示3.scoped原理4.总结 三、data必须是一个函数…

Copilot Venture Studio創始合伙人楊林苑確認出席“邊緣智能2024 - AI開發者峰會”

隨著AI技術的迅猛發展&#xff0c;全球正逐步進入邊緣計算智能化與分布式AI深度融合的新時代&#xff0c;共同書寫著分布式智能創新應用的壯麗篇章。邊緣智能&#xff0c;作為融合邊緣計算和智能技術的新興領域&#xff0c;正逐漸成為推動AI發展的關鍵力量。借助分布式和去中心…

由于找不到mfc140u.dll,无法继续执行的多种解决方法

在我们日常与计算机的密切互动中&#xff0c;或许不少用户都曾遇到过这样一个棘手的问题&#xff1a;系统突然弹出一个提示窗口&#xff0c;告知我们“找不到mfc140u.dll文件”。这个文件是Microsoft Foundation Class&#xff08;MFC&#xff09;库的一部分&#xff0c;用于支…