详细介绍:C语言数据的存储
目录
本章重点
1.数据类型详细介绍
2.整形在内存中存储:源码、反码、补码
3.大小端字节序介绍及判断
4.浮点型在内存中存储解析
1、数据类型介绍
C语言中内置类型:
| char | 字符数据类型 | 1字节 |
| short | 短整型 | 2个字节 |
| int | 整形 | 4个字节 |
| long | 长整型 | 4/8字节;32位机器上4个字节64位机器上8个字节 |
| long long | 更长的整型 | 8个字节(c99出现的long long) |
| float | 单精度浮点数 | 4字节 |
| double | 双精度浮点数 | 8字节 |
类型的意义:
1、使用这个类型开辟内存空间的大小(大小决定了使用范围)
2、如何看待内存空间的视角。
1.1类型的基本归类
整形家族:
char
unsigned char
signed char
short
unsigned short [int]
signed short [int]
int
unsigned int
signed int
long
unsigned long
signed long
long long
unsigned long long [int]
signed long long [int]
char 字符类型的本质是ASCII码值,是整型,所以划分到整型家族。
char到底是signed char还是unsigned char标准是未定义的,取决于编译器的实现。
有符号和无符号的意义:
在生活中有些数据是没有负数的,比如身高、体重、长度等。
浮点型家族
float.
double
浮点类型家族:只要是表示小数就可以使用浮点型。flaot的精度低,存储的数值范围较小,double的精度高,存储的数据的范围更大。
构造类型:
数组类型
结构体类型 struct
枚举类型 enum
联合类型 union
构造类型(自定义类型):我们可以自己创建出新的类型。
指针类型
int* pi;
char *p;
void *p;
空类型:
void 表示空类型(无类型)
通常应用于函数的返回类型,函数的参数,指针类型。
//第一个void表示函数不会有返回值
//第二个void表示函数不需要传参数。
void test(void){ //一个函数
}
2、整型在内存中存储
我们之前提到过一个变量的创建是要在内存中开辟空间的。空间的大小是根据不同的类型而决定的。
接下来我们谈一谈数据在所开辟内存中到底是如何存储的?
比如:
int a = 20;
int b = -10;
我们知道为a分配四个字节的空间。
那如何存储?
下来了解下面的概念:
2.1 源码、反码、补码
计算机中的整数有三种2进制表示方式,即源码、反码和补码。
三种表示方式均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位正数的源、反、补码都相同。
负整数的三种表示方式各不相同。
源码:
直接将数值按照正负数的形式翻译成二进制就可以得到源码。
反码:
将源码的符号位不变,其他位依次按位取反就可以得到反码。
补码:
反码 + 1 就是补码。
对于整形来说:数据存放内存中其实存放的是补码。
为什么呢?
在计算器系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;
同时,加法和减法也可以统一处理(cpu只有加法器)此外,补码与源码相互转换,其运算过程是相同的,不需要额外的硬件电路。(源码和补码相互转换都是取反 + 1)。
例如:计算1 - 1——> 1 + (- 1)
00000000 00000000 00000000 00000001——>1的补码
11111111 11111111 11111111 11111111——>-1的补码
相加:
1 00000000 00000000 00000000 00000000——>33位了,截断得到结果为0。
我们看一下再内存中的存储:

我们可以看一下a存储的补码。但是发现存储的顺序有点不对劲
这是为什么呢?
2.2 大小端介绍
什么大端小端:
大端(存储)模式,是指数据的低位保存在内存的高地址,而数据的高位,保存在内存的低地址中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中。
为什么有大小端?
这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
例如:一个16bit的short型x,在内存中的地址0x0011,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在地址值中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的x86结果是小端模式,而KETL C51则为大端模式,很多的ARM,DSP都为小端模式,有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。
百度2015年系统工程师笔试题:
请简述大端字节和小端字节序的概念,设计一个小程序来判断当前机器的字节序(10分)。
代码1:
int check_sys() {
int i = 1;
return *((char*)&i);
}
#include
int main() {
int ant = check_sys();
if (ant == 1) {
printf("小端");
}
else {
printf("大端");
}
return 0;
}

代码2:利用联合(共用体)
union un {
int i;
char c;
}s;
int check_sys(union un* s) {
s->i = 1;
return s->c;
}
#include
int main() {
int ant = check_sys(&s);
if (ant == 1) {
printf("小端");
}
else {
printf("大端");
}
return 0;
}
2.3 练习
有符号的char取值范围 -128 - 127
无符号的char的取值范围是 0 - 255
有符号的short的取值范围 - 32768 ~ 32767
无符号的short的取值范围 0 ~ 65535
练习1:

练习2:

练习3:

练习4:

代码5:
代码5出现死循环。
代码6:

strlen是求字符串的长度,关注的是字符串中‘\0‘(就是0)之前出现多少字符。
代码7:
死循环:原因是因为无符号char类型范围在0 - 255不可能下于255,。所以出现死循环。

代码8:

如果比较两个字符串的长短可以直接比较不要用相减;strlen("abc") < strlen("abcv").或者强制类型转换为int类型。
3、浮点型在内存中存储
常见的浮点数:
3.14159
1E10
浮点数家族包括:float、double、long double(在C99中引用的)类型
浮点数表示的范围:float.h中定义。
3.1例子:
#include
#include
#include
unsigned char i = 0;
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);
}

3.2浮点数存储规则


对于float类型:

对于double类型:






E全为1



浙公网安备 33010602011771号