【C语言初阶(NEW)】五、操作符详解(二)|隐式类型转换|算术转换|操作符的属性

news2024/11/27 15:42:24

目录

一、表达式求值

1.1 隐式类型转换

1.1.1 什么是整型提升(整型提升)

1.1.2 整型提升的意义

1.1.3 有符号(signed)与无符号(unsigned)的区别

1.1.4 有符号(signed)类型的整型提升

1.1.5 无符号(unsigned)整形提升

1.1.6 整型提升例子

1.2 算术转换

1.3 操作符的属性

二、位操作符的一些例题

三、数据类型大小


一、表达式求值

        表达式求值的顺序一部分是由操作符的优先级和结合性决定。同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型

1.1 隐式类型转换

1.1.1 什么是整型提升(整型提升)

        C语言的整型算术运算总是至少以缺省整型类型的精度来进行的,为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升

1.1.2 整型提升的意义

        表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。

        因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度

        通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值都必须先转换为int或unsigned int,然后才能送入CPU去执行运算

1.1.3 有符号(signed)与无符号(unsigned)的区别

        首先在计算机中,有符号数是可以用来区分数值的正负,而无符号数仅有正值,没有负值

         其次当一个数是无符号数时,它的最高位仅用来表示该数的大小。而当一个数是有符号数时,此时的最高位称为符号位;该符号位为1时表示该数为负值,为 0 时则表示为正值

        最后有符号数和无符号数两者表示的范围不同,即同样长度的字节,有符号数比无符号数的最大值出现缩水

二者最明显的区别就是二者表示的范围不同:

  • 无符号数中,所有的位都用于直接表示该值的大小
  • 有符号数中最高位用于表示正负,所以,当为正值时,该数的最大值就会变小

1.1.4 有符号(signed)类型的整型提升

有符号类型整形提升的时候,高位补充符号位,即为 0 或 1

假设平台都是 32位 

1)正数的整形提升

char b = 1;
1 的补码是:00000000 00000000 00000000 00000001
变量b 的类型是char,二进制位(补码)中只有8个比特位(一个字节):
b 在内存中存储为:00000001(补码截取8个bit)

因为 char 为有符号的 char,如果 b 进行整型计算,就会发生整型提升
整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000 00000000 00000000 00000001

         简单说一下,char 虽然是字符类型,但字符类型储存的时候,储存的是字符的ASCII码值,ASCII值是整数,所以 char 的存储依旧与整型存储一样

        char 在我当前的编译器 vs2019 是有符号型,不同的编译器会有不同的情况,因为 char 在C语言中未定义为有符号还是无符号,有符号还是无符号取决的编译器

2)负数的整型提升


char b = -1;
-1 的补码是:11111111 11111111 11111111 11111111
变量b 的类型是char,二进制位(补码)中只有8个比特位(一个字节):
b 在内存中存储为:11111111(补码截取后8个bit)

因为 char 为有符号的 char,如果 b 进行整型计算,就会发生整型提升
整形提升的时候,高位补充符号位,即为1
提升之后的结果是:
11111111 11111111 11111111 11111111

1.1.5 无符号(unsigned)整形提升

有符号类型整形提升的时候,高位补充 0

char b = -1;
-1 的补码是:11111111 11111111 11111111 11111111
变量b 的类型是char,二进制位(补码)中只有8个比特位(一个字节):
b 在内存中存储为:11111111(补码截取后8个bit)

因为 char 为无符号的 char,如果 b 进行整型计算,就会发生整型提升
整形提升的时候,高位补 0
提升之后的结果是:
00000000 00000000 00000000 11111111

 之上简而言之,有符号与无符号的整型提升的区别就是

有符号的整型提升高位补 符号位

无符号的整型提升高位补 0

1.1.6 整型提升例子

例子1: 

测试代码

#include <stdio.h>
 
int main()
{
	char a = 3;
	char b = 127;
	char c = a + b;
	printf("%d\n", c);
 
	return 0;
}

运行结果是:-126

原因解释如下:

首先,我们先看 3是一个整型,占 4 个字节,32 个bit位;127 也是如此,占4个字节 

3 和 127 的二进制原码的补码

  3的补码:00000000 00000000 00000000 00000011
127的补码:00000000 00000000 00000000 01111111
(正数的原、反、补相同)

        int类型是 4 个字节,32 个bit位,而char类型只能储存 1 个字节,也就是 8 个 bit 位,所以 char 会发生截断,即选择 32 位中的最低位放入 char 中,也就是后八位

