1.进制转化
二进制转十进制
十进制转二进制
二进制转八进制
二进制转十六进制
2.原码反码和补码------->都是二进制的
1)有符号 signed类型
含符号位和数值位两部分,二进制序列中,最高位的那一位被当做符号位,剩余都是数值位
符号位0表示“正”,1表示“负”
2)无符号 unsigned类型
不含符号位,都是数值位
整数在内存中的存储是二进制的补码,打印出来的数是补码转化为原码再二进制转为十进制,打印出的是十进制
1.正数的原码反码补码都相同
2.负数的原码反码补码各不相同
原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码
反码:原码的符号位不变,其他位次依次按位取反就可以得到反码
补码:符号位不变,反码加一
3.int类型有32bit位
3.移位操作符------->移动的是存储在内存中的二进制位(补码)
<< 左移操作符
>> 右移操作符
移位操作符的操作数只能是整数
1:左移操作符
左边抛弃右边补0
正数
负数
2.右移操作符
逻辑右移:左边用0填充,右边丢弃
算数右移:左边用原该值的符号位填充,右边丢弃
采用哪种右移方式是取决于编译器的,通常采用的是算术右移
eg:
对于移位操作符,不要移动负数位,这是标准定义
4.位操作符-------->操作数必须是整数也是针对二进制的补码进行计算
1. & 按位与 ------------------------- 对应的每一位有0则为0,都为1才为1
2. | 按位或 -------------------------- 有1则为1,同时为0才为0
3. ^ 按位异或 -------------------------- 相同为0,相异为1
不会存在溢出的现象
支持交换律----3^3^5==3^5^3==5
4. ~ 按位取反 -------------------------- 二进制的每一位都取反
5.逗号表达式
从左向右依次执行,整体表达式的结果是最后一个表达式的结果
一定要从左向右依次计算,因为前面表达式的计算可能会影响后面计算的结果
6.下标访问[ ] 函数调用()
//下标引用操作符 函数调用的操作数至少有一个,
因为函数名不可缺少
int arr[10]; 接受一个或多个操作数:第一个操作数是函数
arr[9]=10;//使用下标引用操作符 名, 剩余的操作数就是传递给函数的参数
[ ]的两个操作数是arr和9
7.结构体访问操作符
结构是一些值的集合,这些值成为成员变量,结构体的每个成员可以说不同类型的变量、
标量,数组,指针,也可以是其他结构体
增加了结构体这种自定义的数据类型,让程序员可以自己创建适合的类型
1.结构体的声明
struct tag
{
member-list;
}variable-list;
描述一个学生:
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
};//注意分号
结构体成员的访问
结构体成员的直接访问是通过操作符(.)访问的,点操作符接受两个操作数
使用方式:结构体变量.成员名
间接访问得到的不是一个结构体变量,而且得到了一个指向结构体的指针
使用方式:结构体指针->成员名
8.优先级和结合性
参考:https://zh.cppreference.com/w/c/language/operator_precedence
即使有操作符的优先级和结合性,我们写出的表达式依然有可能不能通过操作符的属性确定唯一的计算路径
9.整型提升(讨论的是表达式中char和short类型的值)
C语言中整型算术运算总是至少以缺省整型类型的精度来进行的
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换被称为整型提升
整型提升的方式:
1.有符号的整数提升是按照变量的数据类型的符号位来提升的
2.无符号整数提升,高位补0
9.算数转换(讨论的是类型大于等于整型的类型的类型)
如果某个操作符的各个操作数属于不同的类型,除非其中一个操作数的类型转换为另一个操作数的类型,否则操作无法进行
long double
double
float
unsigned long int
long int
unsigned int
int
向上转换