数据在内存中的存储练习题

数据在内存中的存储练习题

文章目录

  • 数据在内存中的存储练习题
    • 1. 练习一
    • 2.练习二
    • 3. 练习三
    • 4. 练习四
    • 5. 练习五
    • 6. 练习六
    • 7. 总结

1. 练习一

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

代码运行结果:
a = -1 b = -1 c = 255

解释:
char默认是有符号的
首先 a 和 b 都是有符号的char
-1的原码: 1000 0000 0000 0000 0000 0000 0000 0001
-1的反码: 1111 1111 1111 1111 1111 1111 1111 1110
-1的补码: 1111 1111 1111 1111 1111 1111 1111 1111
由于char只有1个字节,也就是8个bit位,所以会发生截断
char中-1的值为 1111 1111

%d打印的是有符号的整数,会将char类型整型提升至int类型
由于c是无符号的char,整型提升时高位补0
0000 0000 0000 0000 0000 0000 1111 1111
将这个二进制翻译成10进制就是255
所以为255

2.练习二

#include <stdio.h>int main()
{char a = -128;printf("%u", a);return 0;
}

代码运行结果:
4294967168

解释:
-128的原码: 1000 0000 0000 0000 0000 0000 1000 0000
-128的反码: 1111 1111 1111 1111 1111 1111 0111 1111
-128的补码: 1111 1111 1111 1111 1111 1111 1000 0000
char只有一个字节,会发生截断
-128: 1000 0000

%u打印的是无符号的整数
按照原来的类型进行整型提升
由于char是有符号的char,整型提升时高位补符号位
1111 1111 1111 1111 1111 1111 1000 0000
将这个二进制翻译成十进制就是要打印的数值,这是个相当大的数
可以打开电脑自带的计算器,切换成程序员模式
在这里插入图片描述
打印的数就是4294967168

3. 练习三

#include <stdio.h>int main()
{char a = 128;printf("%u", a);return 0;
}

代码运行结果:
4294967168

解释:
128的原码:0000 0000 0000 0000 0000 0000 1000 0000
128的反码:0111 1111 1111 11111 1111 11111 0111 11111
128的补码:0111 1111 1111 11111 1111 11111 1000 0000
char只有一个字节,发生截断
128: 1000 0000

char的取值范围只有-128~127,存不下128
char中128的值和-128一样,所以系统会认为我们存的是-128
所以打印的值和练习二一样4294967168

4. 练习四

#include <stdio.h>
#include <string.h>int main()
{char a[1000];int i = 0;for (i = 0; i < 1000; i++){a[i] = -1 - i;}printf("%zd\n", strlen(a));return 0;
}

代码运行结果:
255

解释:
循环1000次,一次赋一个值,但是strlen计算的是’\0’之前的元素个数,'\0’的ASCII就是0
所以要在循环中找到第一个0的位置,char类型的取值范围是-128~127
在这里插入图片描述
当char中的值为127时再加一,值就变成了-128
当char中的值为-128时再减一,值就变成了127
如此循环
a[i]的值为 -1 -2 -3 -4 … -127 -128 127 126 125 … 3 2 1 0

所以打印的值为128 + 127 = 255

5. 练习五

代码一:

#include <stdio.h>unsigned int i = 0;
int main()
{for (i = 0; i <= 255; i++){printf("Hello World!\n");}return 0;
}

运行结果:
死循环打印Hello World!
代码二:

#include <stdio.h>
#include <windows.h> //使用Sleep需包含的头文件int main()
{unsigned int i = 0;for (i = 9; i >=0 ; i--){printf("%u\n",i);Sleep(1000); //暂停一秒便于观察}return 0;
}

代码运行结果:
死循环打印
9 8 7 6 5 4 3 2 1 4294967295 42949672954 …

解释:
代码一中定义了一个无符号的char,取值范围是0~255,永远不会超过255,当超过255时,又会从0开始,所以造成了死循环
代码二中定义了一个无符号的int,和无符号char同理永远不会超过它的取值范围
0~4294967295,当超过最大值时,就会从0继续开始,如果超过最小值0时,又会从最大值开始

6. 练习六

#include <stdio.h>
int main()
{int a[4] = { 1,2,3,4 };int* p1 = (int*)(&a + 1);int* p2 = (int*)((int)a + 1);printf("%x,%x", p1[-1], *p2);return 0;
}

在VS2022,X86的环境下,代码运行结果:
4,200000

解释:
&a取出的是数组的地址,+1跳过了整个数组,p1指向4后的地址
p1[-1] 等价于*(p1 - 1),p1是int*类型的,-1后退4个字节,整型数组中的元素也是4个字节,所以p1从指向4后的地址变成了指向4,所以p1[-1]是4,打印十六进制也是4
在这里插入图片描述

a表示首元素的地址,将地址转化为int类型的,+1,也就是整数+整数,假设a的地址为0x010,转化为int类型,就是16,+1等于17,转化为十六进制就是0x011,p2的地址从0x010变成了0x011,地址只加了一个字节,也就是跳过了一个字节,p2指向首元素的第二个字节的位置,int解引用访问四个字节,从首元素的第二个字节的位置向后访问四个字节

在这里插入图片描述
访问得到 00 00 00 02,由于小端字节序是低字节存放在低地址,所以是倒着放的,转化为十六进制要反过来02 00 00 00,所以打印的是02000000

7. 总结

在这里插入图片描述

在这里插入图片描述

  1. 有符号的char取值范围是-128~127,当要超过127时,值会-128开始
    1 2 3 … 125 126 127 -128 -127 -126 … -3 -2 -1 0 1 2 3 …
    其他数据类型也一样

  2. char类型的二进制会截断,不管前面是什么,只管最后8个bit的数值
    例如:-1
    -1的原码: 1000 0000 0000 0000 0000 0000 0000 0001
    -1的反码: 1111 1111 1111 1111 1111 1111 1111 1110
    -1的补码: 1111 1111 1111 1111 1111 1111 1111 1111
    截断之后1111 1111
    只会存最后8个bit位,这时候就要看最高位是符号位还是数值位
    有符号值就为-1
    无符号就为255

  3. 有符号的char整型提升时补符号位
    例如:-1
    1111 1111
    -1的补码:1111 1111 1111 1111 1111 1111 1111 1111
    -1的原码:1000 0000 0000 0000 0000 0000 0000 0001
    打印出来就是-1

  4. 无符号的char整型提升时补0
    例如:-1
    1111 1111
    0000 0000 0000 0000 0000 0000 1111 1111
    打印出来就是255

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

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

相关文章

Java的特性

Java是一种广泛使用的编程语言&#xff0c;它具有许多独特的特性&#xff0c;包括简单易学、面向对象、可移植性、安全性、多线程等。下面我将对这些特性进行详细的介绍&#xff0c;并阐述它们的重要性。 一、简单易学 Java是一种相对容易学习的编程语言。它的语法简单明了&…

人工智能|机器学习——机器学习如何判断模型训练是否充分

一、查看训练日志 训练日志是机器学习中广泛使用的训练诊断工具&#xff0c;每个 epoch 或 iterator 结束后&#xff0c;在训练集和验证集上评估模型&#xff0c;并以折线图的形式显示模型性能和收敛状况。训练期间查看模型的训练日志可用于判断模型训练时的问题&#xff0c;例…

C++ 泛型编程,函数模版和类模版

1.泛型编程 泛型编程&#xff1a;编写与类型无关的通用代码&#xff0c;是代码复用的一种手段。模板是泛型编程的基础 就比如说活字印刷术&#xff0c;就是提供一个模具&#xff0c;然后根据模具来印刷出不同的字。 泛型编程跟着类似&#xff0c;提供一个模版&#xff0c;根据这…

微服务--05--配置管理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 配置管理这些问题都可以通过统一的配置管理器服务解决。而Nacos不仅仅具备注册中心功能&#xff0c;也具备配置管理的功能&#xff1a; 1.配置共享1.1.添加共享配置…

【Spark基础】-- RDD 转 Dataframe 的三种方式

一、环境说明 Oracle JDK 11Scala 2.12.17Apache Spark 3.1.1Apache Hadoop 3.1.0 二、RDD 转 Dataframe 的方法 1、通过 StructType 创建 Dataframe(强烈推荐使用这种方法) /*** 方法一:通过 StructType 创建 Dataframe* @param spark SparkSession* @param rdd 输入* @…

【封装UI组件库系列】封装Button图标组件

封装UI组件库系列第四篇封装Button按钮组件 &#x1f31f;前言 &#x1f31f;封装Button组件 1.分析封装组件所需支持的属性与事件 支持的属性&#xff1a; 支持的事件&#xff1a; 2.创建Button组件 &#x1f31f;封装功能属性 type主题颜色 plain是否朴素 loading等…

方舟笔记:方舟开发框架概述

方舟笔记 方舟开发框架概述 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/134677116 今年&#xff08;…

API接口测试工具的主要作用及选择指南

API接口测试是现代软件开发中至关重要的一环。为了确保不同组件之间的无缝集成和功能正常运作&#xff0c;API接口测试工具应运而生。本文将介绍API接口测试工具的主要作用&#xff0c;以及在选择适合项目的工具时需要考虑的因素。 1、功能测试&#xff1a;API接口测试工具的首…

Linux内存回收:LRU算法

linux操作系统再内存不足时会使用Swap机制&#xff0c;将一些不经常使用的匿名内存页放到磁盘当中&#xff0c;等下次需要时再读取到内存当中&#xff0c;而这个LRU算法就是用来选择把哪些不常使用的匿名内存页放到磁盘当中的。 LRU&#xff08;Least Recently Used&#xff09…

【面经八股】搜广推方向:面试记录(四)

【面经&八股】搜广推方向:面试记录(四) 文章目录 【面经&八股】搜广推方向:面试记录(四)1. 自我介绍2. 项目问答3. 八股4. 编程题4.1 大数加法4.2 平面最近点对问题求解5. 反问环节1. 自我介绍 。。。。。。 2. 项目问答 问的有点细。。。。。。 3. 八股 1)…

使用 eyed3 从 mp3 文件名获取歌曲名设置 ID3 属性

需求 近期有朋友拜托弄一批 mp3 放 U 盘里面以便开车的时候听&#xff0c;于是下载了一批歌曲&#xff0c;都整理成 歌曲名-歌唱者.mp3 这样的文件名。可是有些播放器会优先使用 ID3&#xff08;即 mp3 文件的一个自带的信息段。顺便吐槽一下&#xff0c;官方网站 https://id3…

android交叉编译pidstat iostat mpstat

android交叉编译pidstat iostat mpstat 文章目录 android交叉编译pidstat iostat mpstat编译环境编译工具下载 编译过程编译环境系统环境NDK版本的选择 源码下载只编译简单的pidstat mpstat iostat编译编译脚本问题 使用技术支持 编译环境 编译工具下载 参考这个&#xff1a;…

python避坑指南(更新中)

os.path.join 避免连续的/&#xff0c;看示例即清楚&#xff0c;最好的避免方法是字符串首末都不要加’/&#xff1a; join用法 用join前面的符号将参数数组里面的字符串连接起来&#xff0c;注意join只有一个参数

tlais智能学习辅助系统-修改部门功能实现

学习黑马程序员的JavaWeb课程&#xff0c;自己写的部门信息修改部分程序 控制层&#xff1a; //DeptController.java /** * 根据ID查询部门信息 * param id * return */ GetMapping("/{id}") public Result select(PathVariable Integer id){log.info("查询id…

电子学会C/C++编程等级考试2021年03月(二级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:石头剪刀布 石头剪刀布是常见的猜拳游戏。石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,则不分胜负。 一天,小A和小B正好在玩石头剪刀布。已知他们的出拳都是有周期性规律的,比如:“石头-布-石头-剪刀-石头-布-石头…

整数的补码转换(以[+, -]7为例)

要找到 -7 的二进制补码&#xff0c;我们可以按照以下步骤进行&#xff1a; 写出正数的二进制表示: 首先&#xff0c;写出 7 的二进制表示。假设我们在一个 8 位的系统中工作&#xff08;使用 8 位二进制数&#xff09;&#xff0c;那么 7 的二进制表示是 0000 0111。 取反&am…

Linux shell编程学习笔记31:alias 和 unalias 操作 命令别名

目录 0 前言1 定义别名2 查看别名 2.1 查看所有别名2.2 查看某个别名 2.2.1 alias 别名2.2.2 alias | grep 别名字符串2.2.3 使用 CtrlAltE 组合键3 unalias&#xff1a;删除别名4 如何执行命令本身而非别名 4.1 方法1&#xff1a;使用 CtrlAltE 组合键 && unalias4…

电动汽车的400V和800V充电技术

文章目录 400V充电和800V充电对比电动汽车400V充电和800V充电速度对比电动汽车400V充电技术电动汽车400V充电系统电动汽车800V充电系统电动汽车800V充电技术 400V充电和800V充电对比 400V充电和800V充电是指电动汽车充电系统的不同电压等级。这两种充电方式的主要区别在于充电…

使用 sync.Cond 来协调并发 goroutine 的访问共享资源

关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等&#xff0c;您的关注将是我的更新动力&#xff01; 使用 sync.Cond 解决并发访问共享资源问题 在并发编程中&#xff0c;当多个 goroutine 需要访问共享资源时&#xff0c;我们需要…

Redis 主库挂了,如何不间断服务?

目录 1、哨兵机制的基本流程 2、主观下线和客观下线 3、如何选定新的主库&#xff1f; 总结 // 你只管前行&#xff0c;剩下的交给时间 在 reids 主从库集群模式下&#xff0c;如果从库发生故障了&#xff0c;客户端可以继续向主库或其他从库发送请求&#xff0c;进行相关的…