『C语言初阶』第八章 -隐式类型转换规则

这篇具有很好参考价值的文章主要介绍了『C语言初阶』第八章 -隐式类型转换规则。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

『C语言初阶』第八章 -隐式类型转换规则,C语言初阶知识,c语言,c++
🔥博客主页 小羊失眠啦.
🔖系列专栏 C语言
🌥️每日语录但行前路,不负韶华!
❤️感谢大家点赞👍收藏⭐评论✍️


『C语言初阶』第八章 -隐式类型转换规则,C语言初阶知识,c语言,c++

前言

今天小羊又来给铁汁们分享关于C语言的隐式类型转换规则,在C语言中类型转换方式可分为隐式类型转换显式类型转换(强制类型转换),其中隐式类型转换是由编译器自动进行,无需程序员干预,今天小羊课堂说的就是关于隐式类型转换,隐式类型转换分为两种情况:整型提升和算术转换


一、隐式类型转换的规则

在c语言中,自动类型转换遵循以下规则:

  1. 若参与运算量的类型不同,则先转换成同一类型,然后进行运算。
  2. 转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算。
    a、若两种类型的字节数不同,转换成字节数高的类型
    b、若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型
  3. 所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。
  4. char型和short型参与运算时,必须先转换成int型。
  5. 在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。

二、整型提升

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

原理

有符号补符号位,无符号位无脑补0

1.负数的整型提升

高位补充符号位,即补1

char a=-1;
变量a的二进制位(补码)中只有8个比特位:
11111111
因为char是有符号的char
所以整型提升的时候,补符号位,即补1
提升结果:
11111111 11111111 11111111 11111111

2.正数的整型提升

高位补充符号位,即补0

char a=1;
变量a的二进制位(补码)中只有8个比特位:
00000001
因为char是无符号的char
所以整型提升的时候,补符号位,即补0
提升结果:
00000000 00000000 00000000 00000001

3.无符号的整型提升

无符号整型提升,高位补0(无符号只有正数)


三、整型提升实例

例1:

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

运行结果:

c=-124
d=132

分析:

char a=5
0000 0101 --> a=5
char b=127
0111 1111 --> b=127
因为参与了运算,并且char类型的精度小于int类型,所以这里进行整型提升:
00000000 00000000 00000000 00000101 --> a=5
00000000 00000000 00000000 01111111 --> b=127
00000000 00000000 00000000 10000100 --> c=132

//1:>

将结果存入类型为char的变量c中,c只能存储8位,所以保留结果最后81000 0100 --> c=132
由于char类型也是有正负的,且计算结果是以补码形式,转化为原码
补码:1000 0100
反码:1000 0011
原码:1111 1100 --> -124
原码值为-124

//2:>

运算还是先整型提升再运算,二进制同上,最后结果存放到int类型的b中,所以直接就是132

例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;
}

运行结果:

c

分析:

a=0xb6
整型提升前:10110110 
整型提升后:11111111 11111111 11111111 10110110 可以直接看出这是一个负数的补码
b=0xb600
整型提升前:10110110 00000000
整型提升后:11111111 11111111 10110110 00000000 可以直接看出这也是一个负数的补码
c=0xb6000000
无需整型提升,故结果为真

例3:

#include<stdio.h>
int main()
{
	char c = 1;
	printf("c=%u\n", sizeof(c));//%u按无符号整形unsigned int打印
	printf("c=%u\n", sizeof(+c));
	printf("c=%u\n", sizeof(-c));
	return 0;
}

运行结果:

c=1
c=4
c=4

分析:

sizeof(c),c没有参与运算,故就是求char类型大小
sizeof(+c)sizeof(-c),c参与运算,整型提升为int,故就是求int类型大小

四、算术转移

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

//从高到低
long double
double
float
unsigned long int
long int
unsigned int
int

注:
如果在同一运算中操作数类型不同,等级低的要往等级高的转换。
算术转换要合理,否则会存在潜在的问题

例1:

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

例2:

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

运行结果:

a = 254

分析:

b和c的值都需要提升为整型,再执行加法运算

b\c:>
整型提升前:11111111
整型提升后:11111111 11111111 11111111 11111111

 11111111 11111111 11111111 11111111 --> b
 11111111 11111111 11111111 11111111 --> c
111111111 11111111 11111111 11111110 --> a
 结果保留最后的811111110 --> 补码
 由于是无符号char类型,那么原反补一样
 原码也是11111110 即为254

总结

发生转换的原因:
硬件:CPU寄存器的比特位是统一的,将内存中的数据放入寄存器中就会发生隐式转换
软件:C语言的操作符对多个操作数进行操作时,必须保证其类型一致


五、操作符的属性

1.操作符

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

  1. 操作符的优先级。决定了有多个操作符和多个操作数时,先执行哪部分。
  2. 操作符的结合性。当优先级相同,多个或单个操作符之间从左向右执行还是从右向左执行。
  3. 是否控制求值顺序。特定的某些表达式在进行求值,根据不同的条件产出不同的求值过程。

两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。

2.操作符优先级

操作符优先级,从上往下,重点的

操作符 结合性 是否控制求值顺序
() N/A
, L-R
-> L-R
++ L-R
L-R
++ R-L
R-L
* R-L

3.问题表达式

表达式1

a*b + c*d + e*f

注释:代码1在计算的时候,由于乘法的优先级比+的优先级高,只能保证的乘法计算是比+早,但是优先级并不能决定第三个*比第一个+早执行。

