C语言的操作符

前言

C语言中的操作符是用于操作变量、常量和表达式的符号,以下是我学习操作符整理的相关知识点。

操作符分类

算数操作符

算数操作符: + - * / %

  1. +-*/可以用于操作整数和浮点数
  2. %只能操作整数,返回整除后的余数

移位操作符

<< 左移操作符

>> 右移操作符

这两个只能用于整数

  1. << 操作符

    • // 往左移,左边丢掉,右边补0
      
      // 例子
      int a = 3;  // 3在内存中二进制 00000000 00000000 00000000 00000011
      a = a << 1;  // 往左移1位,左边的丢掉,右边的补0,结果为 00000000 00000000 00000000 00000110  
      // 此时a=6
      
  2. >>操作符

    • /*
      往右移,分两种情况
      	逻辑移位: 左边补0,右边丢掉
      	算数移位: 左边补原符号,右边丢掉
      
      这里还有一个知识点,就是负数在内存中是以补码的形式存在的
      以下是-7的原码,反码,补码
      原码: 第一位代表符号位
      	10000000 00000000 00000000 00000111
      反码: 右原码除了符号位,其他位取反
      	11111111 11111111 11111111 11111000
      补码: 由反码+1得到
      	11111111 11111111 11111111 11111001
      */
      
      // 例子
      int a = -7;  // -1在内存中二进制 11111111 11111111 11111111 11111001
      a = a >> 1;  // 往右移一位,通常是使用算数移位,补原符号,得11111111 11111111 11111111 11111100
      /*
      补码: 11111111 11111111 11111111 11111100   
      -1得到反码: 11111111 11111111 11111111 11111011
      取反得到原码: 10000000 00000000 00000000 00000100  -> 4
      此时a=4
      */
      

位操作符

位操作符: & | ^
位操作符只能操作整数

  • &按位与

    • /*
      使用两个数的二进制进行运算,只要有0就是0,全1才为1
      */
      
      #include <stdio.h>
      
      int main()
      {
      	int x = 2;  // 00000000 00000000 00000000 00000010
      	int y = 1;  // 00000000 00000000 00000000 00000001
      	printf("%d\n", x & y);  // 00000000 00000000 00000000 00000000 -> 0
      	
          int a = 15;  // 00000000 00000000 00000000 00001111
      	int b = 8;  // 00000000 00000000 00000000 00001000
      	printf("%d\n", a & b);  // 00000000 00000000 00000000 00001000 -> 8
      	return 0;
      }
      
  • |按位或

    • /*
      使用两个数的二进制进行运算,全0才为0,只要有1就为1
      */
      
      #include <stdio.h>
      
      int main()
      {
      	int x = 2;  // 00000000 00000000 00000000 00000010
      	int y = 1;  // 00000000 00000000 00000000 00000001
      	printf("%d\n", x | y); // 00000000 00000000 00000000 00000011  -> 3
          
      	int a = 15;  // 00000000 00000000 00000000 00001111
      	int b = 8;  // 00000000 00000000 00000000 00001000
      	printf("%d\n", a | b);  // 00000000 00000000 00000000 00001111 -> 15
      	return 0;
      }
      
  • ^ 按位异或

    • /*
      使用两个数的二进制进行运算,相同为0,不相同为1
      */
      
      #include <stdio.h>
      
      int main()
      {
          int x = 2;  // 00000000 00000000 00000000 00000010
          int y = 1;  // 00000000 00000000 00000000 00000001
          printf("%d\n", x ^ y);  // 00000000 00000000 00000000 00000011  ->  3
          
          int a = 15;  // 00000000 00000000 00000000 00001111
          int b = 8;  // 00000000 00000000 00000000 00001000
          printf("%d\n", a ^ b);  // 00000000 00000000 00000000 00000111  -> 7
          return 0;
      }
      
  • 练习题

    • 不能创建临时变量(第三个变量),实现两个数的交换

      #include <stdio.h>
      
      int main()
      {
          int a = 2;  // 00000000 00000000 00000000 00000010
          int b = 3;  // 00000000 00000000 00000000 00000011
          a = a ^ b;  // a -> 00000000 00000000 00000000 00000001  -> 1
          b = a ^ b;  // b -> 00000000 00000000 00000000 00000010  -> 2
          a = a ^ b;  // a -> 00000000 00000000 00000000 00000011  -> 3
          // 最后a=3,b=2,实现了交换
          return 0;
      }
      
    • 编写代码实现:求一个整数存储在内存中的二进制中1的个数。

      #include <stdio.h>
      
      int main()
      {
          int a = 15;  // 00000000 00000000 00000000 00001111
          int count = 0;
          while(a)
          {
              // 这里就只写后8位了
              // 第一轮: 00001111 & 00001110 -> 00001110  第二轮: 00001110 & 00001101 -> 00001100
              a = a & (a - 1);
              count += 1;
          }
          printf("%d\n", count);  // 4
          return 0;
      }
      

