一.数据类型
基本类型 | 打印类型 | 所占大小(字节) |
char 字符型 | %c | 1 |
short 短整型 | %d | 2 |
int 整形 | %d | 4 |
long 长整形 | %ld | 4 |
long long 更长整形 | %lld | 8 |
float 单精度浮点型 | %f | 4 |
double 双精度浮点型 | %lf | 8 |
类型的意义:
- 使用这个类型开辟内存空间的大小(大小决定了使用范围)。
- 如何看待内存空间的视角。
简单归类:
整型家族
char
//(直接使用char类型,不确定它是unsigned还是signed,取决于编译器,一般为signed型)
//char存储的时候,存的是它的ASCII码值,也是个整数,故归于整形家族
unsigned char
signed char
short(signed short)
unsigned short [int]
signed short [int]
int(signed int)
unsigned int
signed int
long(signed long)
unsigned long [int]
signed long [int]
浮点型家族
float
double
构造类型-自定义类型
> 数组类型
> 结构体类型 struct
> 枚举类型 enum
> 联合类型 union
指针类型
int *pi;
char *pc;
float* pf;
void* pv;
空类型
void
void 表示空类型(无类型)
(通常应用于函数的返回类型、函数的参数、指针类型)
二.整形在内存中的存储
(补码在内存中是倒序存储)
整数在内存中存储形式之前讲过,在此就不多说
图中的是十六进制形式,4个二进制位换一个十六进制位
a的补码的十六进制形式为FFFFFFF6
注意:对于整形:
1.数据存放的是补码
2。整形表达式计算是用补码计算的
3.打印和显示出来是原码
例子:
#include<stdio.h>
int main()
{
char a = -1
//由于char是1个字节
//所以是11111111 存储到a中
signed char b = -1;
//11111111
unsigned char c = -1;
//11111111
printf("a=%d,b=%d,c=%d", a, b, c);//a=-1,b=-1,c=255
//打印的是%d,会整型提升
//整形提升看的是原符号位
//a由于是char所以按符号位来提升
//a:1111111111111111111111111111111 内存中补码
//以%d打印的时候看的是其原码,所以为10000000000000000000000000000001
//a与b类似
//有符号整型提升的时候会把符号位当作最高位
//a b:1000 0000 0000 0000 0000 0000 0000 0001 -1的原码
//c:无符号整型提升后面补0
//c:00000000000000000000000011111111-->无符号c的补码
//c:00000000000000000000000011111111-->无符号c的原码
return 0;
}
1.*****
//%u是打印无符号整型,认为内存中存放的补码对应的是一个无符号数
//%d是打印有符号整型,认为内存中存放的补码对应的是一个有符号数
#include <stdio.h>
int main()
{
char a = -128;
//a的补码 :1111 1111 1111 1111 1111 1111 1000 0000
//截断后为:1000 0000
//由于是%u打印,发生整形提升,又为有符号char,高位补1
//提升后内存中放的是补码,且是无符号数补码,高位不是符号数,其补码,原码相同---> 1111 1111 1111 1111 1111 1111 1000 0000
printf("%u\n", a);//4294967168//当为%d是结果为-128
return 0;
}
2.char的取值范围
a:有符号的char的取值范围:-128~127
127为最大值,加1不会变成128,而回是-128
b:无符号的char的取值范围:0~255
(无符号整形减为0时还能再减,但不会减成负数,而是到无符号最大数,像个循环。而无符号最大数加1变成0)
例子:
#include<stdio.h>
int main()
{
unsigned int i;//无符号说明i值都不为负数
for (i = 9; i >= 0; i--)//恒成立
{
printf("%u\n", i);//当为%d是会认为内存中储存的是一个有符号的数字
}
return 0;
}
三.大小端字节序介绍及判断
大端(存储)模式,是指数据的低位存放在内存的高地址中,而数据的高位存放在内存的低地址中;
小端(存储)模式,是指数据的低位存放在内存的低地址中,而数据的高位存放在内存的高地址中。
注意:存储中靠右的是低地址,靠左是高地址
在0x11223344中44是低地址
int main()
{
int a = 0x11223344;
return 0;
}
a: 11 22 33 44 将其存到内存中可分为两种:
1: 低 11 22 33 44 高 --->大端字节序
2: 低 44 33 22 11 高 --->小端字节序
例题:判断当前机器的字节序
//可以通过获取第一个字节来判断
#include<stdio.h>
int main()
{
int a = 1;
char* p = (char*)&a;
if (*p == 1)
printf("小端\n");
else
printf("大端\n");
return 0;
}
//函数法
#include<stdio.h>
int check_sys()
{
int a = 1;
//0000 0000 0000 0000 0000 0000 0000 0001
//大端存储:0x 00 00 00 01 解引用->0
//小端存储:0x 01 00 00 00 解引用->1
return (*(char*)&a);
//&a取出a的地址,然后把这个int*类型的地址转化为char*,最后解引用
//为大端存储,返回0;小端存储,返回1
}
int main()
{
int ret = check_sys();
if (ret == 1)
printf("小端\n");
else
printf("大端\n");
return 0;
}
四.浮点型在内存中的存储
浮点数家族:float 、double 、long double类型
#include<stdio.h>
int main()
{
int n = 9;
float* pFloat = (float*)&n;
printf("n的值为:%d\n", n);//9
printf("*pFloat的值为:%f\n", *pFloat);//0.000000
//当以*pFloat是以 浮点数 的视角考的,以%f打印
*pFloat = 9.0;
printf("num的值为:%d\n", n);//1091567616
//以浮点型放进去,以整数视角拿的
//说明浮点数和整数在内存中存储方式是有区别的
printf("*pFloat的值为:%f\n", *pFloat);//9.000000
return 0;
}
任意一个二进制浮点数V的存储形式规则:(-1)^S*M*2^E
(-1)^S表示符号位,当S=0时,V为整数,当S=1时,V为负数
M表示有效数字,1<=M<2
2^E表示指数位