C语言常见操作符的个人理解

首先说一下常见的操作符分类:
  1. 算数操作符
  2. 移位操作符
  3. 位操作符
  4. 赋值操作符
  5. 单目操作符
  6. 关系操作符
  7. 逻辑操作符
  8. 条件操作符
  9. 逗号表达式
  10. 下标引用、函数调用和结构成员
下面对它们做详细的介绍:
算术操作符
    +     -      *      /      %
  1. + - * 与正常运算相同,在这不做过多介绍。
  2. /操作符,如果两个操作数都为整数,那么,执行整数除法,如果两个操作数中有一个为浮点数,那么执行的就是浮点数的除法。
  3. %操作符的两个操作数必须为整型。

     下面我们对上面说到的情况做一演示:
这里写图片描述
     如果将%操作符的一个操作数改为非整型:
这里写图片描述

移位操作符
<<  左移操作符      >>  右移操作符
  1. 左移操作符 <<
    规则:左边丢弃,右边补0
    举个栗子:
    这里写图片描述
  2. 右移操作符>>
    规则:

    1. 逻辑移位:
      左边补0, 右边丢弃。
    2. 算术移位:
      左边补符号位,右边丢弃。

    举个栗子:

    这里写图片描述

  3. 移位操作符使用的过程中还需要注意一点:对于移位操作符来说,不能移动负数位,这个在标准中是未定义的。
    举个栗子:

    这里写图片描述

位操作符
 & 按位与
 | 按位或
 ^ 按位异或 

注意:

  • 它们的操作数必须为整数。
  • 它们的操作都是针对二进制位进行的。

举个栗子:

#include<stdio.h>
int main()
{
    int a = 15;
    printf("%d \n", a & 1);
    printf("%d \n", a | 1);
    printf("%d \n", a ^ 1);
    return 0;
}

       运行结果:
              这里写图片描述
原理:
这里写图片描述

赋值操作符
= 赋值操作符

举个栗子:

#include<stdio.h>
int main()
{
    int a = 15;
    int b = 16;
    printf("a = %d, b = %d \n", a, b);
    a = b = 6;
    printf("a = %d, b = %d \n", a, b);
    return 0;
}

       运行结果:

              这里写图片描述
注意:

  • 我们需要注意的是赋值操作符的返回值:
#include<stdio.h>
int main()
{
    int a = 15;
    printf("%d\n", a = 0);
    printf("%d\n", a = 3);
    printf("%d\n", a = 4);
    printf("%d\n", a = 5);
    return 0;
}
  • 赋值操作符还包括复合操作符:

    += -= *= /= %= >>= <<= &= |= ^=

    举个栗子:

#include<stdio.h>
int main()
{
    int a = 15;
    a += 1;
    printf("a = %d \n", a);
    a = 15;
    a -= 1;
    printf("a = %d \n", a);
    a = 15;
    a ^= 1;
    printf("a = %d \n", a);
    a = 15;
    a >>= 1;
    printf("a = %d \n", a);
    a = 15;
    a %= 2;
    printf("a = %d \n", a);
    return 0;
}

        运行结果:
            这里写图片描述

单目操作符
!         逻辑反操作
—         负值
+         正值
&         取地址
sizeof    操作数的类型长度(以字节为单位)
~         对一个数的二进制位取反
--        前置、后置--
++        前置、后置++
*         间接访问操作符(解引用操作符)
()        强制类型转换

       举个栗子:

#include<stdio.h>
int main()
{
    int a = 15;
    printf("!a = %d\n", !a);
    printf("-a = %d\n", -a);
    printf("&a = %p\n", &a);
    printf("sizeof(a) = %d\n", sizeof(a));
    printf("~a = %d\n", ~a);
    printf("--a = %d\n", --a);
    printf("a = %d\n", a);
    printf("a-- = %d\n", a--);
    printf("a = %d\n", a);
    a = 65;
    int *p = &a;
    printf("*p = %d\n", *p);
    printf("(char *)a = %c", (char*)a);
    return 0;
}

       运行结果:
               这里写图片描述
注意:
1. sizeof是在编译期间计算的,所以sizeof中的参数如果是语句,那么它是不执行的。

#include<stdio.h>
int main()
{
    int a = 15;
    printf("sizeof(a) = %d\n", sizeof(a = 6));
    printf("a = %d\n", a);
    return 0;
}

         运行结果:
                这里写图片描述
2. sizeof与数组:

#include<stdio.h>
int main()
{
    int a[10] = {0};
    printf("sizeof(a) = %d\n", sizeof(a));     //数组名单独放在sizeof中,大小为数组大小
    printf("sizeof(&a) = %d\n", sizeof(&a));   //&a 放在sizeof中,表示的是数组的地址
    printf("sizeof(a[0]) = %d\n", sizeof(a[0])); //数组首元素的字节大小
    printf("sizeof(a[10]) = %d\n", sizeof(a[10])); //由于sizeof在编译阶段计算,所以这个语句是正确的,表示的是a[10]大小
    printf("num = %d\n", sizeof(a) / sizeof(a[0]));  // 数组总大小/数组首元素大小 表示的是数组元素个数
    return 0;
}

         运行结果:
                  这里写图片描述