赋值操作符

可以随意操作变量的值

普通的赋值符 =

复合赋值符 +=、-=、*=、/=、%=、>>=、<<=、&=、|=、^=

// 复合赋值符
int a = 10;
a += 10; // 跟 a = a + 10 效果一样
a <<= 10; // 跟 a = a >> 10 效果一样

单目操作符

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

    • // 非0取反就是0,0取反就是1
      
      #include <stdio.h>
      
      int main()
      {
      	printf("%d\n", !6);  // 0
      	printf("%d\n", !0);  // 1
      	return 0;
      }
      
  • -代表负值和+代表正值

  • &取地址

    • // 获取变量的地址
      
      #include <stdio.h>
      
      int main()
      {
      	int num = 66;
      	printf("%p\n", &num); // 这里%p是打印的是地址,输出的是num在内存中的00000048F81CF884
      	return 0;
      }
      
  • sizeof计算操作符的类型长度

    • #include <stdio.h>
      
      int main()
      {
      	int num = 10;
      	printf("%d\n", sizeof(num));  // 4 因为Int类型的字节数就是4
      	printf("%d\n", sizeof num);  // 4 因为sizeof是操作符,不是函数,所以可以这样写
      	return 0;
      }
      
      // 以下是关于sizeof的一个练习,依次输出的数字是什么
      #include <stdio.h>
      
      void test1(int arr1[])
      {
      	printf("%d\n", sizeof(arr1));  // 这里输出的是内存的字节数,64位操作系统,输出8,32位则是4
      }
      
      void test2(char arr2[])
      {
      	printf("%d\n", sizeof(arr2));  // 这里输出的是内存的字节数,64位操作系统,输出8,32位则是4
      }
      
      int main()
      {
      	int arr1[10] = { 0 };
      	char arr2[10] = { 0 };
      	printf("%d\n", sizeof(arr1));  // 这里输出的是10个int类型的字节数,40
      	printf("%d\n", sizeof(arr2));  // 这里输出的是10个char类型的字节数,10
      	test1(arr1);
      	test2(arr2);
      	return 0;
      }
      
      // 所以答案是: 40 10 8 8
      
  • ~操作符

    • // 二进制按位取反
      
      int a = 1;  
      /* 
      1 -> 00000000 00000000 00000000 00000001 
      ~取反 -> 11111111 11111111 11111111 11111110  此时是负数,存的是补码,需要求出原码
      +1获得反码 -> 11111111 11111111 11111111 11111101
      取反获得原码,符号不变 -> 10000000 00000000 00000000 00000010  -> -2
      */
      printf("%d\n", ~a);  // -2
      
  • ++--

    • // ++和-- 原理一致,以下以++为例
      
      // 前置++,就是先++,后引用
      int a = 3;
      int b = ++a;
      // 最后 a -> 4 ; b -> 4
      
      // 后置++,就是先引用,后++
      int a = 3;
      int b = a++;
      // 最后 a -> 4 ; b -> 3
      
  • *间接访问操作符

    • // 一般配合&使用
      #include <stdio.h>
      
      void test(int* num)
      {
          *num = 666;
      }
      
      int main()
      {
          int num = 0;
          // 此时需要一个函数改变num的值
          test(&num);
          printf("%d\n", num);  // 666
          return 0;
      }
      
  • (类型)可以强制类型转换

    • int a = 3.16;  // 当出现将double类型赋值给int类型的变量时,编译的时候会提示3.16是double类型的,使用a来接收的话可能会丢失数据
      int a = (int) 3.16;  // 这样就不会先出警告了
      

