操作符详解(1)

1. 操作符分类:

算术操作符
移位操作符 
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用和结构成员

2. 算术操作符

+ - * / %

1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。

3. 移位操作符

<< 左移操作符
>> 右移操作符
注:移位操作符的操作数只能是整数。

 移位操作符移动的是二进制的位。

整数的二进制表示形式有三种:原码,反码,补码。

原码:按照数值的正负,直接写出的二进制序列就是原码,一个整数4个字节,32个bit位,一个整数的二进制序列就是32个bie位。对于有符号的整数来说,最高位是符号位,0为正数,1为负数。对于无符号整数来说,没有符号位,所有位都是有效位。

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

补码:反码的二进制+1得到补码。

对于正整数来说,原码,反码,补码相同,无需计算。

对于负整数来说,原码,反码,补码需要计算。

不管是正整数还是负整数,在内存中存储的都是补码的二进制序列。

整数在计算的时候使用的也是补码。

10
原码:00000000 00000000 00000000 00001010
反码:00000000 00000000 00000000 00001010
补码:00000000 00000000 00000000 00001010
-10
原码:10000000 00000000 00000000 00001010
反码:11111111 11111111 11111111 11110101
补码:11111111 11111111 11111111 11110110

3.1 左移操作符

移位规则:
左边抛弃、右边补0.

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{//左移操作:左边丢弃,右边补0//00000000000000000000000000000111int m = 7;int n = m << 1;//00000000000000000000000000001110printf("%d\n", m);printf("%d\n", n);return 0;
}

 在左移后m的值还是7,m只是参与运算,<<操作符有*2的类似效果。

负数:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{//左移操作:左边丢弃,右边补0//原码:10000000000000000000000000000111//负数要计算补码//反码:11111111111111111111111111111000//补码:11111111111111111111111111111001int m = -7;int n = m << 1;//左移后:11111111111111111111111111110010//打印出来的是原码,所以我们计算左移后的原码,-1取反得到原码//11111111111111111111111111110001//10000000000000000000000000001110printf("%d\n", m);printf("%d\n", n);return 0;
}

  

左移操作符可以使得一些二进制数字来到我们想要的地方。 

3.2 右移操作符

移位规则:
首先右移运算分两种:
1. 逻辑移位
左边用0填充,右边丢弃
2. 算术移位
左边用原该值的符号位填充,右边丢弃

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{int a = -10;//原码:10000000 00000000 00000000 00001010//反码:11111111 11111111 11111111 11110101//补码:11111111 11111111 11111111 11110110int b = a >> 1;//逻辑位移:01111111 11111111 11111111 11111011//算数位移:11111111 11111111 11111111 11111011//反码:11111111 11111111 11111111 11111010//原码:10000000 00000000 00000000 00000101-> -5printf("a=%d\n", a);printf("b=%d\n", b);return 0;
}

  

使用逻辑位移还是算术位移取决的是编译器,大部分是算术右移,逻辑右移太简单粗暴。

右移有类似除2的效果。

警告⚠:
对于移位运算符,不要移动负数位,这个是标准未定义的。

例如:

int num = 10;
num>>-1;//error

4. 位操作符

位操作符有:

& //按位与
| //按位或
^ //按位异或
注:他们的操作数必须是整数。

 &运算,用补码进行运算,对应的二进制位有0则为0,两者为1才为1。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{int a = 3;int b = -5;int c = a & b;//按(2进制)位与//00000000000000000000000000000011 --- 3的补码//10000000000000000000000000000101 //11111111111111111111111111111010//11111111111111111111111111111011 --- -5的补码//00000000000000000000000000000011 --- 3的补码//00000000000000000000000000000011printf("%d\n", c);return 0;
}

 &的特点是得到某一个你想要的位。任何数字&1得到的他二进制位的最后一位。配合移位操作符将我们想要的二进制数字移位到最后一位,&1就可以得到这一位。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{int a = 3;//如果想要得到3的最低位//a&1//00000000000000000000000000000011 --- 3的补码//00000000000000000000000000000001 ---1的补码//遇到0则为0,3的最低位之前的所有位都会变成0,如果结果是0,表示3的最低位是0,如果结果是1,3的最低位就是1return 0;
}

