【26】C语言_数据存储

news2025/1/10 16:43:06

目录

数据类型的意义

大小端介绍

例题1:设计一个小程序输出存储方式:

例题2:下列程序输出什么,为什么

例题3:下列程序输出什么,为什么

例题4:下列程序输出什么,为什么

例题6:下列程序输出什么,为什么

例题7:下列程序输出什么,为什么

例题8:下列程序输出什么,为什么

浮点型在内存中的存储


数据类型的意义

类型的意义

1、使用这个类型开辟内每空间的大小(大小决定了使用范围)。

2、如何看待内存空间的视角。

案例:看a在内存是怎么存放的 

int main()
{
    int a = -10;
 //原码:10000000 00000000 00000000 00001010
 //反码:11111111 11111111 11111111 11110101
 //补码:11111111 11111111 11111111 11110110
 //换成16进制:FF FF FF F6
  
    return 0;
}
//数据在内存中以2进制的形式存储
//对整数来说:
//整数二进制有3种表示形式:原码、反码、补码
//正整数:原码、反码、补码相同
//负整数:原码、反码、补码进行计算
//按照数据的数值直接写出的二进制序列就是原码
//原码的符号位不变,其他位按位取反,得到的就是反码
//反码+1,得到的就是补码
//内存存储的是补码

 F10调试,查看内存的信息:

大小端介绍

什么大端小端:

  • 大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
  • 小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。

为什么有大端和小端:

  • 这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
  • 例如一个16bit的short型x,在内存中的地址为0x0010,的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的x86 结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

例题1:设计一个小程序输出存储方式:

int main()
{
    int a = 1;
    char* p = (char*)&a;
    if(*p == 1)
    {
        printf("小端存储\n");
    }
    else
        printf("大端存储\n");
    return 0;
}

或者写一个函数输出存储方式:

int check_sys()
{
    int i = 1;
    char* p = (char*)&i;
    return *p;
}
int main()
{
    int ret = check_sys();
    if(ret == 1)
    {
        printf("小端存储\n");
    }
    else
        printf("大端存储\n");

    return 0;
}

例题2:下列程序输出什么,为什么

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

原因为下列:

int main()
{
    char a =-1;
    //补码位:11111111 11111111 111111111 11111111
    //因为为char,所以为:11111111
    //因为默认为signed,高位第一个1为符号位,又因为要输出%d,所以要整形提升
    //整形提升为:11111111 11111111 111111111 11111111(有符号的补符号位)
    //所有原码为:-1

    signed char b = -1;
    //和char一样的,上面的额char是省略了signed

    unsigned char c = -1;
    //补码位:11111111 11111111 111111111 11111111
    //因为为char,所以为:11111111
    //因为为unsiged,所有整形提升前面补0
    //整形提升为:00000000 00000000 000000000 11111111
    //所以原码为:255

    printf("a=%d,b=%d,c=%d",a,b,c);

    return 0;
}

例题3:下列程序输出什么,为什么

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

因为:

int main()
{
    char a =-128;
    //原码:10000000 00000000 00000000 10000000
    //反码:11111111 11111111 11111111 01111111
    //补码:11111111 11111111 11111111 10000000
    //因为char,所以只能存放8个bit位:10000000
    //因为是以%u(无符号整形)的方式打印的,需要整形提升
    //又因为整形提升是用之前的char提升的为:11111111 11111111 11111111 10000000
    //所以原码为:11111111 11111111 11111111 10000000为:4294967168

    printf("%u\n",a);
    return 0;
}

例题4:下列程序输出什么,为什么

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

因为:

int main()
{
    char a = 128;
    //原码:00000000 00000000 00000000 10000000
    //因为char,所以只能存放8个bit位:10000000
    //因为是以%u(无符号整形)的方式打印的,需要整形提升
    //又因为整形提升是用之前的char提升的为:11111111 11111111 11111111 10000000
    //所以原码为:11111111 11111111 11111111 10000000为:4294967168

    printf("%u\n",a);
    return 0;
}
//char类型的取值范围:-128到127

例题5:下列程序输出什么,为什么

