转载原文地址:http://www.cnblogs.com/webary/p/4967868.html

在牛客网看到一道关于abs()函数返回值的题目,见下图,当时还没反应过来,第一反应是:自从我开始学C语言,就知道它是用来求int数的绝对值的,返回值当然是0或者正数啊,一看答案就是A。

  后来思来想去,质问自己 难道这道题就这么简单?于是果断先查函数库,得到:

#include <stdlib.h> //或math.h
int abs( int num );

  发现库函数的返回值形式都写的是int,为什么是int?经过深入的思考、验证和查阅资料,最后得出:

当num为0或正数时,函数返回num值;
当num为负数且不是最小的负数时(即0x80000000),函数返回num的对应绝对值数,即将内存中该二进制位的符号位取反,并把后面数值位取反加一;
当num为最小的负数时,由于正数里int类型32位表示不了这个数的绝对值,所以依然返回该负数。
  贴上代码运行结果:
      
  也就是说,对于普通程序员来说,直接用abs来求一个数的绝对值并没有想象中那么安全,如果恰好给它传递了一个最小的负数作为参数,得到的依然是这个负数,而不是它的绝对值,也许后面将会发生各种意想不到的情况。因此,每一位程序员都应该明白:调用函数后检查函数返回值是一个优秀程序员应该具备的基本素养。
  “经常反问:这个变量或表达式会上溢或下溢吗?”(《编程精粹-Microsoft编写优质无错C程序秘诀》P80,Steve Maguire 著)
 
  引用一段来自一个博客的话作为结束:

ANSI C标准规定了每种整数类型的最小值域(但没有规定它们必须采用哪种编码方案),并要求所有的C语言实现都要在limits.h头文件中通过诸如INT_MIN、INT_MAX这样的宏来指定该实现中整型数据的实际值域,而且这些实际的值域一定不能比标准规定的最小值域还要小(也即要求每种实现在limits.h中定义的宏的绝对值不小于C标准规定的同名宏的绝对值,并且正负号要保持一致)。

标准定义的INT_MIN是-(2^15 - 1),INT_MAX是(2^15 - 1),换句话说,标准保证了int型数据至少能表示-(2^15 - 1)到(2^15 - 1)这样一个对称区间内的所有整数,因此程序员可以放心大胆地用int变量存储以上范围内的任何整数。但与此同时请特别注意,用int变量表达超出上述范围的数将是一件没有法律(标准即是程序员的法律)保障的事情,所以不应该想当然地认为-32768(即-2^15)一定可以用int型来表达,尽管它确实位于用二次补码记法(twos-complement notation)进行编码的16位整数的值域内。熟悉以上背景后再回顾abs函数的问题就会发现,实际上该函数对于标准规定范最小值域内的所有整数都能正常工作,而上面提到的引起错误的输入数据已经不在此范围内了,所以此错误不应由abs而应由函数调用者负责。由此可见,为了安全以及可移植性,将表达式欲表示的值严格限制在标准指定的最小值域内是一个良好的编程习惯。

 #include <bits/stdc++.h>

 using namespace std;

 int main()
{
int a=0x80000000;
int b=0x7FFFFFFF;
cout<<a<<endl;
cout<<abs(a)<<endl<<abs(b)<<endl;
}