| 运算:

用补码进行运算,对应的二进制位有1则为1,两者为0才为0。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{int a = 3;int b = -5;//00000000000000000000000000000011 --- 3的补码//10000000000000000000000000000101 //11111111111111111111111111111010//11111111111111111111111111111011 --- -5的补码int c = a | b;//00000000000000000000000000000011 --- 3的补码//11111111111111111111111111111011 --- -5的补码//11111111111111111111111111111011 //11111111111111111111111111111010//10000000000000000000000000000101   -5printf("%d\n", c);return 0;
}

^操作符:

相同为0,相异为1.\

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{int a = 3;int b = -5;//00000000000000000000000000000011 --- 3的补码//10000000000000000000000000000101 //11111111111111111111111111111010//11111111111111111111111111111011 --- -5的补码int c = a ^ b;//00000000000000000000000000000011//11111111111111111111111111111011//11111111111111111111111111111000//10000000000000000000000000000111//10000000000000000000000000001000//printf("%d\n", c);return 0;
}

接下来我们看一道面试题:不创建临时变量,实现两个数的交换。

 这个代码存在缺陷,变量的值如果太大就出问题了。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{int a = 3;int b = 5;printf("a=%d b=%d\n", a, b);a = a + b;b = a - b;a = a - b;printf("a=%d b=%d\n", a, b);return 0;
}

这个代码使用^操作符来实现,但是这种方法的效率不是很高,创建临时变量是最好的。 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{int a = 3;int b = 5;int c = 0;//中间变量printf("a=%d b=%d\n", a, b);a = a ^ b;//a = 3^5b = a ^ b;//b=3^5^5 b=3a = a ^ b;//a= 3^5^3^5^5 a=5printf("a=%d b=%d\n", a, b);return 0;
}

5. 赋值操作符

赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值。

int weight = 120;//体重
weight = 89;//不满意就赋值
double salary = 10000.0;
salary = 20000.0;//使用赋值操作符赋值
赋值操作符可以连续使用,比如:
int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//连续赋值
这样的代码感觉怎么样?
那同样的语义,你看看:
x = y+1;
a = x;
这样的写法是不是更加清晰爽朗而且易于调试

复合赋值符

+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^=

这些运算符都可以写成复合的效果。
比如:

int x = 10;
x = x+10;
x += 10;//复合赋值
//其他运算符一样的道理。这样写更加简洁。

6. 单目操作符

6.1 单目操作符介绍

单目操作符就是只有一个操作数。

! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换

!可以把假变成真,把真变成假。
&是取地址操作符,用指针变量来存储。

*是解引用操作符,*x是通过x中存放的地址,知道x指向的对象。

sizeof其实我们之前已经见过了,可以求变量(类型)所占空间的大小。

前置++:计算口诀:先+1,后使用。

后置++:口诀:先使用,后+1。

--跟++是一样的。

6.2 sizeof 和 数组

数组传参是是首元素地址,是指针,地址的大小在32位平台是4个字节,64位平台是8个字节。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <stdio.h>
void test1(int arr[])
{printf("%d\n", sizeof(arr));//(2)
}
void test2(char ch[])
{printf("%d\n", sizeof(ch));//(4)
}
int main()
{int arr[10] = { 0 };char ch[10] = { 0 };printf("%d\n", sizeof(arr));//(1)printf("%d\n", sizeof(ch));//(3)test1(arr);test2(ch);return 0;
}


 

 7. 关系操作符

>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等

这些关系运算符比较简单,没什么可讲的,但是我们要注意一些运算符使用时候的陷阱。
警告:
在编程的过程中== 和=不小心写错,导致的错误。

8. 逻辑操作符

&& 逻辑与
|| 逻辑或

&&都真才为真,||一个为真就是真。

360笔试题

#include <stdio.h>
int main()
{
int i = 0,a=0,b=2,c =3,d=4;
i = a++ && ++b && d++;
//i = a++||++b||d++;
printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
return 0;
}

