C语言---操作符详解

1.操作符的分类

• 算术操作符: + 、- 、* 、/ 、%

• 移位操作符: >

• 位操作符: & | ^

• 赋值操作符: = 、+= 、 -= 、 *= 、 /= 、%= 、>= 、&= 、|= 、^=

• 单⽬操作符: !、++、--、&、*、+、-、~ 、sizeof、(类型)

• 关系操作符: > 、>= 、< 、<= 、 == 、 !=

• 逻辑操作符: && 、||

• 条件操作符: ? :

• 逗号表达式: ,

• 下标引⽤: []

• 函数调⽤: ()

2.二进制和进制转换

2进制、8进制、10进制、16进制是数值的不同表达形式

2进制:1111
8进制:17     7*8的0次方加1*8的1次方
10进制:15
16进制:F

2进制数字都是0~1组成的

8进制都是0~7的数字组成的

10进制的数字都是由0~9的数字组成

16进制的数字是0~9,a~f的数字组成

二进制满2进一

假设输入的10进制数字是125,一次除以2
然后依次是125 62 31 15 7 3 1 0余数依次是 1 0 1 1 1 1 1,所以10进制的125转换的2进制是:111110120用二进制来表达就是10100
2进制   0 1 1 0 1 0 1 1
8进制    1    5     3从二进制的右边开始换算成八进制,每3个换算一次不足3个的2进制位直接换算,2进制的01101011换算成8进制的数字就是153注意:0开头的数字,会被当做8进制
 2进制   0 1 1 0 1 0 1 1
16进制      6       b
从二进制序列的最右边开始转换
每4个数字转换一次,不足4个数字的二进制直接转换二进制右边的1011转换为10进制的数就是11,在16进制中用b表示
二进制左边的0110转换为10进制就是6,在16进制中用6表示2进制的01101011转换成16进制0x6b,
16进制表示的时候前面加上0x

如果进行8进制转换成2进制甚至16进制转化为2进制只需要用反思路就可以算出

8进制位中的3换算成2进制就是011

8进制位中的5换算成2进制就是101

16进制的0x47转换为2进制就是01000111,因为7用二进制来表达就是0111,4用二进制来表达就是0100

8进制的047转换为2进制就是100111,因为8进制的7转换为2进制就是111,4转换板为二进制就是100

8进制是以二进制的三个数为一个单位的

16进制是以二进制的四个数为一个单位的

3.原码反码补码

整数的二进制表达形式有3种,即原码、反码和补码

有符号整数的三种表达方式均有符号位和数值位两部分,

2进制位中,最高位的1位是被当做符号位,剩余的都是数值位

符号位都是0表示正,1表示负

一个整型占的是4个字节,10占了8个字节,也就是32个bit位

正整数的原码反码补码都相同

负整数的三种表示方式个不同

原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码

反码:将原码的符号位不变,其他位依次按位取反就可以得到反码

补码:反码+1就是补码----仅针对于负数

负数的反码除了开头的符号位不改变,其他的0变成1,1变成0

int a =10

原码:00000000000000000000000000001010

反码:00000000000000000000000000001010

补码:00000000000000000000000000001010

int a =-10

原码:10000000000000000000000000001010

反码:11111111111111111111111111110101

补码:11111111111111111111111111110110

对于负数,原码反码补码是要计算的,但是正数的原码反码补码都相同

原码取反得到反码,+1得到补码

补码-1取反得到原码,补码取反+1也能得到原码

11111111111111111111111111110110--补码

10000000000000000000000000001001--反码--补码取反

10000000000000000000000000001010---+1==原码--反码+1

数据存放在内存中的其实是补码

整数在内存中存储的其实是补码

原码得到补码和补码得到原码都是取反+1

1+(-1)用原码算的话得出来的数是-2

但是用补码算的话就是0

计算的时候都是用补码

4.移位操作符

<<左移操作符

>>右移操作符

注意:操作符的操作数只能是整数

移动的是存纯在内存中的二进制位---补码

左移规则:左边抛弃,右边补0

