练习题——整型数据在内存中的存储

简介: 练习题——整型数据在内存中的存储

一、

题目:

请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。

思路:

数据是存储在内存当中,假设将1存储到内存之中,小端存储和大端存储区别就在于第一个字节内容是1/0;而我们知道指针类型的作用有解引用操作时访问几个字节,char类型的指针就访问一个字节

指针类型的意义:

1、指针类型决定了指针解引用操作符能访问几个字节:char *p;*p 访问了一个字节,int *p; *p 就访问4个字节。

2、指针类型决定了指针+1,-1,加的或者减的是几个字节; char *p;p+1, 跳过一个字节,int *p;p+1;跳过一个整型4个字节

image.png

解答:

大端字节序:数据的低位存储在内存的高地址中,数据的高位存储在内存的低地址中。

小端字节序:数据的低位存储在内存的低地址中,数据的高位存储在内存的高地址中。

#include<stdio.h>
int check_sys()
{
  int a = 1;
  char* p = (char*)&a;//强制类型转换为char
  return *p;
}
int main()
{
  int ret = check_sys();
  if (ret == 1)
  {
    printf("小端\n");
  }
  else
  {
    printf("大端\n");
  }
  return 0;
}

二、

题目:

以下代码输出结果是什么?

image.png

解析:

-1是整型,但要存储在char里面,所以肯定需要进行缩减,首先将-1的反码计算出来(因为在内存中存储的是补码形式),并且-1的补码全是1,需要牢记!缩减时根据最后结果需要的比特位数从低位开始选取。又因为输出结果是整型类型,所以又需要整型提升(有符号数按照符号位补全,无符号数直接补0),所以a,b都是有符号数,因此整型提升之后全是1,而输出结果使用的是原码,因此直接输出-1。而c无符号整型,整型提升后前缀是0,所以原码反码补码一致,按照整型提升后的结果直接翻译输出即可。

结论

  • char和signed char本质上是一样的,因此答案也相同。
  • 无符号和有符号位的区别在于整型提升时,补位是0,还是按照符号位。并且无符号数的原码反码补码相同,不需要在考虑打印时转换,直接翻译补码即可,而有符号数在打印时需要考虑将补码转换为源码再进行打印


答案:

-1,-1,255

三、

题目:

image.png

解析:

本题前面思路与上一题一致,首先需要,缩减,然后根据数据类型进行整型提升。唯一区别在于本题输出结果是%u,因此是无符号整型,所以整型提升后的结果不需要再翻译成原码,因为无符号整型原码补码反码相同,直接补码即可

小结论:

只要有%u或者unsigned char其中一个,就可以直接翻译,不需要考虑原码反码补码的转换。

总结:

原先数据类型决定整型提升时需要补位的数字,而输出结果如果是无符号整型,直接打印补码,不需要像有符号数那样还需要输出时将反码翻译成补码!

四、char类型表示数据范围

image.png

有符号的char范围:-128~127

无符号的char的范围:0~255

TIP:

image.png


128是存储不到char类型,但我们可以看成127+1就是-128,因此两者输出结果一样!

五、

题目:

请问以下代码输出结果?

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

解析:

先将200转换为补码形式:00000000000000000000000011001000,因为将200存储在char类型的变量,所以需要截断,只留下一个字节,即8个比特位:11001000

100同理,最后存储在b里面的形式是:01100100

当进行加法运算时,需要整型提升(这是规则,防止最后结果溢出)!

所以最后结果就是:00000000000000000000000000100101100

注意最后输出结果的区别一个是直接a+b的形式,而另一个先把内容存储在一个char类型里面,因此需要截断,所以最本质的区别在于一个需要截断,而另一个不需要截断。而刚才的结果恰好经过截断(只保留最后8个比特位)把1给去掉了,造成两者差别的根源!

TIP:

也可以根据无符号char类型的区间范围是0~255,可以看出最后的相加结果肯定是超出范围的!

六、

题目:在32位大端模式处理器上变量b等于?

int main()
{
  unsigned int a=0x1234;
  unsigned char b=*(unsigned char*)&a;
  return 0;
}

解答:

注意一个完整的整型十六进制表达有8个十六进制位,所以应该先把a的形式补充完整。

就是0x 00 00 12 34  (两个十六进制位就表示一个字节,因此就是4个字节一个整型)。

题目又说大端处理器,所以数据的低位存储在内存的高地址中,数据的高位存储在内存的低地址中

image.png

因为强制类型转换为unsigned char*类型,所以我们在访问时只访问一个字节,注意都是从内存的低地址开始访问(所以把00取走),结果就是0.

相关文章
|
20天前
|
存储 编译器 数据处理
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
45 11
|
2月前
|
监控 算法 应用服务中间件
“四两拨千斤” —— 1.2MB 数据如何吃掉 10GB 内存
一个特殊请求引发服务器内存用量暴涨进而导致进程 OOM 的惨案。
|
2月前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
81 1
|
2月前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
18天前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
154 1
|
7天前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
16天前
|
Java
JVM内存参数
-Xmx[]:堆空间最大内存 -Xms[]:堆空间最小内存,一般设置成跟堆空间最大内存一样的 -Xmn[]:新生代的最大内存 -xx[use 垃圾回收器名称]:指定垃圾回收器 -xss:设置单个线程栈大小 一般设堆空间为最大可用物理地址的百分之80
|
17天前
|
Java
JVM运行时数据区(内存结构)
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一 (3)程序计数器:保存指令执行的地址,方便线程切回后能继续执行代码
18 3
|
18天前
|
存储 缓存 监控
Elasticsearch集群JVM调优堆外内存
Elasticsearch集群JVM调优堆外内存
42 1
|
27天前
|
Arthas 监控 Java
JVM进阶调优系列(9)大厂面试官:内存溢出几种?能否现场演示一下?| 面试就那点事
本文介绍了JVM内存溢出(OOM)的四种类型:堆内存、栈内存、元数据区和直接内存溢出。每种类型通过示例代码演示了如何触发OOM,并分析了其原因。文章还提供了如何使用JVM命令工具(如jmap、jhat、GCeasy、Arthas等)分析和定位内存溢出问题的方法。最后,强调了合理设置JVM参数和及时回收内存的重要性。

热门文章

最新文章