C语言进阶学习笔记之数据的存储(上)

本文详细介绍了编程中的数据类型,包括整型(有符号、无符号)、浮点型,以及构造类型如数组、结构体、枚举和联合。重点讨论了指针类型和空类型void。深入讲解了整型在内存中的存储机制,如原码、反码和补码的概念,并通过实例展示了大小端字节序的判断方法。文章还提供了几个练习题,以加深读者对整型提升和内存表示的理解。

🍋数据类型详细介绍

在这里插入图片描述

类型的意义:
1.使用这个类型开辟内存空间的大小(大小决定了使用的范围)。比如:如果使用char类型的变量就向内存中申请一个字节的空间。类型决定了使用这个类型所申请的空间的大小。
2.如何看待内存空间的视角。比如:int类型和float类型同样是占四个字节的内存空间,站在int类型的角度里面存放的是整型,站在float的角度里面存放的是浮点数。

🍒整型的基本归类

在这里插入图片描述

字符的本质是ASCII码值,是整型,所以划分到整型家族。对于整型int来说,int相当于signed int 有符号的整型。而char类型不同,char到底是signed char还是signed char标准是未定义的,取决于编译器的实现。

在这里插入图片描述

上图,如果a是无符号整型的话,符号位是1时,就是2^31次方。如果需要创建一个有正负数的就用int或者signed int,如果创建的数不需要正负,就用unsigned int。

🍒浮点型的基本归类

在这里插入图片描述

🍒构造类型(自定义类型)

数组类型
结构体类型 struct
枚举类型 enum
联合类型 union

int arr1[5],去掉数组名arr1就是它的类型。int arr2[8],去掉数组名,int [8]就是它的类型。可以看到每次换元素个数,就是一个新的数组类型。

🍒指针类型

int *pi;
char *pc;
float *pf;
void *pv;!

🍒空类型

void表示空类型(无类型)
通常应用于函数的返回类型、函数的参数、指针类型。

在这里插入图片描述

🍋整型在内存中的存储

数值有不同的表示形式,2进制、8进制、10进制、16进制

十进制的21,转换成二进制就是0b10101,转换成八进制就是025,十六进制就是0x15。在这里插入图片描述

🍒原码、反码、补码

整数的二进制也有三种表示形式:
原码:根据一个数的正负直接用二进制写出来就是它的原码。
反码:原码符号位不变,数值位按位取反。
补码:反码加一就是补码。
前提:
1.正的整数,原码、反码、补码相同。
2.负的整数,原码、反码、补码,需要通过计算

在内存中到底存放的是原码、反码、还是补码呢?
来看看下面这个例子:
在这里插入图片描述

我们通过调试直接打开内存
在这里插入图片描述

查看a和b的地址
我们倒着读发现,整数内存中存放的是补码的二进制序列。
&a:在这里插入图片描述
&b:
在这里插入图片描述

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

🍒大小端字节序及其判断

上面看到的补码存放的二进制序列是倒着存放的。这是为什么呢?这就涉及到了大小端字节序的问题。

什么是大小端:
大端字节序(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
小端字节序(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。

为什么会有大小端:
这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8 bit的char之外,还有16 bit的short型32 bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。在这里插入图片描述>如图:在内存中存放一个十六进制数字,在十六进制中一位等于二进制中四个比特位,两个十六进制位就等于八个比特,也就是一个字节,十六进制中就有四个字节,在内存中就涉及到字节的存放问题。我们可以看到,它在内存中可以储存的方式五花八门,但是会发现这样会很麻烦,所以最后只有两种储存方式。

设计一个小程序来判断当前机器的字节序。
解析:假设一个整型a等于1,那它存储在内存中就会是如下图所示的两种模式。我们可以看到,当取出a的第一个字节时,可能取出0或者1。取出的是1的时候说明此时的机器存储是小端模式;取出的是0时,则是大端模式。
在这里插入图片描述

代码如下:

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

实现效果:
在这里插入图片描述

🍒练习

知识先导:
整形提升是按照变量的数据类型的符号位来提升的。
有符号数和无符号数的内存:singned char取值范围是-127-128,unsigned char的取值范围是0-255。如下图所示。
在这里插入图片描述在这里插入图片描述

接下来是几个练习,我们来看看以下的程序会输出什么?

练习一

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

这个程序输出的是什么?我们来看看。
在这里插入图片描述

解析:在这里插入图片描述
在这里插入图片描述

练习二

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

在这里插入图片描述

解析:在这里插入图片描述

练习三

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

在这里插入图片描述

解析:
在这里插入图片描述

写在最后🍎:码字不易,如果对你有帮助的话,给个三连或者关注一下吧🍰,感谢支持!📣

评论 24
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值