整数
int main()
{int a = 10;//注意,移动的是存纯在内存中的二进制位---补码int b = a << 1;//a向左移动2位//10的二进制是1010//10放到a里面存储,4个字节,32个比特位//00000000000000000000000000001010----10的二进制数//a向左移动一位,最左边的被挤出去了,最右边就补上一个0//00000000000000000000000000010100----最后打印的b就是20printf("%d\n", b);//输出结果是20printf("%d\n", a);//结果仍然是10return 0;
}负数
int main()
{int a = -1;//10000000000000000000000000000001-----   -1的原码//11111111111111111111111111111110-----    取反//11111111111111111111111111111111-----    +1----   -1的补码int b = a << 1;//移位后//11111111111111111111111111111110---b的补码//10000000000000000000000000000001---取反//10000000000000000000000000000010---+1---b的原码----   -2printf("b=%d\n", b);//打印的是b的原码-2printf("a=%d\n", a);//-1return 0;
}

右移规则:首先右移运算分两种

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

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

到底采用逻辑右移还是算术右移,取决于编译器

通常采用的都是算术右移

左边用原该值的符号填充,右边的丢弃

int main()
{int a = -10;//10000000000000000000000000001010---原码//11111111111111111111111111110101---取反//11111111111111111111111111110110---补码//采用算术右移,左边填充原来该值的符号,右边的丢弃//11111111111111111111111111111011--右移后的补码//10000000000000000000000000000100--取反//10000000000000000000000000000101--+1--原码//右移后的就是-5int b = a >> 1; printf("a=%d\n", a);//-10printf("b=%d\n", b);//-5return 0;
}

5.位操作符:&、|、^、~

& 按位与

| 按位或

^ 按位异或

~ 按位取反

操作数必须是整数

这里的位都是二进制位,只关注与二进制的计算

以下两种操作符只关注真假

&&逻辑与

||逻辑或

int main()
{int a = 6;//00000000000000000000000000000110---6的补码int b = -7;//10000000000000000000000000000111--  -7的原码//11111111111111111111111111111000--  -7的反码//11111111111111111111111111111001--  -7的补码int c = a & b;//a和b的补码的二进制位进行运算//对应的二进制位,有0则为0,两个同时为1才为1//00000000000000000000000000000110---6的补码//11111111111111111111111111111001--  -7的补码//00000000000000000000000000000000printf("c=%d\n", c);//c=0return 0;
}//对应的二进制位,有0则为0,两个同时为1才为1
int main()
{int a = 6;//00000000000000000000000000000110---6的补码int b = -7;//10000000000000000000000000000111--  -7的原码//11111111111111111111111111111000--  -7的反码//11111111111111111111111111111001--  -7的补码int c = a | b;//a和b的补码的二进制位进行运算//规则:只要有1就是1,两个同时为0才为0//00000000000000000000000000000110---6的补码//11111111111111111111111111111001--  -7的补码//11111111111111111111111111111111----运算出的补码//10000000000000000000000000000000---取反//10000000000000000000000000000001  +1--转换出的原码printf("c=%d\n", c);//c=-1return 0;
}规则:只要有1就是1,两个同时为0才为0
int main()
{int a = 6;//00000000000000000000000000000110---6的补码int b = -7;//10000000000000000000000000000111--  -7的原码//11111111111111111111111111111000--  -7的反码//11111111111111111111111111111001--  -7的补码int c = a ^ b;//a和b的补码的二进制位进行运算//规则:对应的二进制位上,相同为0,相异为1//00000000000000000000000000000110---6的补码//11111111111111111111111111111001--  -7的补码//11111111111111111111111111111111----运算出的补码//10000000000000000000000000000000---取反//10000000000000000000000000000001  +1--原码printf("c=%d\n", c);//c=-1return 0;
}对应的二进制位上,相同为0,相异为1//不让创建临时变量(第三个变量),实现两个整数的交换
int main()
{int a = 3;int b = 5;printf("交换前:a=%d b=%d\n", a, b);//不存在溢出现象a= a ^ b;//111b= a ^ b;///222//a ^ b^ b=a  将111中a 的值带到222中a= a ^ b;///333//a ^ b^a=b   将222中b的值带到333中printf("交换后:a=%d b=%d\n", a, b);return 0;
}011--a
101--b
110---a ^ b    =a
011---a ^ b ^ b=b
101---a ^ b
//3^3=0
//a^a=0
//0^a=a/*
* 异或是支持交换的
3^3^5=5
3^5^3=5*///另外一种写法
//不让创建临时变量(第三个变量),实现两个整数的交换
int main()
{int a = 3;int b = 5;int c = 0;printf("交换前:a=%d b=%d\n", a, b);//不存在溢出现象c = a;a = b;b = c;printf("交换后:a=%d b=%d\n", a, b);return 0;
}
int main()
{int a = 0;printf("%d\n", ~a);/*结果为 - 1*///~是按(二进制)位取反//00000000000000000000000000000000---0的补码//11111111111111111111111111111111---//10000000000000000000000000000000//10000000000000000000000000000001--最后的补码return 0;
}

