C语言进阶——数据在内存中的存储
Posted better,faster
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言进阶——数据在内存中的存储相关的知识,希望对你有一定的参考价值。
目录
数据类型的基本归类
数据类型的介绍
在学习一定的C语言初阶知识后,我们知道以下的基本数据类型:
char 字符数据类型
short 短整型
int 整形
long 长整型
long long 更长的整形
float 单精度浮点数
double 双精度浮点数
数据类型的意义
1.使用这个类型开辟内存空间的大小
在我们定义一个数据后,会在内存中动态分配一块内存来存储这个数,这快内存需要分配多大的空间就由定义的数据的类型决定。
2.如何看待内存空间视角
在写入数据后,在读取这块内存空间时,我们需要根据不同的数据类型去读取这块内存。
基本归类
整形类型:
char
unsigned char //注意:char类型存储的是ASCII值因此归为整形
signed char //C语言并没有规定char是unsigned还是signed的
short
unsigned short [int]
signed short [int]
int
unsigned int
signed int
long
unsigned long [int]
signed long [int]
浮点型:
float
double
//以下为了解内容,本文不做重点讲解
构造类型(自定义):
数组
#include<stdio.h>
int main()
{
int arr[10]; // int [10] 这就是一种类型
int arr2[5]; //int [5] 另一种类型
return 0;
}
struct 结构体类型
enum 枚举
union 联合体
指针类型:
int* pi
char* pc
float* pf
void* pv
空类型:
void
函数返回类型 void test()
函数参数 void test(void)
指针 void* p
整形在内存中的存储
数据在内存中是以二进制的形式存在
对于整数 :在内存中以补码形式存储(为什么以补码的形式存储,我们先了解以下知识)
补码
计算机中整数分无符号数和带符号数两种,带符号指的是数的第一位 为它的符号位,0代表正数,1代表负数,无符号数则没有符号位之分,全部为正数。
带符号数有三种形式 :原码、反码、补码
三种形式的都由两部分组成:符号位:数值的第一位,代表数据的正负,0代表正,1代表负
数值位:原码,补码,补码在数值位有区别
正整数的原码、反码、补码都相同
负整数的补码需要计算,方法如下:
原码-------------------------------------------------------------------反码--------------------------------------------------------补码
(直接按正负写出) (符号位/第一位不变,其他位取反——0变1.1变0;) (反码加一)
举个“栗子”:
#include<stdio.h>
int main()
{
int a = -10;
//原码:10000000 00000000 00000000 00001010 写出二进制序列即可,负数第一位为1
//反码:11111111 11111111 11111111 11110101 第一位不变,其他按位取反
//补码:11111111 11111111 11111111 11110110 加一
return 0;
}
unsigned char 和 signed char
前面提到char类型在内存中以转换的ascii码整数类型存储,所以也算是整型家族。
无符号的char类型:与正整数一样,只能表示正数,范围在0-255
带符号的char类型:
①规定的1000 0000为-128,不能按上述计算,因为会导致进位溢出,所以人为规定。
②范围:-128——127
图解如下:
为什么是补码
在明白补码是什么之后,你是否也有疑惑,为什么不是原码存储,而是选择复杂的补码呢?
原因如下:
使用补码,可以将符号位和数值位统一处理;
CPU只有加法器,在计算减法时,需要转化成加负数;
补码与原码相互转换,运算过程相同(即取反,在+1),不需要额外的硬件电路,运用取反电路和加法电路即可完成。
例子:
#include<stdio.h>
int main()
{
int a = 10;
int b = -10;
//原码计算:
//10:00000000 00000000 00000000 00001010
//-10:10000000 00000000 00000000 00001010
//等于:100000000 00000000 00000000 00010100 -20显然错误
//补码计算:
//10: 00000000 00000000 00000000 00001010
//-10: 11111111 11111111 11111111 11110110
//等于 00000000 00000000 00000000 00000000 结果为0,正确
return 0;
}
大端 小端
在知道了整数是以二进制补码的形式存储后,还有一个问题需要解决。整型多字节时,需要不止一个存储单元存放,在存储单元中有两种分配方式
大端存储模式:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。
小端存储模式:是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中。
如图就是大端的存储方式:
将00000001放入,将低位的01放在高地址,类比可知将01放在低地址就是小端存储,不同的存储模式在不同的编译器中是不同的。
实例:判断当前机器的字节序:
设计一个程序判断当前机器的字节序(即判断是大端存储还是小端存储)。
#include<stdio.h>
int main()
{
int a = 1;
char* p =(char*) &a;//int型强转为char型,只观察一个字节
if (*p == 1)//首地址是1,即为小端
{
printf("小端");
}
else //为0为大端
{
printf("大端");
}
return 0;
}
优化:设计一个函数实现
int check_sys()
{
int a = 1;
return *(char*)&a;//返回1表示小端,返回0表示大端
}
int main()
{
int ret = check_sys();
if (ret == 1)
{
printf("小端\\n");
}
else
{
printf("大端\\n");
}
return 0;
}
以上是关于C语言进阶——数据在内存中的存储的主要内容,如果未能解决你的问题,请参考以下文章