学C的第十五天【操作符详解:1. 操作符分类;2. 算术操作符;3. 移位操作符;4.位操作符;5.赋值操作符;6.单目操作符;7. 关系操作符;8. 逻辑操作符】-2

简介: ^ : 按(二进制)位异或 -- 对应二进制位相同为0, 相异为1

^ :        按(二进制)位异或 -- 对应二进制位相同为0相异为1

                               

//位操作符
#include <stdio.h>
int main()
{
  int a = 3;
  // 00000000000000000000000000000011 -- 补码(正整数的原码、反码、补码相同)
  int b = -5;
  // 10000000000000000000000000000101 -- 原码
  // 11111111111111111111111111111010 -- 反码
  // 11111111111111111111111111111011 -- 补码
  int c = a ^ b;
  // ^ -- 按(二进制)位异或 -- 对应二进制位相同为0, 相异为1
  // 00000000000000000000000000000011 -- a补码
  // 11111111111111111111111111111011 -- b补码
  //        得:
  // 11111111111111111111111111111000 -- 补码(两个补码计算出来的也是补码)
  // 
  // 这里计算出来的结果符号位是 1 ,说明是 负整数,还要计算 反码 和 补码
  // 10000000000000000000000000000111 -- 反码
  // 10000000000000000000000000001000 -- 原码
  printf("%d\n", c); // 所以结果是-8
  return 0;
}

e2e81779ab1d469583a9d8e1c90a0977.png

^(按位异或) 的一些规律

               

1.         变量 ^ 变量 = 0

         

2.         0 ^ 变量 = 变量

3.         满足交换律

                 

(实例:)

//异或是支持交换律的
#include <stdio.h>
int main()
{
  int a = 3;
  int b = 5;
  printf("%d\n", a ^ a); // 0 (每一位都是相同的,32位全是0)
  printf("%d\n", a ^ 0); // a = 3
  // 011 - 3 (a)
  // 000 - 0
  // 011 -- 异或结果 :a = 3 
  printf("%d\n", a ^ b ^ a); // b = 5
  // 011 - 3 (a)
  // 101 - 5 (b)
  // 110 -- 异或结果
  // 011 - 3 (a)
  // 101 -- 异或结果 : b = 5
  printf("%d\n", a ^ a ^ b); // b = 5
  // a ^ a --> 0
  // 0 ^ b --> b = 5
  return 0;
}

4173356ff5994009a0e6260e28b8412d.png

一道变态面试题:不使用临时变量,交换两个数的值

               

(^异或 不会造成进位,所以不会产生栈溢出,但可读性不高,不易理解)

//一道变态面试题:不使用临时变量,交换两个数的值
#include <stdio.h>
int main()
{
  int a = 3;
  int b = 5;
  printf("交换前:a=%d b=%d\n", a, b);
  a = a ^ b;
  b = a ^ b;
  a = a ^ b;
  printf("交换后:a=%d b=%d\n", a, b);
  return 0;
}

653cecbcb1404dd6acfcf6559d234322.png

练习:求一个整数存储在内存中的二进制中1的个数

                   

#include <stdio.h>
int main() {
    int input = 0;
    int count = 0; //统计 1 的个数
    //输入
    scanf("%d", &input);
    int i = 0;
    for (i = 0; i < 32; i++)
    { // 共32位,判断32次
        int test = input & 1; //按位与1 取出32位最低位
        //判断是不是1
        if (test == 1) {
            count++; //是的话,统计加1
        }
        //判断下一位:
        input >>= 1; //向右移一位,继续判断,使用循环
    }
    //输出:
    printf("%d", count);
    return 0;
}

7ee9cadd4e4f44979878cc20f19aafb8.png

5.赋值操作符

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

                   

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; //选择赋值
//先把 y+1 赋给 x ,再把 x 赋给 a
//更好的写法:
x = y + 1;
a = x;
//这样写更加清晰而且方便一步步调试 

复合赋值符

             

+= :        加等

 

-= :        减等


 

*= :        乘等

 

/= :        除等

 

%= :        模等于      

>>= :        右移等

 

<<= :        左移等

 

&= :       按位与等  

|= :        按位或等

 

