C语言操作符分类解析

目录

算术运算符

关系运算符

逻辑运算符

位运算符

赋值运算符

三目运算符

取址/解引用运算符

下标运算符

sizeof

成员访问/间接成员访问运算符

其它

运算符的优先级

数据提升


这些是我在学习C语言操作符过程中的一些整理的学习心得,首先我将一部分操作符运算的优先级放在本文开头,后面是详解。

C语言部分运算符优先级表

优先级

运算符

名称或含义

1

[ ]

数组下标

()

圆括号

.

成员选择(对象)

->

成员选择(指针)

2

-

负号运算符

~

按位取反运算符

++

自增运算符

--

自减运算符

*

取值运算符

&

取地址运算符

!

逻辑非运算符

(类型)

强制类型转换

sizeof

长度运算符

3

/

*

%

余数(取模)

4

+

-

5

<< 

左移

>> 

右移

6

大于

>=

大于等于

小于

<=

小于等于

7

==

等于

!=

不等于

8

&

按位与

9

^

按位异或

10

|

按位或

11

&&

逻辑与

12

||

逻辑或

13

?:

条件运算符

14

=

赋值运算符

/=

除后赋值

*=

乘后赋值

%=

取模后赋值

+=

加后赋值

-=

减后赋值

<<=

左移后赋值

>>=

右移后赋值

&=

按位与后赋值

^=

按位异或后赋值

|=

按位或后赋值

15

逗号运算符

算术运算符

+
-
*
/
%

++
--
  • 注意点

    • % 取余 只适合于整数(char)

    • / 整数不能除以0(浮点数除外)

    • ++/--

      • 前++/-- 在表达式先自增/减,然后参与运算

      • 后++/-- 先取值进行运算,然后自增/减

      • 在同一个表达式,尽量避免对同一个变量进行多次自增/自减

      • 在调用函数传递参数时,避免对传递进行自增/减,特别是宏函数

关系运算符

>
>=
<
<=
==
!=
  • 注意

    • 关系表达式的结果为0/1

    • 多个关系表达式需要用逻辑运算符连接

      int a = 0;
      scanf("%d",&a);
      if(0 < a < 10){  //恒成立    (0<a) < 10    0<a的结果要么是0,要么是1
      	printf("a在(0,10)区间\n");
      }
      
      if(0 < a && a < 10){  //判断a是否在(0,10)区间
      
      }

    • 判断相等,不要写成赋值

      if(a == 10) ==>   if(10 == a)

逻辑运算符

&&
||
!
  • 数据与逻辑值

  • 在逻辑领域,非"零"即真,真即"1"

    int a = 10,b = 20;
    if(a && b){  //10 && 20     这里面的10和20逻辑真
    
    }

  • 逻辑表达式的结果是 0或者1

  • 短路特性

    • 0&&++i;

      • 逻辑与&&运算符,&&前面表达式如果为假(0),则后半表达式不运算

    • 1||++i;

      • 逻辑或||运算符,||前面表达式如果为真(1),则后半表达式不运算

    • 后面部分结果影响不了表达式最终的结果,短路径

  • 逻辑&&运算符优先级 高于 逻辑||

    a || b && c     ===>   a || (b && c)
    a && b || c     ===>   (a && b) || c

位运算符

&
|
^
~
>>
<<
  • 只适用于整数

  • &|^ 相同位置的二进制位进行运算

    num & -1   ==  num
    num | -1   ==  -1
    num | 0    ==  num
    num ^ 0    ==  num
    num ^ -1   ==  ~num  == -(num + 1)
    	num 如果是正数   -num = ~num + 1

  • 右移分情况

    • 有符号的数 左边空出的位全部补符号位

    • 无符号的数 左边补0

  • 左移

    • 右边空出的位补0

  • 右移1位相当于除以2 (负奇数除外 n/2-1)

  • 左移1位相当于乘以2

赋值运算符

=  +=  -=  *=  /=   >>=  <<=   &=  |=  ^=    &&=   %=
  • 数据溢出

    • 整数数据,宽字节整数赋值窄字节变量时,只截取低字节数据,多出部分舍弃

    • 浮点数赋值整数,直接舍弃小数部分,且整数也可能溢出

  • 数据填充

    • 整数数据,窄字节数据赋值给宽字节变量时,需要在高位填充

      • 窄字节数据如果是signed类型,则高位填充符号位

      • 窄字节数据如果是unsigned类型,则高位填充0

三目运算符

?:
expr?res1:res2

if(expr){
	return res1;  //res1  可以是一个语句
}else{
	return res2;  //res2  可以是一个语句
}

取址/解引用运算符

&     获取变量的存储地址         虚拟内存   编号      %p     十六进制的整数
*     解引用                   *(指针/内存)    取得内存地址中的数据
如果内存/指针的类型为  void *    则不能解引用

下标运算符

[]

arr[index]    <==>     *(arr+index)
  • 本质是指针偏移解引用

  • 下标运算符的操作数可以交换

    arr[i]   <===>   i[arr]

sizeof

  • sizeof是操作符,不是函数

  • sizeof操作数可以是类型,也可以是变量,表达式,语句

    • 操作数如果是类型,必须要有小括号 sizeof(类型)

    • 操作数如果不是类型名,则()可省 sizeeof ret

  • sizeof只关心操作数的类型,不会计算结果

    • sizeof(表达式) 表达式不会运算

    • sizeof(函数(参数)) 不会调用函数,只关心函数返回值类型

    • sizeof(函数名) == 1 C语法规定,未定义的结果

void func(int arr[],int len){     //arr    <===>  int *arr
    printf("%lu\n",sizeof(arr));  //4/8
}

void func1(int arr[10]){          //int arr[10]   形参列表   int *arr
    printf("%lu\n",sizeof(arr));  //4/8
}
int main(){
    int arr[10] = {};
    printf("%lu\n",sizeof(arr));  //40
    func(arr,10);
    return 0;
}

sizeof("pointer");   //8   包含'\0'
char *s = "pointer";
sizeof(s);           //4/8    求指针变量s的内存空间大小

sizeof("ab");       //3
char *s1 = "ab";
sizeof(s1);         //4/8


char s2[] = "hello";
sizeof(s2);        //6
char s3[10] = "hello";
sizeof(s3);        //10

sizeof('a');       //4
char ch = 'a';
sizeof(ch);        //1
    
  • sizeof(long) 4/8

  • sizeof(long double) 12/16

  • sizeof(指针) 4/8

成员访问/间接成员访问运算符

.
->

结构体变量.成员名

结构体指针->成员名

其它

,
()

(x,y,c,a+b,c+d,w*y)    从左往右依次计算,最终的结果取最后一个表达式的结果

运算符的优先级

  • 逻辑非 > 算术运算符 > 关系运算符 > 逻辑&& > 逻辑|| > 赋值运算符

  • 位运算符~ > 算术运算符 > 移位(>>/<<)

char ch = 188;
int num = ~ch >> 1 + 2;

unsigned ch1 = 188;
int num = ~ch >> 1 + 2;

数据提升

  • 在混合类型运算时

    • char 会自动提升为 int类型

    • unsigned char ---> unsigned int

    • short 会自动提升为 int类型

  • 在有符号和无符号数据进行运算符时

    • 有符号 --> 无符号

  • 11
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值