所以 3 和 127 在char类型中只能储存 8 个 bit,如下(补码)

  3:00000011
127: 01111111

接下来 a 和 b 是如何相加的

        a 和 b自身的大小都是8个比特位占一个字节(char类型),没有达到一个整型的大小(4字节)。在计算时为了能够提升计算精度,要将a和b整型提升

整型提升是按照变量的数据类型的符号位来进行提升的

a 和 b,a 和 b 现在是有符号的字符型变量,最高位0是它的符号位。高位通通补0,补全32个比特位

a整型提升前:00000011 //最高位的0是它的符号位
a整型提升后:00000000 00000000 00000000 00000011
b整型提升前:01111111 //最高位的0是它的符号位
b整型提升后:00000000 00000000 00000000 01111111

 整型提升后 a 和 b 进行二进制相加,结果为

a+b:00000000 00000000 00000000 10000010

现在要将结果放入 c 中,而c又是 char 型,又要发生截断

c:100000010

 此时还不能直接打印输出,因为 printf 函数中是以 %d 的形式进行打印,又要对 c 进行整型提升

c 的类型是有符号字符型,最高位 1 为他的符号位,高位通通补1,补全32个比特位

c整型提升前:10000010
c整型提升后:11111111 11111111 11111111 10000010

此时 c 得到的是补码,还要反推原码才能打印

c的补码:11111111 11111111 11111111 10000010
c的反码:11111111 11111111 11111111 10000001
c的原码:10000000 00000000 00000000 01111110

接下来二进制转换成十进制就可以打印 c 了,结果是 -126

例子2:

测试代码

#include <stdio.h>
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;
}

运行结果

解释: 

        a,b要进行整形提升,但是c不需要整形提升;a,b整形提升之后,变成了负数,所以表达式 a==0xb6 , b==0xb600 的结果是假,但是c不发生整形提升,则表达式 c==0xb6000000 的结果是真,所以最后打印 c

例子3:

#include <stdio.h>
int main()
{
	char c = 1;
	printf("%d\n", sizeof(c));
	printf("%d\n", sizeof(+c));
	printf("%d\n", sizeof(-c));
	return 0;
}

 运行结果

解释:

        c 只要参与表达式运算,就会发生整形提升,表达式 +c 就会发生提升,所以 sizeof(+c) 是4个字节。表达式 -c 也会发生整形提升,所以 sizeof(-c) 是4个字节,但是 sizeof(c) ,就是1个字节

 ----------------我是分割线---------------   

1.2 算术转换

        如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行

下面的层次体系称为寻常算术转换

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

如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算,简单来说就是:从下往上转换。比如,a 的类型是 int,b 的类型是 double,进行 a+b 是,int 就会转换成 double 类型,再进行计算

例如

#include<stdio.h> 
 
int main()
{
	int a = 3;
	float b = 3.5;
	float c = a + b;
	//算术转换,int-->float 
    //结果为 6.5
 
	return 0;
}

 调试查看:

注意区分:整型提升是不足 4 个字节才会发生整型提升,像 char(1字节) short(2字节)...(32位平台下),这些就会发生整型提升。如果超过了4个字节的不同类型计算,就会发生算术转换,向高位进行转换

警告:但是算术转换要合理,要不然会有一些潜在的问题

float f = 3.14;
int num = f;//隐式转换,会有精度丢失

  ----------------我是分割线---------------   

1.3 操作符的属性

复杂表达式的求值有三个影响的因素

  • 1. 操作符的优先级
  • 2. 操作符的结合性
  • 3. 是否控制求值顺序

两个相邻的操作符先执行哪个?

取决于他们的优先级,如果两者的优先级相同,取决于他们的结合性

优先级图表

 

 

 

结合性说明:N/A 意思是同级运算没有顺序要求;L-R 意思是同级运算有顺序要求,方向为自左向右;R-L 意思是同级运算有顺序要求,方向为自右向左

注意:我们写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的 

二、位操作符的一些例题

1、编写代码实现:求一个整数存储在内存中的二进制中1的个数

思路:用位操作符解决比较优,也可以使用其它方法 

int a = 3;
00000000000000000000000000000011

a&1
00000000000000000000000000000011
00000000000000000000000000000001
00000000000000000000000000000001
//>> <<

代码如下:

#include <stdio.h>
int main()
{
	int num = -1;
	int i = 0;
	int count = 0;//计数
	for (i = 0; i < 32; i++)
	{
		if (num & (1 << i))
			count++;
	}
	printf("二进制中1的个数 = %d\n", count);

	return 0;
}

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