所以表达式的计算机顺序就可能是:

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

非法表达式1

int main()
{
	int i = 10;
	i = i-- - --i * (i = -3) * i++ + ++i;
	printf("i = %d\n", i);
	return 0;
}

非法表达式2

int fun()
{
     static int count = 1;
     return ++count; }
int main()
{
     int answer;
     answer = fun() - fun() * fun();
     printf( "%d\n", answer);//输出多少?
     return 0; }

这两个表达式,铁汁们要好好思考这为什么是非法的,不懂得可以私信小羊哦

总结:

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


好了,今天小羊分享的C语言的隐式类型转换规则就讲到这里了,欢迎大家评论区留言~~

『C语言初阶』第八章 -隐式类型转换规则,C语言初阶知识,c语言,c++文章来源地址https://www.toymoban.com/news/detail-647284.html

到了这里,关于『C语言初阶』第八章 -隐式类型转换规则的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java核心知识点1-java和c++区别、隐式和显示类型转换

    java和c++区别 java通过虚拟机实现跨平台特性,但c++依赖于特定的平台。 java没有指针,它的引用可以理解为安全指针,而c++和c一样具有指针。 java支持自动垃圾回收,而c++需要手动回收。 java不支持多重继承,只能通过实现多个接口来达到相同目的,而c++支持多继承。  隐式(

    2024年02月03日
    浏览(48)
  • 【C语言】表达式求值相关问题汇总—>隐式类型转换(整型提升)、算数转换与操作符优先级汇总(收藏查阅)

     👀 樊梓慕: 个人主页   🎥 个人专栏: 《C语言》《数据结构》《蓝桥杯试题》 🌝 每一个不曾起舞的日子,都是对生命的辜负。 目录 前言: 一、隐式类型转换 (一)整型提升的意义 (二)如何进行整型提升呢? 二、算数转换 三、操作符的属性 (一)操作符优先级汇

    2024年02月16日
    浏览(45)
  • 考研C语言第八章

    这个东西看着像数据库里面属性的定义,也像java里面的类的定义 关于结构体里面scanf读取输入的数据,并进行相关的存储, 这里面字符串就像之前的,取数据时可以和前面的不加空格,可以不加取地址符号 (但是为了好记和规范,建议直接所有的一视同仁) 就想数据库在输

    2024年02月10日
    浏览(39)
  • MySQL隐式类型转换

    当运算符与不同类型的操作数一起使用时,会发生类型转换以使操作数兼容。有些转换是隐式发生的。例如,MySQL会根据需要自动将字符串转换为数字,反之亦然。 如果一个或两个参数都为 NULL ,则比较结果为 NULL 。但是相等比较运算符 = 除外,对于 NULL=NULL ,结果为1,不需

    2023年04月23日
    浏览(48)
  • 《汇编语言》王爽(第四版)第八章 实验7

    文章目录 前言 一、题目 二、分析 1.内存分配情况 2.数据结构分析 3.实现思路 (1)设置段寄存器 (2)复制“年份”数据 (3)复制“年总收入”数据 (4)复制“雇员人数”数据 (5)计算“人均收入” 三、代码 1.实现代码 2.优化代码 3.最终代码 总结 王爽老师《汇编语言》

    2024年02月04日
    浏览(73)
  • 自然语言处理: 第八章chatGPT的搭建

    Transformer 大模型家族可以分成三类, 至于三者的区别可以参考上一章: Encoder-only, Decoder-only, 只需要Pre_train Encoder-decoder , 可以在一些任务上无需进行fine_tune 必须要在下游任务进行微调比如Bert , Bart 。 T5 这种无需要微调就能完成一些任务 。最后GPT从3开始,只需要预训练就能适

    2024年02月12日
    浏览(45)
  • JS隐式转换与类型比较

    隐式转换(Implicit Conversion)是指在表达式求值或操作中自动发生的类型转换。当使用不同的数据类型进行操作时,JavaScript 会自动进行类型转换以满足操作的要求。 隐式转换在编写逻辑时经常会出现,特别是在需要进行判断的逻辑场景中。举个例子: 需要注意的是,隐式转

    2024年02月07日
    浏览(33)
  • 【C语言初阶】带你轻松掌握指针基础知识(1)——指针的定义,类型,大小

    君兮_的个人主页 勤时当勉励 岁月不待人 C/C++ 游戏开发 Hello,这里是君兮_,最近刚回家有点懒,从今天开始恢复更新并开始更新新的刷题系列,我们先继续更新0基础入门C语言的内容,今天给大家带来的是指针方面的内容,但由于是初阶,一些高级的用法我们放在进阶篇再讲

    2024年02月12日
    浏览(44)
  • 【c++】类和对象(六)深入了解隐式类型转换

    🔥个人主页 : Quitecoder 🔥 专栏 : c++笔记仓 朋友们大家好,本篇文章我们来到 初始化列表,隐式类型转换以及explicit的内容 在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值 虽然上述构造函数调用之后,对象中已经有了一个初始值,但是

    2024年04月13日
    浏览(51)
  • c++中static静态成员变量和静态成员函数、explcit和隐式类型转换、友元函数()详解

    声明为 static 的类成员 称为 类的静态成员 ,用 static 修饰的 成员变量 ,称之为 静态成员变量 ;用 static 修饰 的 成员函数 ,称之为 静态成员函数 。 静态成员变量一定要在类外进行初始化   静态成员 为 所有类对象所共享 ,不属于某个具体的对象,存放在静态区   静态成

    2024年02月04日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包