C语言整数类型(含取值范围和长度)

C语言支持 5 种带符号的整数类型。其中大多数整数类型具有多个同义词,见表1。

表1:带符号的标准整数类型
类型 同义词
signed char  
int signed, signed int
short short int, signed short, signed short int
long long int, signed long, signed long int
long long (C99) long long int, signed long long,signed long long int

对于表1列出来的 5 种带符号整数类型,它们每个都有对应的无符号类型。与带符号类型相比,对应的无符号类型内存大小相同,对齐方式(alignment)也相同。换句话说,如果编译器将 signed int 对象对齐到偶数地址上,则 unsigned int 对象也对齐到偶数地址。表2列出了无符号类型。

表2:无符号的标准整数类型
类型 同义词
_Bool bool(在 stdbool.h 头文件中定义)
unsigned char  
unsigned int unsigned
unsigned short unsigned short int
unsigned long unsigned long int
unsigned long long unsigned long long int

C99 引入了无符号整数类型 _Bool 用来表示布尔值。布尔值真(true)被定义为 1,假(false)被定义为成 0。如果程序中包含 stdbool.h 头文件,也可以使用标识符 bool、true 以及 false,这是 C++ 程序员相当熟悉的三个关键字。宏 bool 是 _Bool 类型的同义字,但 true 和 false 是符号常量,它们的值分别为 1 和 0。

char 类型也是一个标准的整数类型。但是,仅有一个单词的类型名称 char,既可以是 signed char 的同义词,又可以是 unsigned char 的同义词,这由编译器决定。因为这是由所采用的实现版本自行选择的,所以严格地说,char、signed char和unsigned char 是三种不同的数据类型。

如果程序会用到的 char 值包括小于 0 或大于 127 的情况,则应该使用 signed char 或者 unsigned char,而不是 char。

可以对字符变量做算术操作。由程序自身决定是否将 char 变量的值解释为字符码或其他东西。例如,下面的小程序将属于 char 类型的 ch 变量,既看成一个整数又看成一个字符,不过是在不同时刻:
char ch= 'A';                  // 数据类型为char的变量
printf("The character %c has the character code %d.\n", ch, ch);
for ( ; ch <= 'Z' ; ++ch )
    printf("%2c", ch);
在 printf() 语句中,ch 先被视为一个字符以获得显示,然后被视为该字符的整数编码。同样,for 循环在执行 ++ch 的时候将 ch 视为整数,在执行 printf() 的时候,将 ch 视为字符。在使用 7 位 ASCII 码或者扩展 ASCII 码的系统中,上述程序代码将输出以下内容:

The character A has the character code 65.
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

各种类型的长度和取值范围

char 类型的值占用一个字节(换句话说,sizeof(char)总是等于1),并且 1 个字节至少是 8 位长。基本字符集中的每个字符都可以作为一个正整数值以 char 对象表示。

对于其他标准类型,C语言只定义了其最小的存储空间:
  • short 类型至少占用 2 个字节;
  • long 类型至少占用 4 个字节;
  • 而 long long 类型至少占用 8 个字节。

此外,虽然整数类型实际所占用的空间可能大于它们的最小空间,但是不同类型的空间大小一定遵循以下次序:

sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long)

int 类型是最适应计算机系统架构的整数类型,它具有和 CPU 寄存器相对应的空间大小和位格式。

表3列出了标准整数类型的存储空间大小和值范围。

表3:标准整数类型常见存储空间大小和取值范围
类型 存储空间大小 最小值 最大值
char (与 signed char 或 unsigned char 相同)  
unsigned char 1个字节 0 255
signed char 1个字节 -128 127
int 2个或4个字节 -32 768 或 -2 147 483 648 32767 或 2 147 483 647
unsigned int 2个或4个字节 0 65 535 或 4 294 967 295
short 2个字节 -32 768 32 767
unsigned short 2个字节 0 65 535
long 4个字节 -2 147 483 648 2 147 483 647
unsigned long 4个字节 0 4 294 967 295
long long (C99) 8个字节 -9 223 372 036 854 775 808 9 223 372 036 854 775 807
Unsigned long long (C99) 8个字节 0 18 446 744 073 709 551 615

在下面的示例中,如果系统运行平台是32位,则int类型的iIndex和iLimit变量分别占用4个字节:
int iIndex,         // 定义两个int变量
    iLimit= 1000;        // 初始化第二个
利用 sizeof 运算符,可以获取一个数据类型或变量的空间大小。表达式 sizeof(type)输出指定类型的大小;sizeof expression 输出指定表达式类型的大小。输出结果是类型为 size_t 的一组字节。如果操作数是一个表达式,则输出结果是该表达式的类型。
size_t 类型作为一个无符号整数类型(如 unsigned long)定义在头文件 stddef.h、stdio.h,以及其他头文件中。
在上述示例中,sizeof(int) 的值会和 sizeof(iIndex)一样(都是4)。sizeof(iIndex) 的圆括号可以去掉,因为 iIndex 是一个表达式,不是一个类型。

可以在头文件 limits.h 中找到所采用编译器中整数类型的取值范围,它们定义为宏,例如宏 INT_MIN、INT_MAX 和 UINT_MAX 等。下面的程序使用这些宏来显示 char 和 int 类型的最小值和最大值。

例1:char和int类型的取值范围
#include <rstdio.h>
#include <limits.h>  // 该文件包含了CHAR_MIN、INT_MIN等宏
int main()
{
    printf("Storage sizes and value ranges of the types char and int\n\n");
    printf("The type char is %s.\n\n", CHAR_MIN<0? "signed":"unsigned");

    printf(" Type Size (in bytes)   Minimum             Maximum\n"
        "--------------------------------------------------\n");
    printf("char %8zu %20d %15d\n", sizeof(char), CHAR_MIN, CHAR_MAX );
    printf("int %8zu %20d %15d\n",  sizeof(int), INT_MIN, INT_MAX );
    return 0;
}

在标准头文件中定义的整数类型

标准库的头文件针对特定用途定义了很多整数类型,例如用来显示宽字符的 wchar_t 类型。这些类型是 typedef 名称,它们是标准整数类型的同义词。

类型 ptrdiff_t、size_t 和 wchar_t 定义在头文件 stddef.h 中(以及其他头文件中);类型 char16_t 和 char32_t 定义在头文件 uchar.h 中。为了特殊需要,指定位长度的整数类型(带符号和无符号变量)定义在头文件 stdint.h 中。

此外,头文件 stdint.h 也为标准库中的所有整数类型可显示的最大值与最小值定义了宏。例如,SIZE_MAX 等于可以在 size_t 类型变量中存储的最大值。