思路:使用位操作解决

3^3 = 0 -> a^a=0
   3:011
   3:011
结果:000

0^5=5 -> 0^a = a
000
101
101

3^3^5 = 5
3^5^3 = 5
结论:异或操作符支持交换律

代码如下:

#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a = %d b = %d\n", a, b);
	return 0;
}

三、数据类型大小

char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
float //单精度浮点数
double //双精度浮点数

代码如下:

#include <stdio.h>
int main()
{
	printf("%d\n", sizeof(char));
	printf("%d\n", sizeof(short));
	printf("%d\n", sizeof(int));
	printf("%d\n", sizeof(long));
	printf("%d\n", sizeof(long long));
	printf("%d\n", sizeof(float));
	printf("%d\n", sizeof(double));
	printf("%d\n", sizeof(long double));

	return 0;
}

运行结果(32位平台)

文章就到这里 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis学习笔记②实战篇_黑马点评项目

若文章内容或图片失效&#xff0c;请留言反馈。部分素材来自网络&#xff0c;若不小心影响到您的利益&#xff0c;请联系博主删除。 资料链接&#xff1a;https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA&#xff08;提取码&#xff1a;eh11&#xff09;在线视频&#xff1a;…

知道创宇ScanA免费试用|守护网络空间内容安全生命线

《淮南子说山训》中有言&#xff0c;“众曲不容直&#xff0c;众枉不容正&#xff0c;故……众议成林&#xff0c;无翼而飞&#xff0c;三人成市虎”。随着互联网社交、即时通讯工具等社交媒体的蓬勃发展&#xff0c;大众发布、传播和获取信息的方式更加简便、渠道更为广泛。也…

安科瑞 ARCM300-Z-4G 导轨式智慧用电监控装置 猪舍无线火灾探测器

安科瑞 王晶淼/刘芳 1 概述 智慧用电在线监控装置是针对 0.4kV 以下的 TT、TN 系统设计的智能电力装置&#xff0c;具有单、三相交流电测量、四象限电能计量、谐波分析、遥信输入、遥信输出功能&#xff0c;以及 RS485 通讯或 GPRS 无线通讯功能&#xff0c;通过对配电回路的剩…

YOLO V5 详解

YOLO V5 Backbone SPPF SPP 是使用了3个kernel size不一样大的pooling 并行运算。SPPF是将kernel size为5的 pooling 串行运算&#xff0c;这样的运算的效果和SPP相同&#xff0c;但是运算速度加快。因为SPPF减少了重复的运算&#xff0c;每一次的pooling 运算都是在上一次运…

IP-guard产品相关端口和服务名称

数据库 SQL Server (SQLEXPRESS) 服务器 OCULAR V3 SERVER 中继器 OCULAR V3 MIDTIER SERVER 客户端 WINDOWS HELPER SERVICE 报表 OCULAR V3 REPORT SERVER web服务器 Ocular web server,OCULAR Console Web Service 云备份服务器 OCULAR File Cloud Backup Server,OCULAR Fil…

Java——迷你图书管理器(JDBC+MySQL+Apache DBUtils)

​ ✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;乐趣国学的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java案例…

沉睡者IT - Web3的未来在哪里?

欢迎关注沉睡者IT&#xff0c;点上面关注我 ↑ ↑ 专家说&#xff0c;web3将颠覆现在的互联网 今天我们来讨论一下&#xff0c;web3会颠覆现在的互联网呢&#xff1f; 看了小编往期的作品你应该知道&#xff0c;如果同样的作品发在web3平台上&#xff0c;你将获取到收益。 那…

【笔试强训】Day 5

&#x1f308;欢迎来到笔试强训专栏 (꒪ꇴ꒪(꒪ꇴ꒪ )&#x1f423;,我是Scort目前状态&#xff1a;大三非科班啃C中&#x1f30d;博客主页&#xff1a;张小姐的猫~江湖背景快上车&#x1f698;&#xff0c;握好方向盘跟我有一起打天下嘞&#xff01;送给自己的一句鸡汤&#x…

强化学习泛化性 综述论文阅读 A SURVEY OF GENERALISATION IN DEEP REINFORCEMENT LEARNING

强化学习泛化性 综述论文阅读摘要一、介绍二、相关工作&#xff1a;强化学习子领域的survey三、强化学习中的泛化的形式3.1 监督学习中泛化性3.2 强化学习泛化性背景3.3 上下文马尔可夫决策过程3.4 训练和测试上下文3.6 应用实例3.7 更可行泛化的其他假设3.8 备注和讨论4. 强化…

