转载原文地址: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. Communication - 01.Foreword

    冷落博客已有一年,理由种种,想来是腾出了些时间,但未见得其他方面有了什么可观的进步.打理博客犹如健身,每天不抬几次杠铃活动活动筋骨则憋的荒.消耗了大量的体力,一天下来却倍感清爽,人清爽了做什么都很来劲 ...

  2. spring源码分析之spring-web remoting模块概况及基本概念

    spring-web总体分为三部分:caucho.httpinvoker.jaxws,其总体构造图如下: uml结构: 先看看网上搜索到的上述实现的原理吧:Spring RMI,Hessian/Bur ...

  3. gulp-notify处理报错----gulp系列(二)

    上一节,以less为例,入门了gulp,并为任务结构做了抽离. 前端们,gulp该用起来了,简单的demo入门——gulp系列(一) 本节学习下gulp-notify,官方这样解释的: gulp-no ...

  4. Mysql学习笔记(九)索引查询优化

    PS:上网再次看了一下数据库关于索引的一些细节...感觉自己学的东西有点少...又再次的啃了啃索引.... 学习内容: 索引查询优化... 上一章说道的索引还不是特别的详细,再补充一些具体的细节... ...

  5. ExtendHelper

    public static class ExtendHelper { /// <summary> /// 检查当前字符串是否符合某种格式 /// </summary> /// ...

  6. 复利计算6.0—软件工程(web版本)

    复利计算再升级------------------------------------------------------------ 客户在大家的引导下,有了更多的想法: 这个数据我经常会填.... ...

  7. ASP.NET MVC5--Contains

    前言: * The Contains  method is run on the database, not the c# code above. On the database, Contains  ...

  8. XmlNodeList循环读取节点值

    foreach (XmlNode item in XmlNodeList) { string oid = item.SelectSingleNode("oid").InnerTex ...

  9. 重新想象 Windows 8.1 Store Apps (91) - 后台任务的新特性: 下载和上传的新特性, 程序启动前预下载网络资源, 后台任务的其它新特性

    [源码下载] 重新想象 Windows 8.1 Store Apps (91) - 后台任务的新特性: 下载和上传的新特性, 程序启动前预下载网络资源, 后台任务的其它新特性 作者:webabcd 介 ...

  10. FreeBSD 10 发布

    发行注记:http://www.freebsd.org/releases/10.0R/relnotes.html 下文翻译中... 主要有安全问题修复.新的驱动与硬件支持.新的命名/选项.主要bug修 ...