逻辑操作符

&& 逻辑与

|| 逻辑或

  • &&逻辑与

    • // 有0则为0,全非0为1
      
      int main()
      {
      	int a = 5;
      	int b = 0;
      	printf("%d\n", a && b);  // 0
          
      	int x = 2;
      	int y = 3;
      	printf("%d\n", x && y);  // 1
      }
      
      
  • ||逻辑或

    • // 只有有非0就为1,全0才为0
      
      int main()
      {
      	int a = 5;
      	int b = 0;
      	printf("%d\n", a || b);  // 1
      
      	int x = 0;
      	int y = 0;
      	printf("%d\n", x || y);  // 0
      }
      
  • 练习题

    • 写出程序输出的结果
      #include <stdio.h>
      
      int main()
      {
      	int i = 0, a = 0, b = 2, c = 3, d = 4;
      	c = a++ && ++b && d++;
      	printf("a = %d\t b = %d\t c = %d\t d = %d\n", a, b, c, d);
      	return 0;
      }
      
      /*
      当执行到c = a++ && ++b && d++;时,此时是a++先引用后++
      c = 0 && ++b && d++;因为0与上任何数都是0,所以后面的++b和d++不会执行
      最后输出 a = 1   b = 2   c= 0   d = 4
      */
      
      // 扩展,以下输出结果是什么
      #include <stdio.h>
      
      int main()
      {
      	int i = 0, a = 0, b = 2, c = 3, d = 4;
      	c = a++ || ++b || d++;
      	printf("a = %d\t b = %d\t c = %d\t d = %d\n", a, b, c, d);
      	return 0;
      }
      
      // 这里输出是a = 1   b = 3   c= 1   d = 4
      

条件操作符

格式: exp1 ? exp2 : exp3

当exp1成立,执行exp2,否则exp3

  • 例子

    • // 请输入一个整数,如果这个整数比10大,输出比10大,反之输出小于等于10
      #include <stdio.h>
      
      int main()
      {
      	int num = 0;
      	scanf("%d", &num);
      	num > 10 ? printf("比10大\n") : printf("小于等于10\n");  // 这里使用的就是条件操作符
      	return 0;
      }
      

逗号表达式

格式: exp1, exp2, exp3, exp4

从左往右依次执行,表达式的结果是最后一个表达式的结果

  • 例子

    • int main()
      {
      	int a = 1;
      	int b = 1;
      	int c = (a++, b += a, a += b);
      	printf("%d\n", c);  // 5
      	return 0;
      }
      
      /*
      解析:
      	先是a++,a=2
      	然后b+=a,b=3
      	最后a+=b,a=5
      	所以c=5
      */
      

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

  • 下标引用操作符[]

    • 格式: 一个数组名 + 一个索引值
      #include <stdio.h>
      
      int main()
      {
      	int arr[5] = { 0 };
      	printf("%d\n", arr[2]);  // 0
      	arr[2] = 10;  // 这里使用下标引用操作符修改了数组里的元素
      	// 2[arr] = 5; 这个其实也能生效,但是不会用,其实底层是*(2+arr) = 5;
      	printf("%d\n", arr[2]);  // 10
      	return 0;
      }
      
  • 函数调用操作符()

    • 格式: 函数名+()
      int test()
      {
          return 1;
      }
      
      int main()
      {
          int num = test();  // 函数后面的()就是函数调用操作符
          return 0;
      }
      
  • 访问一个结构的成员

    • .:结构体.成员名,->:结构指针->成员

      // 定义结构体
      struct Stu
      {
      	char name[10];
      	int age;
      	char sex[5];
      };
      
      // 使用结构指针
      void set_age(struct Stu* pStu)
      {
      	pStu->age = 20;
      }
      
      // 使用结构体
      void print_age(struct Stu stu)
      {
      	printf("%d\n", stu.age);
      }
      
      int main()
      {
      	struct Stu stu;
      	set_age(&stu);
      	print_age(stu);  // 20
      	return 0;
      }
      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/16826.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

