C语言——操作符详解
目录
1.操作符的分类
2.原码、反码和补码
3.移位操作符
3.1 左移操作符
3.2 右移操作符
4.位操作符
4.1 按位与&
4.2 按位或|
4.3 按位异或^
编辑 4.4 按位取反~
4.5 应用题
4.5.1 题目:不能创建临时变量,实现两个整数的交换
4.5.2 题目:求一个整数存储在内存中的二进制中1的个数
4.5.3 题目:写一个代码,判断n是否为2的次方数
4.5.4 二进制位置0或者置1
5.单目操作符
6.逗号表达式
7.下标访问[ ]、函数调用( )
7.1 [ ] 下标引用操作符
7.2 函数调用操作符
8.结构成员访问操作符
8.1 结构体
8.1.1 结构体的声明
8.1.2 结构体的定义和初始化
9.操作符的属性:优先级和结合性
9.1 优先级
9.2 结合性
10.表达式求值
10.1 整型提升
10.2 算数转换
10.3 问题表达式解析
10.3.1 表达式1
10.3.2 表达式2
10.3.3 表达式3
10.3.4 表达式4
10.3.5 表达式5
1.操作符的分类
操作符可以分为很多类
2.原码、反码和补码
整数的二进制表示方法有三种:原码、反码和补码
有符号整数的三种表示方法均有符号位和数值位两部分,二进制序列中最高位的一位是被当做符号位,剩余的都是数值位;符号位都是用0表示“正”,用1来表示“负”。
正整数的三码均相同;
负整数的三种表示方法不同。
原码:直接翻译成二进制的就是原码
反码:符号位不变,其他位次依次取反
补码:反码加1就得到补码
补码得到原码可以用——取反,+1的操作
对于整数来说,数据存放内存中其实存放的是补码
3.移位操作符
移动的是存储在内存中二进制位(即补码)
<<为左移操作符
>>为右移操作符
3.1 左移操作符
规则:左边遗弃,右边补0
例如:
#include<stdio.h>
int main()
{int a = 10;int b = a << 1;printf("a=%d\n", a);printf("b=%d\n", b);return 0;
}
运行结果为:
分析:根据规则,a不变,其二进制表示为1010,而b为a的基础上在最后加了一个0,则b为10100
3.2 右移操作符
运算分为两种:
1.逻辑右移:左边用0填充,右边丢弃
2.算数右移:左边用原该值的符号位填充,右边丢弃
右移到底采用哪一种方法,取决于编译器,通常是采用算数右移
4.位操作符
位操作符有四种:
1. & 按位与
2.| 按位或
3.^ 按位异或
4.~ 按位取反
注意:他们的操作数必须为整数
4.1 按位与&
运算规则:有0为0,全1为1
例如:
int main()
{int a = 6;//00000000000000000000000000000110 ->6的补码int b = -7;//10000000000000000000000000000111 ->-7的原码//11111111111111111111111111111000 ->-7的反码//11111111111111111111111111111001 ->-7的补码//00000000000000000000000000000110 ->6的补码//00000000000000000000000000000000 ->&之后,因此为0int c = a & b;printf("c = %d\n", c);return 0;
}
根据推算,我们可以得到c为0,则运行结果为:
则可以知道推算结果正确。
4.2 按位或|
运算规则:有1为1,全0为0
例如:
int main()
{int a = 6;//00000000000000000000000000000110 ->6的补码int b = -7;//10000000000000000000000000000111 ->-7的原码//11111111111111111111111111111000 ->-7的反码//11111111111111111111111111111001 ->-7的补码//00000000000000000000000000000110 ->6的补码//11111111111111111111111111111111 ->|之后//10000000000000000000000000000000//10000000000000000000000000000001 ->因此为-1int c = a | b;printf("c = %d\n", c);return 0;
}
运行结果为:
因此,我们可以知道,推算结果是正确的。
4.3 按位异或^
运算规则:相同为0,相异为1
例如:
int main()
{int a = 6;//00000000000000000000000000000110 ->6的补码int b = -7;//10000000000000000000000000000111 ->-7的原码//11111111111111111111111111111000 ->-7的反码//11111111111111111111111111111001 ->-7的补码//00000000000000000000000000000110 ->6的补码//11111111111111111111111111111111 ->^之后//10000000000000000000000000000000//10000000000000000000000000000001 ->因此为-1int c = a ^ b;printf("c = %d\n", c);return 0;
}
运行结果为:
4.4 按位取反~
与前三个不同的是,~操作符是单目操作符
例如:
int main()
{int a = 0;printf("%d\n", ~a);//00000000000000000000000000000000//11111111111111111111111111111111//10000000000000000000000000000000//10000000000000000000000000000001//所以最终结果为-1return 0;
}
运行结果为:
4.5 应用题
4.5.1 题目:不能创建临时变量,实现两个整数的交换
方法一:
int main()
{int a = 3;int b = 5;//实现过程printf("交换前:a = %d, b = %d", a, b);a = a + b;b = a - b;a = a - b;printf("交换后:a = %d, b = %d", a, b);return 0;
}
运行结果为:
这样看似是正确的,但是,我们需要注意的是int 类型是有范围的,当a和b所代表的数都很大的时候,就可能会出现问题,所以,我们还要对代码进行改进。
方法二:
运用上述的操作符来解决
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;
}
运行结果为:
我们需要记住一个结论为:a = b ^ b ^ a,即b ^ b = 0 ,0 ^ a = a
4.5.2 题目:求一个整数存储在内存中的二进制中1的个数
方法一:结合原先分别列出一个数据的方法来进行求解
int count_bit_one(unsigned int n)
{int count = 0;while (n){if ((n % 2) == 1)count++;n /= 2;}return count;
}int main()
{int num = 0;scanf("%d", &num);int ret = count_bit_one(num);printf("%d\n", ret);return 0;
}
需要注意的是:我们要注意负数的情况,因此在函数定义的时候,应该为unsigned int
方法二:运用操作符来进行解决
分析:当n & 1 == 1时, 我们可以得出32位二进位中最后一个为1
int count_bit_one(unsigned int n)
{int i = 0;int count = 0;for (i = 0; i < 32; i++){if ((n >> i) & 1 == 1)count++;}return count;
}int main()
{int num = 0;scanf("%d", &num);int ret = count_bit_one(num);printf("%d\n", ret);return 0;
}
运行结果为:
所以,我们学习了操作符的知识后,要学会把它们运用到常见的问题中
方法三:
对第二种方法进行改进——
用n = n & (n - 1)来进行循环,循环了多少次,那么n中就有几个1(此处省略证明过程,有兴趣的可以举例进行验证)
int count_bit_one(int n)
{int i = 0;int count = 0;while (n){n = n & (n - 1);count++;}return count;
}int main()
{int num = 0;scanf("%d", &num);int ret = count_bit_one(num);printf("%d\n", ret);return 0;
}
运行结果为:
4.5.3 题目:写一个代码,判断n是否为2的次方数
分析:2的次方数中,只含有一个1
因为 n & (n - 1) 是去掉一个1,因此,当 n & (n - 1) == 0 时,此时满足题意。
该题省略代码过程。
4.5.4 二进制位置0或者置1
例题:编写代码将13二进制序列的第五位修改为1,然后再改回0
int main()
{int a = 13;//00000000000000000000000000001101//00000000000000000000000000010000 ->借助这个数来得到改为1的数//00000000000000000000000000011101 ->改为1int n = 5;a = a | (1 << (n - 1));printf("%d\n", a);//00000000000000000000000000011101//11111111111111111111111111101111 ->&之后就可以得到原来的数//00000000000000000000000000001101 ->改为0a = a & ~(a << (n - 1));printf("%d\n", a);return 0;
}
运行结果为:
5.单目操作符
单目操作符常见的有:| ++ -- & * + - sizeof (类型)
单目操作符的特点是只有一个操作数。
其中单目操作符时&为取地址操作符,在指针中运用广泛。
6.逗号表达式
逗号表达式,从左到右依次执行,整个表达式的结果是最后一个表达式的结果
为了比较好理解我们给出一个例子:
int main()
{int a = 1;int b = 2;int c = (a > b, a = b + 10, a, b = a + 1);printf("%d\n", c);return 0;
}
算c的值的时候,首先执行a > b 的语句,这里没有任何值的改变,接着执行 a = b + 10,此时a的值发生改变,a的值变为12,然后执行a的语句,最后执行b = a + 1 的语句,此时b = 13,因此,最终c的值为13,我们运行一下来进行检验——
7.下标访问[ ]、函数调用( )
7.1 [ ] 下标引用操作符
操作数 :一个数组名 + 一个索引值(下标)
int arr[10];//创建数组
arr[9] = 10;//使用下标引用操作符
[ ]的两个操作数是arr和9
7.2 函数调用操作符
例如:
int main()
{printf("hello\n");//()就是函数调用操作符printf("%d \n", 1000);return 0;
}
操作数就是函数名和()中的内容,那么我们可以得出,函数调用操作符最少有一个操作数(函数名)。
8.结构成员访问操作符
8.1 结构体
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如:标量、数组、指针,甚至是其他结构体。
8.1.1 结构体的声明
struct 名字
{结构体内容
};
例如:描述一个学生可以为
struct student
{char name[20];//名字int age;//年龄double score;//成绩
};
8.1.2 结构体的定义和初始化
通过以下的代码示例,我们来了解一下结构体的定义和初始化
struct student
{char name[20];//名字int age;//年龄double score;//成绩
}s4, s5, s6;//第一种定义方式struct student s3;//第二种定义方式int main()
{int a;struct student s1 = { "zhangsan", 20, 98.50 };//第三种定义方式struct student s2 = { "lisi", 35, 91.98 };//初始化方式return 0;
}
其中,第一种和第二种方法定义的变量为全局变量。
结构体方面的知识点在后续会有专门的补充,今天我们先简单了解一下~
9.操作符的属性:优先级和结合性
这两个属性决定了表达式求值的计算顺序。
9.1 优先级
各种运算符的优先级是不一样的,相邻操作符中,优先级高的先进行计算。
例如:
int main()
{int r = 3 + 4 * 5;printf("%d\n", r);return 0;
}
在上述的操作符中‘*’的优先级大于‘+’,所以应该先计算4 * 5 这一部分。
关于优先级,我们可以在网上搜索相应的规则和知识,这里就不再赘述。
9.2 结合性
相邻的操作符的优先级相同的情况下,由结合性来决定。
10.表达式求值
10.1 整型提升
C语言中,整型算数运算总是至少以默认整型类型的精度进行的,为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
例如:
int main()
{char a = 20;char b = 130;char c = a + b;printf("%d\n", c);return 0;
}
此时,就把a和b转换为了普通整型来进行运算。
意义:CPU内的整型运算器(ALU)的操作数的字节长度和int相同,也是CPU的通用寄存器长度。表达式中各种长度可能小于Int长度的整型值,都必须先转换为unsigned int 或者Int,才能送入CPU进行运算。
如何进行整型提升呢?
1.有符号的整数提升是按照变量的数据类型的符号位来提升的
2.无符号整数提升,高位补0
10.2 算数转换
算数转换讨论的就是类型大于等于整型类型的类型,如long double、double、float、long int、int等类型的数据。
下面的层次为寻常算数转换:
1 long double
2 double
3 float
4 unsigned long int
5 long int
6 unsigned int
7 int
为从下到上进行转换。
10.3 问题表达式解析
10.3.1 表达式1
a * b + c * d + e * f
在这个表达式中,只能确定 * 的计算比 + 的早,但是优先级并不能决定第三个 * 比第一个 + 早执行。
10.3.2 表达式2
c + --c;
这时,前一个c中存的数不确定是原来的,还是--之后的。
10.3.3 表达式3
表达式过于复杂,影响可读性。
例如:
i = i-- - --i * (i = -3) * i++ + ++i
经过运行,我们可以发现在不同的编译器中,所得到的结果不同,这样代码本身就存在问题。
10.3.4 表达式4
int fun()
{static int count = 1;return ++count;
}int main()
{int answer;answer = fun() - fun() * fun();printf("%d\n", answer);return 0;
}
这时,存在的问题是,我们不知道fun( )所调用出来的数赋值在哪里。
10.3.5 表达式5
int main()
{int i = 1;int ret = (++i) + (++i) + (++i);printf("%d\n", ret);printf("%d\n", i);return 0;
}
这时代码也存在问题,我们不知道 ret 中 i 进行了几次自增。
在不同的编译器中,所得到的结果也是不一样的。所以,这个代码是存在问题的。
所以——即使我们知道了操作符的优先级和结合性,我们写出的代码也是存在风险的,因此,我们最好不要写过于复杂的表达式,既影响了可读性,也容易出错。
今天就到这里,我们下个知识点见~
相关文章:
C语言——操作符详解
目录 1.操作符的分类 2.原码、反码和补码 3.移位操作符 3.1 左移操作符 3.2 右移操作符 4.位操作符 4.1 按位与& 4.2 按位或| 4.3 按位异或^ 编辑 4.4 按位取反~ 4.5 应用题 4.5.1 题目:不能创建临时变量,实现两个整数的交换 4.5.2 …...
【Linux】内核全量函数添加日志打印摸索
1、操作系统在空载时要把函数调用次数非常多的注释掉,这里打印时不能带进程名称,高执行概率函数不同进程执行到的概率也很高,不然操作业务会增加卡死的概率; 2、卡死一般是调用次数太多导致,会卡住操作系统十多秒&…...
24/8/17算法笔记 CQL算法离线学习
离线学习:不需要更新数据 CQL(Conservative Q-Learning)算法是一种用于离线强化学习的方法,它通过学习一个保守的Q函数来解决标准离线RL方法可能由于数据集和学习到的策略之间的分布偏移而导致的过高估计问题 。CQL算法的核心思想…...
C++第十一弹 -- STL之List的剖析与使用
文章索引 前言1. list的介绍2 list的使用2.1 list的构造函数2.2 iterator的使用2.3 list capacity2.4 list element access2.5 list modifiers 3. list的迭代器失效4. list与vector的对比总结 前言 本篇我们旨在探讨对于STL中list的使用, 下一篇我们将会对list进行底层剖析以及…...
物流快递外卖管理平台系统-计算机毕设Java|springboot实战项目
🍊作者:计算机毕设匠心工作室 🍊简介:毕业后就一直专业从事计算机软件程序开发,至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长:按照需求定制化开发项目…...
开源BaaS 平台介绍
以下是几款常见的开源后端平台,它们提供了用户管理、权限验证、文件存储、API 管理等类似的后端功能。 1. Parse Server 简介: Parse 是一个非常流行的开源后端服务平台,它最初由 Facebook 开发,后来开源。它支持用户管理、数据存储、文件存…...
分享一个基于python爬虫的“今日头条”新闻数据分析可视化系统(源码、调试、LW、开题、PPT)
💕💕作者:计算机源码社 💕💕个人简介:本人 八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题可以一起交流&…...
QT自定义信号槽
1.自定义信号槽 使用connect()可以让我们连接系统提供的信号和槽,同时也可以自定义信号槽。 例如以学生和老师构建类同时当老师触发信号下课同学收到信号执行“吃饭”这一动作代码示例 #include "SignalAndSlot.h" //Teacher Student 总框架…...
one-shot 序列图像红外小目标分割
one-shot 序列图像红外小目标分割 IEEE TRANSACTIONS ON GEOSCIENCE AND REMOTE SENSING 代码还未开源 GitHub - D-IceIce/one-shot-IRSTS few-shot:利用少量标注样本进行学习 one-shot: 属于few-shot的特殊情况,只用一个样本进行学习 zero-shot&am…...
JavaScript 单线程防阻塞的原理
JavaScript 是一种单线程语言,这意味着它一次只能执行一个任务。这种设计可能会导致一些问题,比如当遇到耗时的操作时,整个程序可能会被阻塞。为了解决这个问题,JavaScript 使用了事件循环和回调函数的机制,实现了非阻塞式的异步操作。 事件循环 JavaScript 有一个事件队列,用…...
Shell脚本发送邮件的详细步骤与配置方法?
Shell脚本发送邮件的进阶技巧?怎么配置Shell脚本发信? 使用Shell脚本发送邮件是一种高效的自动化手段,特别是在需要定期发送报告、通知或警告信息时。AokSend将详细介绍Shell脚本发送邮件的步骤与配置方法,帮助您更好地掌握这一技…...
如何把Phalcon 集成到PhpStorm里面
一 背景 按照上一篇文章里面写的Phalcon 创建项目过程中的一些坑, 最终我们在终端可以基于Phalcon命令创建对应的开发项目。但在这个过程中,存在一个问题:那就是写代码的时候,发现Phalcon对应的依赖提示都没有,如下: 从上面这个截图来看,就能发现,Phalcon的啥…...
python从入门到精通:循环语句
目录 前言 1、while循环的基础语法 2、while循环的嵌套 3、for循环的基础语法 range语句: for循环临时变量作用域: 4、for循环的嵌套 5、循环中断:break和continue 前言 循环普遍存在于日常生活中,同样,在程序中…...
Codeforces Round 965 (Div. 2)
前言 有人在过七夕,我在打 cf ,还有某人独自一人在学校机房,凌晨一点骑上共享单车回宿舍欣赏沿途的秋风扫落叶。 Standings:2166 题目链接:Dashboard - Codeforces Round 965 (Div. 2) - Codeforces A. Find K Distin…...
Win10下载安装Mysql服务
Win10下载安装MySQL 一、官网下载MySQL 1.官网地址: https://www.mysql.com/ 2.在官网首页拉到最下方,点击MySQL Community Server: 3.根据个人电脑的操作系统选择,此处以Windows x64为例,选择第2个,点击…...
MVVM(Model-View-ViewModel)架构模式
在Android开发中,MVVM(Model-View-ViewModel)架构模式已经成为构建可维护和可扩展应用程序的重要选择。MVVM模式通过分离视图(View)、模型(Model)和视图模型(ViewModel)来…...
C#MVC返回DataTable到前端展示。
很久没写博客了,闭关太久,失踪人口回归,给诸位道友整点绝活。 交代下背景:要做一个行转列的汇总统计,而且,由于是行转列,列的数量不固定,所以,没法使用正常的SqlSugar框…...
HttpUtils工具类(二)Apache HttpClient 5 使用详细教程
目录 一、Apache HttpClient 5介绍 (1)核心特性 (2)Apache HttpClient 5 的新特性 (3)在 Java 项目的主要使用场景及缺点 使用场景: 缺点: 二、在实际项目中的应用 …...
Vue3.0生命周期钩子(包含:Vue 2.0 和 Vue 3.0)
1、Vue 2.0 生命周期钩子 每个应用程序实例在创建时都有一系列的初始化步骤。例如,创建数据绑定、编译模板、将实例挂载到 DOM 并在数据变化时触发 DOM 更新、销毁实例等。在这个过程中会运行一些叫做生命周期钩子的函数,通过这些钩子函数可以定义业务逻…...
遥感之常用各种指数总结大全
目前在遥感领域基本各种研究领域都会用到各种各样的指数,如水体指数,植被指数,农业长势指数,盐分指数,云指数,阴影指数,建筑物指数,水质指数,干旱指数等等众多。 本文对上…...
【C++】C++11新增特性
目录 C11简介: 1、统一的列表初始化: std::initializer_list 2、自动类型推导: auto: decltype: 3、final 和 override final: override: 4、默认成员函数控制: 显示缺省…...
【LeetCode每日一题】——662.二叉树最大宽度
文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 广度优先搜索 二【题目难度】 中等 三【题目编号】 662.二叉树最大宽度 四【题目描述】 给…...
第二十三节、血量更新逻辑的实现
一、创建代码 引入命名空间 using UnityEngine.UI; 调用UI必须有这个代码 二、ScriptObject类 1、是一个持久化存储文件的类型 接收所有的事件方法 先继承SO类,然后创建项目菜单 2、进行订阅 放入事件类,关联代码,即可进行广播 传递给这…...
Spring Authorization Server 认证服务器搭建
Spring Authorization Server实现了oauth2和oidc,最近有了解相关技术的需求,所以就尝试着进行了基本的环境搭建和技术测试,目前只测试了授权码模式,做一个记录,后续需要用时方便查找和参考。 1. 版本要求 Spring Authorization Server 版本:1.3.1 JDK 版本:17 Spring B…...
秋招突击——8/15——知识补充——垃圾回收机制
文章目录 引言正文指针引用可达性分析算法垃圾回收算法标记清除算法标记整理算法复制分代收集 垃圾收集器Serial收集器ParNew并行收集器Parallel Scavenge吞吐量优先收集器Serial Old老年代收集器Parallel old收集器CMS收集器G1收集器(Garbage First垃圾优先&#x…...
【iOS】UITableViewCell的重用问题解决方法
我自己在实验中对cell的重用总结如下: 非自定义Cell和非自定义cell的复用情况一样: 第一次加载创建tableView的时候,是屏幕上最多也显示几行cell就先创建几个cell,此时复用池里什么都没有开始下滑tableView,刚开始滑…...
开发一个微信小程序商城需要哪些技术栈
开发一个小程序商城需要掌握以下技术栈: 前端技术:包括HTML、CSS和JavaScript,用于定义商城的页面结构、样式设计和交互功能。 微信小程序专用技术:如WXML、WXSS、JavaScript和JSON,用于描述小程…...
望繁信科技荣膺上海市浦东新区博士后创新实践基地称号
近日,上海望繁信科技有限公司(简称“望繁信科技”)凭借在大数据流程智能领域的卓越表现,成功入选上海市浦东新区博士后创新实践基地。这一荣誉不仅是对望繁信科技创新能力和技术实力的高度认可,也标志着公司在推动产学…...
Nginx--代理与负载均衡(扩展nginx配置7层协议及4层协议方法、会话保持)
前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 一、代理原理 1、反向代理产生的背景 单个服务器的处理客户端(用户)请求能力有一个极限,当接入请求过多时&#…...
Ubuntu20.4 系统安装后无wifi图标
0. 问题排查 1.检查 BIOS 设置: 有时候,无线网卡可能在 BIOS 中被禁用。重启电脑,进入 BIOS 设置,确保无线网卡选项是启用的。 2.检查硬件开关: 检查您的笔记本电脑是否有物理开关或键盘快捷键来启用或禁用无线网卡。 3.在软件更新中切换…...
网站哪些付款二维码是怎么做的/太原做网站推广的公司
本章介绍了数组和指针。数组和指针所提供的功能类似于标准库的 vector 类与string 类和相关的迭代器所提供。我们可以把vector 类型理解为更灵活、更容易管理的数组,同样,string 是 C 风格字符串的改进类型,而 C 风格字符串是以空字符结束的字…...
有什么网站是做中式酒店大堂的/seo优化什么意思
1、用JS判断你的显示器分辨率:var iWidth window.screen.availWidth; var iHeight window.screen.availHeight; ,获取长与宽两个参数,将这两个参数赋给第二层的Div,作为他的长与宽的像素值,这样的话,无论…...
怎么做干果网站/电商seo优化是什么
以下是 PHP 代码示例,用于从 MySQL 数据库导出数据到 Excel 文件: <?php // 连接数据库 $conn = mysqli_connect("hostname", "username", "password", "database_name");// 检查连接是否成功 if (!$conn) {die("连接失败:…...
建设雅马哈电动车官方网站/推广普通话的意义
tr属性bgcolor,行的背景颜色。但是HTML 4.01中不赞成使用这种属性,要用CSS进行代替。<tr style "background-color:red"> td属性,跨列:colspan。以后这么,关于什么的标签直接找寻,看里面…...
长链接缩短在线生成/优化师是干嘛的
说到降噪耳机,大家第一想到的可能是苹果AirPods Pro和索尼的1000XM3(降噪豆)。囿于技术和成本,目前能够运用主动降噪技术且技术成熟度高的一般都是一些千元级高端耳机,但千元以下就没有“大牌平替”吗?捂紧…...