C语言(二) 补码,运算值与表达式

举报
槿泽 发表于 2022/11/30 19:31:33 2022/11/30
【摘要】 补码正数的原码反码补码相同计算机存正数和负数存的都是补码负数的原码是正数原码符号位变为1反码是原码按位取反 符号位不改补码是反码加18 00001000-8 原码 10001000反码 11110111补码 11111000大小端问题 :高位数据在高字节 低位数据在低字节 arm高位数据在低字节 低位数据在高字节 x86 类型转换 隐式转换不同类型之...

补码

正数的原码反码补码相同
计算机存正数和负数存的都是补码
负数的原码是正数原码符号位变为1
反码是原码按位取反 符号位不改
补码是反码加1

8 00001000

-8 原码 10001000
反码 11110111
补码 11111000

大小端问题 :

高位数据在高字节 低位数据在低字节 arm
高位数据在低字节 低位数据在高字节 x86

类型转换

隐式转换

不同类型之间可以进行混合运算,但是会发生自动类型转换

不同类型数据在一起进行数学运算的时候,先把类型转成一致
C语言自动转 但是要注意 最好自己手动转
提升原则:小的转大的
char ->short -> int -> double
image.png

思考:
10 + ’a’ + 1.5 - 8765.1234 * ’b’ 是什么类型?

强制类型转换

强制类型转换
一般形式:(类型名)(表达式)
例 (int)(x + y)
(int)x + y
(double)(3/2)
(int)3.6
说明:强制转换得到所需类型的中间变量,原变量类型、变量值保持不变

image.png

较高类型向较低类型转换时可能发生:精度损失问题

类型转换本质

​ unsigned short a = 256;
​ char b = a;
​ printf("%d",b);

​ 这样赋值后,输出变量b的值并非预期的256,而是0,原因是256超出了char类型能够装载最大值,b只截取了a的低8位的数据,如下:
image.png

当把占字节较小的数据赋值给占字节较大的数据时,可能出现以下两种情况。
第1种情况,当字节较大数是无符号数时,转换时新扩充的位被填充成0
char b = 10;
unsigned short a = b;
printf("%u",a);
这样赋值后,变量a中输出的值是10,原因如下:
image.png

第2种情况,当字节较大数是有符号数时,转换时新扩充的位被填充成符号位
char b = 255;
short a = b;
printf("%d",a);
这样赋值后,变量a输出的值是-1,变量a扩充的高8位,根据变量b的最高位1都被填充成了1,所以数值由正数变成了负数,因为变量a的最高位符号位是1,至于为什么16个1表示的是-1,涉及到二进制数的原码和补码问题,大家回顾下补码。转换图示如下:

image.png

运算符与表达式

字符类型的存储:

​ 字符本质是整数

​ 编译器做的事很复杂:

​ 编程语言,编译器,计算机 外国人发明的
​ 他们用到的符号 不多 加起来不超过256个
​ a-z A-Z @!#$ 0-9

​ char 1个字节

​ 象形文字 我们的符号多不多
​ 解决方案1: 中文的符号 不再是字符类型 而是字符串
​ 有些编译器 一个汉字 gbk 2个字节 有些 一个汉字 ufg-8 3个字节

​ 解决方案2: 字符集
​ char 1字节
vs char_t 2字节 unsigned short

小数的存储

​ float 符号位s(1位)和、指数e(8位)、 底数m(23位) 4
​ double 符号位s(1 bit)指数e(11 bit)尾数(52 bit) 8
​ 最高位为符号位: 0负 1正

指数:2进制科学计数法
尾数:

10进制科学计数法:
1111.111
1.111111*10^3
1.111111E3

0.0000009 9E-7

2进制科学计数法:
1.5 十进制
1.1 二进制

11.625 十进制

0.625*2=0.5

1011.101 二进制
1.011101E3 —> 1011.101
2^2 2^1 2^0 . 0.5 0.25 0.125

float: 0 00000011 00000000000000000011101
double: 0 00000000011 00…000000000000000011101
11.625

0.625*2 == 1.250
0.25*2 == 0.5
0.5*2 == 1

十进制: 0.625
二进制: 0.101
二进制科学计数法: 1.01E-1
float: 0 11111111 00000000000000000000001

表达式:

具备唯一返回值的式子

返回值:

就是算完后有一个值

运算符

具备特殊功能的符号
, 连接多个语句组成一条语句
= 赋值运算符 赋值
把右边的值 赋予 左边 绑定的内存段
; 结束一条语句
() 提升优先级

左值 右值 左操作数 右操作数

赋值运算符: =   += -= *= /= %=   &=  |=  ^=  <<=  >>=
	n = 5;
	n += 5;//  n = n + 5;
	n <<= 5;//  n = n << 5;

自运算符:  n-- --n n++ ++n
	n--  后自减
	n++  后自增
		先参与运算,后自增
	--n  前自减
	++n  前自增 
	++n  ==    n=n+1  == n+=1
		先自增  后参与运算

逻辑运算符:  !  &&  ||
关系运算符: >  <   ==  !=  >=  <=
其他运算符:  ,   ;   #  &  ?:   () () ()  [] []  {}  <>  ''  ""  *  .
	->    \   /    //   /**/    

目数:

单目 双目 三目 操作数的个数
, 双目
; 单目
?: 唯一的三目运算符
() 强制类型转换 双
(int)表达式
() 优先级提升

整体是一个表达式 表达式1 ? 表达式2 : 表达式3
整体表达式 的结果 取决于 表达式1的逻辑值
如果为真:整体表达式 的结果 等同于 表达式2
如果为假:整体表达式 的结果 等同于 表达式3

位运算符:   ~  &   |   ^    <<    >>    针对二进制位
	数学运算
	字符串匹配
	加密解密
	音视频 
	pe

	~   单目   按位取反
		负数的二进制形式     
		正数的 原码 反码 补码 相同
		负数的 原码 反码 补码 
		计算机存储的是补码

		计算机存储的都是   二进制形式   原码
		一个负号 等同于  求一次补码
		补码 : 反码 + 1  
		反码 : 按位取反
  	^ 	按位异或:    相同为0 不同为1
	&   按位与    双目     两边对应的二进制位 做 按位与运算  都为1才为1
		1&0 == 0  0&1 == 0  0&0 == 0  1&1 == 1   
		1&1 == 1 0&1 == 0 任何数据&1 等于它本身
		任何数据&0 等于0
	|   按位或    双目     两边对应的二进制位 做 按位或运算  都为0才为0
		1|0 == 1  0|1 == 1  0|0 == 0  1|1 == 1   
		任何数据|1 等于 1 任何数据 | 0 等于它本身
	<< 按位左移:  n<<m      n左移m位
	左边去掉m个二进制位,右边补m个0
		128 
		00000000 00000000 00000000 10000000  << 24
符号位去掉:
		10000000 00000000 00000000 00000000   
	>> 按位右移:  n>>m		n右移m位
	右边去掉 m 个二进制位,左边补m个符号位

逻辑值:

要么真 1 要么假 0
值 和 逻辑值
非0为真 0为假
1.1 真
‘a’ 真
66.66 56 “abcdefg” 真
‘0’ 48
‘\0’ 0 假
“” 0 假
0 假
NULL

程序的运行顺序

和现代阅读顺序相同
从上往下 从左往右

从上往下一行一行执行
优先级
看主体 看运算符

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。