转载原文地址: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. [Node.js] 使用File API 异步上传文件

    原文地址:http://www.moye.me/2014/11/05/html5-filereader/ 最近在做一个网盘的项目,不出意外的涉及到大文件的上传,那么问题来了:如何实时的显示文件上传的进 ...

  2. 前端优化:RequireJS Optimizer 的使用和配置方法

    RequireJS Optimizer 是 RequireJS 自带的前端优化工具,可以对 RequireJS 项目中的 JavaScript & CSS 代码使用 UglifyJS 或者 C ...

  3. 《HelloGitHub月刊》第02期

    <HelloGithub>第02期 兴趣是最好的老师,而<HelloGitHub> 就是帮你找到兴趣! 因为我比较熟悉python语言,所以月刊中python语言的项目居多,个 ...

  4. Entity Framework的默认值BUG解决方法

    在使用.Net 3.5里的Entity Framework开发网站的时候,遇到了一个问题:添加记录时,对于DateTime型的数据,无法使用数据库的默认值. 具体的情况是这样的,我的数据库有个User ...

  5. 关于SQL SERVER高并发解决方案

    现在大家都比较关心的问题就是在多用户高并发的情况下,如何开发系统,这对我们程序员来说,确实是值得研究,最近找工作面试时也经常被问到,其实我早有去关心和了解这类问题,但一直没有总结一下,导致面试时无法很 ...

  6. 译:Datetime类型的扩展

    译文出处:http://www.codeproject.com/Articles/870939/Datetime-Extensions 本文主要针对System.DateTime类型的一系列扩展.包括 ...

  7. 【循序渐进学Python】6.Python中的函数

    1. 创建函数 一个函数代表一个行为并且返回一个结果(包括None),在Python中使用def关键字来定义一个函数,如下: def hello(name): print 'hello,' + nam ...

  8. Aspose.Word 操作word复杂表格 拆分单元格 复制行 插入行 文字颜色

    private void button3_Click(object sender, EventArgs e)         {             object savePathWord =&q ...

  9. 别误用IsDigit与IsNumber函数

    1.起因 最近发现程序中有一段控制TextBox数字输入的代码,相信大家都不会太陌生,如下: void int_KeyPress(object sender, KeyPressEventArgs e) ...

  10. 怎样解决asp.net.mvc上传附件超过长度问题?

    最近,在做一个上传附件功能,但是文件超过4M,就报上传的文件超过长度问题