int main()
{
    int i = -20;
    unsigned int j = 10;
    printf("%d\n",i + j);
    return 0;
}
int main()
{
    int i = -20;
    //原码:10000000 00000000 00000000 00010100
    //反码:11111111 11111111 11111111 11101011
    //补码:11111111 11111111 11111111 11101100

    unsigned int j = 10;
    //原反补码:00000000 00000000 00000000 00001010

    printf("%d\n",i + j);
    //i补码: 11111111 11111111 11111111 11101100
    //j补码: 00000000 00000000 00000000 00001010
    //相加得:11111111 11111111 11111111 11110110
    //因为要%d,所以要以有符号位打印         
    //得反码:11111111 11111111 11111111 11110101
    //得原码:10000000 00000000 00000000 00001010  -> -10


    return 0;
}

例题6:下列程序输出什么,为什么

int main()
{
    unsigned int i;
    for (i = 9; i>= 0;i--)
    {
        printf("&u\n",i);
    }
    return 0;
}
//死循环

例题7:下列程序输出什么,为什么

#include<string.h>
int main()
{
    char a[1000];
    int i;
    for (i =0;i<1000;i++)
    {
    a[i] = -1-i;
    }
printf("%d\n", strlen(a));
return 0;
}
#include<string.h>
int main()
{
    char a[1000];
    int i;
    for (i =0;i<1000;i++)
    {
    a[i] = -1-i;
    }
    //-1 -2 -3 ... -127 -128 127 126 123 ...3 2 1 0 -1 -2 ...
    //128+127=255
    //所以输出255
printf("%d\n", strlen(a));
return 0;
}

例题8:下列程序输出什么,为什么

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

    return 0;
}
//输出死循环

浮点型在内存中的存储

根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式:

  • (-1)^S*M*2^E
  • (-1)^S表示符号位,当s=0,V为正数;当=1,V为负数。
  • M表示有效数字,大于等于1,小于2。
  • 2^E表示指数位

举例:

  • 十进制的 5.0 ,写成二进制是 101.0 ,相当于 1.01×2^2 。
  • 那么,按照上面 V 的格式,可以得出 s=0 , M=1.01 , E=2 。
  • 十进制的 -5.0 ,写成二进制是 - 101.0 ,相当于 - 1.01×2^2 。
  • 那么, s=1 , M=1.01 , E=2 。

对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。

对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M

下面例子:

int main()
{
    float f = 5.5f;
    //101.1
    //1.011 * 2^2
    //s=0 M=1.011 E=2
    //s=0 M=011 E=2+127
    //0100 0000 1011 0000 0000 0000 0000 0000
    //40 b0 00 00
    return 0;
}

 

 

  • IEEE 754 对有效数字 M 和指数 E ,还有一些特别规定。
  • 前面说过, 1≤M
  • IEEE 754 规定,在计算机内部保存 M 时,默认这个数的第一位总是 1 ,因此可以被舍去,只保存后面的xxxxxx部分。比如保存 1.01 的时候,只保存01 ,等到读取的时候,再把第一位的 1 加上去。这样做的目的,是节省 1 位有效数字。以 32 位浮点数为例,留给M 只有 23 位,将第一位的1 舍去以后,等于可以保存 24 位有效数字。
  • 因为M都是1.XXX的形式,所以只存XXXX的形式,这样M就可以多存1位有效数字,能过提高精准度
  • 至于指数 E ,情况就比较复杂。
  • 首先, E 为一个无符号整数( unsigned int )
  • 这意味着,如果 E 为 8 位,它的取值范围为 0~255 ;如果 E 为 11 位,它的取值范围为 0~2047 。但是,我们知道,科学计数法中的E 是可以出 现负数的,所以 IEEE 754 规定,存入内存时 E 的真实值必须再加上一个中间数,对于 8 位的 E,这个中间数是127 ;对于 11 位的 E ,这个中间 数是1023 。比如, 2^10 的 E 是 10 ,所以保存成 32 位浮点数时,必须保存成 10+127=137,即 10001001 。

解释下下面代码输出什么

int main()
{
    int n = 9;
    float* pFloat = (float*)&n;
    printf("n的值为:%d\n",n);
    printf("*pFloat的值为:%f\n",*pFloat);

    *pFloat = 9.0;
    printf("n的值为:%d\n",n);
    printf("*pFloat的值为:%f\n",*pFloat);

    return 0;
}

 

输出:

n的值为:9

*pFloat的值为:0.000000

n的值为:1091567616

*pFloat的值为:9.000000

请按任意键继续. .