07 Kubernetes 网络与服务管理

课件 Kubernetes Service是一个抽象层&#xff0c;用于定义一组Pod的访问方式和访问策略&#xff0c;其作用是将一组Pod封装成一个服务&#xff0c;提供一个稳定的虚拟IP地址和端口号&#xff0c;以便于其他应用程序或服务进行访问。 以下是Kubernetes Service YAML配置文件的…

transformer and DETR

RNN 很难并行化处理 Transformer 1、Input向量x1-x4分别乘上矩阵W得到embedding向量a1-a4。 2、向量a1-a4分别乘上Wq、Wk、Wv得到不同的qi、ki、vi&#xff08;i{1,2,3,4}&#xff09;。 3、使用q1对每个k&#xff08;ki&#xff09;做attention得到a1,i&#xff08;i{1,2,3,4…

项目经理在项目中是什么角色?

有人说&#xff0c;项目经理就是一个求人的差事&#xff0c;你是在求人帮你做事。 有人说&#xff0c;项目经理就是一个与人扯皮的差事&#xff0c;你要不断的与开发、产品、测试等之间沟通、协调。 确实&#xff0c;在做项目的时候&#xff0c;有的人是为了完成功能&#x…

( 数组和矩阵) 769. 最多能完成排序的块 ——【Leetcode每日一题】

❓769. 最多能完成排序的块 难度&#xff1a;中等 给定一个长度为 n 的整数数组 arr &#xff0c;它表示在 [0, n - 1] 范围内的整数的排列。 我们将 arr 分割成若干 块 (即分区)&#xff0c;并对每个块单独排序。将它们连接起来后&#xff0c;使得连接的结果和按升序排序后…

1. 先从云计算讲起

本章讲解知识点 什么是云计算&#xff1f; 为什么要用云计算&#xff1f; 物理服务器与云服务器对比 云计算服务类型 云计算部署类型 1. 什么是云计算&#xff1f; 云计算是一种通过计算机网络以服务的方式提供动态可伸缩的虚拟化资源的计算模式。按照服务层次分为IaaS、…

Nautilus Chain 测试网第二阶段,推出忠诚度计划及广泛空投

随着更多的公链底层面向市场&#xff0c;通过参与早期测试在主网上线后获得激励成为了行业的一个热点话题&#xff0c;在 Apots、Arbitrum One、Optimism等陆续发放了测试空投后&#xff0c;以 Layer3为主要特性的 Nautilus Chain 也在前不久明确表示将会有空投&#xff0c;引发…

ESP8266_RTOS_SDK之SPIFFS

需要在ESP8266的FLASH中存储一些可变参数&#xff0c;有两种方式&#xff0c;一种是调用SPI Flash API直接指定地址读写FLASH&#xff1b;二是在SPI FLASH上创建一块SPIFFS 分区&#xff0c;以读写文件的形式存取数据。 下面记录第二种方式&#xff0c;使用SPIFFS文件系统存取…

【Unity入门】20.三维向量

【Unity入门】三维向量 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity入门系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;空间向量 &#xff08;1&#xff09;什么是三维向量 为什么会有这么一篇博客呢&#xff1f;主要是三维向量在unity中…

数据库之事务隔离级别详解

事务隔离级别详解 一、事务的四大特性&#xff08;ACID&#xff09;1. 原子性(atomicity)&#xff1a;2. 一致性(consistency)&#xff1a;3. 隔离性(isolation)&#xff1a;4. 持久性(durability)&#xff1a; 二、事务的四种隔离级别1. 读未提交(Read uncommitted)&#xff1…

吧佬联手抵制奸商,百元级游戏电脑横出江湖

