【C语言】数据的存储

目录

一、 数据类型详细介绍

1.数据类型的基本归类

(1)整型家族

(2)浮点型家族

(3)构造类型

(4)指针类型

2.整型在内存中的存储

(1)正整数

(2)负整数

(3)补码存储数据的意义

二、原、反、补码的具体应用

1.截断和整型提升

2.算数转换

(1)当无符号数和有符号数进行比较时,会发生算数转换,比较两数的补码。

(2)当不同类型的数在同一个表达式中进行运算时,会发生算数转换。

三、大、小端字节序存储模式

1.大端字节序存储

(1)大端存储

(2)小端存储

2.意义

四、有符号位和无符号位字符类型的数值范围

五、浮点型在内存中的存储

1.举例

2.浮点数存储规则

(1)详细解读

(2)具体存储方式


一、 数据类型详细介绍

1.数据类型的基本归类

(1)整型家族

char 类型:  char 、unsigned char、signed char

short类型:     short/signed short、unsigned short

int类型:       int/signed int、unsigned int

long(long long)类型:      long/signed long、unsigned long

注:

1.短整型和长整型后的int可加可不加。

2.short类型、int类型、long类型在不写明unsigned或者signed的时候,系统默认为为有符号类型,但char类型由具体的编译器决定

(2)浮点型家族

单精度浮点型float

双精度浮点型double

(3)构造类型

数组类型

结构体类型 struct

枚举类型 enum

联合类型 union

(4)指针类型

整型指针int* p

字符型指针char* p

浮点型指针float* p

空类型指针void* p

注:空类型指针可以接受所有类型变量或常量的地址,但是必须强制类型转换才能解引用,因为无法判断空类型指针解引用可以访问多大的空间

2.整型在内存中的存储

    整型在内存中以补码的方式存在。

(1)正整数

    正数的原、反、补码都相同。

(2)负整数

    负数的原、反、补码表示方式各不相同

    原码:直接将数值转化为对应的二进制数,即为原码

    反码:在原码的基础上,除符号位之外,其他位(数值位)按位取反

    补码:反码+1

(3)补码存储数据的意义

     符号位与数值位统一处理;加法减法统一处理

    另外:原码 -> 补码   取反+1;补码 ->  原码   -1取反/取反+1 两种转换运算过程相同,不需要额      外的硬件电路。

二、原、反、补码的具体应用

1.截断和整型提升

例题:

#include <stdio.h>

int main()
{
	unsigned char a = 200;
	//00000000 00000000 00000000 11001000
	//11001000    a   截取
	unsigned char b = 100;
	//00000000 00000000 00000000 01100100
	//01100100    b   截取
	//a+b  整型提升
	//00000000 00000000 00000000 11001000  a
	//00000000 00000000 00000000 01100100  b
	//00000000 00000000 00000001 00101100  a+b  补码  正数,原码等于补码  300

	unsigned char c = 0;
	//00000000 00000000 00000000 00000000
	//00000000 截断
	c = a + b;
	//00000000 00000000 00000001 00101100  截断得到   00101100   32+8+4=44   赋值给c
	printf("%d %d", a + b, c);
	return 0;
}
//输出结果: 300 44

   当原数值的字节数大于将要赋值的对象时,会进行截断操作,选取从低位到高位截取相应长度的部分赋值;当数值输出前未及输出格式对应的字节长度,会进行整型提升,如果是无符号整型或有符号但符号位为0(为正),则整型提升的部分全为0,如果是有符号整型且符号位为1(为负),则整型提升的部分全为1。

注:在内存中的存储和表达式计算都是使用补码;打印是原码。

2.算数转换

(1)当无符号数和有符号数进行比较时,会发生算数转换,比较两数的补码。

举例:

#include <stdio.h>

int i;
int main()
{
    i--;
    if (i > sizeof(i))
    {
        printf(">\n");
    }
    else
    {
        printf("<\n");
    }
    return 0; 
}

 内容解释:i是全局变量,系统默认为初始化为0,i--;后i的值变为-1,此时i是有符号整型;而sizeof()是用来计算变量字节大小的,其返回值是无符号整型,当两数进行比较时,i进行算术转换转为无符号数,而-1的补码是11111111 11111111 11111111 11111111转为无符号数后表示2^32-1,很明显,比sizeof(i)也就是4大。所以输出结果是  > 。

(2)当不同类型的数在同一个表达式中进行运算时,会发生算数转换。

比如,当char类型、int类型、float类型、double类型的数进行运算时,会一步一步进行算数转换。

例题1:

假定 x 和 y 为 double 型,则执行 x=2; y=x+3/2; 后y的值为(D)

A 3.500000

B 3

C 2.000000

D 3.000000

思路分析:3/2==1,x和1进行运算前1从整型转换成double型与x进行加法运算,然后赋值给y,所以y的值为3.000000,故选D。

例题2:

char a; int b; float c; double d;

则表达式a*b+c-d值的类型为double类型。

三、大、小端字节序存储模式

1.大端字节序存储

(1)大端存储

数据的低位保存在内存的高地址中,数据的高位保存在内存的低地址中。

(2)小端存储

数据的低位保存在内存的低地址中,数据的高位保存在内存的高地址中。

2.意义

一个byte是8个bit位,当数据的存储需要大于一个字节的存储空间时,字节的排序成了一个问题,其他可能可行的排序方法都比较凌乱,读取比较困难,大小端的两种存储方式就比较方便。

例题:

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

#include <stdio.h>

int main()
{
    int a = 1;
    char* p = (char*)&a;

    if(*p == 1)
        printf("小端\n");
    else
        printf("大端\n");

    return 0;
}

解释:char*类型指针p只能访问一个字节的空间,如果a是小端字节序,则p可以访问的部分是0x01,*p=1;如果是大端字节序,则p可以访问的部分是0x00,*p=0。可以由此判断是大端还是小端。

四、有符号位和无符号位字符类型的数值范围

 -128~127(不能表示128)

五、浮点型在内存中的存储

1.举例

//浮点数在内存中的存储
#include <stdio.h>

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

 为什么输出结果两两不相同?  

初步推测是因为整型和浮点型在内存中的存储方式不同。

2.浮点数存储规则

(1)详细解读

任意二进制数都可以表示为(-1)^S * 1.M * 2^e,其中S为0或1,M是尾数部分,e是指数部分。

例如:(-15)10 = (-1111)2 = (-1.111 * 2^3)2

根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成标准化格式的浮点数: (-1)^S * M * 2^E,其中,E = e+127。

上面的例子中,S = 1,E = e + 127 = 1000 0010,M = 1110...0(最后一个1后面共20个0)

(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。

M表示尾数部分。

E表示指数在内存中的实际存储。

(2)具体存储方式

float类型

32个比特位,最高位存放符号位;其次的8个比特位存放指数部分,实际存储的值为127+指数;剩余23个比特位存放有效值部分(尾数部分),因为必为1.。。。所以存储时将1舍弃,读取时再将1加上。

double类型

与上类似;

64个比特位,最高位存放符号位;其次的11个比特位存放指数部分,实际存储的值为1023+指数,如果出现全0的情况,则该数通常很小,无限接近于0;剩余52个比特位存放有效值部分(尾数部分),因为必为1.。。。所以存储时将1舍弃,读取时再将1加上。 

结语:数据的存储是C语言的一个重要内容,希望大家都能理解并掌握。

本文中如果出现了错误,烦请各位大佬斧正!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值