区别数学与C语言中的数据表示:
- 数学中数据的表示无类型,但是C语言中每一种数据都有类型
- 数学有无穷,但是C语言中每一种数据类型都有范围
应用:二分查询时若下标值较大时就需要
int mid = (right - left) / 2 + left;
- 数学表达式不能直接应用于C语言(>=…)
补码形式存放数据
计算机存放数据都是以二进制补码的形式存放
原码:二进制定点表示
正数的原码 = 补码 = 反码
int main()
{
// char是一字节整型,存放字符的ASCALL码值,即可以存放有符号数,也可以存放无符号数
char a = 5; // 0000 0101 05
char b = -5; // 原码:1000 0101
// 反码:1111 1010
// 补码:1111 1011 fb
return 0;
}
原因:
计算机受限与硬件电路的设计,CPU只能实现加法逻辑,位移是求反逻辑,以补码的形式表示数据时,就可以把减法变成加法,乘法就是累加运算,除法就是累减运算。
类型示例
int main()
{
for (char c = 0;c < 128;++c)
{
printf("%6d", c);
}
return 0;
}
改变类型:
int main()
{
for (unsigned char c = 0;c < 128;++c)
{
printf("%6d", c);
}
return 0;
}
数值转换(强制类型转换)
表示范围小的扩展给表示范围大的
变量一旦定义,类型就不会改变,即便是强制类型转换也只是改变了变量所表示的范围
将表示范围小的整型强转给表示范围大的整型时,有符号数扩展符号位。
原因:
- 不改变数据的符号
- 不改变数值的大小
无符号数扩展时,扩展的字节全部填充0
表示范围大的扩展给表示范围小的
切片现象:
例题
例题一:
当数据类型不匹配,参与计算的过程,会有一个类型提升过程
int main()
{
char a = -5;
unsigned int b = 10;
if (a > b)//比较时会将a强转位无符号整型
{
printf("%d>%d \n", a, b);//10 进制方式输出(有符号)
printf("%x>%x \n", a, b);
}
else
{
printf("%d<%d \n",a, b);
printf("%x<%x \n", a, b);
}
return 0;
}
例题二:
例题三:
int main()
{
char c = 128;
unsigned char uc = 128;
unsigned short us = 0;
us = c + uc;
// c = 1000 0000 打印-128 1111 1111 1000 0000
//uc = 1000 0000 打印128 0000 0000 1000 0000
// 1 0000 0000 0000 0000
printf("%x \n", us);// 0
us = (unsigned char)c + uc;
// c = 1000 0000 // 0000 0000 1000 0000
//uc = 1000 0000 // 0000 0000 1000 0000
// 0000 0001 0000 0000 -->(unsigned short)
printf("%x \n", us);// 1 0 0
us = c + (char)uc;
// c = 1000 0000 // 1111 1111 1000 0000
//uc = 1000 0000 // 1111 1111 1000 0000
// 1 1111 1111 0000 0000
printf("%x \n", us);// f f 0 0
us = (unsigned short)c + uc;
// c = 1000 0000 // 1111 1111 1000 0000
//uc = 1000 0000 // 0000 0000 1000 0000
// 1 0000 0000 0000 0000
printf("%x \n", us);// 0
}