目录
一.数据类型介绍
基本的内置类型:
char----1字节 // 字符类型数据
int------4字节//整型
short---2字节//短整型
long----4字节(32位) 8字节(64位)//长整型
longlong-8字节//更长整型
float---4字节//单精度浮点数
double--8字节//双精度浮点数
类型的意义:
a. 使用这个类型开辟内存空间的大小(大小决定了使用范围)
b. 如何看待内存空间的视角
1.类型的基本归类
浮点数家族:
float
double
二.整型在类型中的存储
一个变量的创建是要在内存中开辟空间的 空间的大小是根据不同类型而决定的
那么好了好了接下来就是弄清楚数据在内存中是怎样存储的
2.1 原码、反码、补码
首先就是搞清楚 原码 反码 补码的概念
三种表示方法均有符号位和数值位两部分 符号位都是用0表示“正” 用1表示“负” 而数值位正数的原、反、补码都相同
负整数的三种表示方法各不相同:
原码:直接将数值按照正负数的形式翻译成二进制就可以得到原码
反码:将原码的符号位不变 其他位依次按位取反就可以得到反码
补码:反码+1就得到补码
2.2 大小端介绍
这时就涉及到大端和小端
关于大端(存储)模式:是指数据的低位保存在内存的高地址中 而数据的高位 保存在内存的低地址
关于小端(存储)模式:是指数据的低位保存在内存的低地址中 而数据的高位 保存在内存的高地址
为什么有大端和小端?
三.练习
//设计常规函数来解决
#include <stdio.h>
int skycheck(int i)
{
return(*(char*)&i);
}
int main(void)
{
int i = 1;
int ret = skycheck(i);
if(ret == 1)
{
printf("小端\n");
}
else
printf("大端\n");
return 0;
}
//用联合体来解决
int skycheck(void)
{
union
{
int i;
char c;
}u;
u.i = 1;
return u.c;
}
#include <stdio.h>
int main()
{
char a = -1;
// //10000000000000000000000000000001
// //11111111111111111111111111111110
// //11111111111111111111111111111111
// //11111111 - 截断
// //整型提升
// //11111111111111111111111111111111
// //11111111111111111111111111111110
// //10000000000000000000000000000001 -1
//
signed char b = -1;
// //-1
//
unsigned char c = -1;
// //10000000000000000000000000000001
// //11111111111111111111111111111110
// //11111111111111111111111111111111
// //00000000000000000000000011111111
// //
printf("a=%d,b=%d,c=%d", a, b, c);
//
return 0;
}
#include <stdio.h>
int main()
{
char a = -128;
// 1000 0000 0000 0000 0000 0000 1000 0000
// 1111 1111 1111 1111 1111 1111 0111 1111
// 1111 1111 1111 1111 1111 1111 1000 0000
// 1000 0000
// 因为是char 类型即 1代表为负数
// 1111 1111 1111 1111 1111 1111 1000 0000
// 以无符号 u 打印 视作正数 原 反 补 相同即4294967168
printf("%u\n", a);
return 0;
}
#include <stdio.h>
int main()
{
char a = 128;
// 0000 0000 0000 0000 0000 0000 1000 0000
// 1000 0000
// 因为是char 类型即 1代表为负数
// 1111 1111 1111 1111 1111 1111 1000 0000
// 以无符号 u 打印 视作正数 原 反 补 相同即4294967168
printf("%u\n", a);
return 0;
}
#include <stdio.h>
int main()
{
int i= -20;
// 1000 0000 0000 0000 0000 0000 0001 0100 -20
// 1111 1111 1111 1111 1111 1111 1110 1011
// 1111 1111 1111 1111 1111 1111 1110 1100
unsigned int j = 10;
// 0000 0000 0000 0000 0000 0000 0000 1010 10
printf("%d\n", i+j);
// 1111 1111 1111 1111 1111 1111 1111 0110
// 1111 1111 1111 1111 1111 1111 1111 0101
// 1000 0000 0000 0000 0000 0000 0000 1010 -10
return 0;
}
#include <stdio.h>
int main()
{
unsigned int i;
for(i = 9; i >= 0; i--)
{
//当打印到0后 开始从-1以无符号数开始打印
printf("%u\n",i);
}
return 0;
}
#include <stdio.h>
#include <string.h>
int main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a)); //255
return 0;
}
四.浮点型在内存中的存储
常见的浮点数:
1E10
3.14159
浮点数家族包括: float、double、long double 类型
浮点数的表示范围:float.h中定义
1.一个例子
讲解在最后哦
2.浮点数存储规则
要理解上面的结果 就要弄清楚浮点数在计算机内部的表示方法
根据国际标准IEEE(电气和电子工程协会) 754 任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^S表示符号位 当S=0 V为正数;当S=1 V为负数
M表示有效数字 大于等于1 小于2
2^E表示指数位
举例来说:
十进制的5.0 写成二进制是 101.0 相当于 1.01×2^2 。
那么 按照上面V的格式 可以得出S=0,M=1.01,E=2。
十进制的-5.0 写成二进制是 -101.0 相当于 -1.01×2^2 那么 S=1,M=1.01,E=2
#include<stdio.h>
int main(void)
{
int n = 9;
// //00000000000000000000000000001001 - 9的补码
// //
// //0 00000000 00000000000000000001001
// //E = 1-127 = -126
// //M = 0.00000000000000000001001
// //(-1)^0 * 0.00000000000000000001001 * 2^-126
// //
float* pFloat = (float*)&n;
printf("n的值为:%d\n", n);
printf("*pFloat的值为:%f\n", *pFloat);//0.0
// *pFloat = 9.0;//以浮点数的视角,存放浮点型的数字
// //1001.0
// //1.001 * 2^3
// //(-1)^0 * 1.001 * 2^3
// //S=0
// //E=3
// //M=1.001
// //0 10000010 00100000000000000000000
// //
printf("num的值为:%d\n", n);//1,091,567,616
printf("*pFloat的值为:%f\n", *pFloat);//9.0
return 0;
}