最近小忆闲得在电商平台搜索了下关键词「游戏主机」&#xff0c;不出意外销量榜前列清一色全是「i9 级高端游戏主机」。 这些主机不论配置单介绍还是十万百万级销量宣传标语&#xff0c;都给人一种血赚不亏的「豪华」感。 咱就说时代在变&#xff0c;唯一不变的是奸商们的套路与…

指针函数和函数指针

本文目录 • 前言 • 一、返回指针的函数 二、指向函数的指针回到顶部 一、返回指针的函数 指针也是C语言中的一种数据类型&#xff0c;因此一个函数的返回值肯定可以是指针类型的。 返回指针的函数的一般形式为&#xff1a;类型名 * 函数名(参数列表) 比如下面这个函数&#…

「Codeforces」771-div2 E. Colorful Operations

E. Colorful Operations https://codeforces.com/contest/1638/problem/E 题目描述 给你一个数组&#xff0c;默认初始元素为 0 &#xff0c;颜色为 1&#xff0c;有三种操作&#xff1a; Color l r c&#xff1a;将 [l, r] 区间内的颜色修改为 cAdd c x&#xff1a;将所有颜…

SpringBoot整合Minio,一篇带你入门使用Minio

本文介绍SpringBoot如何整合Minio&#xff0c;解决文件存储问题 文章目录 前言环境搭建项目环境搭建添加依赖库yml配置 Docker安装minio 代码实现MiniConfigservicecontroller 测试 前言 参考链接&#xff1a; 官网 环境搭建 项目环境搭建 将minio单独封装成一个module&am…

LeetCode单链表OJ题目做题思路分享

目录 移除链表元素链表的中间节点链表中倒数第K个节点合并两个有序链表 移除链表元素 链接: link 题目描述&#xff1a; 思路分享&#xff1a; 我们上个博客分享了第一种方法&#xff0c;下面我们分析第二种方法&#xff1a;思路就是将每一个不等于我们要删除的值的节点依次尾…

如何快速获取已发表学术论文的期刊封面及目录(caj格式下载和caj转pdf)

目录 1 下载caj格式的封面和目录 2 CAJ格式的封面和目录转PDF格式 在进行职称评审或成果申报时&#xff0c;一般要求提交你发表的成果所在的期刊的当期封面和目录。本文就手把手带带你制作一个期刊目录。 重要提示&#xff1a;下载期刊封面和目录需要你有知网账号&#xff0…

Java读取Properties配置文件的6种方式

Java读取Properties的方式 项目结构&#xff1a;经典的maven项目结构 配置文件1和2内容一致&#xff1a; jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urlmysql://localhost:3306/database?useUnicodetrue&characterEncodingutf-8&serverTimezoneAsia/Shanghai jdbc.…

【深度学习】计算机视觉(13)——模型评价及结果记录

1 Tensorboard怎么解读&#xff1f; 因为意识到tensorboard的使用远不止画个图放个图片那么简单&#xff0c;所以这里总结一些关键知识的笔记。由于时间问题&#xff0c;我先学习目前使用最多的功能&#xff0c;大部分源码都包含summary的具体使用&#xff0c;基本不需要自己修…

找高清无水印视频素材,就上这9个网站。

推荐几个我的视频素材库&#xff0c;有免费、收费、商用&#xff0c;希望对大家有帮助&#xff01; 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYwNDUx 菜鸟图库可以找到设计、办公、图片、视频、音频等各种素材。视频素材就有上千个&#xff0c;全部都很高清&…

unityt光线透射目标

介绍 在Unity中&#xff0c;光线透射目标通常指的是在场景中放置的一些物体&#xff0c;用于模拟光线从一个物体透过到另一个物体的效果。canvas子物体组件中&#xff0c;勾不勾选“光线透射目标”有什么区别&#xff1f; 方法 在Canvas子物体组件中勾选“光线透射目标”时&…

Python基础合集 练习17(类与对象)

class Dog: pass papiDog() print(papi) print(type(papi)) 构建方法 创建类过后可以定义一个特殊的方法。在python中构建方法是__init__(),init()必须包含一个self参数 class pig(): #def__init__(self) -> None&#xff1a; print(‘你好’) pipgpig() 属性和方法 cl…
最新文章