当前位置: 首页 > news >正文

4.数据存储**

目录

1. 整形存储规则,原反补

2. 大小端及如何判断(常考)

3. 类型提升和截断

1.这个程序输出什么:(无符号char提升为int)

2. 这个程序输出什么:

3.这个程序输出什么:

4.这个程序输出什么:

4.浮点数的存储(很少考)


1. 整形存储规则,原反补

计算机中的整数有三种表示方法,原码,反码,补码。

三种表示方法均有符号位和数值位两部分,符号位都是用0表示正,1表示负,而数值位这三种表示方法各不相同。

原码:直接按照正负数的形式翻译成二进制就可以

反码:将原码的符号位不变,其他位按位取反

补码:反码+1就是补码

正数的原反补是相同的,对于整形来说:数据存放内存中其实存的是补码。

为什么?

        使用补码可以将符号位和数值部分统一处理;同时,CPU只有加法器,补码可以让加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程相同,不需要额外的硬件电路。

int main()
{
    int a = 20;
    int b = -2;
    return 0;
}

上面是紫色的&b的值,绿色的是&a的值,可以看出a,b分别存的是补码。但是我们发现顺序有点不对劲。

2. 大小端及如何判断(常考)

大端:数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中。

小端:数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。

上面的例子就是小端,-2的补码:ff ff ff fe,fe是数据的低位,保存在5ffe58这个低位

上一章讲联合的时候我们讲过一种判断大小端的方法。

这里是另一种:

int check_sys()
{
    int i = 1;
    return (*(char *)&i);
}

int main()
{
    if (check_sys())
        printf("小端\n");
    else
        printf("大端\n");
}
  • (char *)&i 将这个地址强制转换为 char* 类型,即指向 char 的指针。这样做的目的是为了能够访问 i 的第一个字节(低地址)。

  • *(char *)&i 解引用这个指针,获取 i 的第一个字节的值。

  • 如果系统是小端序,最低有效字节存储在内存的低地址处,因此 i 的第一个字节是 1check_sys() 返回 1

  • 如果系统是大端序,最高有效字节存储在内存的低地址处,因此 i 的第一个字节是 0check_sys() 返回 0

3. 类型提升和截断

  • 类型提升是为了避免数据丢失,自动将较小的类型转换为较大的类型。

  • 类型截断可能导致数据丢失,通常发生在将较大的类型赋值给较小的类型时。

1.这个程序输出什么:(无符号char提升为int)

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;
}
  • ab 的输出

    • ab 都是有符号字符类型,值为 -1

    • charsigned char 被提升为 int 时,会按符号位提升-1 的二进制表示为 11111111(8 位),提升为 int 后变为 11111111 11111111 11111111 11111111(32 位),仍然是 -1

    • 因此,ab 的输出都是 -1

  • c 的输出

    • c 是无符号字符类型,值为 255(因为 -1 被解释为无符号数)。

    • unsigned char 被提升为 int 时,高位补0255 的二进制表示为 11111111(8 位),提升为 int 后变为 00000000 00000000 00000000 11111111(32 位),仍然是 255

    • 因此,c 的输出是 255

2. 这个程序输出什么:

int main()
{
    char a = -128;
    printf("%u\n", a);
    return 0;
}
  1. char a = -128; 的二进制表示

    • char 是 8 位有符号类型,范围是 -128127

    • -128 的二进制补码表示是 10000000(8 位)。

  2. a 被提升为 int

    • char 被提升为 int 时,符号位会扩展。-128 的二进制表示为 10000000(8 位),提升为 int 后变为 11111111 11111111 11111111 10000000(32 位),这仍然是 -128

  3. %u 格式输出

    • %u 是无符号整数格式,它会将 int 类型的值解释为无符号整数。

    • -128 的二进制补码表示为 11111111 11111111 11111111 10000000(32 位),直接解释为无符号整数时,其值为 4294967168(即 2^32 - 128)。

3.这个程序输出什么:

int main()
{
    char a = 128;
    printf("%u\n", a);
    return 0;
}
  1.  char a = 128;
  • char 类型通常是一个 8 位有符号整数,取值范围是 -128127

  • 赋值 128char 类型的变量 a 时,128 超出了 char 的范围,因此会发生 类型截断

  • 128 的二进制表示为 10000000。对于有符号的 char 类型,最高位是符号位,10000000 被解释为 -128(因为这是有符号整数的二进制补码表示)。

4.这个程序输出什么:

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

1. 变量定义

  • unsigned char a = 200;

    • unsigned char 是无符号字符类型,占用 8 位,取值范围是 0255

    • a 被赋值为 200,这是一个合法的值。

  • unsigned char b = 100;

    • b 被赋值为 100,这也是一个合法的值。

  • unsigned char c = 0;

    • c 被初始化为 0

2. c = a + b;

  • a + b 的计算:

    • a 的值是 200b 的值是 100

    • a + b = 200 + 100 = 300

  • 但是,unsigned char 的取值范围是 0255300 超出了这个范围。

  • 由于 unsigned char 是 8 位无符号整数,超出范围的值会被 截断,只保留低 8 位。

    • 300 的二进制表示是 100101100(9位)

    • 只保留低 8 位,得到 00101100,即 44

  • 因此,c 被赋值为 44

最后打印时类型提升为int。

4.浮点数的存储(很少考)

        了解一下整数部分怎么存,小数部分怎么存。

相关文章:

  • Attention又升级!Moonshot | 提出MoE注意力架构:MoBA,提升LLM长文本推理效率
  • Python爬虫实战:基于 Scrapy 框架的腾讯视频数据采集研究
  • 蓝桥-数字接龙
  • 事业单位ABCDE类
  • qwen2.5-vl使用vllm部署gradio页面调用
  • 网络安全防护总体架构 网络安全防护工作机制
  • TC IT 技术图标
  • 深入理解与应用 JavaScript 中的回调函数
  • 前端UI编程基础知识:Flex弹性布局
  • ICMP、UDP以及IP、ARP报文包的仲裁处理
  • css动画实现铃铛效果
  • springboot EasyExcel 实现导入导出
  • 麒麟系统如何安装Anaconda
  • JobScheduler省电机制
  • 【渗透测试】反弹 Shell 技术详解(二)
  • Easyocr图片识别小结
  • Flutter_学习记录_ ImagePicker拍照、录制视频、相册选择照片和视频、上传文件
  • 无监督学习——降维问题:主成分分析(PCA)详解
  • 【原创】在宝塔面板中为反向代理添加Beare认证
  • 【Linux 指北】常用 Linux 指令汇总
  • 网站建设工作流程/百度爱采购官网
  • 海林建设局网站/杭州优化seo公司
  • 还有专门给别人做性奴的网站/做小程序要多少钱
  • 有了域名空间怎么做网站/十大舆情网站
  • 建设自己的网站首页/怎么把广告发到各大平台
  • js做网站登录界面/网络营销有什么特点