【C语言】简单介绍进制和操作符

请添加图片描述

🌈个人主页:是店小二呀
🌈C语言笔记专栏:C语言笔记
🌈C++笔记专栏: C++笔记
🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅
请添加图片描述

请添加图片描述

本文简要介绍进制和操作符,愿能为您提供帮助!

文章目录

    • 进制和操作符
    • **二进制介绍**
    • 二级制转换为十进制
    • 十进制转换二进制
    • 二进制转换为八进制和十六进制
    • **原码、反码、补码**
    • 原码、反码、补码之间的转换
    • 移位操作符(操作数只能是整数)
    • 位操作符(操作符必须是整数)
    • 下标访问[]、函数调用()(简单过一下)
    • 优先级
    • **结合性**
    • 表达式求值
    • 整型提升
    • 算术转化

进制和操作符


二进制介绍

十进制属于一种常见的进制,它满足满十进一并且数字每一位都是0~9数字组成的。 二进制也是同理满二进一并且数字每一位都是0~1数字组成的。

:二级制、八进制、十六进制,只是数值的不同表现形式

比如

数字:15
二级制表示:1111
八进制表示:17
十进制表示:15
十六进制表示:F

##进制之间转换

关于这一点,首先知道每个进制的每一位有权重,N进制的数字从右到左是个位、十位、百位…,分为每一位权重是(N)0 ,(N)1 ,(N)2…。

二级制转换为十进制

请添加图片描述

说明:将2进制的每个位乘于对应的权重值,再全部相加

十进制转换二进制

请添加图片描述

二进制转换为八进制和十六进制

  • 八进制:八进制的数字每一位是0~7的数字,各自写成二进制,最大数字7的二进制是111,所以最多有3个2进制位就足够了

  • 十六进制:十六进制的数字每一位是0~9,a ~f各自写成二进制,最大数字f的二进制是1111,所以最多有4个2进制位就足够了

对于2进制转换为8进制和16进制时,是从2进制序列中右边低位开始向左每3(4)个2进制位会换算一个8(16)进制为,剩余不够3(4)个2进制的直接换算。

比如:

二进制转换八进制二进制:001 101 011八进制:1    5    3二进制转换十六进制二进制:0110  1011八进制:  6     b(11)

原码、反码、补码

整型的2进制表示方法有三种:原码、反码和补码

三种表示方法均有符号位和数值位两部分组成

  • 符号位:是一个二进制数的最高位(最左边的位),如果符号位为0,则表示该数为正数;如果符号位为1,则表示该数为负数
  • 数值位:除了符号位,剩余的都是数值位

原码、反码、补码之间的转换

  1. 正整数的原码、反码、补码**都是相同**

  2. 负整数的三种表示方式各不同

  • 原码:直接将数值按照正负数的形式翻译为二进制得到的就是原码
  • 反码:将原码的符号位不变,其他位依次按位取反就可以得到反码
  • 补码:反码+1就得到补码

请添加图片描述

对于整型来说:数据存放在内存中其实存放的是补码

  • 在计算机系统中,数值一律用补码来表示和存储。使用补码,可以将符号位和数值位统一处理
  • 加法和减法可以统一处理(CPU只有加法器) 此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路

移位操作符(操作数只能是整数)

左移操作数 <<

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

请添加图片描述

右移操作数 >>

移位规则:分为逻辑右移、算术右移

  1. 逻辑右移:左边用0填充,右边丢弃

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

请添加图片描述

请添加图片描述

注:对于移位运算符,不要移动负数位,这个是标准未定义的。

在位运算中,将一个数向左移动一位相当于将其乘以2;将一个数向右移动一位相当于将其除以2


位操作符(操作符必须是整数)