abs()函数的返回值问题的更多相关文章

  1. Swift2.0语言教程之函数的返回值与函数类型

    Swift2.0语言教程之函数的返回值与函数类型 Swift2.0中函数的返回值 根据是否具有返回值,函数可以分为无返回值函数和有返回值函数.以下将会对这两种函数类型进行讲解. Swift2.0中具有 ...

  2. python学习笔记1 -- 函数式编程之高阶函数 使用函数作为返回值

    使用函数作为返回值,看起来就很高端有木有,前面了解过函数名本身就是一个变量,就比如abs()函数,abs只是变量名,而abs()才是函数调用,那么我们如果把ads这个变量作为返回值返回会怎么样呢,这就 ...

  3. 测试函数用Return 返回值和用函数名返回值的区别

    '*************************************************************************'**模 块 名:工程1 - Form1'**说   ...

  4. Shell入门教程:Shell函数的返回值

    shell函数返回值一般有3种方式: 1.return语句(默认的返回值) shell函数的返回值可以和其他语言的返回值一样,通过return语句返回. 比如: #!/bin/bash functio ...

  5. GDB 修改当前判断函数的返回值(即修改寄存器的值)的方法

    工作中遇到的问题: 在GDB调试时要进入下边该判断后边的函数,而m_EtherDecode.Chk_MakeSure_IP_Pkt(pPacket,dwPacketLen)的返回值是false,所以需 ...

  6. JavaScript 在函数中使用Ajax获取的值作为函数的返回值

    解决:JavaScript 在函数中使用Ajax获取的值作为函数的返回值,结果无法获取到返回值 原因:ajax默认使用异步方式,要将异步改为同步方式 案例:通过区域ID,获取该区域下所有的学校 var ...

  7. c++特性:指向类成员的指针和非类型类模板参数和函数指针返回值 参数推导机制和关联型别

    一.c++允许定义指向类成员的指针,包括类函数成员指针和类数据成员指针 格式如下: class A { public: void func(){printf("This is a funct ...

  8. getchar()函数的返回值赋给char型,用if(ch=getchar() != EOF)测试,输入ctrl+z同样可以结束循环的分析

    2013-07-18 21:35:58 getchar()函数的返回值赋给char型,用if(ch=getchar() != EOF)测试,输入ctrl+z同样可以结束循环的分析. char是字符型数 ...

  9. Python的函数式编程-传入函数、排序算法、函数作为返回值、匿名函数、偏函数、装饰器

    函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元. ...

随机推荐

  1. list2json

    list2json方法 System.Web.Script.Serialization.JavaScriptSerializer serial = new System.Web.Script.Seri ...

  2. Google的分布式关系型数据库F1和Spanner

    F1是Google开发的分布式关系型数据库,主要服务于Google的广告系统.Google的广告系统以前使用MySQL,广告系统的用户经常需要使用复杂的query和join操作,这就需要设计shard ...

  3. 进入IT企业必读的200个.NET面试题

    点击打开链接 点击打开链接 版权声明:本文为博主原创文章,未经博主允许不得转载.

  4. Servlet-Jsp

    Jsp实际就是Servlet. 我们访问Http://localhost:8080/Web/index.jsp的流程: 1 [jsp文件名].jsp转义为[jsp文件名_jsp].java,文件存储在 ...

  5. 测试驱动开发(TDD)的思考

    极限编程 敏捷开发是一种思想,极限编程也是一种思想,它与敏捷开发某些目标是一致的.只是实现方式不同.测试驱动开发是极限编程的一部分. 1.极限编程这个思路的来源 Kent Beck先生最早在其极限编程 ...

  6. 小白初学ABP框架,着实累啊

    这几天在学习ABP相关的知识AutoMapper ,AngularJS,Less,DI(dependencyInjection),EntityFramework code first以及相关NuGet ...

  7. dbcp 1.4 底层连接断开时内存泄露bug

    在dbcp 1.4中,如果底层的连接已经与数据库断开了,此时dbcp 1.4的实现并不释放内部连接,虽然早已提供了removeAbandoned和removeAbandonedTimeout参数,但是 ...

  8. Erlang高阶函数

    对于函数式语言来说,函数也想普通的数据类型一样无处不在.函数即可以当成参数进行传递,也可以当成函数的返回值.当我第一次学习函数式编程的时候,我被这样的写法弄的头昏脑涨.下面我举例说明下(例子摘录自Le ...

  9. 趣味问题:画图(c++实现)

    描述:在一个定义了直角坐标系的纸上,画一个(x1,y1)到(x2,y2)的矩形指将横坐标范围从x1到x2,纵坐标范围从y1到y2之间的区域涂上颜色.下图给出了一个画了两个矩形的例子.第一个矩形是(1, ...

  10. Windows 2012 R2中安装SharePoint 2013 sp1参考

    之前介绍过在window 2012中安装SharePoint 2013,这次,借着SharePoint 2013 sp1补丁发布之际,介绍下在window 2012 r2中安装SharePoint 2 ...