c语言进阶 数据在内存中的存储(下)

简介: c语言进阶 数据在内存中的存储(下)

一. 练习题目


我们先从几道题目开始 复习下上一篇博客的内容


练习1


下面这段代码的输出结果是什么?


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

首先来分析下题目 根据我们在前面学到的知识 signed char 和 char其实是同一种类型

所以说 a 和 b的输出结果都是一样的 都是-1

我们都知道 在计算机中存储一个数字的补码

我们画图来表示下c的存储过程

f4cff96399fb4f08bedb7480447d9f9c.png

关于整型提升的相关知识大家可以参考我的这篇博客


整型提升相关知识


所以说 输出的三个数字分别是 -1 -1 255


练习2


代码如下


int main()
{
  char a = -128;
  printf("%u\n", a);
  return 0;
}


题目分析如下


a07a16d5c75f460d936efebdd5dd4293.png


我们得到的最终结果是


1faec5dff45b42118c9f8f697df084dc.png


扩展题


如果我们打印char a 是 128呢?


它的结果会是什么?


大家可以自己思考一下


(注意char类型的取值范围)


练习3


以下代码的输出结果是?


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


还是一样 我用画图的方式来给大家解决这个问题


a350e7cd2cb640358934214a2f91c1bc.png


所以说 它打印出来的十进制数字是- 10


通过上面几道题目的计算 相信大家对于有符号数 无符号数的理解应该会加深一层


练习4


代码表示如下


int main()
{
  char a[1000];
  int i;
  for ( i = 0; i < 1000; i++)
  {
    a[i] = -1 - i;
  }
  printf("%d", strlen(a));
  return 0;
}


要想知道这个题目的答案我们首先要知道两个知识点


1 字符串结束的表示是‘\0’,它的ascll码值就是0

2 char类型作为一个无符号数的时候有范围 它的范围是-128~127


如下图

31b9ca62ebdd44acb3cd71244d5c2ad5.png



由上面这些知识我们可以知道


数组i里面存储的值会是这样子的规律


-1 - 2 … …-128 127 126 … 3 2 1 0


其中-1到0一共经历了 127 +128 一共255个字符


所以说字符串长度为255


3e375c81c49041abbfb0afc26bbd46e7.png


练习5


请问下面代码运行的结果是?


int main()
{
  unsigned int i;
  for ( i = 9; i >= 0; i++)
  {
    printf("%u\n", i);
  }
  return 0;
}


这里我们要注意的是

unsigned int i 是一个无符号数

所以说它的值恒大于等于0


因此 我们可以说这个代码一定会进入死循环


练习6


unsigned char i = 0;
int main()
{
  for ( i = 0; i <= 255; i++)
  {
    printf("hello world\n");
  }
  return 0;
}


上面代码的运行结果是?


我们说

unsigned char i 是一个无符号数 占用一个字节的大小

所以说它的表示范围是 0000 0000(0) 到 1111 1111 (255)

因此 它小于等于255恒成立


所以说 代码会进入死循环


二. 浮点数在内存中的存储


老规矩 我们先来看一段代码


int main()
{
  int n = 9;
  float* p = &n;
  printf("%d\n", n);
  printf("%f\n", *p);
  *p = 9.0;
  printf("%d\n", n);
  printf("%f\n", *p);
  return 0;
}


请问上面四个printf程序从上到下依次输入的值是?


让我们带着这个问题 来进入下面的浮点数规则学习


浮点数的储存规则


根据国际标准IEEE 任意一个二进制浮点数V可以表示成下面的形式


  1. 1(-1)^ S * M * 2^E
  2. 2其中(-1)^ S表示符号位 当s=0时 表示为一个正数 当s=1时表示为一个负数
  3. 3M表示有效位数字 大于等于1 小于2
  4. 42^E表示指数位


我们举例来说

十进制的5.5 写成二进制就是101.1 相当于1.011x2^2


那么 按照相面形式 我们可以得到


S = 0

M = 1.011

E = 2


我们规定


在32位的系统中


最高位1位是符号位S

接着8位是指数E

剩下23位是有效数字M


在64位的系统中

最高位1位是符号位S

接下来11位是指数E

剩下23位是有效位数字M


我们规定 在存浮点数的时候省略M最前面的数字1

对于8位数的E 我们在储存中加上一个127

对于11位数的E 我们在储存中加上一个1023


还是以5.5为例 它的浮点数存储形式为


0 (S) 1000 0001(E) 01110 00000 00000 00000 000 (M)


补充


当指数E从内存中取出的时候


E不全为0或者不全为1


这时候指数E的计算值减去127(或1023)得到真实值


E全为0时


我们可以将它看作为0


E全为1时


我们将它看作无限


好了 这时候我们运用我们目前所学到的知识来解决上面的题目


9的整数储存应该是

0000 0000 0000 0000 0000 0000 0000 1001


9的浮点数储存应该是

0 1000 0010 001 0000 0000 0000 0000 0000


所以说上面两个输出的值应该为 9 和0.000000


下面两个输出的值应该为 一个很大的正数 和9.000000


以上就是本篇博客的全部内容啦 由于博主才疏学浅 所以难免会出现纰漏 希望大佬们看到错误之后能够


不吝赐教 在评论区或者私信指正 博主一定及时修正


那么大家下期再见咯

相关文章
|
1月前
|
存储 程序员 编译器
C 语言中的数据类型转换:连接不同数据世界的桥梁
C语言中的数据类型转换是程序设计中不可或缺的一部分,它如同连接不同数据世界的桥梁,使得不同类型的变量之间能够互相传递和转换,确保了程序的灵活性与兼容性。通过强制类型转换或自动类型转换,C语言允许开发者在保证数据完整性的前提下,实现复杂的数据处理逻辑。
|
1月前
|
存储 数据管理 C语言
C 语言中的文件操作:数据持久化的关键桥梁
C语言中的文件操作是实现数据持久化的重要手段,通过 fopen、fclose、fread、fwrite 等函数,可以实现对文件的创建、读写和关闭,构建程序与外部数据存储之间的桥梁。
|
2月前
|
存储 数据建模 程序员
C 语言结构体 —— 数据封装的利器
C语言结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个整体。它支持数据封装,便于管理和传递复杂数据,是程序设计中的重要工具。
|
2月前
|
存储 编译器 数据处理
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
69 11
|
3月前
|
监控 算法 应用服务中间件
“四两拨千斤” —— 1.2MB 数据如何吃掉 10GB 内存
一个特殊请求引发服务器内存用量暴涨进而导致进程 OOM 的惨案。
|
3月前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
140 1
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
65 1
|
7月前
|
程序员 C语言 C++
【C语言基础】:动态内存管理(含经典笔试题分析)-2
【C语言基础】:动态内存管理(含经典笔试题分析)
|
7月前
|
程序员 编译器 C语言
【C语言基础】:动态内存管理(含经典笔试题分析)-1
【C语言基础】:动态内存管理(含经典笔试题分析)
|
Java 数据库连接 C语言
C语言进阶教程(内存分配常见问题分析)
C语言进阶教程(内存分配常见问题分析)
81 0