3. 由于sizeof是操作符,所以sizeof还可以这样用(不推荐这样使用):

#include<stdio.h>
int main()
{
    int a[10] = {0};
    printf("sizeof a = %d\n",sizeof a);
    return 0;
}

         运行结果:
                  这里写图片描述

关系操作符
>   >=   <   <=   !=   ==

以上是常用的关系操作符。
注意:

  1. 在编程过程中容易将===混淆,因此应该特别注意。
逻辑操作符
&&     逻辑与
||     逻辑或

注意:

1. 使用过程中应注意逻辑与、逻辑或和按位与、按位或的区别。

    1 & 2   ------->   0
    1 | 2   ------->   3

    1 && 2  ------->   1
    1 || 2  ------->   1

2. 逻辑与和逻辑或的特点:

  • &&特点:
#include<stdio.h>
int main()
{
    int a = 0, b = 1, c = 2, d = 3;
    int w = a++ && b++ && c++ && ++d;
    printf("a = %d  b = %d  c = %d  d = %d \n", a, b, c, d);
    w = a++ && b++ && c++ && ++d;
    printf("a = %d  b = %d  c = %d  d = %d \n", a, b, c, d);
    return 0;
}

         运行结果:
                  这里写图片描述

          逻辑与只要有一个表达式为false,就不再计算右边的表达式,直接得出false。类似于短路了右边。

  • ||特点:
#include<stdio.h>
int main()
{
    int a = 0, b = 1, c = 2, d = 3;
    int w = a++ || b++ || c++ || ++d;
    printf("a = %d  b = %d  c = %d  d = %d \n", a, b, c, d);
    w = a++ || b++ || c++ || ++d;
    printf("a = %d  b = %d  c = %d  d = %d \n", a, b, c, d);
    return 0;
}

         运行结果:
                  这里写图片描述

         逻辑或只要有一个表达式为true,就不计算再右边的表达式,直接得出true。类似于短路了右边。

条件操作符
x = exp1 ? exp2 : exp3

举个栗子:

#include<stdio.h>
int main()
{
    int a = 1, b = 5, c = 0;
    if (a > b)
        c = a;
    else c = b;
    printf("c = %d\n", c);
    c = a < b ? a : b;
    printf("c = %d\n", c);
    return 0;
}

         运行结果:
                  这里写图片描述

逗号表达式
exp1, exp2, exp3, exp4, …, expn
//逗号表达式,就是用逗号隔开的多个表达式。
//逗号表达式,从左向右依次执行,逗号表达式的结果是最后一个表达式的结果。   

举个栗子:

#include<stdio.h>
int main()
{
    int a = 0;
    while ((a++, printf("a = %d\n", a), a < 5))
    {
    }
    return 0;
}

         运行结果:
                  这里写图片描述

下标引用、函数调用和结构成员
[]   下标引用
()   函数调用
.    结构体.成员名
->   结构体指针->成员名

1. [] 下标引用
操作数: 数组名 + 索引值
举个栗子:

#include<stdio.h>
int main()
{
    int a[10] = {0};
    printf("%d\n", a[5]);
    return 0;
}

// []的两个操作数是 a 和 5

2. () 函数调用操作符
接收一个或者多个操作数: 第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
举个栗子:

#include<stdio.h>
void Print1()
{
    printf("Print\n");
}
void Print2(int a)
{
    printf("Print: a = %d\n", a);
}
int main()
{
    int a = 6;
    Print1();
    Print2(a);
    return 0;
}

         运行结果:
                  这里写图片描述

3. . 结构体.结构体成员
    -> 结构体指针->结构体成员

举个栗子:

#include<stdio.h>
struct student
{
    char name[20];
    int age;
};
int main()
{
    struct student A = {"zhangsan", 15};
    struct student *B = &A;
    printf("name : %s    age : %d\n", A.name, A.age);
    printf("name : %s    age : %d\n", B->name, B->age);
    return 0;
}

         运行结果:
                  这里写图片描述

最后需要注意的是:
复杂操作符的求值有三个影响因素:

  1. 操作符的优先级
  2. 操作符的结合性
  3. 是否控制求值顺序

两个相邻的操作符优先执行哪个,取决于它们的优先级,如果优先级相同,则取决于它们的结合性。
下面附上操作符的优先级表:
图片来自《C和指针》
这里写图片描述
这里写图片描述
这里写图片描述
以上即为我对于常见操作符的个人理解,不足之处还望指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值