操作符分类:
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用和结构成员
算术操作符
+ - * / %
这个就很常见了,基本的数学运算,但还是有一些需要注意的地方:
除法操作符的两个操作数都是整数,执行整数除法
除法操作符的两个操作数只要有一个是小数的话,小数除法
取模操作符的操作符必须是整数,不能是其他
移位操作符
<< 左移操作符
>> 右移操作符
注:移位操作符的操作数只能是整数。
首先来看左移操作符
移位规则:
左边抛弃,右边补0
右移操作符
移位规则:
首先右移运算分两种:
1. 逻辑移位
左边用0填充,右边丢弃
2. 算术移位
左边用原该值的符号位填充,右边丢弃
警告 :
对于移位运算符,不要移动负数位,这个是标准未定义的。
例如:
int num = 10;
num>>-1;//error
位操作符
这里的位:是二进制位
& //按位与
| //按位或
^ //按位异或
注:他们的操作数必须是整数。
#include <stdio.h>
int main()
{
int num1 = 1;
int num2 = 2;
num1 & num2;
num1 | num2;
num1 ^ num2;
return 0;
}
如果有0,按位与的结果就为0 2&0=0
按位或,只要有1就为1,两个是0才为0
按位异或,相同为0,相异为1
一道变态的面试题:
不能创建临时变量(第三个变量),实现两个数的交换
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a^b;
b = a^b;
a = a^b;
printf("a = %d b = %d\n", a, b);
return 0;
}
赋值操作符
赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋
值。
int weight = 120;//体重
weight = 89;//不满意就赋值
double salary = 10000.0;
salary = 20000.0;//使用赋值操作符赋值。
赋值操作符可以连续使用,比如:
int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//连续赋值
但是这样的代码迷惑性很强,是从前往后定义呢,还是先计算后边再计算前边
所以,优化我们的代码,增强它的可读性,是很有必要的
如下:
//那同样的语义,你看看:
x = y+1;
a = x;
//这样的写法是不是更加清晰爽朗而且易于调试。
复合赋值符
+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^=
这些运算符都可以写成复合的效果。
比如:
int x = 10;
x = x+10;
x += 10;//复合赋值
//其他运算符一样的道理。这样写更加简洁。
单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
其中
sizeof 和 数组
看一段代码
#include <stdio.h>
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;
}
问:
(1)、(2)两个地方分别输出多少?
(3)、(4)两个地方分别输出多少?
请大家在评论区把答案打出来吧!
关系操作符
>
>=
<
<=
!= 用于测试“不相等”
==
其中,=和==容易搞混,=是赋值,==是判断相等,千万别搞混。
逻辑操作符
&& 逻辑与
|| 逻辑或
注意:要区分开逻辑与、逻辑或和按位与、按位或的区别
1&2----->0
1&&2---->1
1|2----->3
1||2---->1
条件操作符
这个我们前边提到过,详情请看作者以前的博客
逗号表达式
exp1, exp2, exp3……
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗号表达式
c是多少
答:c=13
下标引用操作符
1. [ ] 下标引用操作符
操作数:一个数组名 + 一个索引值
int arr[10];//创建数组
arr[9] = 10;//实用下标引用操作符。
[ ]的两个操作数是arr和9。
[]就是下标引用。
函数调用操作符
函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
#include<stdio.h>
int run_year(int year)
{
scanf("%d", &year);
if ((year % 4 == 0) && ((year % 100) != 0) || (year % 400 == 0))
return 1;
return 0;
}
int main()
{
int year=0;
if (run_year(year))
{
printf("");
}
return 0;
}
这是一个判断闰年的函数,实用()作为函数调用操作符。
![](https://img-blog.csdnimg.cn/img_convert/5f6b31ddf90df027cd96c286c71b0954.png)
结构体访问
结构体访问的方式有两种:
. 结构体.成员名
-> 结构体指针->成员名
请看代码理解
#include <stdio.h>
struct Stu
{
char name[10];
int age;
char sex[5];
double score;
};
void set_age1(struct Stu stu)
{
stu.age = 18;
}
void set_age2(struct Stu* pStu)
{
pStu->age = 18;//结构成员访问
}
int main()
{
struct Stu stu;
stu.age = 20;//结构成员访问
set_age1(stu);
pStu->age = 20;//结构成员访问
set_age2(pStu);
return 0;
}
算术转换
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类
型,否则操作就无法进行。下面的层次体系称为寻常算术转换。
long double
double
float
unsigned long int
long int
unsigned int
int
操作符的属性
复杂表达式的求值有三个影响的因素。
1. 操作符的优先级
2. 操作符的结合性
3. 是否控制求值顺序。
两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。
操作符优先级
欢迎大家到我的gitee访问,提取更多有趣代码。