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

news2024/12/24 9:39:52

操作符

  • 一.操作符的分类
  • 二.原码、反码、补码
  • 三.移位操作符
    • 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;
}

在这里插入图片描述

在这里插入图片描述

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

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

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

相关文章

MATLAB 数据输出

MATLAB 数据输出 数据导出(或输出)在 MATLAB 的意思是写入文件。MATLAB 允许您在另一个读取 ASCII 文件的应用程序中使用您的数据。为此&#xff0c;MATLAB 提供了几个数据导出选项。 您可以创建以下类型的文件- 数组中的矩形、分隔的ASCII数据文件。 击键的日记&#xff08…

导数之光:探寻机器学习中的微变奥秘

在当今这个数据驱动的时代&#xff0c;机器学习以其强大的学习和预测能力&#xff0c;成为了推动科技进步的重要力量。而在机器学习的背后&#xff0c;数学原理&#xff0c;尤其是导数的应用&#xff0c;为其提供了坚实的理论支撑。本文将详细探讨导数在机器学习中的体现&#…

细说SVPWM原理及软件实现原理,关联PWM实现

细说SVPWM原理及软件实现原理&#xff0c;关联PWM实现 文章目录 细说SVPWM原理及软件实现原理&#xff0c;关联PWM实现1. 前言2. 基础控制原理回顾2.1 FOC 原理回顾2.2 细说 SVPWM2.2.1 矢量扇区计算2.2.2 矢量作用时间计算 2.2.3 如何理解 U4 U6 2/3Udc?2.2.4 如何理解 U4m…

flash attention 参数(笔记)

目录 一、flash attention官方 1.1、flash attention安装 二、flash attention 常见函数 2.1、flash_attn_varlen_qkvpacked_func 2.2、flash_attn_varlen_kvpacked_func 2.3、flash_attn_varlen_func ​​​​​​​2.4、flash_attn_with_kvcache 2.5、flash_attn_func 一、…

1. 深度学习笔记--神经网络中常见的激活函数

1. 介绍 每个激活函数的输入都是一个数字&#xff0c;然后对其进行某种固定的数学操作。激活函数给神经元引入了非线性因素&#xff0c;如果不用激活函数的话&#xff0c;无论神经网络有多少层&#xff0c;输出都是输入的线性组合。激活函数的意义在于它能够引入非线性特性&am…

魔方阵(C语言)

一、魔方阵规律&#xff1b; 8 1 6 3 5 7 4 9 2 魔方阵中各数的排列规律如下&#xff1a; (1)将1放在第1行中间一列。 (2)从2开始直到nn止&#xff0c;各数依次按此规则存放&#xff1a;每一个数存放的行比前一个数的行数减1&#xff0c;列数加1(例如上…

Go 语言基础(二)【数组、切片、指针、map、struct】

1、数组 特别需要注意的是&#xff1a;在 Go 语言中&#xff0c;数组长度也是数组类型的一部分&#xff01;所以尽管元素类型相同但是长度不同的两个数组&#xff0c;它们的类型并不相同。 1.1、数组的初始化 1.1.1、通过初始化列表{}来设置值 var arr [3]int // int类型的数…

HSDB使用教程

HSDB&#xff1a;Hostspot Debugger&#xff0c;JVM内置的工具&#xff0c;用于深入分析JVM运行时的内部状态 启动HSDB java -cp D:/tools/jdk-1.8/lib/sa-jdi.jar sun.jvm.hotspot.HSDB 获取进程id jps 连接到指定进程 查找类 通过查询查找对象 输入查询语句 select d from …

Linux 学习 --- 编辑 vi 命令

1、vi 基本概念&#xff08;了解&#xff09; 基本上 vi 可以分为三种状态&#xff0c;分别是命令模式 (command mode)、插入模式 (Insert mode) 和底行模式 (last line mode)&#xff0c;各模式的功能区分如下: 命令行模式 command mode&#xff09;  控制屏幕光标的移动&a…

「笔试刷题」:字母收集

一、题目 描述 有一个 &#x1d45b;∗&#x1d45a; 的矩形方阵&#xff0c;每个格子上面写了一个小写字母。 小红站在矩形的左上角&#xff0c;她每次可以向右或者向下走&#xff0c;走到某个格子上就可以收集这个格子的字母。 小红非常喜欢 "love" 这四个字母。…

kubernetes中使用ELK进行日志收集

目录 一、需要收集哪些日志 1、kubernetes集群的系统组件日志 2、应用日志 二、日志收集方案ELK 1、收集日志&#xff1a;Logstash 2、存储日志&#xff1a;Elasticsearch 3、展示日志&#xff1a;Kibana 三、安装elk 1、下载安装包 2、创建用户并切换到新用户 3、上…

【Web】CTFSHOW 中期测评刷题记录(1)

目录 web486 web487 web488 web489 web490 web491 web492 web493 web494 web495 web496 web497 web498 web499 web500 web501 web502 web503 web505 web506 web507 web508 web509 web510 web486 扫目录 初始界面尝试文件包含index.php&am…

ubuntu与redhat的不同之处

华子目录 什么是ubuntu概述 ubuntu版本简介桌面版服务器版 安装部署部署后的设置设置root密码关闭防火墙启用允许root进行ssh登录更改apt源安装所需软件 网络配置Netplan概述配置详解配置文件DHCP静态IP设置设置 软件安装方法apt安装软件作用常用命令配置apt源 deb软件包安装概…

基于React实现B站评论区

今天继续来学习一下React&#xff0c;使用React实现B站评论区&#xff0c;如下图&#xff1a; 在使用React开发类似B站评论区的功能时&#xff0c;我们需要考虑以下几个关键点来构建一个基本的评论系统&#xff1a; 1. 设计组件结构 首先&#xff0c;设计组件结构是关键。至少…

【数据结构】:链表的带环问题

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;数据结构 &#x1f337;追光的人&#xff0c;终会万丈光芒 前言&#xff1a; 链表的带环问题在链表中是一类比较难的问题&#xff0c;它对我们的思维有一个比较高的要求&#xff0c;但是这一类…

ThreeJS:Mesh网格与三维变换

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

Unity ParticleSystem 入门

概述 在项目的制作过程成&#xff0c;一定少不了粒子系统的使用吧&#xff0c;如果你想在项目粒子效果&#xff0c;那这部分的内容一定不要错过喔&#xff01;我添加了理解和注释更好理解一点&#xff01; 这次的内容比较多&#xff0c;右侧有目录&#xff0c;可以帮助快速导…

高中数学:三角函数公式汇总及推导

一、定义 常用三角函数值 参考&#xff1a; 三角函数定义 二、基本三角函数及相互关系 sinx cosx tanx cscx secx cotx 函数间相互关系 参考&#xff1a; cosx、sinx、tanx的函数图像与性质 secx、cscx、cotx函数图像及相关关系 三、诱导公式 口诀&#xff1a;奇变…

通信接口——时钟和信号

前言 所有接口只要抓住三个核心点就能分清&#xff1a;时钟同步和异步&#xff0c;时钟的来源&#xff0c;信号的传输方向。 一、时钟同步和异步 接口之间的交互方式存在多种形式&#xff0c;如果按照是否有公共时钟CLK的参与&#xff0c;可以分为同步传输和异步传输。 同步&…

C语言——队列的实现

队列按照先进先出&#xff08;FIFO&#xff0c;First In First Out&#xff09;的原则管理数据。这意味着最先进入队列的元素会被最先移出&#xff0c;类似于排队等候服务的情况。队列通常有两个主要操作&#xff1a;入队&#xff08;enqueue&#xff09;&#xff0c;将元素添加…