int main()
{
    int n = 9;
    float* pFloat = (float*)&n;
    printf("n的值为:%d\n",n);
    printf("*pFloat的值为:%f\n",*pFloat);
    //9的二进制:00000000 00000000 00000000 00001001
    //上面二进制第一位:S,第二位到第9位:E,余下位:M
    //E全0所以打印出来就是0.0000000

    *pFloat = 9.0;
    printf("n的值为:%d\n",n);
    printf("*pFloat的值为:%f\n",*pFloat);
    //9.0:1001.0
    //1.001*2^3
    //E=3
    // 0 10000010 001000000000000000
    //0100 0001 0001 0000 0000 0000 0000 0000
    //81 10 00 00
    //

 

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

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

相关文章

函数知识点总结

函数知识点总结 函数知识点总结 一、平面直角坐标系中点的坐标 1. 各象限内2. 坐标轴上3. 各象限角平分线上4. 与坐标轴平行的直线上的点5. 点到坐标轴及原点的距离6. 平面上两点距离 一、平面直角坐标系中点的坐标 1. 各象限内 象限x,yx,\,yx,y 的关系第一象限x>0,y&…

powerDesigner如何将数据库中已有表逆向生成pdm文件

问题背景 系统升级&#xff0c;要在原有数据库表结构基础之上重构表系统&#xff0c;为了节省时间&#xff0c;原来能使用的表结构保留&#xff0c;制作升级变动&#xff0c;所以用到了powerDesigner的逆向生成工具。 解决方案 第一种 创建新的PDM工程 点击左上角File&…

一起Talk Android吧(第四百七十六回:缩放类视图动画)

文章目录使用方法属性介绍示例代码各位看官们大家好&#xff0c;上一回中咱们说的例子是"渐变类视图动画",这一回中咱们说的例子是" 缩放类视图动画"。闲话休提&#xff0c;言归正转&#xff0c;让我们一起Talk Android吧&#xff01;使用方法 缩放类动画…

Servlet进阶2:JSP≈Servlet、MVC=JSP+Servlet

Servlet进阶2一、JSP的运行1. 启动tomcat2. 准备JSP文件3. 将JSP文件放在Tomcat的webapps文件夹下4. 利用Tomcat运行JSP文件二、JSP和Servlet的异同三、MVC JSP Servlet1. Servlet与JSP的优缺点2. MVC的出现一、JSP的运行 1. 启动tomcat 2. 准备JSP文件 <span style&quo…

【Ⅰ绪论】1.数据结构起源

一、起源 1、早期理解 人们都把计算机理解为数值计算工具 数值计算的特点&#xff1a;有数学方程&#xff0c;可以用计算机去做传统的数值计算 比如&#xff1a;一个线性回归的模型【机器学习】 ①根据历史数据&#xff08;黑点&#xff09;&#xff0c;去拟合这条线&#x…

【算法基础】快速排序(分治思想)

一、快速排序原理 1. 算法介绍 快速排序算法通过多次比较和交换来实现排序,其排序流程如下: (1)首先设定一个分界值,通过该分界值将数组分成左右两部分。(记左端为L,最右端为R) 分界点的选取有如下四种方法:(1)q[L];(2)q[(L+R)/2];(3)q[R];(4)随机选取 (2)…

node封装一个控制台进度条插件

说在前面 控制台的进度条大家都见得不少了吧&#xff1f;大家都知道控制台的进度条是怎么实现的吗&#xff1f;最近自己在写几个node脚本工具&#xff0c;期间有需要进度展示的一个需求&#xff0c;所以就顺手写了一个可以自定义的进度条插件&#xff0c;可以直接引入并配置使用…

【自然语言处理】情感分析(三):基于 Word2Vec 的 LSTM 实现

情感分析&#xff08;三&#xff09;&#xff1a;基于 Word2Vec 的 LSTM 实现本文是 情感分析 系列的第 333 篇&#xff0c;前两篇分别是&#xff1a; 【自然语言处理】情感分析&#xff08;一&#xff09;&#xff1a;基于 NLTK 的 Naive Bayes 实现【自然语言处理】情感分析…

web字体和图标 web字体 字体图标

目录web字体和图标web字体字体图标网站图标使用方法&#xff08;font class 版本&#xff08;推荐&#xff09;&#xff09;图标离线使用方法图标使用方法&#xff08;Unicode 版本&#xff09;web字体和图标 web字体 用户电脑上没有安装相应字体&#xff0c;强制让用户下载该…

C++动态内存管理:new 和 delete

目录 一.前言 二.new和delete的基本使用 1.new/delete操作内置类型 三.定位new表达式(placement-new) 四.new操作数出现内存申请错误时的处理方式&#xff1a;抛异常 五.new和malloc的区别 一.前言 C沿用了C语言的底层内存管理机制&#xff1a; 然而在动态内存管理方面&am…

Java——三角形最小路径和

题目链接 leetcode在线oj题——三角形最小路径和 题目描述 给定一个三角形 triangle &#xff0c;找出自顶向下的最小路径和。 每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 1 的两个结点。也就是…

AcWing 1057. 股票买卖 IV(状态机DP)

AcWing 1057. 股票买卖 IV &#xff08;1&#xff09;问题 &#xff08;2&#xff09;分析 这道题我们首先得明确一点&#xff0c;我们只有一支股票&#xff0c;只是这支股票在不同天有着不同的价格&#xff0c;因此我们可以把天作为单位划分不同的状态。同时这道题中还有一个…

极限存在准则 两个重要极限——“高等数学”

各位uu们你们好呀&#xff0c;今天小雅兰要学习的内容仍然是高等数学&#xff0c;是为&#xff1a;极限存在准则 两个重要极限。那现在就让我们一起进入高等数学的世界吧 引例 夹逼准则 准则Ⅰ 数列的夹逼准则 准则Ⅰ’ 函数的夹逼准则 重要极限Ⅰ 准则Ⅱ 单调有界数列必有极…

Servlet进阶1:Servlet原理

Servlet进阶一、Dispatcher二、doGet、doPost、Service方法的区别1. 三者联系2. 使用规则三、Servlet的生命周期四、Servlet、Servlet容器、Web服务器一、Dispatcher 一个Web App就是由一个或多个Servlet组成的&#xff0c;每个Servlet通过注解说明自己能处理的路径。早期的Se…

FreeRTOS-信号量详解

✅作者简介&#xff1a;嵌入式入坑者&#xff0c;与大家一起加油&#xff0c;希望文章能够帮助各位&#xff01;&#xff01;&#xff01;&#xff01; &#x1f4c3;个人主页&#xff1a;rivencode的个人主页 &#x1f525;系列专栏&#xff1a;玩转FreeRTOS &#x1f4ac;保持…

【algorithm】认真讲解前缀和与差分 (图文搭配)

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f4e3;系列专栏&#xff1a;AcWing算法笔记 今天的月色好美 文章目录前言一、前缀和算法1.1 什么是前缀和&#xff1f;1.2 一维前缀和二、二维前缀和三、一维差分四…

Java---微服务---分布式搜索引擎elasticsearch(1)

分布式搜索引擎elasticsearch&#xff08;1&#xff09;1.elasticsearch1.1.了解ES1.1.1.elasticsearch的作用1.1.2.ELK技术栈1.1.3.elasticsearch和lucene1.1.4.为什么不是其他搜索技术&#xff1f;1.1.5.总结1.2.倒排索引1.2.1.正向索引1.2.2.倒排索引1.2.3.正向和倒排1.3.es…

表单标签的使用

1、input标签 场景&#xff1a;在网页中显示收集用户消息的表单效果&#xff0c;如登录页、注册页 通过type属性值的不同&#xff0c;展示不同的效果 type属性值说明text文本框&#xff0c;用于输入单行文本password密码框&#xff0c;用于输入密码radio单选框&#xff0c;用…

检查 malloc 函数返回内容的四个理由

写在前面&#xff1a; 一些开发人员可能对检查不屑一顾&#xff1a;他们故意不检查malloc函数是否分配了内存。他们的推理很简单——他们认为会有足够的记忆。如果没有足够的内存来完成操作&#xff0c;请让程序崩溃。似乎是一个糟糕的事实。 注意。在本文中&#xff0c;mall…

Opencv 之 DNN 与 CUDA综述

Opencv 之 DNN 与 CUDA 目录 Opencv官方手稿&#xff08;包含各模块API介绍及使用例程&#xff09; Opencv在github的仓库地址&#xff1a;https://github.com/opencvOpencv额外的测试数据 下载&#xff1a;https://github.com/opencv/opencv_extra #可通过git下载拉取 git c…