且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

操作符详解

更新时间:2022-10-04 09:25:29

1.   算数操作符

如:+    -   *   /   % 

这里着重讲解下 / 和 % 操作符,上代码:

#include<stdio.h>
 
 
int main()
{
    int m = 10 % 3;      //    %---取余(两端必须是整数)
    printf("%d\n", m);   //    1
    int n = 10 / 3;      //    /---取商
    printf("%d\n", n);   //    3
    //  当 /(除号)两端是整数的时候,执行的是整数的除法,两端只要有一个浮点数,执行的就是浮点数的除法
    double z = 10.0 / 3;
    printf("%lf\n", z);  //    3.333333
    return 0;
}

操作符详解2.   移位操作符

注:移位操作符的操作数只能是整数。


引言:


整数有3种二进制的表示形式

1:原码    

2:反码      

3:补码

对于正整数 - 原码 - 反码 - 补码 均相同

对于负整数 - 原码 - 反码 - 补码 不同,要进行计算!

如+5:   整数,整型,32bit

  00000000000000000000000000000101  ---原码---反码---补码

如-5:    整数,负数

  10000000000000000000000000000101  ---原码

  11111111111111111111111111111010  ---反码(原码的符号位不变,其他按位取反)

  11111111111111111111111111111011  ---补码(反码的二进制+1)

整数在内存中存储的是补码!!!


     2.1  右移操作符  (>>)

移位规则: 首先右移运算分两种:


1. 逻辑移位 (左边用0填充,右边丢弃)


2. 算术移位 (左边用原该值的符号位填充,右边丢弃)

#include<stdio.h>
int main()
{
    int a = 5;
    int b = a >> 1;
    printf("%d\n", b);    //输出2
    return 0;
}

 我们来画张图解释下吧:

操作符详解

      2.2  左移操作符 (<<)

原理同右移操作符

移位规则: 左边抛弃、右边补0

上代码:

#include<stdio.h>
int main()
{
    int a = 5;
    //把a在内存中存储的二进制位向左移动2位
    int b = a << 2;
  //此时此刻b的二进制为00000000000000000000000000010100
  //换成10进制表示20
    printf("%d", b);//打印或使用用的是原码的值   20
    return 0; 
}

3.   位操作符

  &  按位与

  |   按位或

  ^  按位异或

//   -5的原码  10000000000000000000000000000101  

//   -5的反码  11111111111111111111111111111010  

//   -5的补码  11111111111111111111111111111011  

//    3的补码  00000000000000000000000000000011

//    &按位与:有0为0,全1为1。

//    c = -5&3:    00000000000000000000000000000011

//    c的内存存的是补码,打印的是原码  上述补码是正数,原码反码补码相同

//    |按位或:有1为1,全0为0

//    ^相同为0,相异为1

//    c的内存存的是补码,打印的是原码


上代码:


#include<stdio.h>
int main()
{
    int a = 3;
    int b = -5;
    int m = a & b;
    int n = a | b;
    int k = a ^ b;
    printf("%d\n", m);   // 3
    printf("%d\n", n);   // -5
    printf("%d\n", k);   // -8
    return 0;
}

画图解析:

操作符详解

操作符详解

//练习:

//交换两个整型变量(不能创建临时变量)

法一:临时变量法 效率高

#include<stdio.h>
int main()
{
    int a = 3;
    int b = 5;
    int c = 0;
    printf("交换前a=%d b=%d\n", a, b);   //交换前a=3 b=5
    c = a;
    a = b;
    b = c;
    printf("交换后a=%d b=%d\n", a, b);   //交换后a=5 b=3
    return 0;
 
 
}

法二:(此法存在溢出的问题)

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

法三:异或操作符 (仅限于整数)

//     3^3=0

//     0^5=5

#include<stdio.h>
int main()
{
    int a = 3;
    int b = 5;
    a = a ^ b;
    b = a^ b;  //即为  a ^ b ^ b = a ^ 0 = a
    a = a ^ b; //即为  a ^ a ^ b = 0 ^ b = b
    printf("a=%d b=%d", a, b); 
}

操作符详解

4.  赋值操作符

赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值。

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;//复合赋值
//其他运算符一样的道理。这样写更加简洁。

5.   单目操作符

操作符详解

! (逻辑反操作)

#include<stdio.h>
int main()
{
    int flag = 0;
    if (!flag)
        printf("hehe\n");  // hehe
    return 0; 
}

 -(负值)

#include<stdio.h>
int main()
{
    int i = 0;
    int flag = 1;
    for (i = 0; i < 10; i++)
    {
        printf("%d ", i * flag);
        flag = -flag;
    }
    return 0;
}
 
 
 
// abs  对整数求绝对值
// fabs 对小数求绝对值

操作符详解 sizeof(操作符的类型长度,以字节为单位)

#include<stdio.h>
int main()
{
    int a = 10;
    printf("%d\n", sizeof(a));    //4字节
    printf("%d\n", sizeof(int));  //4字节
 
 
    int arr[10] = { 1,2,3,4,5,6 };
    printf("%d\n", sizeof(arr));  //40字节
    printf("%d\n", sizeof(int[10]));  //40字节
 
 
}

 ~ 按位取反

#include<stdio.h>
int main()
{
    int a = 0;
    // ~ 按(内存中补码的二进制)位取反
    // 00000000000000000000000000000000
    // 11111111111111111111111111111111   补码
    // 11111111111111111111111111111110   反码
    // 10000000000000000000000000000001   原码
    printf("%d\n", ~a);   // -1
    return 0;
}
#include<stdio.h>
int main()
{
    int a = 10;
    // 00000000000000000000000000001010  
    // 00000000000000000000000000000100    ---   1<<2得到左边
    // 00000000000000000000000000001110
    // 11111111111111111111111111111011    ---   ~(1<<2)
    // 00000000000000000000000000001010
    a = a | (1 << 2);
    printf("%d\n", a);   // 14
    a = a & ~(1 << 2);
    printf("%d\n", a);   // 10
    return 0;
}

