文章目录
- 1,精确宽度类型(exact-width integer type)
- 2,最小宽度类型(minimum width type)
- 3,最快的最小宽度类型(fast minimum width type)
- 4,可以保存指针的整数类型。
- 5, 最大宽度整数类型,用于存放最大的整数。
- 6,注意事项
- 7,小结
C 语言的整数类型(short、int、long)是非常灵活的,C语言标准并没有规定整形的长度,在不同计算机上,占用的字节宽度可能是不一样的,例如,int在某些系统上可能是32位,在其他系统上可能是16位。
程序从一台计算机迁移到另一台计算机时,这种灵活性可能导致一迁移失败,比如从32位int计算机迁移到16位int计算机,在新的计算机上,程序可能出现溢出,进而导致异常。
为了解决这个问题,引入了一些可移植的类型定义,这些类型主要定义在stdint.h和inttypes.h这两个头文件中,它们是C99标准引入的。
1,精确宽度类型(exact-width integer type)
这个类型保证某个整数类型的宽度是确定的。
int8_t:8位有符号整数。
int16_t:16位有符号整数。
int32_t:32位有符号整数。
int64_t:64位有符号整数。
uint8_t:8位无符号整数。
uint16_t:16位无符号整数。
uint32_t:32位无符号整数。
uint64_t:64位无符号整数。
注意,上面这些本质上都是类型别名,C语言标准库并没有对应的真正的数据类型,实际上编译器会将它们指向的标准库的类型。
比如,某个系统中:
- 如果int类型为32位,int32_t就会指向int。
- 如果long类型为32位,int32_t则会指向long。
下面是一个使用示例。
#include <stdio.h>
#include <stdint.h>
int main(void) {
int32_t x32 = 45933945;
printf("x32 = %d\n", x32);
return 0;
}
上面示例中,变量x32声明为int32_t类型,可以保证是32位的宽度。
2,最小宽度类型(minimum width type)
顾名思义,使用这种类型可以保证数据在内存中占用的最小字节宽度。
int_least8_t
int_least16_t
int_least32_t
int_least64_t
uint_least8_t
uint_least16_t
uint_least32_t
uint_least64_t
上面这些类型,可以保证占据的字节不少于指定宽度。
比如,int_least8_t表示可以容纳8位有符号整数的最小宽度的类型。
3,最快的最小宽度类型(fast minimum width type)
可以使整数计算达到最快的类型。
int_fast8_t
int_fast16_t
int_fast32_t
int_fast64_t
uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t
上面这些类型是保证字节宽度的同时,追求最快的运算速度,比如int_fast8_t表示对于8位有符号整数,运算速度最快的类型。
这是因为某些机器对于特定宽度的数据,运算速度最快,举例来说,32位计算机对于32位数据的运算速度,会快于16位数据。
4,可以保存指针的整数类型。
intptr_t:可以存储指针(内存地址)的有符号整数类型。
uintptr_t:可以存储指针的无符号整数类型。
5, 最大宽度整数类型,用于存放最大的整数。
intmax_t:可以存储任何有效的有符号整数的类型。
uintmax_t:可以存放任何有效的无符号整数的类型。
上面的这两个类型的宽度比long long和unsigned long更大。
6,注意事项
使用了上述类型后,标准输出时可能出现异常。
inttypes.h还定义了与这些类型相对应的格式化宏,如PRId32用于打印int32_t类型的变量,确保打印函数的正确使用。在进行输入输出操作时,使用对应类型的格式化宏,避免类型不匹配导致的问题。
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main() {
// 定义一个32位有符号整数
int32_t myInt = 123456789;
// 使用对应的格式化宏进行输出
printf("My 32-bit integer: %" PRId32 "\n", myInt);
// 定义一个无符号的16位整数
uint16_t myUnsignedShort = 65535;
// 输出无符号16位整数
printf("My 16-bit unsigned integer: %" PRIu16 "\n", myUnsignedShort);
return 0;
}
在这个示例中,我们定义了两个可移植类型的变量:一个32位有符号整数myInt和一个16位无符号整数myUnsignedShort。
使用PRId32和PRIu16宏来确保在打印这些变量时使用的格式是正确的,无论程序在何种平台上运行。
这样编写代码能最大程度地确保数据处理的一致性和程序的可移植性。
7,小结
使用这些类型时,可以确保程序中的变量在不同平台上具有一致的大小和行为,从而提高了程序的可移植性。
例如,如果你需要一个确切的32位整数,你应该使用int32_t而不是依赖于int,因为int的大小在不同平台和编译器上可能会有所不同。