存储结构学习笔记
C语言类型
-
内置类型
char
short
int
long
float
double
-
自定义类型(构造类型)
以及他们所占存储空间的大小。类型的意义在于:
- 使用这个类型开辟存储空间的大小(大小决定了使用范围)
- 如何看待内存空间的视角。
整形的基本归类
整形家族:
-
char
unsigned char
signed char
-
short
unsigned short[int]
signed short[int]
-
int
unsigned int
signed int
-
long
unsigned long
signed long
浮点型家族
-
float
-
double
构造类型
-
数组类型
结构体类型
枚举类型 enum
联合类型 union
指针类型
- int *pi;
- char *pc;
- float *pf;
- void *pv;
空类型
void表示空类型(无类型)
通常应用于函数的返回类型,函数的参数,指针类型。
注意:
-
void 是类型,不能定义变量,空类型对应的大小是0,。所以 void 无法开辟空间,即无法定义变量。
-
虽然 void 在linux 系统下大小为 1 个字节,但是系统认定 void 为空类型,同样无法定义变量。
-
虽然 void 不能定义变量,但是 void* 可以,在 32 为平台下,任何指针的大小都是4个字节,但是不能解引用。
-
C 语言中函数的返回值类型可以省略,但是省略之后默认为 int。
-
void* 可以接收任何类型。
整形在内存中的存储
变量的创建是需要在内存中开辟空间的。空间的大小是根据不同的类型而决定的。
那接下来我们谈谈数据在开辟内存中是如何存储的?
比如:
int main()
{
int a = 10;
int b = -20;
return 0;
}
我们知道a分配四个字节的空间,那如何存储?
下面我们了解以下概念:
原码,反码,补码
计算机中的有符号数有三种表达形式,即原码,反码和补码。
三种表示方法均有符号位和数值位两部分,符号位都是0表示正,用1表示负。
三种表示方法各不相同
原码:直接将二进制按照正负数的形式翻译成二进制形式就可以了
反码:将原码的符号位不变,其余位依次按位取反就可以了。
补码:反码+1就得到补码
正数的原码,反码,补码都相同。
对于整形来说:数据存放内存中其实存放的是补码。
这是为什么呢?
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理,同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与源码相互转换,其运算过程是相同的,不需要额外的硬件电路。
我们看看在内存中的存储:
变量a在内存中的存储:

因为a为正数,所以在存储的时候先将十进制数,转化为二进制数原码,并且因为是正数,所以原、反、补码相同,不用转化。
变量b在内存中的存储:

因为b为负数,在进行十进制转化为二进制原码后,要进行原码和补码之间的转化,转化过程为符号位不变其他位按位取反,再加一。
可是有没有觉得怪怪的?为什么数字是反过来排列的?难道不是应该是 00 00 00 14 和 ff ff ff f6 吗?
这里就要引入小端存储和大端存储。
数据是有高、低位之分的,内存地址是有高、低地址之别的。
小端存储模式:是指数据的低位保存在内存的低地址中;而数据的高位,保存在内存高地址中。
上图就是小端存储。
大端存储:是指数据的低位保存在内存的高地址中;而数据的高位,保存在内存低地址中。
注意:整数:
1.有符号数:正数:原码,反码,补码相同
复数:原码,反码,补码不同,要进行计算
2.无符号数:原码,反码,补码相同
实例
百度2015年系统工程师笔试题
请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。
分析一下
int a=20;//0x00 00 00 14
//小端:14 00 00 00
//大端:00 00 00 14
我们只需要拿出第一个数字,如果14就是小端,如果00就是大端。
通过这个思想,我们可以写出一个简单的代码:
#define <stdio.h>
int main()
{
int a = 1;
char* p =(char*) &a;
if (*p == 1)
{
printf("这是小端存储\n");
}
else
{
printf("这是大端存储\n");
}
return 0;
}
下面我们来封装函数进行改进:
int check_sys()
{
int a = 1;
char* p = (char*)&a;
if (*p == 1)
return 1;
else
return 0;//后面几步可直接写成return *(char*)&a;
}
int main()
{
//写一段代码告诉我们当前机器字节序是什么
//返回1,小端
//返回0,大端
int ret = check_sys();
if (ret == 1)
{
printf("这是小端存储\n");
}
else
{
printf("这是大端存储\n");
}
return 0;
}
END TODAY

浙公网安备 33010602011771号