a++,a首先是0,所以这个表达式都为假,后面的不需要算了,所以只有a+1了,其他没变,i=0。 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <stdio.h>
int main()
{int i = 0, a = 0, b = 2, c = 3, d = 4;/*i = a++ && ++b && d++;*/i = a++||++b||d++;printf(" a = %d\n b = %d\n c = %d\n d = %d\n i = %d\n", a, b, c, d,i);return 0;
}

这里有一个数不为0则为真,所以都要运算,i=1.


今天的分享到这里就结束啦!谢谢老铁们的阅读,让我们下期再见。

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

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

相关文章

技术文档如何在线搭建网页形式,方便编辑与管理分享其他人员?

搭建在线技术文档网页形式的平台可以方便编辑、管理和分享给其他人员&#xff0c;促进团队的协作和知识共享。 搭建在线技术文档网页形式的步骤和具体操作的详细介绍&#xff1a; 1. 选择适合的平台 首先&#xff0c;需要选择适合搭建在线技术文档网页形式的平台。市面上有很…

深入完整的带你了解java对象的比较

目录 元素的比较 1.基本类型的比较 2.对象比较的问题 1.运行结果 2.疑问 3.原因 对象的比较 1.覆写基类的equals 2.基于Comparble接口类的比较 3.基于比较器比较 4.三种方式对比 元素的比较 1.基本类型的比较 在Java 中&#xff0c;基本类型的对象可以直接比较大…

dockerfile的概念

目录 一.Dockerfile 概念 1.1 docker镜像的分层 二.Docker镜像的创建 2.1基于已有的镜像创建 2.2基于本地模板创建 2.3基于dockerfile创建 2.3.1dockerfile 结构(四部分) 三.Dockerfile操作指令 3.1ENTRYPOINT指令 3.2CMD 与entrypoint 四.ADD和copy区别 五.镜像分层的原…

Docker运行Nacos容器,过一会就报错`UnsatisfiedDependencyException`

Docker运行Nacos容器&#xff0c;过一会就报错UnsatisfiedDependencyException 问题背景&#xff1a; 最近要上线一个项目&#xff0c;由于要使用Nacos作为服务注册中心&#xff0c;为了方便&#xff0c;我就打算直接使用Docker部署Nacos&#xff0c;没想到Nacos启动没一会就嗝…

spring cloud 之 dubbo nacos整合

整体思路&#xff1a; 搭建本地nacos服务&#xff0c;详见docker安装nacos_xgjj68163的博客-CSDN博客 共三个工程&#xff0c;生产者服务、消费者服务、生产者和消费者共同依赖的接口工程&#xff08;打成jar&#xff0c;供生产者和消费者依赖&#xff09;&#xff1b; …

javaScript:常用的js字符串方法

目录 一.前言 二.字符串方法 1.charAt(num) 获取字符串指定位置上的字符 解释 示例 注意 2.length属性 获取字符串长度 解释 示例讲解 3.substring()字符串的截取 解释 特点 示例 4.slice()字符串截取 解释 特点 示例 应用 单行文本加省略号 字符串劫…

7-5 螺旋方阵

分数 20 全屏浏览题目 切换布局 作者 C课程组 单位 浙江大学 所谓“螺旋方阵”&#xff0c;是指对任意给定的N&#xff0c;将1到NN的数字从左上角第1个格子开始&#xff0c;按顺时针螺旋方向顺序填入NN的方阵里。本题要求构造这样的螺旋方阵。 输入格式&#xff1a; 输入在…

STM32 CubeMX (第一步Freertos任务管理:创建、删除、挂起、恢复)

STM32 CubeMX Freertos STM32 CubeMX &#xff08;Freertos任务&#xff1a;创建、删除、挂起、恢复&#xff09; STM32 CubeMX Freertos前言一、STM32 CubeMX 配置时钟树配置HAL时基选择TIM1&#xff08;不要选择滴答定时器&#xff1b;滴答定时器留给OS系统做时基&#xff09…

css学习1

