C语言(二) 补码,运算值与表达式
补码
正数的原码反码补码相同
 计算机存正数和负数存的都是补码
 负数的原码是正数原码符号位变为1
 反码是原码按位取反 符号位不改
 补码是反码加1
8 00001000
-8 原码 10001000
 反码 11110111
 补码 11111000
大小端问题 :
高位数据在高字节 低位数据在低字节 arm
 高位数据在低字节 低位数据在高字节 x86
类型转换
隐式转换
不同类型之间可以进行混合运算,但是会发生自动类型转换
不同类型数据在一起进行数学运算的时候,先把类型转成一致
 C语言自动转 但是要注意 最好自己手动转
 提升原则:小的转大的
 char ->short -> int -> double
 
思考:
 10 + ’a’ + 1.5 - 8765.1234 * ’b’ 是什么类型?
强制类型转换
强制类型转换
 一般形式:(类型名)(表达式)
 例 (int)(x + y)
 (int)x + y
 (double)(3/2)
 (int)3.6
 说明:强制转换得到所需类型的中间变量,原变量类型、变量值保持不变

较高类型向较低类型转换时可能发生:精度损失问题
类型转换本质
 unsigned short a = 256;
  char b = a;
  printf("%d",b);
 这样赋值后,输出变量b的值并非预期的256,而是0,原因是256超出了char类型能够装载最大值,b只截取了a的低8位的数据,如下:
 
当把占字节较小的数据赋值给占字节较大的数据时,可能出现以下两种情况。
 第1种情况,当字节较大数是无符号数时,转换时新扩充的位被填充成0
 char b = 10;
 unsigned short a = b;
 printf("%u",a);
 这样赋值后,变量a中输出的值是10,原因如下:
 
第2种情况,当字节较大数是有符号数时,转换时新扩充的位被填充成符号位
 char b = 255;
 short a = b;
 printf("%d",a);
 这样赋值后,变量a输出的值是-1,变量a扩充的高8位,根据变量b的最高位1都被填充成了1,所以数值由正数变成了负数,因为变量a的最高位符号位是1,至于为什么16个1表示的是-1,涉及到二进制数的原码和补码问题,大家回顾下补码。转换图示如下:

运算符与表达式
字符类型的存储:
 字符本质是整数
 编译器做的事很复杂:
 编程语言,编译器,计算机 外国人发明的
  他们用到的符号 不多 加起来不超过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
程序的运行顺序
和现代阅读顺序相同
 从上往下 从左往右
从上往下一行一行执行
 优先级
 看主体 看运算符
- 点赞
- 收藏
- 关注作者
 
             
           
评论(0)