目录
C语言中的操作符详解
一、操作符分类
算数操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用和结构成员
1.算数操作符
包括:‘+’ ‘ -’ ‘ *’ ‘ /’ ‘ %’
-
除了 % 操作符之外,其他操作符可以作用于整数和浮点数
-
对于 / 操作符,如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法
-
% 操作符的两个操作数必须为整数,返回的是整除之后的余数
2.移位操作符
<< 左移操作符 左边抛弃,右边补0 (二进制补码左移) 是一种运算符,自身的值不会改变
>> 右移操作符 :
-
算数右移:右边丢弃,左边补原来的符号位
-
逻辑右移:右边丢球,左边补0
注:常见编译器下都是算数右移
注:移位操作符的操作数只能是整数
3.位操作符
& 按(二进制)位与 按补码计算
| 按(二进制)位与 按补码计算
^ 按(二进制)位异或 按补码计算
不创建临时变量实现两个数的变换:
#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;}
4.赋值操作符
a=x=3 连续赋值
复合赋值:
+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^=
5.单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
sizeof和数组:sizeog()内部单独放一个数组名,数组名表示整个数组
6.关系操作符
7.逻辑操作符
#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// && 左边为假,右边不计算 || 左边为真,右边不计算
8.条件操作符
9.逗号表达式
10.下标引用、函数调用和结构成员
-
下标引用操作符:
操作数:一个数组名 + 一个索引值
int arr[10];//创建数组arr[9] = 10;//实用下标引用操作符。[ ]的两个操作数是arr和9。
-
( ) 函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
-
访问一个结构的成员
-
. 结构体.成员名
-
-> 结构体指针->成员名
二、表达式求值
表达式求值的顺序一部分是由操作符的优先级和结合性决定。
同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。
1.隐式类型转换
//负数的整形提升char c1 = -1;变量c1的二进制位(补码)中只有8个比特位:1111111因为 char 为有符号的 char所以整形提升的时候,高位补充符号位,即为1提升之后的结果是:11111111111111111111111111111111//正数的整形提升char c2 = 1;变量c2的二进制位(补码)中只有8个比特位:00000001因为 char 为有符号的 char所以整形提升的时候,高位补充符号位,即为0提升之后的结果是:00000000000000000000000000000001//无符号整形提升,高位补0
2.算术转换
long doubledoublefloatunsigned long intlong intunsigned intint
三、操作符的属性
复杂表达式的求值有三个影响的因素。
1. 操作符的优先级
2. 操作符的结合性
3. 是否控制求值顺序。
两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。
一些问题表达式:
a*b + c*d + e*f注释:代码1在计算的时候,由于*比+的优先级高,只能保证,*的计算是比+早,但是优先级并不能决定第三个*比第一个+早执行。
c + --c;注释:同上,操作符的优先级只能决定自减--的运算在+的运算的前面,但是我们并没有办法得知,+操作符的左操作数的获取在右操作数之前还是之后求值,所以结果是不可预测的,是有歧义的。
int fun(){static int count = 1;return ++count;}int main(){int answer;answer = fun() - fun() * fun();printf( "%d\n", answer);//输出多少?return 0;}注释:无法知道哪个fun()先调用
#include <stdio.h>int main(){int i = 1;int ret = (++i) + (++i) + (++i);printf("%d\n", ret);printf("%d\n", i);return 0;}注释:linux先算++i和++i 再算第一个+号 再算第三个++i 再算第二个+号。而vs 先计算三个++i 然后再算两个+号 故此代码路径不唯一,会导致出错。
总结
以上就是今天要讲的有关操作符的详解,希望大家多多点赞支持,共同进步!