1.算术操作符
+ - / % *
1.如果使用 / 运算符,想要得出浮点数需要注意的是在 / 的两边至少要有一个浮点数,即两边都为整数时执行整数除法,否则执行浮点数除法
2. % 为取余操作符,两边必须要是整数
3.除了 % 其余的算术运算符均可作用于整数或者是浮点数
2.移位操作符
>> 右移操作符
<< 左移操作符
在学习移位操作符之前我们需要学习三个概念,分别是:原码,反码,补码
以 4 这个数字举例,用二进制表示4的一串数字即为4的原码、
而对于正整数来说原码=反码=补码
而移位操作符就是对 4 的补码进行操作的
将4的补码左移1位即变成:00000000 00000000 00000000 00001000 输出8
将4的补码右移1位即变成:00000000 00000000 00000000 00000010 输出2
假如a为负数则 原码,反码,补码各不相同
以 -4 举例
原码:10000000 00000000 00000000 00000100
反码:111111111 111111111 111111111 111111011 按位取反,第一位不变
补码:111111111 111111111 111111111 111111100 反码的最后一位+1
负数的原码即第一位由0变成1
反码则是除了第一位按位取反
补码是反码最后一位 +1 所构成的
将a的补码左移一位后补码反码原码如下:
补码:111111111 111111111 111111111 111111100
反码:111111111 111111111 111111111 111111011
原码:10000000 00000000 00000000 00000100 输出-8
同理可得a右移一位输出-2
所以根据输出结果可以得出对于整数的来说遵循算数移位的规则,即右移时按照原符号位补相应的数字,当原来的整数是正数补0,负数则补1
3.位操作符
& 按位与 同时为1才为1,否则为0
| 按位或 同时为0才为0,否则为1
^ 按位异或 相同为0,相异为1
注:他们的操作数必须是整数
同样的位操作符也是对二进制作用的,以4和1举例
4 & 1 100 001 输出:000 0
4 | 1 100 001 输出:101 5
4 ^ 1 100 001 输出:101 5
4.赋值运算符
= += -= *= /= %= >>= <<= &= |= ^=
对于赋值运算符来说 = 是最为重要的一个运算符
我们需要注意的是在C语言里面如果我们在后续的代码中对初始化的值感到不满意,可以通过赋值运算符重新赋一个自己满意的值,类似于下面的代码
int weight = 200;
weight = 100;
对于复合赋值运算符无疑是将代码变得更加简洁,便于阅读
5.逻辑运算符
&& 与
|| 或
对于&&来说,当 &&两边的表达式均为真时,该表达式输出1,否则输出0
对于 || 来说,当 || 两边的表达式只要有一个为真时,该表达式输出1,否则输出0
这里有一个很坑人的点需要我们注意当我们遇到像下面这样的代码时:
#include <stdio.h>
int main()
{
int i = 0,a=0,b=2,c =3,d=4;
i = a++ && ++b && d++;
//i = a++||++b||d++;
printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
return 0;
}
输出的结果分别为 1 2 3 4 和 1 3 3 4
这道题目告诉我们当&&遇到的值为假时后面的的所有表达式均不执行
当 || 遇到的值为真时后面的所有表达式也不执行
6.条件运算符
a : b ? c
这个条件运算符的意思为判断a是否为真,当a为真时执行b,否则执行c
我们用一段if语句写的代码来更加形象的表现出来
if (a>5):
b = 1;
else
b = 0;
条件运算符同样也被称为三目运算符
7.逗号运算符
exp1,exp2,exp3
从左到右,依次执行表达式,最终输出最后一个表达式的结果
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
printf("%d", c);
}
以这段代码为例,最终的输出结果是 c = 13
8.关系运算符
> 大于
>= 大于等于
< 小于
<= 小于等于
!= 不等于
== 恒等于
这里需要注意的是不要把 = 和 == 两者搞混淆了,一个是赋值运算符,一个是关系运算符
9.单目运算符
! 逻辑反操作符
- 负值
+ 正值
& 取地址
sizeof 求目标对象的字节长度
++ 前置/后置自增1
-- 前置/后置自减1
~ 二进制按位取反
* 间接访问操作符
(类型) 强制类型转换
a++和++a的区别
我们用通俗易懂的话来说就是先读后增和先增后读
所谓先读后增就是编译器读取到的数据是a本身的数据,在执行下一条指令的时候a的数据又自增1了,此时a的大小为a+1;同样的先增后读就是在编译器读取到a的大小之前,a自增1变成a+1,当编译器读取到a时,读到的数据就是a+1
而a--和--a的区别同理可得
强制类型转换
通过强制类型转换我们可以将double类型的值转换成int类型的值,如图所示
sizeof
void test1(int arr[])
{
printf("%d\n", sizeof(arr));//(2)
}
void test2(char ch[])
{
printf("%d\n", sizeof(ch));//(4)
}
int main()
{
int arr[10] = { 0 };
char ch[10] = { 0 };
printf("%d\n", sizeof(arr));//(1)
printf("%d\n", sizeof(ch));//(3)
test1(arr);
test2(ch);
return 0;
}
通过这段代码我们运行以后发现运行结果为
前两个数值我们非常好理解,无非就是 4x10 和 1x10 的输出结果
后两个值都相等是为什么?
这是因为数组传参,传给形参的值是首元素的地址,也就是说这时候形参是一个指针,指向首元素的地址。而 sizeof 对指针求长度无一例外都是 4/8 (环境不同,结果不同)所以最后显示的值为 8