目录
1.unsigned char 与signed char 范围
2.unsigned short 与signed short 范围
一、数据类型介绍
//整型家族:
char //字符数据类型
short //短整型
int //整型
long //长整型
long long //更长的整型
//浮点型家族
float //单精度浮点型
double //双精度浮点型
类型的意义:
1. 使用这个类型开辟内存空间的大小(大小决定了使用范围)。
2. 如何看待内存空间的视角。
比如:
int 开辟4个字节的空间,float 也是开辟4个字节的空间,但是从内存空间的视角来看,
变量a里面存放的是整数,变量f里面存放的是小数
二、数值类型的范围
1.unsigned char 与signed char 范围
2.unsigned short 与signed short 范围
三、原码、反码、补码
计算机中的整数有三种表示方法,即原码、反码和补码。
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,
负整数的三种表示方法各不相同。
原码
直接将数值按照正负数的形式翻译成二进制就可以。
反码
将原码的符号位不变,其他位依次按位取反就可以得到了。
补码
反码+1就得到补码。
正数的原、反、补码都相同。
四、整形在内存中的存储
整数可以写出三种2进制表示形式:
原码:直接将数值按照正负数的形式翻译成二进制就可以
反码:将原码的符号位不变,其他位依次按位取反就可以得到了
补码:反码+1就得到补码。
正整数的原码、反码、补码相同
负数的原码、反码、补码是需要计算的
int main()
{
//int a = 10;//整型值
//原码:00000000000000000000000000001010
//反码:00000000000000000000000000001010
//补码:00000000000000000000000000001010
int b = -10;//整型值
//原码:10000000000000000000000000001010
//反码:11111111111111111111111111110101
//补码:1111 1111 1111 1111 1111 1111 1111 0110
// F F F F F F F 6
//0xff ff ff f6
//
return 0;
}
int main()
{
1 - 1;
//1-1
//1+(-1)
//使用补码的二进制计算
// 00000000000000000000000000000001
// 11111111111111111111111111111111
//100000000000000000000000000000000
// 00000000000000000000000000000000
// 0
// 10000000000000000000000000000001 -1的原码
// 11111111111111111111111111111110 -1的反码
// 11111111111111111111111111111111 -1的补码
//
// 使用原码计算是错误的
//00000000000000000000000000000001
//10000000000000000000000000000001
//10000000000000000000000000000010
//
//CPU 只有加法器
//
return 0;
}
#include <stdio.h>
int main()
{
unsigned int ch = -10;
//-10
//10000000000000000000000000001010
//11111111111111111111111111110101
//11111111111111111111111111110110
//
//printf("%u\n", ch);//%u是打印无符号数,意思是你要我打印的一定是无符号数,不是无符号数,我也认为是无符号数
printf("%d\n", ch);//%d 是打印有符号数,意思是你要我打印的一定是有符号数,不是有符号的数,我也认为是有符号数
return 0;
}
五、大小端字节序
什么是大端小端:
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址
中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地
址中
如何判断自己的电脑是大端存储还是小端存储:
int check_sys()
{
int a = 1;
char* p = (char*)&a;
if (*p == 1)
{
return 1;//小端
}
else
{
return 0;//大端
}
}
int check_sys()
{
int a = 1;
char* p = (char*)&a;
return *p;
}
int check_sys()
{
int a = 1;
return *(char*)&a;
}
int main()
{
int ret = check_sys();
if (ret == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
VS2019就是小端存储 :
六、经典例题
//程序的执行结果为( )
int main()
{
unsigned char a = 200;
unsigned char b = 100;
unsigned char c = 0;
c = a + b;
printf(“%d %d”, a+b,c);//300 44
return 0;
}
//思路:
//128 + 64 +8
//00000000 00000000 00000000 11001000
//11001000 200
// 64 + 32 +4
//00000000 00000000 00000000 01100100
//01100100 100
//00000000 00000000 00000001 00101100
//00101100 32 + 8 + 4
题解:
printf在传入参数的时候如果是整形会默认传入四字节,所以a+b的结果是用一个四字节的整数接收的,不会越界。而c已经在c = a + b这一步中丢弃了最高位的1,所以只能是300-256得到的44了。
由于printf是可变参数的函数,所以后面参数的类型是未知的,所以甭管你传入的是什么类型,printf只会根据类型的不同将用两种不同的长度存储。其中8字节的只有long long、float和double(注意float会处理成double再传入),其他类型都是4字节。所以虽然a + b的类型是char,实际接收时还是用一个四字节整数接收的。另外,读取时,%lld、%llx等整型方式和%f、%lf等浮点型方式读8字节,其他读4字节。