前言
声明一个变量,经常要考虑的问题是这个类型的变量能不能装的下。今天MilkCu就总结下吧,以解除后顾之忧。
关于变量取值范围的问题,在Kernighan的《C程序设计语言》第28页练习2-1就提到过。
编写一个程序以确定分别由signed及unsigned限定的char、short、int与long类型变量的取值范围。采用打印标准头文件中的相应值以及直接计算两种方式实现。后一种方式的实现较困难一些,因为要确定各种浮点类型的取值范围。
这书是针对C89的,随着C99及C++的广泛应用long long int类型也是一种美妙的选择。
实现方案
标准规定:各种类型的取值范围必须在头文件<limits.h>中定义。不同类型在不同的硬件上有不同的长度,所以它们在不同机器上的取值范围也往往会不同。我们可以通过头文件确定类型取值范围。
方案一
可以通过函数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;
}
方案三
可以从头文件<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_ */
阅读头文件,在注释的帮助下,我们可以更明确的看到数据类型的定义。
后记
又一轮新生活开始了,要充实快乐每一天。
借用奥斯托洛夫斯基在《钢铁是怎样炼成》中的几句话吧:
人最宝贵的东西是生命
生命属于人只有一次
一个人的生命是应该这样度过的
当他回首往事的时候
他不会因虚度年华而悔恨
也不会因碌碌无为而羞耻
这样在临死的时候
他才能够说:“我的生命和全部的经历
都献给世界上最壮丽的事业——为人类的解放而斗争”。
(全文完)
分享到:
相关推荐
4. `<limits.h>`:整型界限界定 `<limits.h>`定义了一系列常量,如`CHAR_BIT`, `CHAR_MAX`, `INT_MAX`等,它们分别表示`char`、`int`等类型的位数和最大最小值。这些常量有助于确保程序不会超越特定类型的界限,...
- `<limits.h>`:定义了整型数据类型的取值范围。 - `<locale.h>`:支持本地化功能,如设置区域设置。 - `<math.h>`:包含数学函数,如`sqrt()`、`sin()`、`cos()`等。 - `<setjmp.h>`:支持非局部跳转,用于...
4. `<limits.h>`:整型常量 这个头文件定义了各种整型数据类型的最小和最大值,如`INT_MAX`和`INT_MIN`,这对于了解数据类型范围和避免溢出问题很有帮助。 5. `<locale.h>`:地域环境 `localeconv()`函数提供了关于...
C99引入了一些新的头文件,如`<complex.h>`用于复数处理,`<fenv.h>`处理浮点环境,`<inttypes.h>`提供整数格式转换,`<stdbool.h>`定义布尔环境,`<stdint.h>`定义整型环境,而`<tgmath.h>`提供了通用类型的数学宏...
9. **<limits.h>**:定义了整型数据类型的取值范围,如`INT_MAX`和`INT_MIN`。 10. **<locale.h>**:与本地化(Localization)有关,允许程序适应不同地区和语言的设置。 11. **<setjmp.h>**:支持非局部跳转,...
`<limits.h>`库定义了一系列表示各种整型数据类型的大小和限制的常量。例如`INT_MAX`和`INT_MIN`分别表示`int`类型的最大值和最小值。这对于理解和处理整型数据至关重要,尤其是在需要考虑溢出情况时。例如: ```c ...
6. <limits.h>和<float.h>:分别定义了整型和浮点型的限制值。例如,<limits.h>定义了各种整型数据类型(比如int、long等)的最大值和最小值;<float.h>定义了浮点型数据类型(float、double)的精度限制和取值范围...
4. `<limits.h>`:整型常量 这个头文件定义了各种整型数据类型的最小值和最大值,如`INT_MIN`, `INT_MAX`, `LONG_MIN`, `LONG_MAX`等,方便程序员了解不同整型的取值范围。 5. `<locale.h>`:地域环境 提供了设置...
8. `<limits.h>`:提供数据类型的限制定义,用于定义整数、浮点数等数据类型的范围。 9. `<locale.h>`:提供本地化函数,用于支持多语言环境。 10. `<math.h>`:提供数学函数,用于数学运算。 11. `<stdio.h>`:提供...
4. `<limits.h>`:整型常量 这个头文件定义了各种整型数据类型的取值范围,例如`CHAR_MIN`, `INT_MAX`, `LONG_MIN`等,为开发者提供了安全的数值操作边界。 5. `<locale.h>`:地域环境 `<locale.h>`提供了处理地域...
### C语言函数库详解 #### 第一章:C标准库概览 本章节将详细介绍C语言...以上介绍了 `<assert.h>`、`<ctype.h>`、`<errno.h>`、`<limits.h>` 和 `<locale.h>` 的基本概念和用法,希望对学习C语言的读者有所帮助。
- `<limits.h>`:定义了整型和其他数据类型的最值常量。 - `<locale.h>`:提供本地化支持,如日期、货币格式等。 - `<math.h>`:提供了数学函数,如三角函数、指数函数等。 - `<stdio.h>`:标准输入输出库,用于基本...
<limits.h>用于检测整型数据类型的值范围,如最大值和最小值。 <locale.h>提供了本地化功能,能够处理与本地文化相关的数据格式问题,比如日期、时间的显示格式。 <setjmp.h>提供了“非局部跳转”的机制,允许程序...
4. `<limits.h>`:定义了各种整型数据类型的取值范围,如`INT_MAX`、`LONG_MIN`等,对编写符合标准的代码至关重要。 5. `<locale.h>`:与地域环境有关的函数和常量,用于处理不同地区设置下的文本和数值格式。 6. ...
<float.h>和<limits.h>分别提供了浮点数运算和整型取值范围的相关信息。这些信息有助于了解不同类型在程序中的取值范围,以便更好地处理溢出和其他边界条件问题。 <locale.h>提供了本地化支持,通过setlocale函数...
5. `<limits.h>`: 提供了实现定义的整数类型的限制,比如 `CHAR_BIT` 表示一个字节的位数,`INT_MIN` 和 `INT_MAX` 分别是整型的最小值和最大值,这对于了解和处理不同平台上的数据类型边界非常重要。 6. `<locale....
- `<limits.h>`:定义整型数值范围限制。 - `<float.h>`:定义浮点数值范围限制。 - `<time.h>`:时间日期处理函数。 - `<math.h>`:数学函数库。 - `<setjmp.h>`:非局部跳转支持。 - `<signal.h>`:信号处理函数。...
本篇将详细介绍C语言标准库中的一些核心部分及其功能,特别关注于`<assert.h>`、`<ctype.h>`、`<errno.h>`、`<limits.h>`、`<locale.h>`等头文件。 #### 二、<assert.h>:诊断 **定义:** - `<assert.h>`头文件主要...
- `<limits.h>`:整型限制定义,用于了解整型数值范围。 - `<locale.h>`:区域设置函数,用于处理多语言环境。 - `<math.h>`:数学函数,用于高级数学计算。 - `<setjmp.h>`:异常跳转处理,用于异常处理机制。 - `...