位操作符:``& | ^ ~`

  1. 按位与(&):有0为0,全1为1
  • 使用规则:当两个对应的二进制位,至少存在一边为0,那么结果为0,若当两边全为1,结果才是1

​ 2.按位或(|):有1为1,全0为0

  • 使用规则:当两个对应的二进制位,至少存在有一边为1,那么结果为1,若当两边全为0,结果才是0

​ 3.按位异或(^):相同为零,不同为一

  • 使用规则:当两个对应的二进制位,两边数字相同,那么结果为0,若当两边数字不相同,那么结果为1

​ 4.按位取反(~):

  • 使用规则:用于操作符的每个二进制位取反,将1转化位0,0转化位1

典型两道题:

一道变态的面试题:

题目:实现两个数的交换(不能创建临时变量)

int main()
{int a = 10;int b = 20;a = a ^ b;printf("a = %d,b = %d\n", a, b);//b=a^b^b=a^0=a;b = a ^ b;//a=a^a^b=b;a = a ^ b;printf("a = %d,b = %d", a, b);return 0;
}

小总结:

  1. ^位操作不考虑顺序问题
  2. a^a==0
  3. a^0==a

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

int main()
{int num = 15;//00000000 00000000 00000000 00001111int i = 0;int cout = 0;//计数for (i = 0; i < 32; i++){if (num & (1 << i))//00000000 00000000 00000000 00000001 一开始cout++;}printf("二进制中1的个数=%d", cout);return 0;
}

说明:利用了按位与操作符的特点,有0为0,全是1才是1

缺点:需要循环32次

优化方案:

int main()
{int num = 15;int i = 0;int count = 0;//计数while (num){count++;num = num & (num - 1);}printf("⼆进制中1的个数 = %d\n", count);return 0;
}
达到了优化的效果,但是难以想到

逗号表达式

exp1,exp2,exp3,..expN

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

使用场景:

常规写法
while (a > 0)
{a = get_val();count_val(a);
}
使用逗号表达式while (a = get_val(), count_val(a), a>0)
{
}   

注:

z=(2,3,4)//4 括号里面是表达式
z=2,3,4//2  3,4是逗号表达式

下标访问[]、函数调用()(简单过一下)

下标引用操作符

操作数:一个数组名+一个索引值

int nums[10];
nums[9]=10;
[]的两个操作数是nums和9

函数调用操作符

接收一个或者多个操作数:第一个操作数是函数名;剩余的操作数就是传递给函数的参数

void test()
{printf("hehe\n");
}int main()
{test();//这里()就是函数调用操作符
}

操作符的属性

C语言的操作符有两个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序

优先级

优先级:如果一个表达式包含多个运算符,根据与运算符的优先级判断哪个运算符先执行,并且各种运算符的优先级是不同的

3+4*5;

说明:这个表达式有加法运算符和乘法运算符。由于乘法运算符的优先级高于加法。导致先计算4*5,而不是3+4;

结合性

如果两个运算符优先级相同,优先级无法判断,这个时候就要看结合性,则根据运算符是左结合,还是右结合,决定执行顺序。

大部分运算符是左结合(从左到右执行),少数运算符是右结合(从右到左执行),比如赋值运算符

具体还是看

请添加图片描述

参考:https://zh.cppreference.com/w/c/language/operator_precedence

注意:即使有了操作符的优先级和结合性,写出的表达式依然有可能不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在潜在风险的,建议不要写出特别不负责的表达式

比如:

#include <stdio.h>
int main()
{
int i = 1;
int ret = (++i) + (++i) + (++i);
printf("%d\n", ret);
printf("%d\n", i);
return 0;
}
//尝试在linux 环境gcc编译器,VS2013环境下都执⾏,看结果。

gcc编译器运行结果:

请添加图片描述

vs2022运行结果

请添加图片描述


表达式求值

整型提升

C语言中整型算术运算总是以省缺(默认)整型类型的精度来进行。对于表达式中的字符和短整型操作数为了获得这个精度之前被转换为普通整型,这个转换称为整型提升

整型提升的意义:

  • 表达式的整型运算:CPU对应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int字节长度,同时也是CPU的通用寄存器的长度
  • 关于两个char类型的相加,在CPU执行时实际上也是先转换为CPU内整形操作数的标准长度
  • CPU(genenral-purpose CPU)是难以直接实现两个8比特直接相加运算(虽然机器指令中可能有这种字节相指令)。对此表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算

如何进行整形提升?

  • 有符号整型提升是按照变量的数据类型的符号位来提升的
  • 无符号整数提升,高位补0

负数的整型提升

char c1=-1;
//1111 1111(补码)
char为有符号类型
整型提升的时候,高位补充符号位(1)
提升结果1111 1111 1111 1111 1111 1111 1111 1111

正数的整型提升

char c2=1;
//0000 0001
char为有符号类型
整型提升的时候,高位补充符号位(0)
提升结果0000 0000 0000 0000 0000 0000 0000 0000    

例子:

int main()
{char a = 5;//00000000 00000000 00000000 00000101//00000101 - a (截断后存储到a中)char b = 127;//00000000 00000000 00000000 01111111//01111111 - b (截断后存储到b中)char c = a + b;//00000000 00000000 00000000 00000101//00000000 00000000 00000000 01111111//00000000000000000000000010000100 - a+b//10000100 - cprintf("%d\n", c);//c进行了整型提升 按符号位填充//11111111111111111111111110000100//10000000000000000000000001111011//10000000000000000000000001111100//-124//%d 是按照10进制的形式打印有符号的整型return 0;
}

算术转化

当操作符的各个操作数属于不同的类型,那么除非但其中一个操作数转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换

long double
double
float
unsigned long int
long int
unsigned int
int

如果某个操作数的类型在上面这个列表中排名靠后,那么首先要转化为另外一个操作数的类型后执行运算。
***请添加图片描述

谢谢大家的观看,这里是个人笔记,希望对你学习C有帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS实战开发-如何实现电话服务中SIM卡相关功能

介绍 本示例使用sim相关接口&#xff0c;展示了电话服务中SIM卡相关功能&#xff0c;包含SIM卡的服务提供商、ISO国家码、归属PLMN号信息&#xff0c;以及默认语音卡功能。 效果预览 使用说明&#xff1a; 1.若SIM卡槽1插入SIM卡则SIM卡1区域显示为蓝色&#xff0c;否则默认…

中国科大力作 | 高性能四旋翼无人机复杂环境自主飞行规划器

作者&#xff1a;小柠檬 | 来源&#xff1a;3DCV 在公众号「3DCV」后台&#xff0c;回复「原论文」可获取论文pdf 添加微信&#xff1a;dddvision&#xff0c;备注&#xff1a;3D高斯&#xff0c;拉你入群。文末附行业细分群 详细内容请关注3DCV 3D视觉精品课程&#xff1a;…

c语言中<string.h>的strstr与strtok函数

c语言中string.h的strstr与strtok函数 代码运行结果 代码 #include <stdio.h> #include <string.h>///1.在字符串str1里面,查找第一次出现str2的位置 //char * strstr(const char * str1,const char * str2)///2.sep为分割符,根据分割符来对str进行分割 //char * …

JUC:实现一个简易的数据库连接池(享元模式)

主要是学习享元模式。 享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;旨在通过共享尽可能多的对象来最小化内存使用和提高性能。在该模式中&#xff0c;对象被分为两种状态&#xff1a;内部状态和外部状态。 内部状态&#xff08;Intr…

13.3.1 配置 Android 开发环境(windows)

目录 1. 安装 JDK 及其环境配置 1. 安装 JDK 2. JDK 环境配置 3. JDK的配置验证 2. 安装 Android Studio (2023版本) 为了学习 Xposed 框架&#xff0c;记录安装 JDK 及其环境配置和安装 Android Studio (2023版本)。 1. 安装 JDK 及其环境配置 1. 安装 JDK 安装链接&a…

从零开始:一步步学习爬虫技术的实用指南(一)

从零开始&#xff1a;一步步学习爬虫技术的实用指南&#xff08;一&#xff09; Urllib1.什么是互联网爬虫2.爬虫核心3.爬虫的用途4.爬虫的分类4.1 通用爬虫&#xff1a;4.1 聚焦爬虫&#xff1a; 5.反爬手段5.1 User‐Agent&#xff1a;5.2.代理IP5.3.验证码访问5.4.动态加载网…

2007-2022年上市公司企业绿色创新效率数据

2007-2022年上市公司企业绿色创新效率数据&#xff08;仅结果&#xff09; 1、时间&#xff1a;2007-2022年 2、指标&#xff1a;stkcd、year、绿色科技研发效率、绿色成果转化效率 3、来源&#xff1a;上市公司年报、上市公司社会责任报告、上市公司网站信息 4、计算方法&…

代码随想录-力扣刷题-总结笔记02

代码随想录&#xff1a;代码随想录力扣&#xff1a;力扣 (LeetCode) 全球极客挚爱的技术成长平台 代码随想录-力扣刷题-总结笔记01代码随想录-力扣刷题-总结笔记02 目录 01、代码随想录 00、其他 ArrayList转数组 07、二叉树 7.0、递归法 7.1、二叉树的层序遍历模板 7.2…

(Python)根据经纬度从数字高程模型(DEM)文件获取高度

基本介绍 在地理信息系统&#xff08;GIS&#xff09;和遥感中&#xff0c;数字高程模型&#xff08;Digital Elevation Model&#xff0c;简称DEM&#xff09;是一种表示 地表或地形高程信息的重要数据。DEM数据通常以栅格&#xff08;raster&#xff09;形式存在&#xff0…

牛客 2024春招冲刺题单 ONT82 腐烂的苹果【中等 BFS Java,Go】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/54ab9865ce7a45968b126d6968a77f34 思路 广度优先搜索。首先找到2坐标集合&#xff0c;然后每次往四周为1的坐标扩展参考答案Java import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数…

【C++】用红黑树封装map和set

我们之前学的map和set在stl源码中都是用红黑树封装实现的&#xff0c;当然&#xff0c;我们也可以模拟来实现一下。在实现之前&#xff0c;我们也可以看一下stl源码是如何实现的。我们上篇博客写的红黑树里面只是一个pair对象&#xff0c;这对于set来说显然是不合适的&#xff…

基于51单片机轮胎胎压监测系统—数码管显示

基于51单片机轮胎胎压监测系统 &#xff08;仿真&#xff0b;程序&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1.MPX4115压力传感器胎压检测&#xff1b; 2.ADC0832进行模数转换后&#xff0c;51单片机处理控制&#xff1b; 3.数码管显示胎压&#xff…