SSM整合

整合的思路是&#xff1a; 先创建spring框架 通过spring整合spring mvc 通过spring整合mybatis 工程创建 创建Maven工程–>create for archtype–>webapp 创建项目结构 在recourses目录下创建 dbconfig.properties、log4j.properties、mysqlConfig.xml、springmvc.xml、…

css3实现一个3d楼梯动画

背景 &#x1f44f;&#x1f44f;通过给出的宽/高个数&#xff0c;用css3的transform以及transform-style快速的实现一个3d楼梯&#xff0c;速速来Get吧~ &#x1f947;文末分享源代码。记得点赞关注收藏&#xff01; 1.实现效果 2.实现步骤 定义css变量&#xff1a;宽w、高…

cadence SPB17.4 - allegro - disable recent Designs list

文章目录cadence SPB17.4 - allegro - disable recent Designs list概述笔记效果备注ENDcadence SPB17.4 - allegro - disable recent Designs list 概述 和csdn同学讨论问题, 他的问题如下: cadence如何在不去掉startpage的情况下只Recent Projects呢&#xff1f;&#xff…

【能效管理】变电站综合自动化监控系统在35kV变电站中应用

摘要&#xff1a;Acrel-1000变电站综合自动化系统&#xff0c;是我司根据电力系统自动化及无人值守的要求&#xff0c;总结国内外的研究和生产的先进经验&#xff0c;专门研制出的新一代电力监控系统。本系统具有保护、遥测、遥信、遥脉、遥调、遥控功能&#xff0c;可实现无人…

Lakehouse架构指南

什么是数据湖&#xff0c;为什么需要数据湖&#xff1f; 数据湖是一种存储系统&#xff0c;具有底层数据湖文件格式及其不同的数据湖表格式&#xff0c;可存储大量非结构化和半结构化数据&#xff0c;并按原样存储&#xff0c;但没有特定用途。广泛的技术和非技术数据消费者可…

第10讲:Python列表对象查操作之通过切片获取列表中的元素

文章目录1.切片获取列表中的技术要点1.1切片获取列表中的概念总结1.2.切片的语法格式以及含义3.使用切片方法获取列表中元素3.1.定义一个原始列表列表3.2.当step步长为正数时切片的案例3.3.当step步长为负数时切片的案例3.4.使用负数索引作为切片范围4.将切片后的列表赋值给新的…

【收藏】安科瑞企业微电网能效管理系统云平台演示账号

安科瑞 李亚俊 Acrel8757 1、AcrelCloud-1000变电所电力运维云平台 网址&#xff1a;https://acrelcloud.cn/ 演示账号&#xff1a;acrel 密码:123456 2、SCADA电力监控系统 网址&#xff1a;http://scada.acrel-eem.com/ 演示账号&#xff1a;acrel 密码:…

【手把手】教你玩转SpringCloud Alibaba之Nacos Config深入

1、不同环境相同配置问题-自定义Data ID配置 在实际的开发过程中&#xff0c;项目所用到的配置参数有的时候并不需要根据不同的环境进行区分&#xff0c;生产、测试、开发环境所用到的参数值是相同的。怎么解决同一服务在多环境中&#xff0c;引用相同的配置的问题&#xff1f…

Spring Security(7)

您好&#xff0c;我是湘王&#xff0c;这是我的CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e; 有时某些业务或者功能&#xff0c;需要在用户请求到来之前就进行一些判断或执行某些动作&#xff0c;就像在Servlet中的FilterChain过滤器所做的那样&#xff0c…

A Self-Attentive model for Knowledge Tracing论文笔记

原文链接和代码链接A Self-Attentive model for Knowledge Tracing | Papers With Code motivation&#xff1a;传统方法面临着处理稀疏数据时不能很好地泛化的问题。 本文提出了一种基于自注意力机制的知识追踪模型 Self Attentive Knowledge Tracing (SAKT)。其本质是用 Tra…

我的创作二周年纪念日

我的创作二周年纪念日 文章目录我的创作二周年纪念日机缘最初成为创作者的初心:1. 自我简介2. 日常学习过程中的记录收获在创作的过程中都有哪些收获?1. 获得了多少粉丝的关注?2. 获得了多少正向的反馈&#xff0c;如赞、评论、阅读量?3. 认识和哪些志同道合的领域同行?日常…