^= :        按位异或等

6.单目操作符

操作符只有一个操作数

           

:        逻辑反操作

(if语句、while语句中、表达式中)

       

 

- :      

(改变数字正负)

 

+ :        

(正数默认自带+,常省略,不常用)

       

 

& :        取地址

        (应用于指针)

sizeof :        操作数的类型长度(以字节为单位)

        (不是函数,是操作符;计算的是类型创建变量的大小        

 

~ :        对一个数的二进制按位取反

(对补码32个bit位按位取反,1变成00变成1,取反后还是补码,要转换为原码)

       

 

-- :        前置、后置--

常用

 

++ :        前置、后置++

常用

 

* :        间接访问操作符(解引用操作符)

(应用于指针,告诉我们哪个变量是指针变量;

解引用:通过指针变量中存放的地址,找到指向的 空间/内容 )

       

(类型) :        强制类型转换

         

           

sizeof数组

//sizeof 和 数组
#include <stdio.h>
void test1(int arr[]) 
//传过来的首元素指针 ,一个 int*类型 大小是 4个字节
{
  printf("%d\n", sizeof(arr));
}
void test2(char ch[])
//传过来的首元素指针 ,一个 char*类型 大小是 4个字节
{
  printf("%d\n", sizeof(ch));
}
int main()
{
//整型数组:
  int arr[10] = { 0 };
  printf("%d\n",sizeof(arr)); //使用 数组名
  //40 - 计算整个数组的大小、单位字节
  printf("%d\n", sizeof(int[10])); //使用数组的字符类型,包括[]和元素个数
  test1(arr);
//字符数组
  char ch[10] = { 0 };
  printf("%d\n", sizeof(ch)); //使用 数组名
  //10 -- 字符数组中 sizeof(数组名) 计算 的是 字符个数
  printf("%d\n", sizeof(int[10])); //使用数组的字符类型,包括[]和元素个数
  //40 -- 一个 char类型元素 是 4个字节,10个就是40
  test2(ch);
  return 0;
}

7cb631b34cb4469b8785dab9277457f6.png

~ 按位取反的运用,结合 & (按位与)  和  | (按位或)

                       

(将 13 的 32bit位从右往左第5位换为 1 再换为 0

//~按位取反的运用,结合 & (按位与)和  | (按位或)
//将 13 的 32bit位从右往左第5位,换为 1 ,再换为 0
#include <stdio.h>
int main()
{
  int a = 13;
  // 00000000000000000000000000001101 - 13 的 原、反、补码
  //      按位或:有1就是1
  // 00000000000000000000000000010000 - 1 << 4
  // 00000000000000000000000000011101 -- 29 的 原、反、补码
  a |= (1 << 4);
  // 这样就把第五位换成了 1 , 13 变成了 29 
  printf("%d\n", a); 
  // 再把第五位换成 0
  // 00000000000000000000000000011101 - 29 的 原、反、补码
  // 00000000000000000000000000010000 - 1 << 4
  // 11111111111111111111111111101111 - ~(1 << 4) 进行按位取反
  //      按位或:两个都是 1 才是 1
  // 00000000000000000000000000001101 -- 13 的 原、反、补码
  a &= (~(1 << 4));
  printf("%d", a);
  return 0;
}

image.png

运用 ~按位取反 实现 多组输入

//运用 ~按位取反 实现 多组输入
#include <stdio.h>
int main()
{
  int a = 0;
  // scanf 读取失败返回的是EOF
  // 假设 scanf 读取失败,返回EOF ,即 -1
  // -1 的补码:
  // 11111111111111111111111111111111
  //      ~ 按位取反后:
  // 00000000000000000000000000000000
  //      得0,条件即为假
  while (~scanf("%d", &a))
  {
    printf("%d\n", a);
  }
  return 0;
}

e5de88f6c0144001b32ab5faa82f072f.png

7. 关系操作符

不能比较字符串、自定义类型

             

> :        大于

       

 

>= :       大于等于

       

 

< :       小于

 

<= :        小于等于

       

 

!= :        不等于(用于测试“不相等”)

== :        相等(用于测试“相等”)

=:是赋值        ;        ==:是相等        

 

8. 逻辑操作符

           

&& :        逻辑与(并且:两个为真,才为真)  

feac3032f4684252aed44cd43e175aec.png

 

|| :        逻辑或(或者:多个中一个为真,就为真)

a5e5c53efef440a9a8585ba318618d1a.png

:        逻辑非

演示:判断闰年

//判断闰年
#include <stdio.h>
int main()
{
  int y = 0;
  scanf("%d", &y);
  //1. 能被4整除,并且不能被100整除
  //2. 能被400整除是闰年
  if ( ((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
  {
    printf("闰年\n");
  }
  else
  {
    printf("不是闰年");
  }
  return 0;
}

a1e475b9b1464ff5ad3e19ad3ce67020.png

(下回揭晓:)

       

9. 条件操作符

10. 逗号表达式

11. 下标引用,函数调用和结构函数

12.表达式求值

相关文章
|
7月前
|
C语言
操作符详解(3)C语言复合赋值操作符单目操作符
操作符详解(3)C语言复合赋值操作符单目操作符
|
算法 C语言
算数、赋值、单目操作符介绍
算数、赋值、单目操作符介绍
73 0
|
存储 C语言
C语言操作符[算数操作符,赋值操作符,单目操作符,移位操作符]
C语言操作符[算数操作符,赋值操作符,单目操作符,移位操作符]
|
6月前
|
编译器 C语言
C语言学习记录——操作符详解知识点选记(算术操作符、单目操作符、移位操作符、关系操作符、逻辑操作符、条件操作符......)二
C语言学习记录——操作符详解知识点选记(算术操作符、单目操作符、移位操作符、关系操作符、逻辑操作符、条件操作符......)二
53 3
|
6月前
|
存储 编译器 C语言
C语言学习记录——操作符详解知识点选记(算术操作符、单目操作符、移位操作符、关系操作符、逻辑操作符、条件操作符......)一
C语言学习记录——操作符详解知识点选记(算术操作符、单目操作符、移位操作符、关系操作符、逻辑操作符、条件操作符......)一
44 1
|
7月前
|
C语言
算术操作符、赋值操作符、复合赋值符
这篇文档介绍了算术和赋值操作符。算术操作符包括加&quot;+&quot;、减&quot;-&quot;、乘&quot;×&quot;、除&quot;/&quot;和求余&quot;%”,其中求余只适用于整数,结果正负由第一个运算数决定。赋值操作符有&quot;=&quot;用于给变量赋值,而复合赋值符如&quot;+=&quot;、&quot;-=&quot;等则结合了运算和赋值功能,简化代码编写。
41 1
|
7月前
|
存储 程序员 C语言
操作符详解1(二)
该内容是一个关于C语言操作符和结构体的教程摘要。首先提到了加法操作符`+`的使用,并给出了一种不使用临时变量交换两个数的方法。接着讨论了如何计算整数的二进制表示中1的个数,通过位操作符实现。然后介绍了逗号表达式和函数调用操作符`()`,以及结构体成员访问操作符`.`和`-&gt;`,用于访问和修改结构体内的成员变量。文章以讲解结构体的声明、初始化和通过指针访问结构体成员为重点,展示了如何直接和间接地操作结构体数据。
55 0
|
存储 编译器 C语言
【C语言初阶】带你轻松玩转所有常用操作符(1) ——算数操作符,移位操作符,位操作符
【C语言初阶】带你轻松玩转所有常用操作符(1) ——算数操作符,移位操作符,位操作符
94 0
|
7月前
|
存储 C语言
C learning_12 操作符前篇(算术操作符、移位操作符、位操作符、赋值操作符、单目操作符、关系操作符、逻辑操作符)
C learning_12 操作符前篇(算术操作符、移位操作符、位操作符、赋值操作符、单目操作符、关系操作符、逻辑操作符)
|
7月前
|
编译器 C++ 索引
C learning_13 操作符前篇(条件操作符、 逗号表达式、 下标引用、函数调用和结构成员、 表达式求值)
C learning_13 操作符前篇(条件操作符、 逗号表达式、 下标引用、函数调用和结构成员、 表达式求值)