++ 和 -- 运算符

上代码:

#include<stdio.h>
int main()
{
    int a = 3;
    int b = a++;   //后置++ ,先使用,后++
    printf("a= %d,b=%d\n", a, b);   // a=4  b=3
    return 0;
 
}
#include<stdio.h>
int main()
{
    int a = 3;
    int b = ++a;  //前置++,  先++,后使用
    printf("a=%d b=%d\n", a, b);  // a=4,b=4
    return 0;
}
 //--类似

* 简介访问操作符(解引用操作符)

#include<stdio.h>
int main()
{
    int a = 10;
    int* p = &a;
    *p = 120;   // *p解引用操作符
    printf("%d\n", a);    // 120
    return 0;
}

()强制类型转换

#include<stdio.h>
int main()
{
    int a = (int)3.14;  //3.14 - double -> int a
    printf("%d\n", a);  // 3
    return 0;
}

练习:

#include<stdio.h>
int main()
{
    int a = 10;
    int* p = NULL;
    printf("%d\n", !2);    // 0
    printf("%d\n", !0);    // 1
    a = -a;
    p = &a;
    printf("%d\n", sizeof(a)); // 4
    printf("%d\n", sizeof(int)); // 4
    printf("%d\n", sizeof a);  // 4
    //printf("%d\n", sizeof int); err
 
 
}
#include<stdio.h>
void test1(int arr[])
{
    printf("%d\n", sizeof(arr));  //(2) 4
}
void test2(char ch[]) 
{
    printf("%d\n", sizeof(ch));   //(4) 4
 
}
int main()
{
    int arr[10] = { 0 };
    char ch[10] = { 0 };
    printf("%d\n", sizeof(arr));  //(1)  40
    printf("%d\n", sizeof(ch));   //(3)  10
    test1(arr);
    test2(ch);
    return 0;
}

6.   关系操作符

操作符详解

7.   逻辑操作符

&&     逻辑与

||        逻辑或

要特别区分逻辑操作符和位操作符,&&相当于是两个条件都要满足才可完成的指令,而||相当于两个条件只要有一个完成就可以。

//代码一:逻辑与
#include<stdio.h>
int main()
{
    int age = 0;
    scanf("%d", &age);
    if (age > 0 && age < 18)
    {
        printf("未成年\n");
    }
    return 0;
    return 0;
}
 
 
//代码二:逻辑或
#include<stdio.h>
int main()
{
    int month = 4;
    if (month < 1 || month>12)
    {
        printf("输入错误\n");
    }
    else
    {
     
    }
}
 
// 小练习:
 
#include<stdio.h>
int main()
{
    int i = 0, a = 0, b = 2, c = 3, d = 4;
    i = a++ && ++b && d++;
    //134行代码好比老师让三个同学都去完成一个任务,若其中任何一个没完成,就算任务失败
    //当a++时,先使用=0,为假,则后面不予考虑
    printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d); //  1 2 3 4
    //i = a++ || ++b || d++;
    若有一个满足,后面不予考虑
    //printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d); //  2 2 3 4
 
    return 0;
}

8.   条件操作符

操作符详解

#include<stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    int max = 0;
    max = (a > b ? a : b);
    /*if (a > b)
    {
        max = a;
    }
    else
        max = b;*/
    printf("%d\n", max);   // 20
    return 0;
}

9.   逗号表达式

逗号表达式,就是用逗号隔开的多个表达式。从左向右依次执行,整个表达式的结果是最后一个表达式的结果。

 上代码:

//代码1
#include<stdio.h>
int main()
{
    int a = 3;
    int b = 5;
    int c = 6;
    int d = (a += 2, b = a - c, c = a + 2 * b);
    printf("%d\n", d);   // 3
 
    return 0;
}
//代码2
#include<stdio.h>
int main()
{
    int a = 1;
    int b = 2;  
    int c = (a > b, a = b + 10, a, b = a + 1);
    //  13
 
    printf("%d\n", c);   // 13
    return 0;
 
}

10.下标引用、函数调用和结构成员

1:下标引用:

 
#include<stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    printf("%d\n", arr[7]); // 8
    //arr[7]-- > * (arr + 7)-- > * (7 + arr)-- > 7[arr]
    //解释:因为arr是数组名,访问的的首元素的地址,arr+7即是第八个元素的地址,即 * (arr + 7)
    //      又因为加法交换律支持加号两边变换位置,即* (7 + arr),又可写成7[arr]。----装逼用
    printf("%d\n", arr[7]); // 8
    printf("%d\n", 7[arr]); // 8
    return 0;
 
}

2:函数调用:

#include<stdio.h>
void test()
{
    printf("hehe\n");
}
int Add(int x, int y)
{
    int z = 0;
    return z = x + y;
}
int main()
{
    test(); //函数调用操作符
    int ret = Add(2, 3);
    printf("%d\n", ret);
    return 0;
}

3: 结构成员访问操作符:

#include<stdio.h>
struct stu
{
    char name[20];
    int age;
    double score;
};
int main()
{
    struct stu s = { "zhangsan", 20, 85.5 };
    // .
    printf("%s %d %.1lf\n", s.name, s.age, s.score);   // 结构体变量.结构体成员
    // ->
    struct stu* ps = &s;
    printf("%s %d %.1lf\n", (*ps).name, (*ps).age, (*ps).score);  //此方法写起来过于繁琐
    printf("%s %d %.1lf\n", ps->name, ps->age, ps->score);  //运用->可较为方便
 
}