目录
一 操作符分类
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用操作符
二 算术操作符
算术操作符+ , - , * , / %
这里需要注意的是:
- 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
- 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
- % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
三 移位操作符
<< 左移
和>> 右移
左移操作符
左边除去,右边补零
右移操作符
分为两种:
1.逻辑移位
左边用0填充 ,右边丢弃
2.算术移位
左边用原该值的符号位填充,右边丢弃
举个例子:
int num = -1;
内存中-1的补码是32个1
11111111111111111111111111111111
使用算术右移移一位,左边用符号位填充
11111111111111111111111111111111
-1是负数,所以左边补个1
若使用逻辑移位向右移动1位,直接左边补0
01111111111111111111111111111111
提示:对于移位运算符,不要移动负数位。
int n = 10;
n >> -1; // error
四 位操作符
位操作符有:
& 按位与
| 按位或
^ 按位异或
4.1按位与 &
相当于数学集合里面的交集
4.2 按位或 |
相当于数学集合中的并集
4.3 按位异或 ^
规则 相同为 0 ,不同为1
举个例子
int a = -1; //11111111111111111111111111111111
int b = 1; //00000000000000000000000000000001
int c = a ^ b;//11111111111111111111111111111110
五 赋值操作符
复合赋值符
+=
-=
*=
/=
%=
->>=
<<=
&=
|=
^=
例如 a+= 10 就等于 a = a+10
六 单目操作符
单目操作符介绍
1.单目运算符是指运算所需变量为一个的运算符,即在运算当中只有一个操作数,又叫一元运算符。
1! 逻辑反操作
2- 负值
3+ 正值
4& 取地址
5sizeof 操作数的类型长度(以字节为单位)
6~ 对一个数的二进制按位取反
7-- 前置、后置–
8++ 前置、后置++
9 * 间接访问操作符(解引用操作符)
(类型) 强制类型转换
sizeof可以求变量所占空间的大小
++和 - - 运算符
++分为前置++和后置++
1.前置++举例
这里是先前置++ 让x自增 然后再把11赋值给y
int main()
{
int x = 1;
int y = ++ x;//这里是先前置++ 让x自增 然后再把11赋值给y
return 0;
}
2.后置 ++ 举例
后置++ ,先把10赋值给b然后a再自增
int main()
{
int a = 10;
int b = a++;//后置++ ,先把10赋值给b然后a再自增
return 0;
}
减减同理。
七 关系操作符
这里有这么几种1. >
2. >=
3. <
4. <=
5. != 用于测试“不相等”
6. == 用于测试“相等”
这里主要注意判断相等使用“==”,而不是” = ”(赋值)。
八 逻辑操作符 (逻辑与&& 逻辑或 ||)
逻辑操作符与按位操作符的区别
①代表含义不同
按位与运用二进制进行计算,逻辑与比较符号两边的真假输出逻辑值。
②运算法则不同
按位与对所有的表达式都要判断,逻辑与运算符第一个表达式不成立的话,后面的表达式不运算,直接返回。
③输出不同
按位与&输出运算结果为不同的数值,逻辑与 && 输出逻辑值true或者 false。
例如: 按位与1&2=0;逻辑与1&&2=true(一般用数字1代指ture)。
九 条件操作符(三目操作符)
形式:exp1 ? exp2 : exp3
exp1成立 计算exp2
exp1不成立 计算exp3
十 逗号表达式
逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
例如:exp1,exp2,exp3,expn …
十一 下标引用 结构成员
(1) [ ] 下标引用操作符
操作数:一个数组名 + 一个索引值
int main()
{
int arr[5] = {1,2,3,4,5};
数组通过下标来访问,下标从0开始。如:1的下标是0
printf("数组第五个元素为:%d\n",arr[4]);
return 0;
}
(2)访问结构的成员
“.” 结构体.成员名
”->“ 结构体指针->成员名
上代码
struct Book //创建了一个自定义类型
{
//结构体的成员(变量)
char name[20];
char id[20];
int price;
};
int main()
{
struct Book b = { "C语言", 20210406 ,65 };
struct Book * pb = &b;
printf("书名:%s\n", pb->name); //结构体指针->成员名
printf("书名:%s\n", b.name); //结构体变量名.成员名
printf("书名:%s\n", (*pb).name);
return 0;
}
十二 表达式求值
隐式类型转换
C的整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
例如:
int main()
{
char a = 3; //先写出3的内存二进制补码
//00000000000000000000000000000011
//进行截取 8位 00000011
char b = 127;
//00000000000000000000000001111111
//b也截取八位01111111
//进行整型提升
char c = a + b;
//00000000000000000000000000000011
//00000000000000000000000001111111
//00000000000000000000000010000010 这里对应相加,满2进1
//10000010 -c
//进行整型提升
//11111111111111111111111110000010 补码 补码-1 =反码
//11111111111111111111111110000001 反码 除了符号位取反得到原码
//10000000000000000000000001111110 原码 (-126)
//这里发现a和b都是char类型,都没有达到一个int类型的大小
//这里就会发生整型提升
printf("%d\n", c);//-126
return 0;
}
整型提升的意义
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器 (ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。