C探索碎片——操作符
C的探索碎片——操作符
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用和结构成员
一.算数操作符
+ - * / %
+、-、*此类数学中常见的算数符号我们再熟悉不过,需要注意的是/(除),%(取余)之间的区别。
例:
#include<stdio,h>
int main()
{
int a = 10;
printf("%d",a/3);//结果为3
printf("%d",a%3);//结果为1
return 0;
}
注意:1.除%操作符之外。其他几个操作符可以作用于整数和浮点数。
2./操作符运算时若两个操作数中含浮点数则执行浮点数除法(%lf打印结果);若两操作数都为整数则执行整数除法。
3.%操作符的两个操作数必须为整数。
二、移位操作符
<< 左移操作符
>> 右移操作符
注:移位操作符的操作数只能是整数。
移位操作符移动的是二进制的位,而整数在内存中以补码的形式进行存储,屏幕上又以原码显示。
补充:
原码:把一个数按正负直接翻译成二进制;
反码:对原码进行按位取(即0变为1,1变为0)反得到反码;
补码:反码+1得补码。
对于正整数原码反码补码相同,负整数则需计算。
计算方法:原码符号位(二进制表示的最高一位,是0表示为负数,是1表示为正数)不变,其他位按位取反得到反码,+1得到补码。
编辑
移位规则:
- 左移操作符:左边抛弃、右边补0。
编辑
- 右移操作符(由编译器决定):
逻辑移位
左边用0填充,右边丢弃。
编辑
算术移位
左边用原该值的符号位填充,右边丢弃。
编辑
警告⚠:
对于移位运算符,不要移动负数位,这个是标准未定义的。
三、位操作符
&//按位与
|//按位或
^//按位异或
注:它们的操作数必须为整数。
均对二进制进行操作。
&:有0为0,均1为1;
|:有 1为1,均0为0;
^:相同为0,相异为1,且保证不会栈溢出。
小tip:
a ^ a = 0;
0 ^ a = a;
四、赋值操作符
其实就是对“=”的运用。
赋值操作符可以连续使用,比如:
int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//连续赋值
复合赋值符
+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^=
可以自己进行实践探索具体功能🌸
五、单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
六、关系操作符
>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”
注意:编程过程中不要混淆==和=,不然会变成bug小子。
七、逻辑操作符
&& 逻辑与
|| 逻辑或
区分逻辑与和按位与
区分逻辑或和按位或
1&2----->0
1&&2---->1
1|2----->3
1||2---->1
八、条件操作符
exp1 ? exp2 : exp3
懒鬼懒得解释了直接上🌰
例:
#include<stdio.h>
int main()
{
int a, b;
scanf("%d%d", &a, &b);
int c = (a > b) ? a : b;
printf("%d", c);
return 0;
}//输入5 3 结果为5 输入3 5 结果为3
九、逗号表达式
exp1, exp2, exp3, …expN
逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
十、下标引用、函数调用和结构成员
\1. [ ] 下标引用操作符
操作数:一个数组名 + 一个索引值
int arr[6];//创建数组
arr[6] = 10;//实用下标引用操作符。
[ ]的两个操作数是arr和6
\2. ( ) 函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
#include <stdio.h>
void test1()
{
printf("hehe\n");
}
void test2(const char *str)
{
printf("%s\n", str);
}
int main()
{
test1(); //实用()作为函数调用操作符。
test2("hello bit.");//实用()作为函数调用操作符。
return 0;
}
\3. 访问一个结构的成员
. - > | 结构体.成员名 结构体指针->成员名 |
---|---|
#include<stdio.h>
struct S
{
int num ;
char c ;
};
int main()
{
struct S s = {6,'a'};
printf("%d\n", s.num);
printf("%c", s.c);
}//打印出6 a
#include<stdio.h>
struct S
{
int num ;
char c ;
};
void test(struct S* p)
{
printf("%d\n", p->num);
printf("%c", p->c);
}
int main()
{
struct S s = {6,'a'};
test(&s);
return 0;
}//打印出6 a
*复杂表达式的求值有三个影响的因素:*
\1. 操作符的优先级
\2. 操作符的结合性
\3. 是否控制求值顺序。
💫两个相邻的操作符先执行哪个?取决于他们的优先级;如果两者的优先级相同,取决于他们的结合性。
操作 符 | 描述 | 用法示例 | 结果类型 | 结合性 | 是否控制求值顺序 |
---|---|---|---|---|---|
() | 聚组 | (表达式) | 与表达 式同 | N/A(不适用) | 否 |
() | 函数调用 | rexp(rexp,…,rexp) | rexp | L-R(左到右) | 否 |
[ ] | 下标引用 | rexp[rexp] | lexp | L-R | 否 |
. | 访问结构成员 | lexp.member_name | lexp | L-R | 否 |
-> | 访问结构指针成员 | rexp->member_name | lexp | L-R | 否 |
++ | 后缀自增 | lexp ++ | rexp | L-R | 否 |
– | 后缀自减 | lexp – | rexp | L-R | 否 |
! | 逻辑反 | ! rexp | rexp | R-L(右到左) | 否 |
~ | 按位取反 | ~ rexp | rexp | R-L | 否 |
+ | 单目,表示正值 | + rexp | rexp | R-L | 否 |
- | 单目,表示负值 | - rexp | rexp | R-L | 否 |
++ | 前缀自增 | ++ lexp | rexp | R-L | 否 |
– | 前缀自减 | – lexp | rexp | R-L | 否 |
* | 间接访问 | * rexp | lexp | R-L | 否 |
& | 取地址 | & lexp | rexp | R-L | 否 |
sizeof | 取其长度,以字节 表示 | sizeof rexp sizeof(类 型) | rexp | R-L | 否 |
(类 型) | 类型转换 | (类型) rexp | rexp | R-L | 否 |
* | 乘法 | rexp * rexp | rexp | L-R | 否 |
/ | 除法 | rexp / rexp | rexp | L-R | 否 |
% | 整数取余 | rexp % rexp | rexp | L-R | 否 |
+ | 加法 | rexp + rexp | rexp | L-R | 否 |
- | 减法 | rexp - rexp | rexp | L-R | 否 |
<< | 左移位 | rexp << rexp | rexp | L-R | 否 |
>> | 右移位 | rexp >> rexp | rexp | L-R | 否 |
> | 大于 | rexp > rexp | rexp | L-R | 否 |
>= | 大于等于 | rexp >= rexp | rexp | L-R | 否 |
< | 小于 | rexp < rexp | rexp | L-R | 否 |
<= | 小于等于 | rexp <= rexp | rexp | L-R | 否 |
== | 等于 | rexp == rexp | rexp | L-R | 否 |
!= | 不等于 | rexp != rexp | rexp | L-R | 否 |
& | 位与 | rexp & rexp | rexp | L-R | 否 |
^ | 位异或 | rexp ^ rexp | rexp | L-R | 否 |
| | 位或 | rexp | rexp | rexp | L-R | 否 |
&& | 逻辑与 | rexp && rexp | rexp | L-R | 是 |
|| | 逻辑或 | rexp || rexp | rexp | L-R | 是 |
? : | 条件操作符 | rexp ? rexp : rexp | rexp | N/A | 是 |
= | 赋值 | lexp = rexp | rexp | R-L | 否 |
+= | 以…加 | lexp += rexp | rexp | R-L | 否 |
-= | 以…减 | lexp -= rexp | rexp | R-L | 否 |
*= | 以…乘 | lexp *= rexp | rexp | R-L | 否 |
/= | 以…除 | lexp /= rexp | rexp | R-L | 否 |
%= | 以…取模 | lexp %= rexp | rexp | R-L | 否 |
<<= | 以…左移 | lexp <<= rexp | rexp | R-L | 否 |
>>= | 以…右移 | lexp >>= rexp | rexp | R-L | 否 |
&= | 以…与 | lexp &= rexp | rexp | R-L | 否 |
^= | 以…异或 | lexp ^= rexp | rexp | R-L | 否 |
|= | 以…或 | lexp |= rexp | rexp | R-L | 否 |
, | 逗号 | rexp,rexp | rexp | L-R | 是 |
简单记就是:!>算术运算符>关系运算符符>&&>||>赋值运算符