C语言 – 深度剖析数据的存储 上

文章目录

  • 一、数据类型详细介绍
    • 1、内置类型
    • 2、类型的意义
    • 3、类型的归类
      • 1、整型家族
      • 2、浮点型家族
      • 3、构造类型(自定义类型)
      • 4、指针类型
      • 5、空类型
  • 二、整型在内存中的存储
    • 1、原码、反码、补码
    • 2、为什么在内存中是以补码的形式进行存储
    • 3、-10的存储
  • 三、大小端字节序
    • 1、什么是大端小端
    • 2、为什么会有大端小端
    • 3、实例
      • 1、百度2015年系统工程师笔试题
      • 2、输出什么?
      • 3、输出什么?
      • 4、输出什么?
      • 5、char类型变量的取值范围(敲黑板)
      • 6、输出什么?
      • 7、输出什么?
      • 8、输出什么?
      • 9、输出什么?
  • 四、简单了解整型和浮点型的头
    • 1、整型
    • 2、浮点型
  • 五、浮点型在内存中的存储
    • 1、先看一个例子
    • 2、进一步探讨
      • 1、标准规定
      • 2、举例解读标准
        • 例1:
        • 例2:

一、数据类型详细介绍

1、内置类型

内置类型就是C语言中自带的数据类型。在之前的学习中也有一定的了解:

char

short

int

long

long long

float

double

2、类型的意义

  • 1、使用这个类型开辟内存空间的大小(大小决定了使用范围)
  • 2、如何看待内存空间的视角

3、类型的归类

1、整型家族

C语言 - 深度剖析数据的存储 上

2、浮点型家族

C语言 - 深度剖析数据的存储 上

3、构造类型(自定义类型)

C语言 - 深度剖析数据的存储 上

数组也是一种自定义类型,数组去掉数组名就是类型

int main()
{
    int arr[10];//int [10]
    int arr[5];//int [5]
    return 0;
}

4、指针类型

5、空类型

void表示空类型(无类型)

通常应用于函数的返回类型、函数的参数、指针类型

二、整型在内存中的存储

1、原码、反码、补码

数据在内存中是以二进制的形式进行存储的。对于整数来说,整数的二进制有3种表示形式:原码、反码、补码

对于正负整数来说有符号位之分:如果为正,高位为0;如果为负,高位为1

正整数:原码、反码、补码相同

---------------------------------------------------------分割-----------------------------------------------------------------------

负整数:原码、反码、补码之间的转换是需要计算的

原码:根据数值直接写出它的二进制序列

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

补码:反码+1

注意:整数在内存中存储的是补码,而打印出来给人看到的是原码

2、为什么在内存中是以补码的形式进行存储的

CPU只有加法器,只可以做加法运算,减法等运算都是用加法去模拟的

官方来说:在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理(CPU只有加法器),此外,补码和原码相互转换,其运算过程是相同的,不需要额外的硬件电路

C语言 - 深度剖析数据的存储 上

验证补码在内存中存储并计算:

1 - 1 -> 1 + (-1):

--------------------------------------使用原码进行计算-------------------------------------

C语言 - 深度剖析数据的存储 上

--------------------------------------使用补码进行计算-------------------------------------

3、-10的存储

这里有一个点就是在当前编译器下-10在内存中是倒着存储的

C语言 - 深度剖析数据的存储 上

三、大小端字节序

这里将会解答倒着存储的问题

1、什么是大端小端

大端(存储)模式,是指将数据的高字节内容放到内存的低地址处。而数据的低字节内容放到内存的高地址处

小端(存储)模式,是指将数据的高字节内容放到内存的高地址处。而数据的低字节内容放到内存的低地址处

C语言 - 深度剖析数据的存储 上

2、为什么会有大端小端

这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着1个字节,1个字节为8bit。但是在),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。

3、实例

1、百度2015年系统工程师笔试题

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

概念就不说了,上面有的

#include<stdio.h>
int check_sys()
{
    int a = 1;
    char* p = (char*) &a;
    return *p;//返回1表示小端,返回0表示大端
}
int main()
{
    int ret = check_sys();
    if(1 == ret)
        printf("小端\n");
    else
        printf("大端\n");
    return 0;
}

2、输出什么?

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

结果:

a=-1, b=-1, c=255

分析:

-----------------------------------a-----------------------------------

C语言 - 深度剖析数据的存储 上

-----------------------------------b-----------------------------------

同a

-----------------------------------c-----------------------------------

C语言 - 深度剖析数据的存储 上

-----------------------------------------分割线--------------------------------------------------------------------------

补充:

1、char是signed char还是unsigned char。C语言并没有规定,取决于编译器(大多数编译器下是signed char)

2、int、short是signed是C语言规定的

3、输出什么?

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

结果:

4294967168

分析:

C语言 - 深度剖析数据的存储 上

4、输出什么?

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

结果:

4294967168

分析:C语言 - 深度剖析数据的存储 上