文章目录
前言
我们平时编程时经常存储数据,但是我们往往会忽视数据在内存中是如何创建的,希望看完这篇文章能够对你有些启发。
一、数据类型的介绍
C语言包含的数据类型广泛,不仅包含有传统的字符型、整型、浮点型、数组类型等数据类型,还具有其他编程语言所不具备的数据类型,其中以指针类型数据使用最为灵活,可以通过编程对各种数据结构进行计算。
表列出了关于标准整数类型的存储大小和值范围的细节:
类型 | 存储大小 | 值范围 |
---|---|---|
char | 1 字节 | -128 到 127 或 0 到 255 |
unsigned char | 1 字节 | 0 到 255 |
signed char | 1 字节 | -128 到 127 |
int | 2 或 4 字节 | -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647 |
unsigned int | 2 或 4 字节 | 0 到 65,535 或 0 到 4,294,967,295 |
short | 2 字节 | -32,768 到 32,767 |
unsigned short | 2 字节 | 0 到 65,535 |
long | 4 字节 | -2,147,483,648 到 2,147,483,647 |
unsigned long | 4 字节 | 0 到 4,294,967,295 |
1.整形家族
char unsigned char signed char short unsigned short [ int ] signed short [ int ] int unsigned int signed int long unsigned long [ int ] signed long [ int ]在这里,我们很好奇char为什么也属于整形?原因:char不属于标准整形,
但是char兼容整形,可以看成是一个字节的整形。case中可以用char型的常量,不能是char变量。因为char型的常量对应确定的ascii码值,是一个确定的值。(直接创建的short为有符号的)
我们又提出了一个疑问?什么是有符号的数?什么是无符号的数?
(1)有正负的数据可以放在有符号的变量中
(2)没有正负的数据可以放在无符号的变量中
2.浮点数家族
float double3.构造类型
> 数组类型 > 结构体类型 struct > 枚举类型 enum > 联合类型 union 数组的类型是去掉数组名剩下的部分 例如 :int arr[10]={0};//arr数组的类型是int [10]二、整形在内存中的存储
我们知道创建一个整型变量要在内存中开辟一块空间,但是要怎样存储呢?
计算机底层存储数据时使用的是二进制数字,但是计算机在存储一个数字时并不是直接存储该数字对应的二进制数字,而是存储该数字对应二进制数字的补码。所以接下来我们需要来了解一下原码、反码和补码。(内存中存储的是补码)
对于负整数来说
(1)原码:
原码是将数值从十进制改写为二进制
(2)反码:
反码是将原码(符号位不变)按位取反
(3)补码:
反码加一
对于正整数来说
原码反码补码相同,将数值从十进制改写为二进制
我们比较好奇为什么要存取补码?
例:我们来计算 1-1,相当于1+(-1)
1//00000000000000000000000000000001因为1是整数原码,反码,补码相同
-1//10000000000000000000000000000001原码
//1111111111111111111111111111111111110反码
//11111111111111111111111111111111111111补码
//100000000000000000000000000000000 1与-1的补码相加
得到33位,int行只能存储32位,所以把1舍去得到000000000000000000000000000000000000(32个0)符号位为0,原,反,补,码均为0所以1-1=0
三、大小端
一、什么是大小端?
对于一个由2个字节组成的16位整数,在内存中存储这两个字节有两种方法:一种是将低序字节存储在起始地址,这称为小端(little-endian)字节序;另一种方法是将高序字节存储在起始地址,这称为大端(big-endian)字节序。
二、大小端的判断
我们要知道一个系统是大端字节存储,还是小端字节存储。我们只需要知道第一字节存放的内容就可判断,这时我们想到利用char *类型的指针来操作字符
以下为具体代码
#include<stdio.h>
int panduan()
{
int a = 1;
return *(char*)&a;
}
int main()
{
int ret = panduan();
if (ret == 1)
{
printf("该操作系统为大端存储\n");
}
else
{
printf("该操作系统为小端存储\n");
}
return 0;
}
总结:
大端是高字节存放到内存的低地址
小端是高字节存放到内存的高地址