目录
操作符的分类
算术操作符
+
: 加法-
: 减法*
: 乘法/
: 除法%
: 求余(模运算)++
: 自增--
: 自减
关系(比较)操作符
==
: 等于!=
: 不等于>
: 大于<
: 小于>=
: 大于等于<=
: 小于等于
逻辑操作符
&&
: 逻辑与(AND)||
: 逻辑或(OR)!
: 逻辑非(NOT)
位操作符
&
:按位与(AND)|
:按位或(OR)^
:按位异或(XOR)~ :
按位取反(NOT)<<
:左移>>
:右移
赋值操作符
=
: 简单赋值+=
: 加法赋值-=
: 减法赋值*=
: 乘法赋值/=
: 除法赋值%=
: 求余赋值<<=
: 左移赋值>>=
: 右移赋值&=
: 按位与赋值|=
: 按位或赋值^=
: 按位异或赋值
条件操作符(三元操作符)
? :
: 条件表达式condition ? expr1 : expr2
逗号操作符
,
: 逗号操作符,用于顺序求值,从左到右
指针操作符
*
: 解引用操作符(间接访问)&
: 取地址操作符
长度/大小操作符
sizeof
: 计算类型或对象的大小(以字节为单位)
强制类型转换操作符
(type)
: 强制类型转换,将表达式转换为指定的类型
成员访问操作符
.
: 点操作符,用于访问结构体或联合体的成员->
: 箭头操作符,用于通过指针访问结构体或联合体的成员
二进制和进制转换
我们经常能听到2进制、8进制、10进制、16进制这样的讲法,那是什么意思呢?
首先我们还是得从10进制讲起,其实10进制是我们生活中经常使用的,我们已经形成了很多常识:
1. 10进制中满10进1
2. 10进制的数字每一位都是0~9的数字组成
其实二进制也是一样的
1. 2进制中满2进1
2. 2进制的数字每一位都是0~1的数字组成
二进制与十进制
二进制与八进制和十六进制
3个3个的转
4个4个的转
原码、反码、补码
原码、反码、补码的介绍
整数的2进制表示方法有三种,即原码、反码和补码。
有符号整数的三种表示方法均有符号位和数值位两部分,2进制序列中,最高位的1位是被当做符号
位,剩余的都是数值位。
符号位都是用0表示“正”,用1表示“负”。
正整数的原、反、补码都相同。
负整数的三种表示方法各不相同。
原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
对于整形来说:数据存放内存中其实存放的是补码。
为什么呢?
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理 (CPU只有加法器)。 此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
负整数原码、反码、补码的互相转化
例如
1000 0000 0000 0000 0000 0000 0000 0101 -5的原码
1111 1111 1111 1111 1111 1111 1111 1010 -5的反码
1111 1111 1111 1111 1111 1111 1111 1011 -5的补码
移位操作符
<<
: 左移
>>
: 右移
注:移位操作符的操作数只能是整数。
左移操作符
移位规则:左边抛弃、右边补0
右移操作符
移位规则(取决于编译器):首先右移运算分两种:
1. 逻辑右移:左边用0填充,右边丢弃
2. 算术右移:左边用原该值的符号位填充,右边丢弃(常见)
警告:对于移位运算符,不要移动负数位,这个是标准未定义的。
位操作符
位操作符介绍
&
:按位与 对两个整数的每一位进行与操作。如果两个对应的位都为1,则结果位为1, 否则为0。|
:按位或 对两个整数的每一位进行或操作。如果两个对应的位中至少有一个为1,则结 果位为1,否则为0。^
:按位异或 对两个整数的每一位进行异或操作。如果两个对应的位不同,则结果位为1, 否则为0~ :
按位取反 对一个整数的每一位进行取反操作。如果某一位为1,则结果位为0,如果某 一位为0,则结果位为1。注意:对于带符号整数,按位取反的结果通常是负 数,因为最高位(符号位)也会被取反
注:他们的操作数必须是整数。都在补码上操作。
困难题
不使用第3个变量,使两个整数交换
结构成员访问操作符
结构体
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如:
标量、数组、指针,甚至是其他结构体。
结构的声明
结构成员访问操作符
结构体成员的直接访问
结构体成员的直接访问是通过点操作符( . )访问的。点操作符接受两个操作数。如下所示:
结构体成员的间接访问
间接访问需要另一个成员访问操作符:箭头操作符(->)
注意,箭头操作符是由减号(-)和大于符号(>)组合而在键盘上打出来
操作符的属性:优先级、结合性
C语言的操作符有2个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序。
优先级
优先级指的是,如果一个表达式包含多个运算符,哪个运算符应该优先执行。各种运算符的优先级是不一样的。
结合性
如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符是左结合,还是右结合,决定执行顺序。大部分运算符是左结合(从左到右执行),少数运算符是右结合(从右到左执行),比如赋值运算符(=)
表格
表达式求值
整型提升
介绍
C语言中整型算术运算总是至少以缺省(默认)整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
意义
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是it的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。通用CPU是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于it长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。
如何进行整数提升的
1. 有符号整数提升是按照变量的数据类型的符号位来提升的
2. 无符号整数提升,高位补0
算数转换
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换。
1. long double
2. double
3. float
4. unsigned long int
5. long int
6. unsigned int
7. int
如果某个操作数的类型在上面这个列表中排名靠后,那么首先要转换为另外一个操作数的类型后执行运算。