【C语言】第五章 - 操作符
目录
1.算术操作符
2.移位操作符
左移
右移
3. 位操作符
& 按位与
| 按位或
^ 按位异或
~ 按位取反
4.赋值操作符
5.单目操作符
6.关系操作符
7.逻辑操作符
8.条件操作符
9.逗号表达式
10.下标引用、函数调用和结构成员
11.表达式求值
11.1 隐式类型转换
整形提升
11.2 算术转换
11.3 操作符优先级
操作符在编程运算中有重要作用,本文就来学习一下C语言的操作符。
1.算术操作符
+ - * /
1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
2.移位操作符
<< >>
在介绍移位操作符前先学习一下二进制的表示方法,二进制表示方法有3种:
原码,反码,补码
正数原码,反码,补码相同
负数原码,反码,补码需要计算
例子:5的二进制码
0000 0000 0000 0000 0000 0000 0000 0101 原码
0000 0000 0000 0000 0000 0000 0000 0101 反码
0000 0000 0000 0000 0000 0000 0000 0101 补码
第一位数表示正负。0为正数,1为负数。
-5的二进制码
1000 0000 0000 0000 0000 0000 0000 0101 原码
1111 1111 1111 1111 1111 1111 1111 1010 反码 (符号位不变,其他位按位取反)
1111 1111 1111 1111 1111 1111 1111 1011 补码(最后一位+1)
整数在内存中存的是二进制的补码。回到移位操作符。
左移
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{int a = 5;a = a<< 1;printf("%d", a);return 0;
}
上段代码将 5 的补码左移一位,再最后一位补上0
此时二进制补码变成了 2³+2=8+2=10 。
输出结果
10
这次对-5左移一位
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{int a = -5;//-5 的补码1111 1111 1111 1111 1111 1111 1111 1011a = a<< 1;printf("%d", a);return 0;
}
打印时,将打印原码,因此会先将补码转成原码。正数因为源反补都相同,不需要再换算。
计算发现 -5左移1位的原码就是 - (2³+2)= -10 ,打印结果自然也是-10。接下来介绍右移,右移分为算术右移和逻辑右移。
右移
算术右移:右边丢弃,左边补符号位。
逻辑右移:右边丢弃,左边补0 。
+5 -5 的原反补码及 对补码算术右移1位并转为原码
截图时截少了,左边的0没截到
代码:
int a = -5;a = a >> 1;printf("%d", a);
结果:
-3
右移运算是算术还是逻辑右移,是取决于编译器的,此次结果表明当前编译器采用的是算术右移。
注意:无法移动负数位,标准里未定义。
a>>>-1 //error
3. 位操作符
| & ^ ~
&按位与:类似且的逻辑,二进制按位运算,前后两个运算数同时为“1”得“1”。
| 按位或:前后两个运算数只要其一为“1”,结果就为“1”。
^按位异或:前后两个运算数相同为0,相异为1。
~按位取反:对一个数的二进制按位取反。
& 按位与
程序
int a = -3;int b = 5;int c = a & b;printf("%d", c);
同样先算出a,b的补码
a=-3,b=5a 10000000000000000000000000000011 原a 11111111111111111111111111111100 反a 11111111111111111111111111111101 补b 00000000000000000000000000000101 补
按位与 a&b,每位两者都为1,才得1,否则0, 得:
a 11111111111111111111111111111101 补b 00000000000000000000000000000101 补c 00000000000000000000000000000101 补
因为打印时会打印原码,这里再将补码转为原码,即:
因为c为正数所以正反补都相同c 00000000000000000000000000000101 补c 00000000000000000000000000000101 反c 00000000000000000000000000000101 原
运行结果
5
| 按位或
同理
程序
int a = -3;int b = 5;int c = a | b;printf("%d", c);
运行结果
-3
^ 按位异或
相同为0,相异为1。
程序
void test4() {int a = -3;int b = 5;int c = a ^ b;printf("%d", c);
}
运行结果
-8
异或特殊的两种用法,任何数与0异或是它本身,任何数与它本身异或是0。
程序
int a = 3;printf("%d\n", a ^ 0);printf("%d", a ^ a);
运行结果
3
0
运算过程
相同取0 相异取1a 000000000000000000000000000000000011 原a 111111111111111111111111111111111100 反a 111111111111111111111111111111111101 补0 000000000000000000000000000000000000 补
a^0 111111111111111111111111111111111101 补a 111111111111111111111111111111111101 补a 111111111111111111111111111111111101 补
a^a 000000000000000000000000000000000000 补
可以发现a^0=a,a^a=0 。由此又延伸出一种很常用的算法,异或一组数据就能得到其中不成对的数字。
对1234321这组数据异或
1^2^3^4^3^2^1=4
成对的数字相抵消为0,最后剩下一个4与0异或,就是4本身。
这里能听懂,那这道题对你来说那必是轻而易举(~ ̄▽ ̄)~力扣
有了这样的基础,你甚至能拿两个变量做更nb的操作——无需第三个变量就能交换两个变量的值。
int a = 3;int b = 5;a = a ^ b;b = a ^ b;//此时a = a ^ b;a = a ^ b;//此时b=a^b^b =a,也就是a =a^b^a 最终等于bprintf("a=%d b=%d", a, b);
运行结果
a=5 b=3
当然这里也可以用求和的方式实现交换,但这种方法有缺陷的,当a ,b的值非常大时,他们的和就会溢出,最终得不到想要的值,算权宜之计。
~ 按位取反
将补码全部取反,打印的时候同样要转换成原码打印。
1.下面的程序将二进制某位从0变成1又从1变成0,1变成0的运算用到“~”取反,具体过程看注释。
000000000000000000000000000000001011 ↓ ↑目标位
000000000000000000000000000000001111↓ ↑目标位
000000000000000000000000000000001011
程序
//~取反//000000000000000000000000000000001011int a = 11;a |= (1 << 2);//对1左移2位//000000000000000000000000000000001011 a//000000000000000000000000000000000100 (1 << 2)//000000000000000000000000000000001111 进行位或运算得到结果printf("变形:%d\n", a);a &= ~(1 << 2);//000000000000000000000000000000001011 a//111111111111111111111111111111111011 ~(1 << 2)//000000000000000000000000000000001011 进行位与运算得到结果printf("还原:%d\n", a);
运行结果
变形:15
还原:11
2. 可以用来终止获取输入 while(~scanf() )
scanf 读取失败时返回 -1,而-1的补码是32/64位1,取反后为0,即返回假,所以条件终止。
-1 1111 1111 1111 1111 1111 1111 1111 11110 0000 0000 0000 0000 0000 0000 0000 0000
4.赋值操作符
赋值,字面理解可以给变量赋值的操作符。
复合赋值符
+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^=
这些运算符都可以写成复合的效果。
5.单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
6.关系操作符
关系操作符
>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”
7.逻辑操作符
&& 逻辑与
|| 逻辑或
区分逻辑与和按位与,区分逻辑或和按位或。
逻辑与遇到假就停止判断后面的操作数;
逻辑或遇到真就停止判断后面的操作数。
8.条件操作符
exp1 ? exp2 : exp3
判断是否满足exp1,真执行exp2,假执行exp3。可以做比大小的函数。
9.逗号表达式
逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗号表达式
c是多少?
c最后将收到最后一个表达式,b的返回值,变成13。
10.下标引用、函数调用和结构成员
1. [ ] 下标引用操作符
操作数:一个数组名 + 一个索引值
2. ( ) 函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
3. 访问一个结构的成员
11.表达式求值
表达式求值的顺序一部分是由操作符的优先级和结合性决定,操作过程可能需要转成其他类型。
11.1 隐式类型转换
精度较小的类型数据与精度大的类型数据运算时,会把精度小的类型转为精度大的类型再运算。C的整型算术运算总是至少以缺省整型类型的精度来进行的。
整形提升
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
//负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111
//正数的整形提升
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
//无符号整形提升,高位补0
整形提升的例子:
//实例
int main()
{char a = 0xb6;short b = 0xb600;int c = 0xb6000000;//0xb6,0xb600,0xb6000000这些都是整形常数if(a==0xb6) //a整形提升后前面为一大串1,0xb6前面为一大串0printf("a");if(b==0xb600) printf("b");if(c==0xb6000000)printf("c");return 0;
}
实例中的a,b要进行整形提升,但是c不需要整形提升。(因为c是整形,)
a,b整形提升之后,变成了负数,所以表达式 a==0xb6 , b==0xb600 的结果是假,但是c不发生整形提升,则表达式 c==0xb6000000 的结果是真.
所程序输出的结果是:
c
11.2 算术转换
当操作符的各个操作数的类型不相同时,按下面的顺序,将一个操作数类型转换成另一个操作数类型再进行运算。
long double
double
float
unsigned long int
long int
unsigned int
int
排名在下的类型将往上转换
如:float 见double 会先将float转换成double再运算。
11.3 操作符优先级
优先级 |
运算符 |
名称或含义 |
使用形式 |
结合方向 |
说明 |
1 |
[] |
数组下标 |
数组名[常量表达式] |
左到右 |
-- |
() |
圆括号 |
(表达式)/函数名(形参表) |
-- |
||
. |
成员选择(对象) |
对象.成员名 |
-- |
||
-> |
成员选择(指针) |
对象指针->成员名 |
-- |
||
2 |
- |
负号运算符 |
-表达式 |
右到左 |
单目运算符 |
~ |
按位取反运算符 |
~表达式 |
|||
++ |
自增运算符 |
++变量名/变量名++ |
|||
-- |
自减运算符 |
--变量名/变量名-- |
|||
* |
取值运算符 |
*指针变量 |
|||
& |
取地址运算符 |
&变量名 |
|||
! |
逻辑非运算符 |
!表达式 |
|||
(类型) |
强制类型转换 |
(数据类型)表达式 |
-- |
||
sizeof |
长度运算符 |
sizeof(表达式) |
-- |
||
3 |
/ |
除 |
表达式/表达式 |
左到右 |
双目运算符 |
* |
乘 |
表达式*表达式 |
|||
% |
余数(取模) |
整型表达式%整型表达式 |
|||
4 |
+ |
加 |
表达式+表达式 |
左到右 |
双目运算符 |
- |
减 |
表达式-表达式 |
|||
5 |
<< |
左移 |
变量<<表达式 |
左到右 |
双目运算符 |
>> |
右移 |
变量>>表达式 |
|||
6 |
> |
大于 |
表达式>表达式 |
左到右 |
双目运算符 |
>= |
大于等于 |
表达式>=表达式 |
|||
< |
小于 |
表达式<表达式 |
|||
<= |
小于等于 |
表达式<=表达式 |
|||
7 |
== |
等于 |
表达式==表达式 |
左到右 |
双目运算符 |
!= |
不等于 |
表达式!= 表达式 |
|||
8 |
& |
按位与 |
表达式&表达式 |
左到右 |
双目运算符 |
9 |
^ |
按位异或 |
表达式^表达式 |
左到右 |
双目运算符 |
10 |
| |
按位或 |
表达式|表达式 |
左到右 |
双目运算符 |
11 |
&& |
逻辑与 |
表达式&&表达式 |
左到右 |
双目运算符 |
12 |
|| |
逻辑或 |
表达式||表达式 |
左到右 |
双目运算符 |
13 |
?: |
条件运算符 |
表达式1? 表达式2: 表达式3 |
右到左 |
三目运算符 |
14 |
= |
赋值运算符 |
变量=表达式 |
右到左 |
-- |
/= |
除后赋值 |
变量/=表达式 |
-- |
||
*= |
乘后赋值 |
变量*=表达式 |
-- |
||
%= |
取模后赋值 |
变量%=表达式 |
-- |
||
+= |
加后赋值 |
变量+=表达式 |
-- |
||
-= |
减后赋值 |
变量-=表达式 |
-- |
||
<<= |
左移后赋值 |
变量<<=表达式 |
-- |
||
>>= |
右移后赋值 |
变量>>=表达式 |
-- |
||
&= |
按位与后赋值 |
变量&=表达式 |
-- |
||
^= |
按位异或后赋值 |
变量^=表达式 |
-- |
||
|= |
按位或后赋值 |
变量|=表达式 |
-- |
||
15 |
, |
逗号运算符 |
表达式,表达式,… |
左到右 |
-- |
来源
【C语言】第五章 - 操作符相关推荐
- c语言逐步搜索法求有根区间,[C语言第五章.ppt
[C语言第五章 算法举例 基本思想是,根据提出的问题,列举所有可能的情况,并 用问题中给定的条件检验哪些是需要的,哪些是不需要的. 教学进程 列举与试探 列举法常用于解决"是否存在" ...
- c语言每个整数占9列,c语言 第五章 数据类型和表达式.ppt
c语言 第五章 数据类型和表达式 第五章数据类型和表达式 C语言的基本数据类型 各种基本数据类型的常量和变量的定义 C语言的表达式和各种表达式的求解规则 5.1 数据的存储和基本数据类型 5.1.1数 ...
- C语言第五章实验原理,C语言第五章实验报告.docx
C语言第五章实验报告 C语言第五章实验报告?班级:14金工3班??????????学号???????????姓名:周俐俐一.实验目的?1.?熟悉C语言编程环境.2.?进一步熟悉用C语言调试C语言源程序 ...
- C语言 第五章 选择结构 答案,c语言第五章 选择结构程序设计(习题册答案).doc
第五章 选择结构程序设计 基础练习(A) 一.填空题 1.关系表达式的运算结果是 逻辑 值.C语言没有逻辑型数据,以 1 代表"真",以 0代表"假". 2.逻 ...
- c语言第五章作业,《C语言程序设计》第五章作业.doc
<C语言程序设计>第五章作业 窗体顶端 <C语言程序设计>第5章作业 布置日期:2012-3-15?????截止日期:2012-3-22 一. 单选题 (每小题6分,共102分 ...
- c语言定义int 输出4386,大学C语言第五章课后习题参考程序
考试,二级C语言备考 第五章课后习题参考程序 5.1 编写程序,求100-2000之间所有3的倍数之和,当和大于1000时结束. (参考答案:900) #include int main() { in ...
- 信息学奥赛一本通(C++版)第一部分 C++语言 第五章 数组
第五章 数组 第一节 一维数组 T1102 : 与指定数字相同的数的个数 时间限制: 1000 ms 内存限制: 65536 KB [题目描述] 输出一个整数序列中与指定数字相同的数的个数. [输 ...
- 2022SDUT知到/智慧树----C语言第五章测试题解(答案~)大家看清顺序
第五章测试-答案已加粗 1[判断题](10分) 在C语言中,逻辑运算符"&&"比"||"的优先级高(). A.对 B.错 参考答案:A 2[判断 ...
- 猴子第一天摘下若干个桃子,当时吃了一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个谭浩强c语言第五章第十二题
题目 本题是谭浩强<c语言程序设计>第五章第十二题 题目:猴子第一天摘下若干个桃子,当时吃了一半,又多吃了一个.以后每天早上都吃了前一天剩下的一半零一个.到第10天早上再想吃时,就只剩一个 ...
- c程序设计语言第五章,c程序设计语言第五章第7题答案
7.\(\sum\limits_{k=1}^{100}k\) +\(\sum\limits_{k=1}^{50}{k}^2\) +\(\sum\limits_{k=1}^{10}{\frac{1}{k ...
最新文章
- 这味儿上头,前有文言文,又来东北话,中文编程玩得挺得劲!
- 计算机汉字救亡运动简史丨视频
- springboot根据环境装配配置文件、启动加载外置配置文件
- 在android中ScrollView嵌套ScrollView解决方案
- 说说我在项目中为什么不用实体框架,如果说我在诋毁你所爱的EF,请进来.
- ISE与Notepad++关联
- Mybatis传递多个参数
- docker使用官方仓库上传与下拉images
- 单结晶体管的导电特性_【硬见小百科】二极管基础知识分类,应用,特性,原理,参数(二)...
- pycharm快捷键大全
- 统计通话次数和时间的软件_通话时间统计app下载-通话时间统计安卓版 v2.2.2 - 安下载...
- autojs开发的ip地址查询工具开源代码免费分享
- Pillow(PIL)入门教程(非常详细)
- Python数独算法
- linux删除slave网卡,Linux bonding网卡与其slave共同使用
- idea右键项目找不到show dependencies
- YOLO3多gpu训练方法
- NS版暗黑破坏神3金手指开发教程(3)
- i.MX RT1176 - 简介
- 基于AI伪原创API的python伪原创工具开发
热门文章
- 我推崇的流行唱法:美國Speech Level Singing的介紹和討論(推荐)
- 你以为你以为的三国就是你以为的三国吗——读《三国史话》
- Redis+Zookeeper+NIO+JVM+Dubbo+mq+Kafka+ElasticSearch+POI相关面试题
- 【C语言】实现简单的五子棋
- JavaScript---网络编程(9-2)--DHTML技术演示(2-2)-表格加强
- win10浏览器账户退出
- electron start之后index.html页面不显示
- 嵌入式linux IIO驱动
- 第十五周项目二----用哈希法组织关键字之链地址法
- Android color.xml设置透明度