整型提升+算术转换——“C”
各位CSDN的uu们你们好呀,今天小雅兰的内容是之前操作符那篇博客中没有讲完的内容,整型提升这个小知识点也非常重要,那现在,就让我们进入操作符的世界吧
隐式类型转换
算术转换
操作符的属性
隐式类型转换
表达式求值的顺序一部分是由操作符的优先级和结合性决定。
同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。
C的整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
这一规则是由C语言的发明人丹尼斯·里奇与肯·汤普逊创设的:
"A character, a short integer, or an integer bit-field, all either signed or not, or an object of enumeration type, may be used in an expression wherever an integer maybe used. If an int can represent all the values of the original type, then the value is converted to int; otherwise the value is converted to unsigned int. This process is called integral promotion."
这段话的大意是:表达式中可以使用整数的地方,就可以使用枚举类型,或有符号或无符号的字符、短整数、整数位域。如果一个int可以表示上述类型,则该值被转化为int类型的值;否则,该值被转化为unsigned int类型的值。这一过程被称作integral promotion。
整型提升的意义:
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度 一般就是int的字节长度,同时也是CPU的通用寄存器的长度。
因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长 度。
通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转 换为int或unsigned int,然后才能送入CPU去执行运算。
C语言标准中仅规定了:
char的长度 ≤ short int的长度 ≤ int的长度
这意味着short int与int的长度相等的可能。这种情形下,unsigned short就无法提升为int表示,只能提升为unsigned int。
char a;
char b;
char c;
c=a+b;
b和a的值被提升为普通整型,然后再执行加法运算。
加法运算完成之后,结果将被截断,然后再存储于a中。
说了这么久整型提升,那么,究竟怎样进行整型提升呢?
整型提升是按照变量的数据类型的符号位来提升的。
int main()
{
char a=3;
//00000000000000000000000000000011——3的二进制
//但是,这是一个char类型的变量,会发生截断
//00000011——截断
char b=127;
//00000000000000000000000001111111——127的二进制
//01111111——截断
char c=a+b;
//00000011
//011111111
//整型提升
//00000000000000000000000000000011
//00000000000000000000000001111111
//相加
//00000000000000000000000010000010
//10000010——截断
printf("%d\n",c);
//但是以%d的形式打印,所以c又要发生整型提升
//按照变量的数据类型的符号位来提升
//11111111111111111111111110000010——补码
//11111111111111111111111110000001——反码
//10000000000000000000000001111110——原码
//所以最后的结果是-126
return 0;
}
//负数的整型提升char c1 = -1;//变量c1的二进制位(补码)中只有8个比特位://1111111//因为 char 为有符号的 char//所以整型提升的时候,高位补充符号位,即为1//提升之后的结果是://11111111111111111111111111111111//正数的整型提升char c2 = 1;//变量c2的二进制位(补码)中只有8个比特位://00000001//因为 char 为有符号的 char//所以整型提升的时候,高位补充符号位,即为0//提升之后的结果是://00000000000000000000000000000001//无符号整型提升,高位补0
下面,我们来看一下整型提升的具体例子
int main()
{char a = 0xb6;short b = 0xb600;int c = 0xb6000000;if(a==0xb6)printf("a");if(b==0xb600)printf("b");if(c==0xb6000000)printf("c");return 0;
}
我们会发现,打印结果最后只有c
因为:
a,b要进行整型提升,但是c不需要整型提升
a,b整型提升之后,变成了负数,所以表达式 a==0xb6 , b==0xb600的结果是假,但是c不发生整型提升,则表达式 c==0xb6000000 的结果是真
int main()
{char c = 1;printf("%u\n", sizeof(c));printf("%u\n", sizeof(+c));printf("%u\n", sizeof(-c));return 0;
}
c只要参与表达式运算,就会发生整型提升,表达式 +c ,就会发生提升,所以 sizeof(+c) 是4个字节。
表达式 -c 也会发生整形提升,所以 sizeof(-c) 是4个字节。
但是 sizeof(c) ,就是1个字节。
算术转换
大多数 C 运算符执行类型转换以将表达式的操作数引入常见类型或将较短的值扩展到计算机运算中使用的整数大小。
C 运算符执行的转换取决于特定的运算符和操作数的类型。
但是,许多运算符对整型和浮点型的操作数执行相似的转换。
这些转换称为“算术转换”。
从操作数值到兼容类型的转换会导致不改变其值。
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。
下面的层次体系称为寻常算术转换。
long double
double
float
unsigned long int
long int
unsigned int
int
如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。
- 如果任一操作数是 long double 类型,则将另一个操作数转换为 long double 类型。
- 如果上述一个条件不满足,且其中一个操作数的类型为 double,则另一个操作数被转换为 double 类型。
- 如果上述两个条件不满足,且其中一个操作数的类型为 float,则另一个操作数被转换为 float 类型。
- 如果未满足上述三个条件(所有操作数都不是浮点型),则对操作数执行整型转换,如下所示:
- 如果任一操作数是 unsigned long 类型,则将另一个操作数转换为 unsigned long 类型。
- 如果上述一个条件不满足,且其中一个操作数的类型为 long 类型,另一个操作数的类型为 unsigned int,则这两个操作数都被转换为 unsigned long 类型。
- 如果上述两个条件不满足,且其中一个操作数的类型为 long,则另一个操作数被转换为 long 类型。
- 如果未满足上述三个条件,并且任一操作数是 unsigned int类型,则将另一个操作数转换为 unsigned int 类型。
- 如果未满足上述任何条件,则将两个操作数转换为 int 类型。
但是算术转换要合理,要不然会有一些潜在的问题。
float f = 3.14;
int num = f;//隐式转换,会有精度丢失
操作符的属性
复杂表达式的求值有三个影响的因素。
1. 操作符的优先级
2. 操作符的结合性
3. 是否控制求值顺序。
两个相邻的操作符先执行哪个?
取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。
下面,我们来看看操作符的优先级,这是一张表:
在了解了操作符的优先级之后,有些人就可能会突发奇想,写出一些稀奇古怪的表达式,写出来不仅是坑自己,也是坑队友!!!
猪队友表达式1:
a*b + c*d + e*f
对于这行代码,如果仅由优先级决定这个表达式的求值顺序,那么所有三个乘法运算将在所有加法运算之前进行。事实上,这个顺序不是必需的。实际上只要保证每个乘法运算在它相邻的的加法运算之前执行即可。
这个执行顺序可能是这样的:
- a*b
- c*d
- a*b + c*d
- e*f
- a*b + c*d + e*f
还有另外一种可能是这样:
- a*b
- c*d
- e*f
- a*b + c*d
- a*b + c*d + e*f
这就是一个典型的问题表达式,写出来就是猪队友!!!
猪队友表达式2:
c + --c;
操作符的优先级规则只要求自减运算在加法运算之前进行,但我们并没有办法得知加法操作符的左操作数是在右操作数之前还是之后进行求值。它在这个表达式中将存在区别,因为自减操作符具有副作用,--c在c之前或之后执行,表达式的结果在两种情况下将会不同。
猪队友表达式3:
int main()
{
int i = 10;
i = i-- - --i * ( i = -3 ) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}
这也是一个猪队友表达式,试想:这样的表达式,写出来就是为祸人间!!!
《C和指针》的作者Kenneth A.Reek老师专门研究了这串代码,并在各种不同的编译器下运行出了各种不同的结果。
猪队友表达式4:
int fun()
{
static int count = 1;
return ++count;
}
int main()
{
int answer;
answer = fun() - fun() * fun();
printf( "%d\n", answer);//输出多少?
return 0;
}
虽然在大多数的编译器上求得结果都是相同的。
但是上述代码 answer = fun() - fun() * fun(); 中我们只能通过操作符的优先级得知:先算乘法, 再算减法。
函数的调用先后顺序无法通过操作符的优先级确定。
就是说:调用fun函数要调用3次,第一次fun函数的调用结果为2,第二次fun函数的调用结果为3,第三次fun函数的调用结果为4,但是顺序是不确定的。
- 可能是2-3*4
- 可能是3-2*4
- 可能是4-2*3
猪队友表达式5:
#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编译器,VS2022环境下都执行,看结果。
VS2022环境的结果:
这段代码中的第一个 + 在执行的时候,第三个++是否执行,这个是不确定的,因为依靠操作符的优先级和结合性是无法决定第一个 + 和第 三个前置 ++ 的先后顺序。
总结:我们写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的。
好啦,小雅兰今天的内容就到这里啦,又是一篇拖了好久的博客,小雅兰以后的时间可能就没那么多了,今天,开学考试所有的科目就都已经结束,从明天开始,就要正式上课啦,星期一第一节课就是电路分析,这是破大防了!!!小雅兰以后也会一直努力学C语言和数据结构的!!!
相关文章:
整型提升+算术转换——“C”
各位CSDN的uu们你们好呀,今天小雅兰的内容是之前操作符那篇博客中没有讲完的内容,整型提升这个小知识点也非常重要,那现在,就让我们进入操作符的世界吧 隐式类型转换 算术转换 操作符的属性 隐式类型转换 表达式求值的顺序一部…...
Freemarker介绍
2. Freemarker介绍 FreeMarker 是一个用 Java 语言编写的模板引擎,它基于模板来生成文本输出。FreeMarker与 Web 容器无关,即在 Web 运行时,它并不知道 Servlet 或 HTTP。它不仅可以用作表现层的实现技术,而且还可以用于生成 XML…...
【软件测试开发】Junit5单元测试框架
目录1. 注解Test 注解BeforeEach BeforeAllAfterEach AfterAll2. 断言 assertassertequalsassertTrue assertFalseassertNull assertNotNull3. 用例执行顺序方法排序,通过 Order 注解来排序4. 测试套件 Suite5. 参数化单参数stringsints6. 参数化多参数CsvSourceCsv…...
【C语言技能树】程序环境和预处理
Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…...
数据库的三大范式
1.为什么需要数据库设计 设计数据表的时候,要考虑很多的问题: 用户需要哪些数据,我们在数据表中要保存哪一些数据怎么保证数据表中的数据的正确性如何降低数据表的冗余度开发人员怎么才能更方便的使用数据库 如果数据库设计得不合理的话,可…...
【MT7628】开发环境搭建-Fedora12安装之后无法上网问题解决
1.按照如下图所示,打开Network Connections 2.点击Network Connections,弹出如下界面...
[Android Studio]Android 数据存储-文件存储学习笔记-结合保存QQ账户与密码存储到指定文件中的演练
🟧🟨🟩🟦🟪 Android Debug🟧🟨🟩🟦🟪 Topic 发布安卓学习过程中遇到问题解决过程,希望我的解决方案可以对小伙伴们有帮助。 📋笔记目…...
【openGauss实战9】深度分析分区表
📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…...
XSS跨站脚本攻击剖析与防御:初识XSS
目录 跨站脚本介绍 1. 什么是XSS跨站脚本 2. XSS跨站脚本实例 3. XSS漏洞的危害 XSS的分类 1. 反射型XSS 2. 持久性XSS XSS构造 1. 利用< >标记注射Html /Javascript 2. 利用HTML标签属性值执行XSS 3. 空格回车Tab 4. 对标签属性值转码 5. 产生自己的事件…...
Python 高级编程之网络编程 Socket(六)
文章目录一、概述二、Python socket 模块1)Socket 类型1、创建 TCP Socket2、创建 UDP Socket2)Socket 函数1、服务端socket函数2、客户端socket函数3、公共socket函数三、单工,半双工以及全双工通信方式的区别四、单工,半双工以及…...
centos学习记录
遇到的问题及其解决办法 centos7安装图形化界面 yum groupinstall ‘X Window System’ yum groupinstall -y ‘GNOME Desktop’ 安装完成后输入init 5进入图形化界面 centos7安装vmware-tools 第一步卸载open-vm-tools 输入命令 yum remove open-vm-tools 输入命令 reboot 在…...
为什么说网络安全是风口行业?
前言 “没有网络安全就没有国家安全”。当前,网络安全已被提升到国家战略的高度,成为影响国家安全、社会稳定至关重要的因素之一。 网络安全行业特点 1、就业薪资非常高,涨薪快 2021年猎聘网发布网络安全行业就业薪资行业最高人均33.77万&…...
12-PHP使用过的函数 111-120
111、rowCount if ($stmt->execute($data)) {//true//读:select//写:insert,update,delete,成功后会返回表中受影响的记录数量//!rowCount() 返回受影响的记录数量if ($stmt->rowCount() > 0) {echo 新增成功,id . $db->lastInsertId() . <hr>;} else {//…...
【JavaWeb项目】简单搭建一个前端的博客系统
博客系统项目 本项目主要分成四个页面: 博客列表页博客详情页登录页面博客编辑页 该系统公共的CSS样式 common.css /* 放置一些各个页面都会用到的公共样式 */* {margin: 0;padding: 0;box-sizing: 0; }/* 给整个页面加上背景 */ html, body{height: 100%; }body {backgrou…...
iPerf3 -M参数详解,场景分析
本文目录iPerf3 -M参数说明几个典型测试场景中应该如何设定合适的-M参数值理想局域网模型(无丢包,无抖动)高丢包,无抖动模型高丢包,高抖动模型(网络质量比较差,IP转发路径变化频繁)总…...
java的基本语法以及注意事项
Java 基础语法一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它…...
matlab搭建IAE,ISE,ITAE性能指标
目录前言准备IAEISEITAE前言 最近在使用matlab搭建控制系统性能评价指标模型,记录一下 准备 MATLAB R2020 IAE IAE函数表达式如下所示: IAE函数模型如下所示: ISE ISE函数表达式如下所示: ISE函数模型如下所示ÿ…...
docker安装mysql
在安装Mysql之前,我们可以先查看一下我们的镜像,输入命令: docker images 能发现,镜像里面只有一个Nginx,并没有Mysql 然后我们可以像上一篇安装Nginx一样,安装Mysql镜像。 输入以下命令,安装…...
Leetcode 回溯详解
回溯法 回溯法有“通用解题法”之称,用它可以系统地搜索问题的所有解。回溯法是一个既带有系统性又带有跳跃性的搜索算法。 在包含问题的所有解的解空间树中,按照深度优先搜索(DFS))的策略,从根结点出发深度探索解空间树。当探索…...
AI_Papers:第一期
2023.02.06—2023.02.12 文摘词云 Top Papers Subjects: cs.CL 1.Multimodal Chain-of-Thought Reasoning in Language Models 标题:语言模型中的多模式思维链推理 作者:Zhuosheng Zhang, Aston Zhang, Mu Li, Hai Zhao, George Karypis, Alex Sm…...
C/C++内存管理
C/C内存管理C/C内存分布C语言中内存管理的方式:malloc/calloc/realloc/freeC内存管理方式内置类型自定义类型operator new 与operator deletenew和delete的实现原理内置类型自定义类型定位new表达式(placement-new)new/delete与malloc/free的区别C/C内存分布 我们先…...
【大数据hive】hive 函数使用详解
一、前言 在任何一种编程语言中,函数可以说是必不可少的,像mysql、oracle中,提供了很多内置函数,或者通过自定义函数的方式进行定制化使用,而hive作为一门数据分析软件,随着版本的不断更新迭代,…...
彻底搞懂分布式系统服务注册与发现原理
目录 引入服务注册与发现组件的原因 单体架构 应用与数据分离...
安卓Camera2用ImageReader获取NV21源码分析
以前如何得到Camera预览流回调 可以通过如下方法,得到一路预览回调流 Camera#setPreviewCallbackWithBuffer(Camera.PreviewCallback),可以通过如下方法,设置回调数据的格式,比如 ImageFormat.NV21 Camera.Parameters#setPreview…...
24. 两两交换链表中的节点
文章目录题目描述迭代法递归法参考文献题目描述 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例 1: 输入&a…...
linux006之帮助命令
linux帮助命令简介: linux的命令是非常多的,光靠人是记不住的,在工作中一般都会去网上查,这是有外网的情况下,如果项目中不允许访问外网,那么linux的帮助命令就可以派上用场了, linux帮助命令是…...
【C++初阶】十三、模板进阶(总)|非类型模板参数|模板的特化|模板分离编译|模板总结(优缺点)
目录 一、非类型模板参数 二、模板的特化 2.1 模板特化概念 2.2 函数模板特化 2.3 类模板特化 2.3.1 全特化 2.3.2 偏特化 三、模板分离编译 四、模板总结(优缺点) 前言:之前模板初阶并没有把 C模板讲完,因为当时没有接触…...
Linux之文本搜索命令
文本搜索命令学习目标能够知道文本搜索使用的命令1. grep命令的使用命令说明grep文本搜索grep命令效果图:2. grep命令选项的使用命令选项说明-i忽略大小写-n显示匹配行号-v显示不包含匹配文本的所有行-i命令选项效果图:-n命令选项效果图:-v命令选项效果图:3. grep命令结合正则表…...
微信小程序Springboot 校园拼车自助服务系统java
系统管理员: 管理员账户管理:在线对管理员的账户信息进行管理,包括对管理员信息的增加修改以及密码的修改等。 站内新闻管理:在后台对站内新闻信息进行发布,并能够对站内新闻信息进行删除修改等。 论坛版块管理&#x…...
【Unity3D 常用插件】Haste插件
一,Haste介绍 Haste插件是一款针对 Unity 3D 的 Everthing软件,可以实现基于名称快速定位对象的功能。Unity 3D 编辑器也自带了搜索功能,但是在 project视图 和 Hierarchy视图 中的对象需要分别查找,不支持模糊匹配。Haste插件就…...
客户管理系统推荐/谷歌seo引擎优化
在微信公众平台机型服务器配置的时候,下图中的服务必须先在服务端跑起来,后台接口使用java开发。 authenticate控制器接口如下: /*** 验证只接受微信后台的服务请求* 开发者通过检验signature对请求进行校验。* 若确认此次GET请求来…...
做电商什么外推网站好/怎么营销推广
winR-> cmd –> 到\Inetpub\adminScripts目录-> adsutil.vbs create_vserv w3svc/i i默认为1(Default Web Site), 所以用的时候就写个>1的 然后到iis的GUI界面下去看看吧转载于:https://www.cnblogs.com/fanweixiao/archive/2009/02/03/1382788.html...
win 2012 iis 默认网站/百度推广登录平台
文章目录1 Redis 主从同步2 Redis 主从切换3 Jedis 代码测试笔记: Redis主从配置实现参考:http://blog.csdn.net/hechurui/article/details/49508813https://www.cnblogs.com/jager/p/6349860.html1 Redis 主从同步 原理 如果设置了一个从服务器&#…...
网站建设需要做的事情/免费网络营销推广软件
在PHP中,数组函数 array_uintersect_assoc () 使用用户提供的回调函数比较值,用内置的函数比较键,计算数组交集。 函数语法: array_udiff_assoc ( array $array1 , array $array2 [, array $array3... ], callable $value_compar…...
网站优化qq群/全国新冠疫情最新情况
掌握一定的英语知识,具有一定的英语水平是学习每一个专业都必备的学习计算机专业的话,并不会对英语水平作出特别的要求,因此不存在计算机专业对英语水平要求较高的这种担心,基本的英语术语掌握了就可以了。计算机专业的学习&#…...
网站备案核/磁力搜索器在线
Java 发送会议邀请到 OutlookJava 发送会议邀请到 Outlook1.发件服务器配置2.发送邮件代码3.测试代码Java 发送会议邀请到 Outlook 系统:Win10 IDE:IntelliJ IDEA 2017.3.7 JDK:1.8.0_121 Outlook:Microsoft Office 2016 1.发件服…...