zoukankan      html  css  js  c++  java
  • 由limits.h看整型范围

    欢迎访问我的新博客:http://www.milkcu.com/blog/

    原文地址:http://www.milkcu.com/blog/archives/1367305920.html

    前言

    声明一个变量,经常要考虑的问题是这个类型的变量能不能装的下。今天MilkCu就总结下吧,以解除后顾之忧。

    关于变量取值范围的问题,在Kernighan的《C程序设计语言》第28页练习2-1就提到过。

    编写一个程序以确定分别由signed及unsigned限定的char、short、int与long类型变量的取值范围。采用打印标准头文件中的相应值以及直接计算两种方式实现。后一种方式的实现较困难一些,因为要确定各种浮点类型的取值范围。

    这书是针对C89的,随着C99及C++的广泛应用long long int类型也是一种美妙的选择。

    实现方案

    标准规定:各种类型的取值范围必须在头文件<limits.h>中定义。不同类型在不同的硬件上有不同的长度,所以它们在不同机器上的取值范围也往往会不同。我们可以通过头文件确定类型取值范围。

    函数sizeof()

    可以通过函数sizeof()用字节计算参数并返回的字节数,间接得到类型宽度,源代码如下:

    # include <stdio.h>
    int main(void)
    {
    	printf("byte of short = %d\n", sizeof(short));
    	printf("byte of int = %d\n", sizeof(int));
    	printf("byte of long = %d\n", sizeof(long));
    	printf("byte of long long int = %d\n", sizeof(long long int));
    	return 0;
    }

    打印常量

    可以通过打印头文件的方法获得每种类型的取值范围:

    # include <stdio.h>
    # include <limits.h>
    //determine ranges of types
    int main(void)
    {
    	//signed types
    	printf("signed char min = %d\n", SCHAR_MIN);
    	printf("signed char max = %d\n", SCHAR_MAX);
    	printf("signed short min = %d\n", SHRT_MIN);
    	printf("signed short max = %d\n", SHRT_MIN);
    	printf("signed short min = %d\n", INT_MIN);
    	printf("signed long min = %ld\n", LONG_MIN);
    	printf("signed long max = %ld\n", LONG_MAX);
    	printf("signed long long int min = %lld\n", LONG_LONG_MIN);
    	printf("signed long long int max = %lld\n", LONG_LONG_MAX);
    	//unsigned types
    	printf("unsigned char max = %u\n", UCHAR_MAX);
    	printf("unsigned short max = %u\n", USHRT_MAX);
    	printf("unsigned int max = %u\n", UINT_MAX);
    	printf("unsigned long max = %lu\n", ULONG_MAX);
    	printf("unsigned long long int max = %llu\n", ULONG_LONG_MAX);
    	return 0;
    }

    打印结果如下:

    signed char min = -128
    signed char max = 127
    signed short min = -32768
    signed short max = -32768
    signed short min = -2147483648
    signed long min = -2147483648
    signed long max = 2147483647
    signed long long int min = -9223372036854775808
    signed long long int max = 9223372036854775807
    unsigned char max = 255
    unsigned short max = 65535
    unsigned int max = 4294967295
    unsigned long max = 4294967295
    unsigned long long int max = 18446744073709551615

    头文件

    可以从头文件<limits.h>中更详细的看到它们的宏定义,<limits.h>(来自Dev-Cpp 5.4.0 MinGW 4.7.2)如下:

    /* 
     * limits.h
     * This file has no copyright assigned and is placed in the Public Domain.
     * This file is a part of the mingw-runtime package.
     * No warranty is given; refer to the file DISCLAIMER within the package.
     *
     * Functions for manipulating paths and directories (included from io.h)
     * plus functions for setting the current drive.
     *
     * Defines constants for the sizes of integral types.
     *
     * NOTE: GCC should supply a version of this header and it should be safe to
     *       use that version instead of this one (maybe safer).
     *
     */
    
    #ifndef _LIMITS_H_
    #define _LIMITS_H_
    
    /* All the headers include this file. */
    #include <_mingw.h>
    
    /*
     * File system limits
     *
     * TODO: NAME_MAX and OPEN_MAX are file system limits or not? Are they the
     *       same as FILENAME_MAX and FOPEN_MAX from stdio.h?
     * NOTE: PATH_MAX is the POSIX equivalent for Microsoft's MAX_PATH; the two
     *       are semantically identical, with a limit of 259 characters for the
     *       path name, plus one for a terminating NUL, for a total of 260.
     */
    #define PATH_MAX	260
    
    /*
     * Characteristics of the char data type.
     *
     * TODO: Is MB_LEN_MAX correct?
     */
    #define CHAR_BIT	8
    #define MB_LEN_MAX	2
    
    #define SCHAR_MIN	(-128)
    #define SCHAR_MAX	127
    
    #define UCHAR_MAX	255
    
    /* TODO: Is this safe? I think it might just be testing the preprocessor,
     *       not the compiler itself... */
    #if	('\x80' < 0)
    #define CHAR_MIN	SCHAR_MIN
    #define CHAR_MAX	SCHAR_MAX
    #else
    #define CHAR_MIN	0
    #define CHAR_MAX	UCHAR_MAX
    #endif
    
    /*
     * Maximum and minimum values for ints.
     */
    #define INT_MAX		2147483647
    #define INT_MIN		(-INT_MAX-1)
    
    #define UINT_MAX	0xffffffff
    
    /*
     * Maximum and minimum values for shorts.
     */
    #define SHRT_MAX	32767
    #define SHRT_MIN	(-SHRT_MAX-1)
    
    #define USHRT_MAX	0xffff
    
    /*
     * Maximum and minimum values for longs and unsigned longs.
     *
     * TODO: This is not correct for Alphas, which have 64 bit longs.
     */
    #define LONG_MAX	2147483647L
    #define LONG_MIN	(-LONG_MAX-1)
    
    #define ULONG_MAX	0xffffffffUL
    
    #ifndef __STRICT_ANSI__
    /* POSIX wants this.  */ 
    #define SSIZE_MAX LONG_MAX
    #endif
    
    #if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \
         || !defined(__STRICT_ANSI__)
    /* ISO C9x macro names */
    #define LLONG_MAX 9223372036854775807LL
    #define LLONG_MIN (-LLONG_MAX - 1)
    #define ULLONG_MAX (2ULL * LLONG_MAX + 1)
    #endif
    
    /*
     * The GNU C compiler also allows 'long long int'
     */
    #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
    
    #define LONG_LONG_MAX	9223372036854775807LL
    #define LONG_LONG_MIN	(-LONG_LONG_MAX-1)
    #define ULONG_LONG_MAX	(2ULL * LONG_LONG_MAX + 1)
    
    /* MSVC compatibility */
    #define _I64_MIN LONG_LONG_MIN
    #define _I64_MAX LONG_LONG_MAX
    #define _UI64_MAX ULONG_LONG_MAX
    
    #endif /* Not Strict ANSI and GNU C compiler */
    
    
    #endif /* not _LIMITS_H_ */

    阅读头文件,在注释的帮助下,我们可以更明确的看到数据类型的定义。

    总结

    简而言之,对于MinGW32:

    int类型,能完整表示9位;
    unsigned long long int类型,能完整表示19位。

    后记

    又一轮新生活开始了,要充实快乐每一天。

    借用奥斯托洛夫斯基在《钢铁是怎样炼成》中的几句话吧:

    人最宝贵的东西是生命
    生命属于人只有一次
    一个人的生命是应该这样度过的
    当他回首往事的时候
    他不会因虚度年华而悔恨
    也不会因碌碌无为而羞耻

    这样在临死的时候
    他才能够说:“我的生命和全部的经历
    都献给世界上最壮丽的事业——为人类的解放而斗争”。

    (全文完)

  • 相关阅读:
    【并查集】连接格点C++
    【拓扑排序】威虎山上的分配C++
    CF39D Cubical PlanetC++
    【拓扑排序】排队C++
    [USACO09OCT]Invasion of the Milkweed】乳草的侵占C++
    免杀常用手段
    DELPHI 线程类
    动态注册OCX
    DELPHI 常用文件路径
    套接字(TCP)
  • 原文地址:https://www.cnblogs.com/milkcu/p/3808900.html
Copyright © 2011-2022 走看看