操作符详解(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.mzph.cn/news/46754.shtml

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

相关文章

Redis中的缓存穿透、雪崩、击穿的原因以及解决方案

一&#xff0c;什么是缓存穿透、雪崩、击穿&#xff1f; 1、缓存穿透&#xff1a; 是指用户查询数据&#xff0c;在数据库没有&#xff0c;自然在缓存中也不会有。这样就导致用户查询的时候&#xff0c;在缓存中找不到&#xff0c;每次都要去数据库再查询一遍&#xff0c;然后…

宇宙原理:黑洞基础。

宇宙原理&#xff1a;黑洞基础TOC 黑洞的数理基础&#xff1a;一个由满数组成的数盘&#xff0c;经过自然演进&#xff0c;将会逐步稀疏化、最终会向纯数方案发展&#xff1b;纯数方案虽然只有{2}、无数&#xff08;虚拟&#xff09;、{0,1,2,3}&#xff08;虚拟&#xff09;、…

1.82亿南沙区“数字城市”城市运营中心建设项目采购需求

1. 总体技术需求 项目整体框架 遵循“一个中枢、两大中台、基础底座”的总体架构&#xff0c;构建全区城市治理中枢&#xff0c;实现连通上下、衔接左右、分拨处置和协同指挥等作用。 本项目系统的总体架构分为一个中枢、两大中台、基础底座共五部分&#xff0c;在政务云平台…

netty(一):NIO——处理消息边界

处理消息边界 为什么要处理边界 因为会存在半包和粘包的问题 1.客户端和服务端约定一个固定长度 优点&#xff1a;简单 缺点&#xff1a;可能造成浪费 2.客户端与服务端约定一个固定分割符 *缺点 效率低 3.先发送长度&#xff0c;再发送数据 TLV格式&#xff1a; type…

【ROS】参数服务器--理论模型与参数操作(C++)

一、概念介绍 参数服务器在ROS中主要用于实现不同节点之间的数据共享。参数服务器相当于是独立于所有节点的一个公共容器&#xff0c;可以将数据存储在该容器中&#xff0c;被不同的节点调用&#xff0c;当然不同的节点也可以往其中存储数据。 作用&#xff1a;存储一些多节点…

C语言:库函数atoi及其模拟实现

atoi&#xff1a; atof是C语言标准库中的一个函数&#xff0c;用于将字符串转换为对应的浮点数/整形数。 函数接受一个参数str&#xff0c;该参数是一个指向以null结尾的字符串的指针。atof函数会尝试将这个字符串转换为一个浮点数&#xff0c;并返回转换后的结果。 要注意的是…

飞机打方块(五)游戏音乐

一、新建节点 1.在Start场景中新建Music节点&#xff0c;绑定canvas 2.在Game场景中新建Music节点 3.新建节点 4.新建Music脚本&#xff0c;绑定Canvas Music.ts const { ccclass, property } cc._decorator;ccclass export default class NewClass extends cc.Component {p…

*args无疑是解决函数重载的一大创新利器--我用可变数量参数解决了函数重载问题

需求分析 最近遇到这样一个需求&#xff1a;根据用户传递的不同参数数量执行不同的功能。我这几天一直在思考这个问题&#xff1a;如何根据参数数量去执行不同的功能&#xff0c;最初的设想是把不需要的参数设置为NONE或者""再或者" "(后两者引号均表示传空…

Flink 流式读写文件、文件夹

文章目录 一、flink 流式读取文件夹、文件二、flink 写入文件系统——StreamFileSink三、查看完整代码 一、flink 流式读取文件夹、文件 Apache Flink针对文件系统实现了一个可重置的source连接器&#xff0c;将文件看作流来读取数据。如下面的例子所示&#xff1a; StreamExe…

【无标题】QT应用编程: QtCreator配置Git版本控制(码云)

QT应用编程: QtCreator配置Git版本控制(码云) 感谢&#xff1a;DS小龙哥的文章&#xff0c;这篇主要参考小龙哥的内容。 https://cloud.tencent.com/developer/article/1930531?areaSource102001.15&traceIdW2mKALltGu5f8-HOI8fsN Qt Creater 自带了git支持。但是一直没…

软件测试学术顶会——ISSTA 2023 论文(网络安全方向)清单、摘要与总结

总结 本次会议涵盖的安全研究主题广泛,包括源代码分析、二进制代码分析、恶意软件检测、漏洞检测、模糊测试、程序验证等。一些热门的研究方向包括:基于机器学习的漏洞检测、大型语言模型在软件安全中的应用、区块链智能合约安全分析。这些方向都在最近几年持续发展。一些较冷门…

【C++】IO流

C语言的输入和输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf()。 scanf(): 从标准输入设备(键 盘)读取数据&#xff0c;并将值存放在变量中。printf(): 将指定的文字/字符串输出到标准输出设备(屏幕)。 注意宽度输出和精度输出控制。C语言借助了相应的缓冲区…

postgresql 分组

postgresql 数据汇总 分组汇总聚合函数注意 总结 分组统计总结 高级分组总结 分组汇总 聚合函数 聚合函数&#xff08;aggregate function&#xff09;针对一组数据行进行运算&#xff0c;并且返回单个结果。PostgreSQL 支持以下常见的聚合函数&#xff1a; • AVG - 计算一…

在思科(Cisco)路由器中使用 SNMP

什么是SNMP SNMP&#xff0c;称为简单网络管理协议&#xff0c;被发现可以解决具有复杂网络设备的复杂网络环境&#xff0c;SNMP 使用标准化协议来查询网络上的设备&#xff0c;为网络管理员提供保持网络环境稳定和远离停机所需的重要信息。 为什么要在思科设备中启用SNMP S…

基于springboot+vue的论坛系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

机器学习赋能乳腺癌预测:如何使用贝叶斯分级进行精确诊断?

一、引言 乳腺癌是女性最常见的恶性肿瘤之一&#xff0c;也会发生在男性身上。每年全球有数百万人被诊断出乳腺癌&#xff0c;对患者的生活和健康造成了巨大的影响。早期的乳腺癌检测和准确的诊断对于提高治疗的成功率至关重要。然而&#xff0c;乳腺癌的早期诊断面临着许多挑战…

国际刑警组织逮捕 14 名涉嫌盗窃 4000 万美元的网络罪犯

Bleeping Computer 网站披露&#xff0c;4 月份&#xff0c;国际刑警组织发动了一起为期四个月&#xff0c;横跨 25 个非洲国家的执法行动 “Africa Cyber Surge II”&#xff0c;共逮捕 14 名网络犯罪嫌疑人&#xff0c;摧毁 20000 多个从事勒索、网络钓鱼、BEC 和在线诈骗的犯…

ubuntu20.04共享文件夹—— /mnt/hgfs里没有共享文件夹

参考文章&#xff1a;https://blog.csdn.net/Edwinwzy/article/details/129580636 虚拟机启用共享文件夹后&#xff0c;/mnt/hgfs下面为空&#xff0c;使用 vmware-hgfsclient 查看设置的共享文件夹名字也是为空。 解决方法&#xff1a; 1. 重新安装vmware tools. 在菜单…

【高光谱图像的去噪算法】通过全变异最小化对受激拉曼光谱图像进行去噪研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

nginx防盗链

防盗链介绍 通过二次访问&#xff0c;请求头中带有referer&#xff0c;的方式不允许访问静态资源。 我们只希望用户通过反向代理服务器才可以拿到我们的静态资源&#xff0c;不希望别的服务器通过二次请求拿到我们的静态资源。 盗链是指在自己的页面上展示一些并不在自己服务…