-1大于1,-1乘3不等于-3,C语言这个规则你必须得会!

时间:2022-07-22
本文章向大家介绍-1大于1,-1乘3不等于-3,C语言这个规则你必须得会!,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

哈喽,大家好。今天我们由C语言的一个经典题目入手,跟大家聊聊C语言一个非常重要的规则,不要着急,让我们从-1大于1的例子说起。


unsigned int i=1;
signed int j=-1;

很简单,无符号数i,有符号数j,比较i和j的大小,按照常理i是大于j的,但是实验证明j>i,也就是说-1>1,为什么会这样呢?

其实出现这个情况的原因就是C语言中的自动转换原则,这也是今天我们想给大家说的话题。在C语言中,若遇到无符号数和有符号数之间的操作,这时候会出现数据类型的提升现象,编译器会自动把有符号数转化为无符号数来进行处理,因此i是1没错,但j却不是-1了,而是变成了 4294967295。所以j>i了。

关于数据为何是4294967295,我们今天从数学的角度给大家分析一下,供大家参考。

首先大家知道无符号数unsigned int的表示范围是:[0 4294967295 ]= [0 2147483647] U [2147483648 4294967295],数学上称为值域。而有符号数int的值域是 [-2147483648—2147483647]。两个区间的元素个数都是4294967296个。

由此看出,二者的公共域是[0 2147483647],所以有符号数int的[-2147483648 -1] 对应 unsigned int的[2147483648 4294967295],这种一一对应的关系,数学上叫做映射。到这里,数据的对应关系就一目了然了, -1 自然对应的就是 4294967295了。

由-1大于1的例子,我们对C语言的自动转换原则进行简单总结。

一般来说,C语言存在4种情况的自动转换,也称为隐式转换。

1、算术运算式中,低级类型转换为高级类型。 (下面的图对低级和高级进行了说明,大家可以参考)

2、赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给他。

3、函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参。

4、函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋值给调用函数。

当然,以上情况只是进行了一般的总结,有些细节还没有提到,比如字符必须先转换为整数,short必须转换为int,float型数据在运算时必须转换为double来提高运算精度等等,有兴趣的可以自行去了解学习。

了解自动转换原则后,我们再来看这个微软面试题

#include<iostream>
using namespace std;
int main(void)
{
  unsigned int i=3;
  cout<<i * -1;
  return 0;
 }

问结果会输出什么?有人说不是3而应该是12884901885,因为发生了隐式转换。其实本题的答案是4294967293,哪里有问题呢?我们一步一步分析,有符号数-1与无符号数3进行算数运算,-1变为无符号数4294967295,再乘3得12884901885。到这里都没问题,但是有一点很多人忽略了:那就是无符号数unsigned int只能表示32位,而此时的结果发生了溢出!因此结果是4294967293。

最后,关于本题这里有一点,因为上述代码是C++,大家可以改写成C语言,用printf来输出,再看看运行结果,你会有新的发现哦!好啦,就写到这里吧,希望今天的文章对大家的学习有所帮助。