^: 异或操作可以直接比较两个整数的对应位。当两个整数的对应位相同时,异或结果为0;当对应位不同时,结果为1。这意味着异或结果的每一位都直接告诉我们原始两个整数在该位上是否不同。

6.单目操作符

& -- 取地址操作符

  • -- 解引用操作符

如果写的是a&b,---&的意思就是按位与

但如果int a=10;--&a就是取a的地址

双目操作符的时候就是按位与

单目操作符的时候就是取地址

单目操作符有这些:

++

--

&

+

-

~

sizeof

(类型)

7.逗号表达式

exp1,exp2,exp3,exp4

逗号表达式就是用逗号隔开的表达式

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

int main()
{int a = 1;int b = 2;//逗号表达式//逗号表达式要从左依次向右计算//因为前面表达式的计算可能会影响后面的计算int c = (a > b, a = b + 10, a, b = a + 1);printf("%d", c);//输出结果是13return 0;
}

8.下标访问[]、函数调用()

int main()
{int arr[10] = { 1,2,3,4,5 };int m =arr[4];//数组中下标是4的元素//[]  下标引用操作符--操作数是:arr,4---数组名和下标printf("%d", m);//输出结果是5return 0;}
int Add(int x, int y)
{return x + y;
}int main()
{printf("hehe\n");//这里的()就是函数调用操作符//操作数是:一个是函数名,一个是穿过去的字符串printf("%d\n", 100);//这里的操作数:双引号内的字符串//函数名  还有100int ret = Add(3, 5);//Add,3,5就是这个函数调用//操作符的操作数//函数调用操作符,最少有几个操作数?//至少有一个操作数,就是函数名return 0;
}

9.结构成员访问操作符

结构是一些值的集合,这些值称为成员变量,结构的每个成员可以是不同类型的变量,如:标量、数组、指针、甚至是其他的结构体

结构体的关键字叫struct---

//学生类型
struct Student
{//成员变量char name[20];//名字int age;//年龄float score;//成绩
}a4, a5, a6;//也是全局变量struct Student a3 = {"王",25,68.5};//全局变量struct point
{int x;int y;
};struct S
{char ch;struct point p;int arr[10];double d;
};
int main()
{struct Student a1 = {"翠花",20, 98.0};//用结构体类型创造结构体变量struct Student a2 = {"旺财",18,69.8};//局部变量struct S s = { 'a',{4,5},{1,2,3,4,5,6,7},3.14 };printf("%c", s.ch);printf("坐标是:%d %d\n", s.p.x, s.p.y);printf("%d\n", s.arr[0]);printf("%lf\n", s.d);return 0;
}
//通过结构体的名字加.去查找你存放的数据
//操作符左边是结构体变量.结构体成员名
//如果向往里面输入数据,就将pritnf改成scanf输入数据就行了

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

c语言的操作符有两个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序

int main()
{int r = 3 + 4 * 5;//先算乘法,再算加法return 0;
}

优先级

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

当我们明确了优先级和结合性那我们是否能确定一个表达式的计算结果呢?

11.表达式求值

为了获取精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升

char 是否是signed char?

不一定,是取决于编译器的

vs上,char == signed char

char类型的取值范围是-128~127

算术转换

整型提升讨论的是表达式中char和short类型的值

算术转换讨论的是大于等于整型类型的其他类型

1.long double

2.double

3.float

4.unsigned long int

5.long int

6.unsigned int

7.int

从下向上转换--两种不同类型相加,较低档次的会被很转化为较高档次的

double a=10;

int b =10;

a+b的计算中,a会被转化成和b类型一样的double 类型

即是有操作符的优先级和结核性,我们写出的表达式仍然存在潜在风险的,建议不必要写复杂的表达式

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

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

相关文章

在windows下使用VS Code、CMake、Make进行代码编译

软件环境 Windows11VS CodeNoneCMake3.26.4-windows-x86_64MinGWNone 电脑系统配置 安装MinGW将MinGW安装文件夹中bin文件夹下的mingw32-make.exe复制并重命名为make.exe在文件夹中添加系统路径&#xff0c;具体位置为 系统->系统信息->高级系统设置->高级->环境…

Linux运维:centos环境变量

前言 在 Linux 运维工作中&#xff0c;管理环境变量是至关重要的一项任务。在 CentOS 环境下&#xff0c;正确配置环境变量可以使系统更加高效和易于管理。 本文将重点讨论 CentOS 环境下的环境变量设置&#xff0c;并就python的环境变量配置方案进行讲解&#xff08;不包含Ano…

生成式 AI 的发展方向,应当是 Chat 还是 Agent?

生成式AI的发展方向既可以是Chat&#xff08;聊天&#xff09;也可以是Agent&#xff08;智能代理&#xff09;&#xff0c;这两者并不是互斥的&#xff0c;而是可以相互补充和融合。 Chat&#xff08;聊天&#xff09;方向&#xff1a; 聊天机器人在过去几年中取得了显著的进…

cs客户端测试注意点

客户端安装卸载测试 安装测试 1、GUI测试&#xff1a;安装过程中所有的界面显示&#xff0c;提示信息等是否正确 2、兼容性测试&#xff1a;在不同的操作系统&#xff0c;不同配置的主机上能否正常安装 3、安装路径测试(软件不能自动安装的情况下)&#xff1a; 软件默认路…

YOLOv9中模块总结补充|SPPELAN

专栏相关代码&#xff1a;目前售价售价69.9&#xff0c;改进点80 专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;助力高效涨点&#xff01;&#xff01;&#xff01; 1. SPPELAN SPPELAN是YOLOv9作者在SPPF的基础上创新的模块&#xff08;增加了一次…

基于STM32F401RET6智能锁项目(环境搭建)

工程搭建 MDK&#xff0c;固件库&#xff0c;芯片包下载 下载keil5&#xff0c;stm32f4xx的固件库以及stm32f4的芯片包 keil官网&#xff1a;https://www2.keil.com/mdk5/ stm32中国官网&#xff1a;https://www.stmcu.com.cn/ 创建工程 1、新建一个工程文件夹&#xff0c;…

【勘误】一个错误的快速排序实现

文章目录 问题一&#xff1a;不一致算法描述部分给出的分划实现完整程序部分给出的分划实现 问题二&#xff1a;不正确问题三&#xff1a;把循环条件改为 i < j 程序还是不正确正确的实现总结 从 10 10 10 年前我开始学 C 语言时我就认为快速排序并不是个简单的算法。相比于…

系统权限控制插件封装-实现系统权限控制插件化

背景&#xff1a;按照传统的开发方式方式&#xff0c;每次新开发一个系统&#xff0c;就需要花费大量时间精力去搭建权限控制模块&#xff0c;如果我们把权限控制这一整个模块都抽离成一个独立的权限控制插件&#xff0c;支持单命令安装&#xff0c;全面暴露参数与方法&#xf…

k8s 理论知识基本介绍

目录 一 k8s 理论前言 &#xff08;一&#xff09;微服务是什么 1&#xff0c;应用场景 2&#xff0c;API 是什么 &#xff08;二&#xff09;&#xff0c;微服务 如何做版本迭代 1. Docker镜像构建 2. 版本标记 3. Docker Registry 4. 环境一致性 5. 滚动更新…

美国海军部发布《海军科学与技术战略》

文章目录 前言一、战略目标二、美海军部科学与技术战略总体归纳(一)强化海上统治地位1、实现更快的技术收益2、应用颠覆性技术3、发挥海军部战略优势4、完善试验和兵棋推演机制(二)建立卓越战斗文化1、打造集合作战人员、科学家和工程师的团队2、强化合作和建设能力3、科学…

多进程编程

创建一对父子进程&#xff1a; 父进程负责向文件中写入 长方形的长和宽 子进程负责读取文件中的长宽信息后&#xff0c;计算长方形的面积 代码&#xff1a; #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #inc…

串口通信---了解

1 串口接线方式 RXD&#xff1a;数据输入引脚&#xff0c;数据接受&#xff1b;STC89系列对应P3.0口 TXD&#xff1a;数据发送引脚&#xff0c;数据发送&#xff1b;STC89系列对应P3.1口 接线方式 串口编程要素 输入/输出数据缓冲器叫做SBUF&#xff0c;都用99H地址码&#x…

Java文件与IO操作

1. 文件与IO操作 1.1 文件 什么是文件: 文件,对我们并不陌生,文件是保存数据的地方,比如大家经常使用的word文档,txt文件.excel文件...都是文件。它既可以保存一张图片,也可以保持视频,声音.… 1.1.1 文件流: 1.1.2 常用的文件操作: 创建文件对象相关构造器和方法: 案例&a…

NeRF算法

目录 算法介绍 基本原理 1. 体渲染 2. 多层感知机&#xff08;MLP&#xff09; 3. 位置编码 4. 两阶段层次化体采样 实验展示 代码解析 算法介绍 NeRF&#xff08;Neural Radiance Fields&#xff09;是一种用于从2D图像中重建3D场景的神经网络模型。它通过训练一个深度…

SAP-ABAP-视图

1、什么是视图&#xff1f; 当需要查询多个表中的某些字段的数据时&#xff0c;就可以使用视图。视图不影响数据库中的数据&#xff0c;仅作为查询手段或工具。 2、视图类型&#xff1a; 数据库视图和维护视图经常使用。 3、创建视图SE11 3.1、数据库视图 可以直接输入表名…

VS中Halcon环境配置

环境配置步骤&#xff1a; 1、项目->属性-> C/C 常规 ->附加包含目录->添加include和include\halconcpp目录 目录如下&#xff1a;&#xff08;在你halcon的安装目录下找到include和include\halconcpp目录&#xff09; D:\HALCON\HALCON-22.11-Progress\include…

万能知识付费系统,为什么培训机构一直年年招老师?

培训机构年年招老师&#xff0c;说明机构的老师流失率大&#xff0c;稳定性不强。为什么稳定性不强&#xff0c;小认为主要有以下几个原因&#xff1a; 1、新入职机构的老师流动性是最大的&#xff0c;一方面&#xff0c;刚进入这个行业&#xff0c;对行业高强度工作不适应&…

【面试八股总结】C++11新特性:智能指针

参考资料 &#xff1a;阿秀、代码随想录 智能指针是一个类&#xff0c;用于存储指向动态分配对象的指针&#xff0c;负责自动释放动态分配的对象&#xff0c;防止堆内存泄露。动态分配的资源&#xff0c;交给一个类对象去管理&#xff0c;当类对象声明周期结束时&#xff0c;自…

Linux 文件

文章目录 文件操作回顾(C/C)系统调用接口 管理文件认识一切皆文件C/C的文件操作函数与系统调用接口的关系……重定向与缓冲区 -- 认识重定向与缓冲区 -- 理解使用重定向缓冲区实现一个简单的Shell(加上重定向)标准输出和标准错误(在重定向下的意义) 磁盘文件磁盘存储文件操作系…

Redis大key问题

Big Key就是某个key对应的value很大&#xff0c;占用的redis空间大&#xff0c;本质上是大value问题。比如用String类型的Key存放大体积二进制文件型数据用List数据结构保存热点新闻的评论列表&#xff0c;因为评论数爆发增长导致存放的元素多&#xff0c;value过大。 大key带来…