C语言内存管理陷阱

本文通过实例分析了C语言中不同类型的整数在内存中的存储方式,特别是正负整数的补码表示。同时,解释了printf函数在处理不同类型变量时的类型提升规则,以及在输出时如何根据格式说明符处理不同长度的数据。文章以两道题目为例,揭示了无符号类型和有符号类型在运算和存储过程中的差异,强调了理解类型转换和printf函数行为的重要性。
摘要由CSDN通过智能技术生成

我们都知道C语言中整形是以补码的形式存在的,正整数的源 反 补码,三码相同,但是负数的存储就不一样了,需要由源码得到反码来存储,现在我们来做一道题。

#include <stdio.h>
int main()
{
         char a=-1;
  signed char b=-1;
unsigned char c=-1;
     printf("%d %d %d",a,b,c);
}

这里的答案是a=-1 b=-1 c=255,好像和我们想象的不一样,我们一点点来分析,a为char类型,-1的反码在内存里面是32位,全部为1,但是a为char类型的,所以只取后8位,全部是1,因为pirntf 后面是%d所以,要进行类型提升,取符号位1进行补充前面空缺的24位,那么还是32个1,答案自然就是-1,b也是如此,但是C是无符号类型的所以c为恒正数补冲的时候就是填充的0,那么前面的就都是0,剩下8位1,计算得就是255。
我们再来一道题练习一下

int main()
{
  unsigned char a = 200;
  unsigned char b = 100;
  unsigned char c = 0;
  c = a + b;
  printf(%d %d”, a+b,c);
  return 0;
}

这里的答案是300 44,printf在传入参数的时候如果是整形会默认传入四字节,所以a+b的结果是用一个四字节的整数接收的,不会越界。而c已经在c = a + b这一步中丢弃了最高位的1,所以只能是300-256得到的44了。

※由于printf是可变参数的函数,所以后面参数的类型是未知的,所以甭管你传入的是什么类型,printf只会根据类型的不同将用两种不同的长度存储。其中8字节的只有long long、float和double(注意float会处理成double再传入),其他类型都是4字节。所以虽然a + b的类型是char,实际接收时还是用一个四字节整数接收的。另外,读取时,%lld、%llx等整型方式和%f、%lf等浮点型方式读8字节,其他读4字节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值