1、样式定义如何显示元素。 2、样式通常保存至外部的css文件中。 3、样式可以使内容与表现分离。 4、css主要有两部分组成&#xff1a;选择器与一条或多条声明。 选择器通常为要改变的html元素&#xff0c;每条声明由一个属性和一个值组成。每个属性有一个值&#xff0c;属性…

网络通信原理UDP协议(第五十课)

UDP协议:用户数据包协议,无连接、不可靠,效率高 字段长度描述Source Port2字节标识哪个应用程序发送(发送进程)。Destination Port2字节标识哪个应用程序接收(接收进程)。Length2字节UDP首部加上UDP数据的字节数,最小为8。Checksum2字节覆盖UDP首部和UDP数据,是可…

[Docker] Windows 下基于WSL2 安装

Docker 必须部署在 Linux 内核的系统上。如果其他系统想部署 Docker 就必须安装一个虚拟 Linux 环境。 1. 开启虚拟化 进入系统BIOS&#xff08;AMD 为 SVM&#xff1b;Intel 为 Intel-vt&#xff09;改为启用(enable) 2. 开启WSL 系统设置->应用->程序和功能->…

浅拷贝与深拷贝

作者简介&#xff1a; zoro-1&#xff0c;目前大一&#xff0c;正在学习Java&#xff0c;数据结构等 作者主页&#xff1a; zoro-1的主页 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f496; 浅拷贝与深拷贝 浅拷贝浅拷贝定义浅拷贝代码演示浅…

《Linux运维总结:Centos7.6之OpenSSH7.4p1升级版本至9.4p1》

Centos通过yum升级OpenSSH 在官方支持更新的CentOS版本&#xff0c;如果出现漏洞&#xff0c;都会通过更新版本来修复漏洞。这时候直接使用yum update就可以升级版本。 yum -y update openssh 但是&#xff0c;CentOS更新需要有一段时间&#xff0c;不能在漏洞刚出来的时候就有…

最长公共子序列——力扣1143

解法:动态规划 int longestCommonSubsequence(string text1, string text2){int m=text1.size(), n=text2.size

【微服务】一文了解 Nacos

一文了解 Nacos Nacos 在阿里巴巴起源于 2008 2008 2008 年五彩石项目&#xff08;完成微服务拆分和业务中台建设&#xff09;&#xff0c;成长于十年双十一的洪峰考验&#xff0c;沉淀了简单易用、稳定可靠、性能卓越的核心竞争力。 随着云计算兴起&#xff0c; 2018 2018 20…

opencv进阶03-图像与鼠标的交互示例

在处理图像时&#xff0c;可能需要与当前正在处理的图像进行交互。OpenCV 提供了鼠标事件&#xff0c;使用户可以通过鼠标与图像交互。鼠标事件能够识别常用的鼠标操作&#xff0c;例如&#xff1a;针对不同按键的单击、双击&#xff0c;鼠标的滑动、拖曳等。 例如&#xff0c;…

【Windows系统编程】06.HotFixHook与进程通信(详解HotFixHook)

上一讲讲到的InlineHook&#xff0c;每次Hook的时候&#xff0c;都要读写两次内存&#xff08;先Hook&#xff0c;再还原&#xff09;这种Hook方式&#xff0c;性能比较低&#xff0c;今天我们讲的这种Hook方式&#xff0c;可以说是InlineHook的升级版本 HotFix&#xff08;热…

Android3:布局

一。线性布局 创建项目Linear Layout Example activity_main.xml <?xml version"1.0" encoding"utf-8"?><LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"an…

‘VB6EXT.OLB’ could not be registered

打开VB6提示&#xff1a;‘VB6EXT.OLB’ could not be registered 解决办法&#xff1a; 用管理员打开。 实测可行。 参考&#xff1a;VB6 Error please help-VBForums

uni-app引入sortable列表拖拽,兼容App和H5,拖拽排序。

效果: 拖拽排序 背景&#xff1a; 作为一名前端开发人员&#xff0c;在工作中难免会遇到拖拽功能&#xff0c;分享一个github上一个不错的拖拽js库&#xff0c;能满足我们在项目开发中的需要&#xff0c;下面是我在uniapp中使用SortableJS的使用详细流程&#xff1b; vue开发…